diff --git a/src/elements/Avatar/Avatar.story.tsx b/src/elements/Avatar/Avatar.story.tsx index 74359b57..4f5dbf56 100644 --- a/src/elements/Avatar/Avatar.story.tsx +++ b/src/elements/Avatar/Avatar.story.tsx @@ -6,47 +6,79 @@ export default { title: 'Components/Elements/Avatar', component: Avatar } as Meta; +const ComponentsBlock = args => ( +
+
+ + Active +
+
+ + Disabled +
+
+); -const Template = args => ; - -export const Simple = Template.bind({}); -Simple.args = { +export const Outline = args => ; +Outline.args = { name: 'John Doe', size: 50, - rounded: false + variant: 'outline', + type: 'monochrome' }; -export const Outline = Template.bind({}); -Outline.args = { +export const Filled = args => ; +Filled.args = { name: 'John Doe', size: 50, - rounded: false, - variant: 'outline' + variant: 'filled', + type: 'monochrome' }; -export const RoundedWithImage = Template.bind({}); -RoundedWithImage.args = { - src: 'https://goodcode.us/static/austin-d1a2c5249336c31662b8ee6d4e169b2b.jpg', +export const Colored = args => ; +Colored.args = { + name: 'John Doe', size: 50, - rounded: true + variant: 'filled', + type: 'colored' }; - -export const LargeRounded = Template.bind({}); -LargeRounded.args = { - name: 'John Doe', - size: 100, - rounded: true +export const Image = args => ; +Image.args = { + src: 'https://goodcode.us/static/austin-d1a2c5249336c31662b8ee6d4e169b2b.jpg', + size: 50 }; -export const MultipleAvatars = args => ( +export const Sizes = args => (
- - - console.log('here')} /> + + +
); - -MultipleAvatars.args = { - size: 50, - rounded: true +Sizes.args = { + src: 'https://goodcode.us/static/austin-d1a2c5249336c31662b8ee6d4e169b2b.jpg' }; diff --git a/src/elements/Avatar/Avatar.tsx b/src/elements/Avatar/Avatar.tsx index 1e2e8999..796d408c 100644 --- a/src/elements/Avatar/Avatar.tsx +++ b/src/elements/Avatar/Avatar.tsx @@ -1,8 +1,7 @@ import React, { FC, LegacyRef, forwardRef, useMemo } from 'react'; import getInitials from 'name-initials'; import { generateColor } from '@marko19907/string-to-color'; -import { twMerge } from 'tailwind-merge'; -import { useComponentTheme } from '@/utils'; +import { cn, useComponentTheme } from '@/utils'; import { AvatarTheme } from './AvatarTheme'; export interface AvatarProps extends React.HTMLAttributes { @@ -26,6 +25,11 @@ export interface AvatarProps extends React.HTMLAttributes { */ variant?: 'filled' | 'outline'; + /** + * Style type for the avatar. + */ + type?: 'colored' | 'monochrome'; + /** * Whether the avatar is rounded. */ @@ -36,6 +40,16 @@ export interface AvatarProps extends React.HTMLAttributes { */ color?: string; + /** + * Whether the avatar is disabled. + */ + disabled?: boolean; + + /** + * Whether the avatar is able to interact. + */ + interactable?: boolean; + /** * Custom color options for the color generator. */ @@ -69,9 +83,12 @@ export const Avatar: FC & AvatarRef = forwardRef< color, size = 24, variant = 'filled', + type = 'colored', rounded = true, className, colorOptions, + disabled, + interactable, theme: customTheme, ...rest }, @@ -94,22 +111,34 @@ export const Avatar: FC & AvatarRef = forwardRef< }, [color, name, src, colorOptions]); const theme: AvatarTheme = useComponentTheme('avatar', customTheme); + const themeVariant = src ? 'outline' : variant; return (
diff --git a/src/elements/Avatar/AvatarTheme.ts b/src/elements/Avatar/AvatarTheme.ts index d57a44d1..4e0a8d78 100644 --- a/src/elements/Avatar/AvatarTheme.ts +++ b/src/elements/Avatar/AvatarTheme.ts @@ -1,16 +1,121 @@ export interface AvatarTheme { base: string; rounded: string; + outline: { + base: string; + disabled: string; + focused: string; + hovered: string; + }; + filled: { + base: string; + disabled: string; + focused: string; + hovered: string; + }; + colored: { + base: string; + disabled: string; + focused: string; + hovered: string; + }; + monochrome: { + base: string; + disabled: string; + focused: string; + hovered: string; + }; + disabled: string; } const baseTheme: AvatarTheme = { - base: 'flex justify-center items-center bg-cover bg-center font-bold', - rounded: 'rounded-[50%]' + base: 'flex justify-center items-center bg-cover bg-center font-bold transition-[border-color] ease-in-out duration-300', + rounded: 'rounded-[50%]', + outline: { + base: 'border border-solid', + focused: '', + hovered: '', + disabled: '' + }, + filled: { + base: 'border border-solid border-transparent', + focused: '', + hovered: '', + disabled: '' + }, + colored: { + base: '', + focused: '', + hovered: '', + disabled: '' + }, + monochrome: { + base: '', + focused: '', + hovered: '', + disabled: '' + }, + disabled: 'border border-solid' }; export const avatarTheme: AvatarTheme = { ...baseTheme, - base: [baseTheme.base, 'text-white'].join(' ') + base: [ + baseTheme.base, + 'text-waterloo text-gray-400 light:text-gray-600 focus:outline-none' + ].join(' '), + outline: { + base: [ + baseTheme.outline.base, + 'bg-black border-gray-700 light:border-gray-200 light:bg-gray-100' + ].join(' '), + hovered: [ + baseTheme.outline.hovered, + 'hover:border-primary-hover light:hover:border-primary-hover' + ].join(' '), + focused: [ + baseTheme.outline.focused, + 'focus:border-primary-active light:focus:border-primary-active' + ].join(' '), + disabled: [ + baseTheme.outline.disabled, + 'text-gray-300/40 light:bg-gray-100 light:border-gray-400' + ].join(' ') + }, + filled: { + base: [baseTheme.filled.base, 'bg-gray-700 light:bg-gray-200'].join(' '), + hovered: [ + baseTheme.outline.hovered, + 'hover:border-primary-hover light:hover:border-primary-hover' + ].join(' '), + focused: [ + baseTheme.outline.focused, + 'focus:border-primary-active light:focus:border-primary-active' + ].join(' '), + disabled: [ + baseTheme.filled.disabled, + 'bg-gray-600 light:bg-gray-100 light:border-gray-100 text-gray-300/40' + ].join(' ') + }, + colored: { + base: [baseTheme.colored.base, 'text-white light:text-white'].join(' '), + hovered: [ + baseTheme.outline.hovered, + 'hover:border-primary-hover light:hover:border-primary-hover' + ].join(' '), + focused: [ + baseTheme.outline.focused, + 'focus:border-primary-active light:focus:border-primary-active' + ].join(' '), + disabled: [ + baseTheme.colored.disabled, + 'bg-gray-600 light:bg-gray-100 light:border-gray-100 text-gray-300/40' + ].join(' ') + }, + disabled: [ + baseTheme.disabled, + 'cursor-not-allowed border-gray-600 light:border-gray-400 light:text-gray-400' + ].join(' ') }; export const legacyAvatarTheme: AvatarTheme = {