Skip to content

Commit

Permalink
Avatar component styling
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgeniy committed May 13, 2024
1 parent ac3d512 commit 3e0ae8f
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 52 deletions.
4 changes: 2 additions & 2 deletions .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
--color-layer-transparent: rgba(0, 0, 0, 0.5);

&.light {
background: #E6E6F0;
background: #FFFFFF;
color: #000000;
--body-color: #000000;
}
Expand All @@ -39,7 +39,7 @@

.light .sb-show-main.sb-main-centered {
color: #11111F;
background: #E6E6F0;
background: #FFFFFF;
}

.dark .sb-show-main.sb-main-centered {
Expand Down
82 changes: 55 additions & 27 deletions src/elements/Avatar/Avatar.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,75 @@ export default {
title: 'Components/Elements/Avatar',
component: Avatar
} as Meta;
const ComponentsBlock = args => (
<div
style={{
display: 'flex',
gap: '1em',
flexDirection: 'column',
alignItems: 'start'
}}
>
<div
style={{
display: 'flex',
gap: '1em',
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center'
}}
>
<Avatar {...args} interactable tabIndex={1} />
<span>Active</span>
</div>
<div
style={{
display: 'flex',
gap: '1em',
flexDirection: 'row',
justifyContent: 'start',
alignItems: 'center'
}}
>
<Avatar {...args} disabled />
<span>Disabled</span>
</div>
</div>
);

const Template = args => <Avatar {...args} />;

export const Default = Template.bind({});
Default.args = {
name: 'John Doe',
size: 50,
rounded: false
};

export const Outline = Template.bind({});
export const Outline = args => <ComponentsBlock {...args} />;
Outline.args = {
name: 'John Doe',
size: 50,
rounded: false,
variant: 'outline'
};

export const RoundedWithImage = Template.bind({});
RoundedWithImage.args = {
src: 'https://goodcode.us/static/austin-d1a2c5249336c31662b8ee6d4e169b2b.jpg',
export const Filled = args => <ComponentsBlock {...args} />;
Filled.args = {
name: 'John Doe',
size: 50,
rounded: true
variant: 'filled'
};

export const LargeRounded = Template.bind({});
LargeRounded.args = {
export const Colored = args => <ComponentsBlock {...args} />;
Colored.args = {
name: 'John Doe',
size: 100,
rounded: true
size: 50,
variant: 'colored'
};
export const Image = args => <ComponentsBlock {...args} />;
Image.args = {
src: 'https://goodcode.us/static/austin-d1a2c5249336c31662b8ee6d4e169b2b.jpg',
size: 50
};

export const MultipleAvatars = args => (
export const Sizes = args => (
<div style={{ display: 'flex', gap: '1em' }}>
<Avatar {...args} name="Alice" />
<Avatar {...args} name="Bob Meyer Bogger" />
<Avatar {...args} name="Charlie" onClick={() => console.log('here')} />
<Avatar {...args} size={50} />
<Avatar {...args} size={75} />
<Avatar {...args} size={100} />
</div>
);

MultipleAvatars.args = {
size: 50,
rounded: true
Sizes.args = {
src: 'https://goodcode.us/static/austin-d1a2c5249336c31662b8ee6d4e169b2b.jpg'
};
42 changes: 31 additions & 11 deletions src/elements/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { 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<HTMLDivElement> {
Expand All @@ -24,7 +23,7 @@ export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Style variant for the avatar.
*/
variant?: 'filled' | 'outline';
variant?: 'filled' | 'outline' | 'colored';

/**
* Whether the avatar is rounded.
Expand All @@ -33,9 +32,20 @@ export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement> {

/**
* Color override for the avatar.
* @deprecated
*/
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.
*/
Expand All @@ -58,10 +68,12 @@ export const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(
src,
color,
size = 24,
variant = 'filled',
variant = 'colored',
rounded = true,
className,
colorOptions,
disabled,
interactable,
theme: customTheme,
...rest
},
Expand All @@ -84,22 +96,30 @@ export const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(
}, [color, name, src, colorOptions]);

const theme: AvatarTheme = useComponentTheme('avatar', customTheme);
const themeVariant = src ? 'outline' : variant;

return (
<div
{...rest}
className={twMerge(theme.base, rounded && theme.rounded, className)}
className={cn(
theme.base,
theme[themeVariant].base,
{
'cursor-pointer': interactable,
[theme.rounded]: rounded,
[theme.disabled]: disabled,
[theme[themeVariant].focused]: interactable,
[theme[themeVariant].hovered]: interactable,
[theme[themeVariant].disabled]: disabled
},
className
)}
style={{
width: `${size}px`,
height: `${size}px`,
fontSize: `${fontSize}px`,
backgroundImage: src ? `url(${src})` : 'none',
backgroundColor,
...(variant === 'outline' && {
backgroundColor: 'transparent',
border: `solid 1px ${backgroundColor}`,
color: backgroundColor
})
...(variant === 'colored' && !disabled ? { backgroundColor } : {})
}}
ref={ref}
>
Expand Down
99 changes: 97 additions & 2 deletions src/elements/Avatar/AvatarTheme.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,111 @@
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;
};
disabled: string;
}

const baseTheme: AvatarTheme = {
base: 'flex justify-center items-center bg-cover bg-center font-bold',
rounded: 'rounded-[50%]'
rounded: 'rounded-[50%]',
outline: {
base: 'border border-solid',
focused: '',
hovered: '',
disabled: ''
},
filled: {
base: 'border border-solid border-transparent',
focused: '',
hovered: '',
disabled: ''
},
colored: {
base: 'border border-solid border-transparent',
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(' '),
focused: [
baseTheme.outline.focused,
'hover:border-blue-400 light:hover:border-blue-400'
].join(' '),
hovered: [
baseTheme.outline.hovered,
'focus:border-blue-500 light:focus:border-blue-500'
].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(' '),
focused: [
baseTheme.outline.focused,
'hover:border-blue-400 light:hover:border-blue-400'
].join(' '),
hovered: [
baseTheme.outline.hovered,
'focus:border-blue-500 light:focus:border-blue-500'
].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-secondary light:text-gray-100'].join(
' '
),
focused: [
baseTheme.outline.focused,
'hover:border-blue-400 light:hover:border-blue-400'
].join(' '),
hovered: [
baseTheme.outline.hovered,
'focus:border-blue-500 light:focus:border-blue-500'
].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 = {
Expand Down
20 changes: 10 additions & 10 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ export const colorPalette = {
white: '#FFFFFF',
black: '#000000',
gray: {
100: '#F2F3F7',
200: '#E2E2EA',
300: '#C6CBD9',
400: '#9A9AAF',
500: '#7E7E8F',
600: '#656575',
700: '#535362',
800: '#2E2E3A',
900: '#262631',
950: '#16161E'
100: '#F7F7FA',
200: '#E6E6F0',
300: '#C9C9D6',
400: '#77778C',
500: '#5C5C73',
600: '#3D3D4D',
700: '#242433',
800: '#1E1E2E',
900: '#11111F',
950: '#02020F'
},
magenta: {
100: '#FAE5F6',
Expand Down

0 comments on commit 3e0ae8f

Please sign in to comment.