import type { Meta, StoryObj } from '@storybook/nextjs-vite' import { expect, fn } from 'storybook/test' import { IconButton } from './IconButton' import { iconButtonIconNames, IconButtonProps } from './types' import { config } from './variants' const meta: Meta = { title: 'Core Components/IconButton', component: IconButton, argTypes: { onPress: { table: { type: { summary: 'function' }, defaultValue: { summary: 'undefined' }, }, description: 'Callback function to handle button press events.', }, variant: { control: 'select', options: Object.keys(config.variants.variant), table: { defaultValue: { summary: config.defaultVariants.variant, }, type: { summary: Object.keys(config.variants.variant).join(' | '), }, }, }, size: { control: 'select', options: Object.keys(config.variants.size), table: { defaultValue: { summary: config.defaultVariants.size, }, type: { summary: Object.keys(config.variants.size).join(' | '), }, }, description: 'The size of the `IconButton`. Please note that you control the size of the icon inside the button separately. Please check the examples below for recommended icon sizes for each button size.', }, emphasis: { control: 'boolean', options: Object.keys(config.variants.emphasis), table: { defaultValue: { summary: config.defaultVariants.emphasis.toString(), }, type: { summary: 'boolean', }, }, }, iconName: { control: 'select', options: iconButtonIconNames, table: { type: { summary: iconButtonIconNames.join(' | ') }, defaultValue: { summary: 'undefined' }, }, description: 'Name of the Material Icon to use as icon.', }, isDisabled: { control: 'boolean', table: { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, }, }, }, } const globalStoryPropsInverted = { backgrounds: { value: 'scandicPrimaryDark' }, } export default meta type Story = StoryObj function renderAllSizesFn( args: Story['args'], iconName: IconButtonProps['iconName'] = 'search' ) { return (
{Object.keys(config.variants.size).map((size) => (
{size}
))}
) } export const Default: Story = { args: { onPress: fn(), iconName: 'search', }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const Examples: Story = { render: () => { return (

Filled

{renderAllSizesFn({ ...Default.args, variant: 'Filled' })}

Filled with emphasis

{renderAllSizesFn( { ...Default.args, variant: 'Filled', emphasis: true, }, 'arrow_forward' )}

Outlined

{renderAllSizesFn( { ...Default.args, variant: 'Outlined', }, 'arrow_forward' )}

Elevated

{renderAllSizesFn( { ...Default.args, variant: 'Elevated', }, 'arrow_forward' )}

Faded

{renderAllSizesFn( { ...Default.args, variant: 'Faded', }, 'arrow_forward' )}

Muted

{renderAllSizesFn( { ...Default.args, variant: 'Muted', }, 'arrow_forward' )}

Muted with emphasis

{renderAllSizesFn( { ...Default.args, variant: 'Muted', emphasis: true, }, 'arrow_forward' )}
) }, } export const Filled: Story = { args: { ...Default.args, variant: 'Filled', }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const FilledDisabled: Story = { args: { ...Filled.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, } export const FilledOnDarkBackground: Story = { globals: globalStoryPropsInverted, args: { ...Filled.args, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const FilledWithEmphasis: Story = { args: { ...Filled.args, iconName: 'arrow_forward', emphasis: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const FilledWithEmphasisDisabled: Story = { args: { ...FilledWithEmphasis.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, } export const Outlined: Story = { args: { ...Default.args, iconName: 'arrow_forward', variant: 'Outlined', }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const OutlinedDisabled: Story = { args: { ...Outlined.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, } export const Elevated: Story = { args: { ...Default.args, iconName: 'arrow_forward', variant: 'Elevated', }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const ElevatedDisabled: Story = { args: { ...Elevated.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, } export const Faded: Story = { globals: globalStoryPropsInverted, args: { ...Default.args, iconName: 'arrow_forward', variant: 'Faded', }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const FadedDisabled: Story = { globals: globalStoryPropsInverted, args: { ...Faded.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, } export const Muted: Story = { globals: globalStoryPropsInverted, args: { ...Default.args, iconName: 'arrow_forward', variant: 'Muted', }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const MutedDisabled: Story = { globals: globalStoryPropsInverted, args: { ...Muted.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, } export const MutedWithEmphasis: Story = { args: { ...Muted.args, emphasis: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(1) }, } export const MutedWithEmphasisDisabled: Story = { args: { ...MutedWithEmphasis.args, isDisabled: true, }, play: async ({ canvas, userEvent, args }) => { await userEvent.click(canvas.getByRole('button')) expect(args.onPress).toHaveBeenCalledTimes(0) }, }