import { Meta, StoryObj } from '@storybook/react-webpack5';
import { Leaf, Taxi } from '@transferwise/icons';
import { lorem10 } from '../../test-utils';
import { ProfileType } from '../../common';
import List from '../../list';
import { ListItem } from '../ListItem';
import {
SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
SB_LIST_ITEM_CONTROLS as CONTROLS,
} from '../_stories/subcomponents';
import { disableControls } from '../_stories/helpers';
import type { ListItemAvatarViewProps } from './ListItemAvatarView';
const hideControls = disableControls(['badge', 'children']);
const SIZES = [24, 32, 40, 48, 56, 72] as const;
const BADGES = {
'Country flag badge': { flagCode: 'GBP' },
'StatusIcon badge': { status: 'warning' },
'Icon badge': { icon: },
'Default action badge': {
type: 'action',
},
'Default reference badge': {
type: 'reference',
},
'Action badge with custom icon': {
type: 'action',
icon: ,
},
'Reference badge with custom icon': {
type: 'reference',
icon: ,
},
'Custom badge': {
asset: (
),
},
'Notification badge': { type: 'notification' },
'Online badge': { type: 'online' },
} as const;
export default {
component: ListItem.AvatarView,
title: 'Content/ListItem/ListItem.AvatarView',
args: {
size: 48,
selected: false,
badge: { type: 'action' },
profileName: undefined,
profileType: undefined,
imgSrc: undefined,
},
argTypes: {
size: {
control: 'select',
options: SIZES,
description: 'Size of the avatar',
},
profileName: {
control: 'text',
description: 'Name used to generate initials when no image or icon is provided',
},
imgSrc: {
control: 'text',
description: 'URL of the profile image',
},
profileType: {
control: 'select',
options: [ProfileType.PERSONAL, ProfileType.BUSINESS],
description: 'Type of profile for default icons',
table: {
type: { summary: 'ProfileType' },
},
},
badge: {
control: 'select',
options: ['action', 'notification', 'online'],
description: 'Badge type',
mapping: {
action: { type: 'action' },
notification: { type: 'notification' },
online: { type: 'online' },
},
table: {
type: { summary: 'AvatarViewBadgeProps' },
},
},
selected: {
control: 'boolean',
description: 'Toggles selected state',
},
children: {
table: {
type: { summary: 'ReactNode' },
},
},
style: {
table: {
disable: true,
},
},
},
} satisfies Meta;
type Story = StoryObj;
export const Playground: Story = {
render: (args: ListItemAvatarViewProps) => {
return (
}
control={CONTROLS.iconButton}
additionalInfo={INFO.nonInteractive}
/>
);
},
};
/**
* AvatarView can display different types of content including icons, profile images, and initials.
* Refer to the [design documentation](https://wise.design/components/avatar#:~:text=56%2C%20%E2%80%A8and%2072.-,Media,-There%20are%204) for details.
*/
export const ContentTypes: Story = {
args: {
badge: undefined,
},
argTypes: hideControls(['profileName', 'imgSrc', 'profileType']),
parameters: {
docs: {
canvas: {
sourceState: 'hidden',
},
},
},
render: (args) => {
return (
}
control={CONTROLS.iconButton}
/>
}
control={CONTROLS.iconButton}
/>
}
control={CONTROLS.iconButton}
/>
}
control={CONTROLS.iconButton}
/>
}
control={CONTROLS.iconButton}
/>
);
},
};
/**
* AvatarView supports 6 sizes to fit different list item contexts: `24`, `32`, `40`, `48`, `56`, `72`. If decorated with a Badge, those will be sized accordingly as well.
* Please refer to the [design documentation](https://wise.design/components/list-item#avatar:~:text=of%20the%20avatar.-,Avatar%20sizes,-List%20item%20supports) for details on when to use which one.
*/
export const Sizes: Story = {
parameters: {
docs: {
canvas: {
sourceState: 'hidden',
},
},
},
argTypes: hideControls(['profileName', 'imgSrc', 'profileType', 'size']),
render: (args) => {
return (
{SIZES.map((size) => (
}
control={CONTROLS.iconButton}
/>
))}
);
},
};
/**
* AvatarView supports different types of badges for additional context and information.
* Refer to the [design documentation](https://wise.design/components/avatar#:~:text=support%20the%20information.-,With%20badge,-Badges%20contain%20additional) for details.
*/
export const Badges: Story = {
args: {
imgSrc: '../avatar-square-dude.webp',
},
argTypes: hideControls([
'profileName',
'imgSrc',
'profileType',
'notification',
'dot',
'selected',
]),
parameters: {
docs: {
canvas: {
sourceState: 'hidden',
},
},
},
render: (args) => {
return (
{Object.entries(BADGES).map(([title, badge]) => (
}
control={CONTROLS.iconButton}
/>
))}
);
},
};
/**
* `notification` is a particular `type` of Badge that appears in the top right corner as a red dot. It also adjusts to the Avatar's size.
* **NB:** You can only choose one badge at a time, so the notification badge cannot be combined with any other badge type.
*/
export const Notification: Story = {
parameters: {
docs: {
canvas: {
sourceState: 'hidden',
},
},
},
args: {
badge: undefined,
},
argTypes: hideControls([
'profileName',
'imgSrc',
'profileType',
'size',
'notification',
'dot',
'selected',
]),
render: (args) => {
return (
{SIZES.map((size) => (
}
control={CONTROLS.iconButton}
/>
))}
);
},
};
/**
* Similarly, Badge also has an `online` `type` which is green and also adjusts to the Avatar's size.
* **NB:** You can only choose one badge at a time, so the online badge cannot be combined with any other badge type.
*/
export const Online: Story = {
tags: ['new'],
parameters: {
docs: {
canvas: {
sourceState: 'hidden',
},
},
},
args: {
badge: undefined,
},
argTypes: hideControls([
'profileName',
'imgSrc',
'profileType',
'size',
'notification',
'selected',
]),
render: (args) => {
return (
{SIZES.map((size) => (
}
control={CONTROLS.iconButton}
/>
))}
);
},
};
/**
* AvatarView supports selected state for interactive contexts.
*/
export const Selected: Story = {
argTypes: hideControls([
'profileName',
'imgSrc',
'profileType',
'notification',
'dot',
'selected',
]),
render: (args) => {
return (
}
control={CONTROLS.iconButton}
/>
);
},
};