import type { Meta, StoryObj } from '@storybook/web-components-vite'; import { html } from 'lit'; import './index.ts'; import type { USARangeSlider } from './usa-range-slider.js'; const meta: Meta = { title: 'Forms/Range Slider', component: 'usa-range-slider', parameters: { layout: 'padded', docs: { description: { component: ` # USA Range Slider The USA Range Slider component provides accessible numeric value selection using a visual slider interface with official USWDS styling. This component allows users to select values within a specified range using mouse, keyboard, or touch interaction. ## Features - Numeric range selection with min/max constraints - Visual progress indicator showing current selection - Enhanced keyboard navigation (Home, End, PageUp, PageDown) - Customizable step intervals for precise control - Optional unit display for context (%, $, etc.) - Min/max value display options - Current value display options - Form validation integration - ARIA attributes for screen readers ## Usage Guidelines - Use for numeric value selection within a defined range - Provide clear labels indicating what the slider controls - Consider appropriate step intervals for the use case - Use units when context is helpful (temperature, percentage, currency) - Enable min/max display for user guidance - Test keyboard accessibility for power users ## Applications Perfect for: - Budget allocation controls - Assessment scales - Service level agreements - Performance target setting - Threshold configuration - Resource allocation planning `, }, }, }, argTypes: { value: { control: 'number', description: 'Current value of the slider', }, min: { control: 'number', description: 'Minimum allowed value', }, max: { control: 'number', description: 'Maximum allowed value', }, step: { control: 'number', description: 'Step increment for value changes', }, label: { control: 'text', description: 'Label text for the slider', }, hint: { control: 'text', description: 'Helper text shown below the label', }, disabled: { control: 'boolean', description: 'Whether the slider is disabled', }, required: { control: 'boolean', description: 'Whether the slider is required', }, unit: { control: 'text', description: 'Unit to display with values (%, $, etc.)', }, showValue: { control: 'boolean', description: 'Whether to show the current value', }, showMinMax: { control: 'boolean', description: 'Whether to show min/max values', }, name: { control: 'text', description: 'Form field name', }, }, }; export default meta; type Story = StoryObj; export const Default: Story = { args: { label: 'Select value', hint: 'Choose a value within the range', value: 50, min: 0, max: 100, step: 1, showValue: true, showMinMax: true, name: 'range-slider', }, render: (args) => html` `, }; export const WithValue: Story = { args: { label: 'Pre-selected value', value: 75, min: 0, max: 100, step: 1, hint: 'Slider with initial value set', showValue: true, showMinMax: true, name: 'range-slider-with-value', }, render: (args) => html` `, }; export const Required: Story = { args: { label: 'Required slider', hint: 'This field is required', value: 50, min: 0, max: 100, step: 1, required: true, showValue: true, showMinMax: true, name: 'range-slider-required', }, render: (args) => html` `, }; export const Disabled: Story = { args: { label: 'Disabled slider', value: 60, min: 0, max: 100, step: 1, hint: 'This slider is disabled', disabled: true, showValue: true, showMinMax: true, name: 'range-slider-disabled', }, render: (args) => html` `, }; export const WithUnits: Story = { args: { label: 'Temperature setting', value: 72, min: 60, max: 80, step: 1, unit: '°F', hint: 'Set your preferred temperature', showValue: true, showMinMax: true, name: 'range-slider-temperature', }, render: (args) => html` `, }; export const Percentage: Story = { args: { label: 'Completion percentage', value: 65, min: 0, max: 100, step: 1, unit: '%', hint: 'Track project completion', showValue: true, showMinMax: true, name: 'range-slider-percentage', }, render: (args) => html` `, }; export const Currency: Story = { args: { label: 'Budget allocation', value: 2500, min: 0, max: 10000, step: 100, unit: '$', hint: 'Set budget amount in dollars', showValue: true, showMinMax: true, name: 'range-slider-currency', }, render: (args) => html` `, }; export const CustomRange: Story = { args: { label: 'Custom range (10-90)', value: 45, min: 10, max: 90, step: 5, hint: 'Slider with custom min/max values', showValue: true, showMinMax: true, name: 'range-slider-custom', }, render: (args) => html` `, }; export const FineGrained: Story = { args: { label: 'Precision control', value: 2.5, min: 0, max: 5, step: 0.1, unit: 'x', hint: 'Fine-grained decimal control', showValue: true, showMinMax: true, name: 'range-slider-precision', }, render: (args) => html` `, }; export const HiddenMinMax: Story = { args: { label: 'Clean interface', value: 30, min: 0, max: 100, step: 1, showMinMax: false, showValue: true, hint: 'Slider without min/max display', name: 'range-slider-no-minmax', }, render: (args) => html` `, }; export const HiddenValue: Story = { args: { label: 'No value display', value: 40, min: 0, max: 100, step: 1, showValue: false, showMinMax: true, hint: 'Slider without current value display', name: 'range-slider-no-value', }, render: (args) => html` `, }; export const Minimal: Story = { args: { label: 'Minimal slider', value: 25, min: 0, max: 100, step: 1, showValue: false, showMinMax: false, hint: 'Clean, minimal interface', name: 'range-slider-minimal', }, render: (args) => html` `, }; export const InteractiveDemo: Story = { parameters: { controls: { disable: true }, // Static demo - no interactive controls needed }, render: () => html`

Interactive Range Slider Demo

Test slider interactions, keyboard navigation, and event handling with real-time feedback.

Real-time Output:

No changes yet. Move the slider to see event details.

Testing Instructions:

  • Mouse: Click and drag the slider handle
  • Keyboard: Tab to focus, use arrow keys to adjust
  • Enhanced Navigation: Home (min), End (max), PageUp/PageDown (large steps)
  • Touch: Tap and drag on touch devices
  • Precision: Use arrow keys for single-step adjustments
`, }; export const AccessibilityShowcase: Story = { parameters: { controls: { disable: true }, // Static demo - no interactive controls needed }, render: () => html`

Accessibility Features Demonstration

Showcasing WCAG 2.1 AA compliance and Section 508 accessibility features.

Accessibility Features:

  • Screen Reader Support: ARIA labels, roles, and live regions
  • Keyboard Navigation: Arrow keys, Home, End, PageUp, PageDown
  • High Contrast: Compatible with high contrast themes
  • Focus Management: Clear focus indicators and logical tab order
  • Value Announcement: Screen readers announce current values
  • Semantic HTML: Proper form labels and associations

Testing with Assistive Technology:

  • Navigate using Tab key to focus sliders
  • Use arrow keys for single-step value changes
  • Press Home/End for minimum/maximum values
  • Use PageUp/PageDown for large value jumps
  • Test with screen reader (NVDA, JAWS, VoiceOver)
  • Verify proper value announcements
`, }; export const FormIntegration: Story = { parameters: { controls: { disable: true }, // Static demo - no interactive controls needed }, render: () => html`

Form Integration Example

Example of range slider integration in forms with validation.

Form Output:

Submit the form to see the selected values.
`, };