-
+
diff --git a/docs/components/avatar/examples/AvatarPlaceholderInitialsExample.vue b/docs/components/avatar/examples/AvatarPlaceholderInitialsExample.vue
new file mode 100644
index 0000000..a53b0f4
--- /dev/null
+++ b/docs/components/avatar/examples/AvatarPlaceholderInitialsExample.vue
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/docs/components/avatar/examples/AvatarSizeExample.vue b/docs/components/avatar/examples/AvatarSizeExample.vue
new file mode 100644
index 0000000..cdaf1a6
--- /dev/null
+++ b/docs/components/avatar/examples/AvatarSizeExample.vue
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/docs/components/avatar/examples/StackedAvatarsExample.vue b/docs/components/avatar/examples/StackedAvatarsExample.vue
new file mode 100644
index 0000000..60f25f6
--- /dev/null
+++ b/docs/components/avatar/examples/StackedAvatarsExample.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Avatar/Avatar.vue b/src/components/Avatar/Avatar.vue
index b56b350..1d674fe 100644
--- a/src/components/Avatar/Avatar.vue
+++ b/src/components/Avatar/Avatar.vue
@@ -1,27 +1,30 @@
-
-
+
+
+
![]()
+
diff --git a/src/components/Avatar/StackedAvatars.vue b/src/components/Avatar/StackedAvatars.vue
new file mode 100644
index 0000000..ef4c830
--- /dev/null
+++ b/src/components/Avatar/StackedAvatars.vue
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/components/Avatar/StackedAvatarsCounter.vue b/src/components/Avatar/StackedAvatarsCounter.vue
new file mode 100644
index 0000000..521b367
--- /dev/null
+++ b/src/components/Avatar/StackedAvatarsCounter.vue
@@ -0,0 +1,15 @@
+
+ +{{ total }}
+
+
diff --git a/src/components/Avatar/composables/useAvatarClasses.ts b/src/components/Avatar/composables/useAvatarClasses.ts
new file mode 100644
index 0000000..bfb5619
--- /dev/null
+++ b/src/components/Avatar/composables/useAvatarClasses.ts
@@ -0,0 +1,113 @@
+import { computed } from 'vue'
+import type { Ref } from 'vue'
+import classNames from 'classnames'
+import type { AvatarSize, AvatarStatus, AvatarStatusPosition, AvatarType, avatarDotIndicatorPositionClasses } from '@/components/Avatar/types'
+
+const avatarSizeClasses: Record
= {
+ xs: 'w-6 h-6',
+ sm: 'w-8 h-8',
+ md: 'w-10 h-10',
+ lg: 'w-20 h-20',
+ xl: 'w-36 h-36',
+}
+const avatarTypeClasses: Record = {
+ default: 'rounded',
+ rounded: 'rounded-full',
+}
+const avatarBorderedClasses = 'ring-2 ring-gray-300 dark:ring-gray-500 p-1'
+
+const avatarStatusDotDefaultClasses = 'absolute h-3.5 w-3.5 rounded-full border-2 border-white dark:border-gray-800'
+const avatarStatusDotClasses: Record = {
+ away: 'bg-gray-400',
+ busy: 'bg-yellow-400',
+ offline: 'bg-red-400',
+ online: 'bg-green-400',
+}
+const avatarStatusDotPositionClasses: Record = {
+ 'top-right-rounded': 'top-0 -right-0.5',
+ 'top-right-default': '-top-1.5 -right-1.5',
+ 'top-left-rounded': 'top-0 left-0',
+ 'top-left-default': 'top-0 left-0 transform -translate-y-1/2 -translate-x-1/2',
+ 'bottom-right-rounded': 'bottom-0 -right-0.5',
+ 'bottom-right-default': 'bottom-0 -right-1.5 translate-y-1/2',
+ 'bottom-left-rounded': 'bottom-0 left-0',
+ 'bottom-left-default': '-bottom-1.5 left-0 transform -translate-x-1/2 ',
+}
+
+const avatarPlaceholderDefaultClasses = 'absolute w-auto h-auto text-gray-400'
+const avatarPlaceholderWrapperDefaultClasses = 'inline-flex overflow-hidden relative justify-center items-center bg-gray-100 dark:bg-gray-600'
+const avatarPlaceholderInitialsDefaultClasses = 'font-medium text-gray-600 dark:text-gray-300'
+const avatarPlaceholderSizes = {
+ xs: 'bottom-0',
+ sm: 'bottom-0',
+ md: '-bottom-1',
+ lg: '-bottom-2',
+ xl: '-bottom-4',
+}
+
+export type UseAvatarClassesProps = {
+ status: Ref
+ bordered: Ref
+ img: Ref
+ alt: Ref
+ rounded: Ref
+ size: Ref
+ stacked: Ref
+ statusPosition: Ref
+}
+
+export function useAvatarClasses(props: UseAvatarClassesProps): {
+ avatarClasses: Ref
+ avatarDotClasses: Ref
+ avatarPlaceholderClasses: Ref
+ avatarPlaceholderWrapperClasses: Ref
+ avatarPlaceholderInitialsClasses: Ref
+} {
+
+ const avatarClasses = computed(() => {
+ console.log('border', props.bordered.value)
+ return classNames(
+ avatarSizeClasses[props.size.value],
+ avatarTypeClasses[props.rounded.value ? 'rounded' : 'default'],
+ props.bordered.value ? avatarBorderedClasses : '',
+ props.stacked.value ? 'border-2 border-white dark:border-gray-800' : '',
+ )
+ })
+ const avatarDotClasses = computed(() => {
+ const avatarType = `${props.statusPosition.value}-${props.rounded.value ? 'rounded' : 'default'}`
+ return classNames(
+ avatarStatusDotDefaultClasses,
+ avatarStatusDotClasses[props.status.value],
+ avatarStatusDotPositionClasses[avatarType as avatarDotIndicatorPositionClasses],
+ )
+ })
+ const avatarPlaceholderClasses = computed(() => {
+ return classNames(
+ avatarPlaceholderDefaultClasses,
+ avatarPlaceholderSizes[props.size.value],
+ )
+ })
+ const avatarPlaceholderWrapperClasses = computed(() => {
+ return classNames(
+ avatarPlaceholderWrapperDefaultClasses,
+ avatarSizeClasses[props.size.value],
+ avatarTypeClasses[props.rounded.value ? 'rounded' : 'default'],
+ )
+ })
+ const avatarPlaceholderInitialsClasses = computed(() => {
+ return classNames(
+ avatarPlaceholderInitialsDefaultClasses,
+ )
+ })
+ // TODO: Avatar Initials
+
+ return {
+ avatarClasses,
+ avatarDotClasses,
+ avatarPlaceholderClasses,
+ avatarPlaceholderWrapperClasses,
+ avatarPlaceholderInitialsClasses,
+ }
+}
+
+
diff --git a/src/components/Avatar/types.ts b/src/components/Avatar/types.ts
new file mode 100644
index 0000000..d9903d0
--- /dev/null
+++ b/src/components/Avatar/types.ts
@@ -0,0 +1,5 @@
+export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+export type AvatarStatus = 'away' | 'busy' | 'offline' | 'online'
+export type AvatarStatusPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
+export type AvatarType = 'default' | 'rounded'
+export type avatarDotIndicatorPositionClasses = `${AvatarStatusPosition}-${AvatarType}`
diff --git a/src/index.ts b/src/index.ts
index 64d1910..34a6643 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -7,9 +7,11 @@ export { default as Tab } from './components/Tabs/components/Tab/Tab.vue'
export { default as Dropdown } from './components/Dropdown/Dropdown.vue'
export { default as FlowbiteThemable } from './components/utils/FlowbiteThemable/FlowbiteThemable.vue'
export { default as FlowbiteThemableChild } from './components/utils/FlowbiteThemable/components/FlowbiteThemableChild/FlowbiteThemableChild.vue'
-
-export { default as Accordion } from './components/Accordion/Accordion.vue'
export { default as Avatar } from './components/Avatar/Avatar.vue'
+export { default as StackedAvatars } from './components/Avatar/StackedAvatars.vue'
+export { default as StackedAvatarsCounter } from './components/Avatar/StackedAvatarsCounter.vue'
+export { default as Accordion } from './components/Accordion/Accordion.vue'
+
export { default as Badge } from './components/Badge/Badge.vue'
export { default as Breadcrumb } from './components/Breadcrumb/Breadcrumb.vue'
export { default as Card } from './components/Card/Card.vue'