diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index d81f580..f1b615d 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -35,6 +35,7 @@ function buildSidebar() { function getComponents() { return [ { text: 'Alert', link: '/components/alert/alert.md' }, + { text: 'Avatar', link: 'components/avatar/avatar.md' }, { text: 'Button', link: '/components/button/button.md' }, { text: 'Button Group', link: '/components/buttonGroup/buttonGroup.md' }, { text: 'Dropdown', link: '/components/dropdown/dropdown.md' }, @@ -44,7 +45,6 @@ function getComponents() { { text: 'Toast', link: 'components/toast/toast.md' }, { text: '- Accordion', link: 'components/accordion/accordion.md' }, - { text: '- Avatar', link: 'components/avatar/avatar.md' }, { text: '- Badge', link: 'components/badge/badge.md' }, { text: '- Breadcrumb', link: 'components/breadcrumb/breadcrumb.md' }, { text: '- Card', link: 'components/card/card.md' }, diff --git a/docs/components/avatar/avatar.md b/docs/components/avatar/avatar.md index 63b1c84..2ef1033 100644 --- a/docs/components/avatar/avatar.md +++ b/docs/components/avatar/avatar.md @@ -1,15 +1,102 @@ # Avatar +Use the avatar component to show a visual representation of a user profile using an image element or SVG object based on multiple styles and sizes + +## Default avatar +Use this example to create a circle and rounded avatar on an image element. + + ```vue ``` - +## Bordered +Use this example to create a circle and rounded avatar on an image element. + + + +```vue + + +``` + +## Dot indicator + + + +```vue + + +``` + +## Sizes + + + +```vue + + +``` + +## Dot indicator position + + + +```vue + + +``` diff --git a/docs/components/avatar/examples/AvatarBorderedExample.vue b/docs/components/avatar/examples/AvatarBorderedExample.vue new file mode 100644 index 0000000..1de342b --- /dev/null +++ b/docs/components/avatar/examples/AvatarBorderedExample.vue @@ -0,0 +1,9 @@ + + diff --git a/docs/components/avatar/examples/AvatarDotIndicatorExample.vue b/docs/components/avatar/examples/AvatarDotIndicatorExample.vue new file mode 100644 index 0000000..ca877c0 --- /dev/null +++ b/docs/components/avatar/examples/AvatarDotIndicatorExample.vue @@ -0,0 +1,11 @@ + + diff --git a/docs/components/avatar/examples/AvatarDotIndicatorPositionExample.vue b/docs/components/avatar/examples/AvatarDotIndicatorPositionExample.vue new file mode 100644 index 0000000..5deae90 --- /dev/null +++ b/docs/components/avatar/examples/AvatarDotIndicatorPositionExample.vue @@ -0,0 +1,15 @@ + + diff --git a/docs/components/avatar/examples/AvatarExample.vue b/docs/components/avatar/examples/AvatarExample.vue index 316eb82..a0705b8 100644 --- a/docs/components/avatar/examples/AvatarExample.vue +++ b/docs/components/avatar/examples/AvatarExample.vue @@ -1,6 +1,7 @@ diff --git a/src/components/Avatar/Avatar.vue b/src/components/Avatar/Avatar.vue index b56b350..3826820 100644 --- a/src/components/Avatar/Avatar.vue +++ b/src/components/Avatar/Avatar.vue @@ -1,27 +1,24 @@ diff --git a/src/components/Avatar/composables/useAvatarClasses.ts b/src/components/Avatar/composables/useAvatarClasses.ts new file mode 100644 index 0000000..6766ab6 --- /dev/null +++ b/src/components/Avatar/composables/useAvatarClasses.ts @@ -0,0 +1,79 @@ +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 ', +} + +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 +} { + + 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 : '', + ) + }) + const avatarDotClasses = computed(() => { + const avatarType = `${props.statusPosition.value}-${props.rounded.value ? 'rounded' : 'default'}` + return classNames( + avatarStatusDotDefaultClasses, + avatarStatusDotClasses[props.status.value], + avatarStatusDotPositionClasses[avatarType as avatarDotIndicatorPositionClasses], + ) + }) + // TODO: Placeholder + // TODO: Stacked avatars + // TODO: Avatar Initials + + return { + avatarClasses, + avatarDotClasses, + } +} + + diff --git a/src/components/Avatar/types.ts b/src/components/Avatar/types.ts index 3c75a55..d9903d0 100644 --- a/src/components/Avatar/types.ts +++ b/src/components/Avatar/types.ts @@ -1,3 +1,5 @@ export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' export type AvatarStatus = 'away' | 'busy' | 'offline' | 'online' -export type AvatarStatusPosition = 'bottom-left' | 'bottom-right' | 'bottom-center' | 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' +export type AvatarStatusPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' +export type AvatarType = 'default' | 'rounded' +export type avatarDotIndicatorPositionClasses = `${AvatarStatusPosition}-${AvatarType}`