Files
web/packages/design-system/lib/components/Input/Input.stories.tsx
Erik Tiekstra 3f632e6031 Merged in fix/BOOK-293-button-variants (pull request #3371)
fix(BOOK-293): changed variants and props on IconButton component

* fix(BOOK-293): changed variants and props on IconButton component

* fix(BOOK-293): inherit color for icon


Approved-by: Bianca Widstam
Approved-by: Christel Westerberg
2025-12-19 12:32:52 +00:00

204 lines
5.3 KiB
TypeScript

import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { expect } from 'storybook/test'
import { Input } from './Input'
import { TextField } from 'react-aria-components'
import { MaterialIcon } from '../Icons/MaterialIcon'
import type { SymbolCodepoints } from '../Icons/MaterialIcon/MaterialSymbol/types'
const meta: Meta<typeof Input> = {
title: 'Core Components/Input',
// @ts-expect-error Input does not support this, but wrapping <TextField> does
component: ({ isInvalid, validationState, ...props }) => (
<TextField isInvalid={isInvalid} data-validation-state={validationState}>
<Input {...props} data-validation-state={validationState} />
</TextField>
),
argTypes: {
label: {
control: 'text',
description: 'The label text displayed for the input field',
table: {
type: { summary: 'string' },
},
},
labelPosition: {
control: 'select',
options: ['floating', 'top'],
description: 'Position of the label relative to the input',
table: {
type: { summary: "'floating' | 'top'" },
defaultValue: { summary: "'floating'" },
},
},
placeholder: {
control: 'text',
description: 'Placeholder text shown when input is empty',
table: {
type: { summary: 'string' },
defaultValue: { summary: 'undefined' },
},
},
required: {
control: 'boolean',
description: 'Whether the input is required',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
disabled: {
control: 'boolean',
description: 'Whether the input is disabled',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
showClearContentIcon: {
control: 'boolean',
description: 'Whether the clear content icon is shown',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
showLeftIcon: {
control: 'boolean',
description: 'Whether to show a left icon',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
showRightIcon: {
control: 'boolean',
description: 'Whether to show a right icon',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
leftIconName: {
control: 'select',
options: [
'calendar_month',
'credit_card',
'email',
'info_circle',
'location_on',
'lock',
'phone',
'search',
'sell',
'visibility',
'visibility_off',
],
description: 'Icon name for the left icon',
table: {
type: { summary: 'string' },
defaultValue: { summary: "'person'" },
},
},
rightIconName: {
control: 'select',
options: [
'calendar_month',
'credit_card',
'email',
'info_circle',
'location_on',
'lock',
'phone',
'search',
'sell',
'visibility',
'visibility_off',
],
description: 'Icon name for the right icon',
table: {
type: { summary: 'string' },
defaultValue: { summary: "'lock'" },
},
},
showWarning: {
control: 'boolean',
description: 'Whether to show warning validation state',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any,
}
export default meta
type Story = StoryObj<typeof Input>
export const Default: Story = {
args: {
label: 'Label',
name: 'foo',
required: false,
showLeftIcon: false,
showRightIcon: false,
leftIconName: 'person',
rightIconName: 'lock',
showWarning: false,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any,
render: (args) => {
// Extract custom Storybook args
const {
showLeftIcon,
showRightIcon,
leftIconName,
rightIconName,
showWarning,
...inputProps
} = args as typeof args & {
showLeftIcon?: boolean
showRightIcon?: boolean
leftIconName?: string
rightIconName?: string
showWarning?: boolean
}
const validationState = showWarning ? 'warning' : undefined
return (
<TextField data-validation-state={validationState}>
<Input
{...inputProps}
data-validation-state={validationState}
leftIcon={
showLeftIcon && leftIconName ? (
<MaterialIcon icon={leftIconName as SymbolCodepoints} />
) : undefined
}
rightIcon={
showRightIcon && rightIconName ? (
<MaterialIcon icon={rightIconName as SymbolCodepoints} />
) : undefined
}
/>
</TextField>
)
},
play: async ({ canvas, userEvent }) => {
const textbox = canvas.getByRole('textbox')
expect(textbox).not.toBeDisabled()
expect(textbox).toHaveValue('')
await userEvent.type(textbox, 'Hello World')
expect(textbox).toHaveValue('Hello World')
await userEvent.clear(textbox)
expect(textbox).toHaveValue('')
},
}