import { Meta, StoryObj } from '@storybook/react-webpack5'; import ListItem from '..'; import { Edit } from '@transferwise/icons'; import { fn } from 'storybook/test'; import List from '../../list'; import { SB_LIST_ITEM_ADDITIONAL_INFO as INFO, SB_LIST_ITEM_MEDIA as MEDIA, SB_LIST_ITEM_PROMPTS as PROMPTS, } from '../_stories/subcomponents'; import { disableControls } from '../_stories/helpers'; import type { ListItemIconButtonProps } from './ListItemIconButton'; const hideControls = disableControls([ 'onClick', 'children', 'className', 'addonStart', 'addonEnd', ]); /** * Use IconButton to provide compact action controls within a ListItem context using iconography. * * Refer to the [design documentation](https://wise.design/components/list-item) for more details. */ const meta: Meta = { component: ListItem.IconButton, title: 'Content/ListItem/ListItem.IconButton', args: { partiallyInteractive: false, priority: undefined, type: undefined, 'aria-label': 'Edit details', children: , href: undefined, target: undefined, onClick: fn(), }, argTypes: { children: { description: 'Once of the [Icon components](https://transferwise.github.io/icons/).', table: { type: { summary: 'ReactNode' }, }, control: false, }, priority: { control: 'radio', options: ['unset (undefined)', 'primary', 'secondary', 'tertiary', 'minimal'], mapping: { 'unset (undefined)': undefined, }, description: 'IconButton priority/style variant', }, type: { control: 'radio', options: ['unset (undefined)', 'default', 'negative'], mapping: { 'unset (undefined)': undefined, }, description: 'Sets a visual hierarchy amongst the buttons displayed on the screen.
**NB:** `negative` sentiment only affects the `primary` and `secondary` priorities.', }, partiallyInteractive: { control: 'boolean', description: 'Whether the icon button allows partial interactivity in the ListItem', }, href: { control: 'text', description: 'URL for icon button rendered as link', }, target: { control: 'select', options: [undefined, '_blank', '_self', '_parent', '_top'], description: 'The `target` attribute for HTML anchor. If set to `_blank`, `rel="noopener noreferrer"` is automatically added to the rendered node.', }, }, } satisfies Meta; export default meta; type Story = StoryObj; export const Playground: Story = { render: (args: ListItemIconButtonProps) => { return ( } additionalInfo={INFO.nonInteractive} /> ); }, }; /** * It's strongly encouraged to provide `aria-label` prop for the `IconButton` control to ensure it * follows accessibility best practices. * If not set, the component will provide accessible name via the `title`, `subtitle`, `valueTitle` * and `valueSubtitle` props and accessible description via `additionalInfo` and `prompt`, which * may not be descriptive enough for the screen readers users. */ export const AccessibleName: Story = { args: { children: , href: 'https://wise.com', target: '_blank', onClick: undefined, }, argTypes: hideControls(), render: (args: ListItemIconButtonProps) => { return ( } title="List item with icon button link" subtitle="IconButton rendered as anchor element" media={MEDIA.avatarSingle} /> ); }, }; /** * By default, ListItem is fully interactive, which means its whole surface is clickable * and triggers the control. To remain WCAG-compliant there can be no nested interactive * elements inside the item.
* * To work around this limitation, this control also allows for a partially interactive mode, * which can be enabled via `partiallyInteractive` prop. Once set, only the control will * remain interactive, which allows for interactive element to be attached to the * `ListItem.AdditionalInfo`. This allows for more complex layouts while still providing a * clear, accessible action point for users.
* * If you still require a fully interactive ListItem, you can alternatively use `ListItem.Prompt` * which allows for a single instance of a link or an inline button. * * Refer to the [design documentation](https://wise.design/components/list-item#interaction) for details. */ export const Interactivity: Story = { args: { children: , }, argTypes: hideControls(['partiallyInteractive']), render: (args: ListItemIconButtonProps) => { return ( } title="Fully interactive ListItem" subtitle="IconButton in fully interactive context" media={MEDIA.avatarSingle} additionalInfo={INFO.nonInteractive} prompt={PROMPTS.interactive} /> } title="Partially interactive ListItem" subtitle="IconButton in partially interactive context" media={MEDIA.avatarSingle} additionalInfo={INFO.interactive} prompt={PROMPTS.interactive} /> ); }, }; /** * There are two different types of icon button – default and negative – designed to emphasise the nature of the action.
* **NB:** Sentiment only applies to `primary` and `secondary` priorities.
* [Design documentation](https://wise.design/components/icon-button#types) */ export const Sentiment: Story = { argTypes: hideControls(['sentiment', 'priority']), render: (args) => { return ( } title="Default Sentiment - Primary" subtitle="Default sentiment with primary priority" media={MEDIA.avatarSingle} /> } title="Default Sentiment - Secondary" subtitle="Default sentiment with secondary priority" media={MEDIA.avatarSingle} /> } title="Negative Sentiment - Primary" subtitle="Negative sentiment with primary priority" media={MEDIA.avatarSingle} /> } title="Negative Sentiment - Secondary" subtitle="Negative sentiment with secondary priority" media={MEDIA.avatarSingle} /> ); }, }; /** * Priorities set a visual hierarchy amongst the buttons displayed on the * screen to help more important buttons to take precedence over others.
* [Design documentation](https://wise.design/components/icon-button#priorities) */ export const Priority: Story = { argTypes: hideControls(['sentiment', 'priority']), render: (args) => { return ( } /> } /> } /> } /> ); }, }; /** * If `href` prop is set, the component will be automatically rendered as an HTML anchor element. */ export const AsAnchor: Story = { args: { children: , href: 'https://wise.com', target: '_blank', onClick: undefined, }, argTypes: hideControls(), render: (args: ListItemIconButtonProps) => { return ( } title="List item with icon button link" subtitle="IconButton rendered as anchor element" media={MEDIA.avatarSingle} /> ); }, };