import type { Meta, StoryObj } from '@storybook/nextjs' import { useState } from 'react' import Input from '.' const meta = { title: 'Base/Data Entry/Input', component: Input, parameters: { layout: 'centered', docs: { description: { component: 'Input component with support for icons, clear button, validation states, and units. Includes automatic leading zero removal for number inputs.', }, }, }, tags: ['autodocs'], argTypes: { size: { control: 'select', options: ['regular', 'large'], description: 'Input size', }, type: { control: 'select', options: ['text', 'number', 'email', 'password', 'url', 'tel'], description: 'Input type', }, placeholder: { control: 'text', description: 'Placeholder text', }, disabled: { control: 'boolean', description: 'Disabled state', }, destructive: { control: 'boolean', description: 'Error/destructive state', }, showLeftIcon: { control: 'boolean', description: 'Show search icon on left', }, showClearIcon: { control: 'boolean', description: 'Show clear button when input has value', }, unit: { control: 'text', description: 'Unit text displayed on right (e.g., "px", "ms")', }, }, } satisfies Meta export default meta type Story = StoryObj // Interactive demo wrapper const InputDemo = (args: any) => { const [value, setValue] = useState(args.value || '') return (
{ setValue(e.target.value) console.log('Input changed:', e.target.value) }} onClear={() => { setValue('') console.log('Input cleared') }} />
) } // Default state export const Default: Story = { render: args => , args: { size: 'regular', placeholder: 'Enter text...', type: 'text', }, } // Large size export const LargeSize: Story = { render: args => , args: { size: 'large', placeholder: 'Enter text...', type: 'text', }, } // With search icon export const WithSearchIcon: Story = { render: args => , args: { size: 'regular', showLeftIcon: true, placeholder: 'Search...', type: 'text', }, } // With clear button export const WithClearButton: Story = { render: args => , args: { size: 'regular', showClearIcon: true, value: 'Some text to clear', placeholder: 'Type something...', type: 'text', }, } // Search input (icon + clear) export const SearchInput: Story = { render: args => , args: { size: 'regular', showLeftIcon: true, showClearIcon: true, value: '', placeholder: 'Search...', type: 'text', }, } // Disabled state export const Disabled: Story = { render: args => , args: { size: 'regular', value: 'Disabled input', disabled: true, type: 'text', }, } // Destructive/error state export const DestructiveState: Story = { render: args => , args: { size: 'regular', value: 'invalid@email', destructive: true, placeholder: 'Enter email...', type: 'email', }, } // Number input export const NumberInput: Story = { render: args => , args: { size: 'regular', type: 'number', placeholder: 'Enter a number...', value: '0', }, } // With unit export const WithUnit: Story = { render: args => , args: { size: 'regular', type: 'number', value: '100', unit: 'px', placeholder: 'Enter value...', }, } // Email input export const EmailInput: Story = { render: args => , args: { size: 'regular', type: 'email', placeholder: 'Enter your email...', showClearIcon: true, }, } // Password input export const PasswordInput: Story = { render: args => , args: { size: 'regular', type: 'password', placeholder: 'Enter password...', value: 'secret123', }, } // Size comparison const SizeComparisonDemo = () => { const [regularValue, setRegularValue] = useState('') const [largeValue, setLargeValue] = useState('') return (
setRegularValue(e.target.value)} placeholder="Regular input..." showClearIcon onClear={() => setRegularValue('')} />
setLargeValue(e.target.value)} placeholder="Large input..." showClearIcon onClear={() => setLargeValue('')} />
) } export const SizeComparison: Story = { render: () => , } // State comparison const StateComparisonDemo = () => { const [normalValue, setNormalValue] = useState('Normal state') const [errorValue, setErrorValue] = useState('Error state') return (
setNormalValue(e.target.value)} showClearIcon onClear={() => setNormalValue('')} />
setErrorValue(e.target.value)} destructive />
undefined} disabled />
) } export const StateComparison: Story = { render: () => , } // Form example const FormExampleDemo = () => { const [formData, setFormData] = useState({ name: '', email: '', age: '', website: '', }) const [errors, setErrors] = useState({ email: false, age: false, }) const validateEmail = (email: string) => { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) } return (

User Profile

setFormData({ ...formData, name: e.target.value })} placeholder="Enter your name..." showClearIcon onClear={() => setFormData({ ...formData, name: '' })} />
{ setFormData({ ...formData, email: e.target.value }) setErrors({ ...errors, email: e.target.value ? !validateEmail(e.target.value) : false }) }} placeholder="Enter your email..." destructive={errors.email} showClearIcon onClear={() => { setFormData({ ...formData, email: '' }) setErrors({ ...errors, email: false }) }} /> {errors.email && ( Please enter a valid email address )}
{ setFormData({ ...formData, age: e.target.value }) setErrors({ ...errors, age: e.target.value ? Number(e.target.value) < 18 : false }) }} placeholder="Enter your age..." destructive={errors.age} unit="years" /> {errors.age && ( Must be 18 or older )}
setFormData({ ...formData, website: e.target.value })} placeholder="https://example.com" showClearIcon onClear={() => setFormData({ ...formData, website: '' })} />
) } export const FormExample: Story = { render: () => , } // Search example const SearchExampleDemo = () => { const [searchQuery, setSearchQuery] = useState('') const items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape'] const filteredItems = items.filter(item => item.toLowerCase().includes(searchQuery.toLowerCase()), ) return (
setSearchQuery(e.target.value)} onClear={() => setSearchQuery('')} placeholder="Search fruits..." /> {searchQuery && (
{filteredItems.length} result{filteredItems.length !== 1 ? 's' : ''}
{filteredItems.map(item => (
{item}
))}
)}
) } export const SearchExample: Story = { render: () => , } // Interactive playground export const Playground: Story = { render: args => , args: { size: 'regular', type: 'text', placeholder: 'Type something...', disabled: false, destructive: false, showLeftIcon: false, showClearIcon: true, unit: '', }, }