import type { Meta, StoryObj } from '@storybook/web-components-vite'; import { html } from 'lit'; import './index.ts'; import type { USAInputPrefixSuffix } from './usa-input-prefix-suffix.js'; const meta: Meta = { title: 'Forms/Input Prefix Suffix', component: 'usa-input-prefix-suffix', parameters: { layout: 'padded', docs: { description: { component: ` The USA Input Prefix Suffix component enhances input fields with visual context through prefixes and suffixes. This pattern helps users understand the expected input format and reduces form errors. ## Key Features - **Text Prefixes/Suffixes**: Add contextual text like currency symbols, units, or domains - **Icon Prefixes/Suffixes**: Use icons for visual enhancement and recognition - **Multiple Input Types**: Support for text, email, number, tel, url, password, and search - **Full Accessibility**: ARIA attributes and screen reader support - **Form Integration**: Compatible with form validation systems ## Common Use Cases - **Financial Forms**: Currency inputs ($, %), rates, amounts - **Contact Information**: Email domains, phone prefixes (+1), URLs - **Identification**: ID formatting, reference numbers - **Search Interfaces**: Document search, data lookups - **Data Entry**: Units of measure, percentages, standardized formats ## When to Use - When input context improves user understanding - For standardized data formats - To reduce input errors and improve data quality - When visual cues enhance form completion ## When Not to Use - For simple text inputs without additional context - When prefixes/suffixes would cause confusion - If accessibility is compromised by visual additions `, }, }, }, argTypes: { value: { control: 'text', description: 'Current input value', }, name: { control: 'text', description: 'Input name attribute', }, inputId: { control: 'text', description: 'Input ID attribute', }, label: { control: 'text', description: 'Input label text', }, hint: { control: 'text', description: 'Hint text below label', }, placeholder: { control: 'text', description: 'Input placeholder text', }, prefix: { control: 'text', description: 'Text prefix before input', }, suffix: { control: 'text', description: 'Text suffix after input', }, prefixIcon: { control: 'text', description: 'Icon name for prefix', }, suffixIcon: { control: 'text', description: 'Icon name for suffix', }, type: { control: 'select', options: ['text', 'email', 'number', 'tel', 'url', 'password', 'search'], description: 'Input type', }, autocomplete: { control: 'text', description: 'Autocomplete attribute', }, disabled: { control: 'boolean', description: 'Whether input is disabled', }, required: { control: 'boolean', description: 'Whether input is required', }, readonly: { control: 'boolean', description: 'Whether input is read-only', }, }, }; export default meta; type Story = StoryObj; export const Default: Story = { args: { label: 'Input with Prefix', prefix: '$', placeholder: 'Enter amount', hint: 'Enter the dollar amount', }, }; export const WithSuffix: Story = { args: { label: 'Tax Rate', suffix: '%', type: 'number', placeholder: '0.00', hint: 'Enter tax rate as percentage', }, }; // NOTE: USWDS does not support using both prefix AND suffix simultaneously // The component is designed for "Input Prefix OR Suffix" - use one or the other // export const WithBothPrefixAndSuffix: Story = { // args: { // label: 'Website URL', // prefix: 'https://', // suffix: '.com', // type: 'url', // placeholder: 'example', // hint: 'Enter your website domain', // }, // }; export const WithPrefixIcon: Story = { args: { label: 'Search', prefixIcon: 'search', type: 'search', placeholder: 'Search documents', hint: 'Enter keywords to search', }, }; export const WithSuffixIcon: Story = { args: { label: 'Password', suffixIcon: 'visibility', type: 'password', placeholder: 'Enter password', hint: 'Click eye to toggle visibility', }, }; export const Required: Story = { args: { label: 'Annual Income', prefix: '$', type: 'number', placeholder: '0.00', hint: 'Enter your gross annual income', required: true, }, }; export const Disabled: Story = { args: { label: 'Account Balance', prefix: '$', suffix: ' USD', value: '1,234.56', disabled: true, hint: 'This field cannot be edited', }, }; export const ReadOnly: Story = { args: { label: 'Transaction ID', prefix: 'TXN-', value: '2023-ABC123', readonly: true, hint: 'Transaction reference number', }, }; export const CurrencyInput: Story = { args: { label: 'Amount', prefix: '$', type: 'number', placeholder: '0.00', hint: 'Enter dollar amount', name: 'amount', autocomplete: 'off', }, }; export const PhoneNumber: Story = { args: { label: 'Phone Number', prefix: '+1', type: 'tel', placeholder: '(555) 123-4567', hint: 'Enter your phone number', name: 'phone', autocomplete: 'tel', }, }; export const PercentageRate: Story = { args: { label: 'Rate', suffix: '%', type: 'number', placeholder: '0.00', hint: 'Enter rate as percentage', name: 'rate', }, }; export const InteractiveDemo: Story = { name: 'Interactive Prefix/Suffix Demo', render: () => { const handleInputChange = (_e: any) => { // Event handler for demo }; return html`

Event Information

Open browser console to see input-change events with detailed information:

  • detail.value - Current input value
  • detail.name - Input name attribute
  • detail.input - Reference to input element
`; }, parameters: { docs: { description: { story: 'Interactive demonstration showing multiple prefix/suffix patterns with event handling.', }, }, }, }; export const AccessibilityShowcase: Story = { name: 'Accessibility Features Demo', render: () => { return html`

Required Field with Prefix

Email with Domain Suffix

Search with Icon Prefix

Accessibility Features

  • Label Association: Each input has a properly associated label
  • Hint Text: Helper text linked via aria-describedby
  • Required Indicators: Visual and screen reader accessible required markers
  • Decorative Elements: Prefixes and suffixes marked as aria-hidden="true"
  • Icon Accessibility: Icons marked as decorative for screen readers
  • Keyboard Navigation: Full keyboard accessibility maintained
  • Autocomplete: Proper autocomplete attributes for forms
  • Input Types: Semantic input types for better mobile experience

Testing Instructions

  1. Tab through inputs to verify keyboard navigation
  2. Use screen reader to verify label and hint associations
  3. Test with high contrast mode enabled
  4. Verify focus indicators are clearly visible
  5. Check mobile keyboard behavior with different input types
`; }, parameters: { docs: { description: { story: 'Comprehensive accessibility demonstration showing WCAG compliance and form best practices.', }, }, }, };