import type { Meta, StoryObj } from '@storybook/web-components-vite'; import { html } from 'lit'; import './index.js'; import type { USAValidation } from './usa-validation.js'; const meta: Meta = { title: 'Forms/Validation', component: 'usa-validation', parameters: { layout: 'padded', docs: { description: { component: ` The USA Validation component provides comprehensive form field validation with real-time feedback. It supports multiple validation rules, custom validators, and follows USWDS design patterns for error states. ## Features - Multiple input types (text, textarea, select) - Built-in validation rules (required, email, URL, pattern, length, numeric) - Custom validation functions - Real-time validation on input and blur - Accessible error messages with ARIA support - Visual success and error states - Common validation patterns `, }, }, }, argTypes: { value: { control: 'text', description: 'Current input value', }, label: { control: 'text', description: 'Field label text', }, hint: { control: 'text', description: 'Helper text for the field', }, name: { control: 'text', description: 'Field name and ID', }, inputType: { control: 'select', options: ['input', 'textarea', 'select'], description: 'Type of input control', }, type: { control: 'text', description: 'HTML input type (text, email, password, etc.)', }, placeholder: { control: 'text', description: 'Placeholder text', }, disabled: { control: 'boolean', description: 'Disable the input field', }, readonly: { control: 'boolean', description: 'Make the input read-only', }, validateOnInput: { control: 'boolean', description: 'Validate while typing', }, validateOnBlur: { control: 'boolean', description: 'Validate when field loses focus', }, showSuccessState: { control: 'boolean', description: 'Show green success state for valid fields', }, }, }; export default meta; type Story = StoryObj; export const Default: Story = { args: { label: 'Text input', hint: 'Enter your text here', placeholder: 'Type something...', }, }; export const Required: Story = { args: { label: 'Required field', hint: 'This field is required', rules: [{ type: 'required', message: 'This field is required' }], }, }; export const EmailValidation: Story = { args: { label: 'Email address', hint: 'Enter a valid email address', type: 'email', placeholder: 'name@example.com', rules: [ { type: 'required', message: 'Email is required' }, { type: 'email', message: 'Please enter a valid email address' }, ], }, }; export const PasswordStrength: Story = { args: { label: 'Password', hint: 'Must be at least 8 characters with uppercase, lowercase, and numbers', type: 'password', placeholder: 'Enter password', rules: [ { type: 'required', message: 'Password is required' }, { type: 'minlength', value: 8, message: 'Password must be at least 8 characters' }, { type: 'custom', message: 'Password must contain uppercase, lowercase, and numbers', validator: (value: string) => /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(value), }, ], }, }; export const TextareaValidation: Story = { args: { label: 'Comments', hint: 'Please provide detailed comments (minimum 20 characters)', inputType: 'textarea', rows: 5, placeholder: 'Enter your comments here...', rules: [ { type: 'required', message: 'Comments are required' }, { type: 'minlength', value: 20, message: 'Comments must be at least 20 characters' }, { type: 'maxlength', value: 500, message: 'Comments cannot exceed 500 characters' }, ], }, }; export const SelectValidation: Story = { args: { label: 'State', hint: 'Select your state of residence', inputType: 'select', options: [ { value: 'AL', text: 'Alabama' }, { value: 'CA', text: 'California' }, { value: 'FL', text: 'Florida' }, { value: 'NY', text: 'New York' }, { value: 'TX', text: 'Texas' }, ], rules: [{ type: 'required', message: 'Please select your state' }], }, }; export const NumericValidation: Story = { args: { label: 'Age', hint: 'Must be between 18 and 120 years old', type: 'number', placeholder: 'Enter your age', rules: [ { type: 'required', message: 'Age is required' }, { type: 'min', value: 18, message: 'Must be at least 18 years old' }, { type: 'max', value: 120, message: 'Must be no more than 120 years old' }, ], }, }; // Common validation pattern examples export const PersonalIDValidation: Story = { args: { label: 'Personal ID Number', hint: 'Format: XXX-XX-XXXX', placeholder: '123-45-6789', rules: [ { type: 'required', message: 'Personal ID is required' }, { type: 'pattern', value: '^\\d{3}-\\d{2}-\\d{4}$', message: 'Personal ID must be in format: XXX-XX-XXXX', }, ], }, parameters: { docs: { description: { story: 'Personal identification number validation for forms.', }, }, }, }; export const EmployeeID: Story = { args: { label: 'Employee ID', hint: 'Two letters followed by 8 numbers (e.g., AB12345678)', placeholder: 'AB12345678', rules: [ { type: 'required', message: 'Employee ID is required' }, { type: 'pattern', value: '^[A-Z]{2}\\d{8}$', message: 'Employee ID must be 2 letters followed by 8 numbers', }, ], }, parameters: { docs: { description: { story: 'Employee identification number validation.', }, }, }, }; export const BusinessEmail: Story = { args: { label: 'Business Email', hint: 'Enter your business email address', type: 'email', placeholder: 'name@company.com', rules: [ { type: 'required', message: 'Business email is required' }, { type: 'email', message: 'Please enter a valid email address' }, ], }, parameters: { docs: { description: { story: 'Validation for business email addresses.', }, }, }, }; export const ZIPCodeValidation: Story = { args: { label: 'ZIP Code', hint: 'Enter 5-digit ZIP or ZIP+4 format', placeholder: '12345 or 12345-6789', rules: [ { type: 'required', message: 'ZIP code is required' }, { type: 'pattern', value: '^\\d{5}(-\\d{4})?$', message: 'ZIP code must be 5 digits or ZIP+4 format (12345 or 12345-6789)', }, ], }, parameters: { docs: { description: { story: 'U.S. ZIP code validation with optional +4 extension.', }, }, }, }; export const BusinessIDValidation: Story = { args: { label: 'Business ID Number', hint: 'Format: XX-XXXXXXX', placeholder: '12-3456789', rules: [ { type: 'required', message: 'Business ID is required' }, { type: 'pattern', value: '^\\d{2}-\\d{7}$', message: 'Business ID must be in format: XX-XXXXXXX', }, ], }, parameters: { docs: { description: { story: 'Business identification number validation for business forms.', }, }, }, }; export const AccessLevel: Story = { args: { label: 'Access Level', hint: 'Select your current access level', inputType: 'select', options: [ { value: 'basic', text: 'Basic Access' }, { value: 'standard', text: 'Standard Access' }, { value: 'elevated', text: 'Elevated Access' }, { value: 'admin', text: 'Administrator' }, { value: 'super-admin', text: 'Super Administrator' }, ], rules: [{ type: 'required', message: 'Access level is required' }], }, parameters: { docs: { description: { story: 'Access level selection for system permissions.', }, }, }, }; export const NumericIDValidation: Story = { args: { label: 'Document Number', hint: 'Enter your 9-digit document number', placeholder: '123456789', rules: [ { type: 'required', message: 'Document number is required' }, { type: 'pattern', value: '^\\d{9}$', message: 'Document number must be exactly 9 digits', }, ], }, parameters: { docs: { description: { story: 'Numeric document ID validation for various identification documents.', }, }, }, }; export const ComplexForm: Story = { parameters: { controls: { disable: true }, // Static demo - no interactive controls needed }, render: () => html`

Application Form

`, }; export const InteractiveDemo: Story = { parameters: { controls: { disable: true }, // Static demo - no interactive controls needed }, render: () => html`

Validation Status:

Enter text to see validation results
`, };