import type { Meta, StoryObj } from '@storybook/nextjs-vite' import { expect, fn } from 'storybook/test' import { MaterialIcon, MaterialIconProps } from '../Icons/MaterialIcon' import { IconButton } from './IconButton' import { config } from './variants' const meta: Meta = { title: 'Core Components/IconButton', component: IconButton, argTypes: { onPress: { table: { disable: true, }, }, children: { table: { disable: true, }, }, 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', }, }, }, }, } const buttonAndIconSizesMap = Object.keys(config.variants.size).map<{ size: keyof typeof config.variants.size iconSize: number }>((key) => { const typedKey = key as keyof typeof config.variants.size switch (typedKey) { case 'sm': return { size: typedKey, iconSize: 16, } case 'md': return { size: typedKey, iconSize: 20, } case 'lg': return { size: typedKey, iconSize: 24, } case 'xl': return { size: typedKey, iconSize: 28, } default: return { size: typedKey, iconSize: 24, } } }) const globalStoryPropsInverted = { backgrounds: { value: 'scandicPrimaryDark' }, } export default meta type Story = StoryObj function renderAllSizesFn( args: Story['args'], iconName: MaterialIconProps['icon'] = 'search' ) { return (
{buttonAndIconSizesMap.map(({ size, iconSize }) => (
{size}
))}
) } export const Default: Story = { args: { onPress: fn(), children: , }, 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, children: ( ), 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, children: ( ), 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, children: ( ), 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, children: ( ), 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, children: ( ), 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) }, }