@a13y/react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +241 -0
- package/dist/components/index.d.ts +374 -0
- package/dist/components/index.js +849 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.d.ts +725 -0
- package/dist/hooks/index.js +648 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1875 -0
- package/dist/index.js.map +1 -0
- package/dist/patterns/index.d.ts +539 -0
- package/dist/patterns/index.js +1170 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/use-accessible-button-B0syf-Az.d.ts +83 -0
- package/package.json +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-focus-trap.ts","../../src/hooks/use-accessible-dialog.ts","../../src/components/AccessibleDialog.tsx","../../src/patterns/DialogStack.tsx","../../src/patterns/InfiniteList.tsx","../../src/hooks/use-accessible-button.ts","../../src/hooks/use-keyboard-navigation.ts","../../src/patterns/NestedMenu.tsx","../../src/patterns/VirtualizedList.tsx","../../src/patterns/Wizard.tsx"],"names":["useRef","useEffect","jsxs","jsx","useState","useCallback","announce","createContext","useContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @a13y/react - useFocusTrap\n * Focus trap hook for modals and dialogs\n */\n\nimport type { FocusTrap } from '@a13y/core/runtime/focus';\nimport { useEffect, useRef } from 'react';\n\n/**\n * Props for useFocusTrap\n */\nexport interface UseFocusTrapProps {\n /**\n * Whether the focus trap is active\n */\n isActive: boolean;\n\n /**\n * Callback when Escape key is pressed\n */\n onEscape?: () => void;\n\n /**\n * Whether to restore focus when trap is deactivated\n * @default true\n */\n restoreFocus?: boolean;\n\n /**\n * Whether to auto-focus first element when activated\n * @default true\n */\n autoFocus?: boolean;\n}\n\n/**\n * Return type\n */\nexport interface UseFocusTrapReturn {\n /**\n * Ref to attach to the container element\n */\n trapRef: React.RefObject<HTMLElement | null>;\n}\n\n/**\n * Hook for creating focus traps\n *\n * Features:\n * - Traps Tab/Shift+Tab within container\n * - Handles Escape key\n * - Restores focus on deactivation\n * - Auto-focuses first element\n * - Development-time validation\n *\n * @example\n * ```tsx\n * const { trapRef } = useFocusTrap({\n * isActive: isOpen,\n * onEscape: () => setIsOpen(false),\n * });\n *\n * return (\n * <div ref={trapRef} role=\"dialog\">\n * <button>Close</button>\n * </div>\n * );\n * ```\n */\nexport const useFocusTrap = (props: UseFocusTrapProps): UseFocusTrapReturn => {\n const { isActive, onEscape, restoreFocus = true, autoFocus = true } = props;\n\n const trapRef = useRef<HTMLElement>(null);\n const focusTrapRef = useRef<FocusTrap | null>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n\n useEffect(() => {\n if (!isActive || !trapRef.current) {\n return;\n }\n\n // Save previous focus\n if (restoreFocus) {\n previousFocusRef.current = document.activeElement as HTMLElement;\n }\n\n // Create focus trap\n import('@a13y/core/runtime/focus').then(({ createFocusTrap }) => {\n if (!trapRef.current) {\n return;\n }\n\n const options: import('@a13y/core/runtime/focus').FocusTrapOptions = {\n returnFocus: false,\n onEscape: onEscape,\n };\n\n // Only set initialFocus if autoFocus is enabled\n if (autoFocus) {\n // undefined means auto-focus first focusable element\n options.initialFocus = undefined;\n }\n\n const trap = createFocusTrap(trapRef.current, options);\n\n trap.activate();\n focusTrapRef.current = trap;\n\n // Development-time validation\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n import('@a13y/devtools/runtime/validators').then(({ focusValidator }) => {\n if (trapRef.current) {\n focusValidator.validateFocusTrap(trapRef.current, true);\n }\n });\n }\n });\n\n // Cleanup\n return () => {\n if (focusTrapRef.current) {\n focusTrapRef.current.deactivate();\n focusTrapRef.current = null;\n }\n\n // Restore focus\n if (restoreFocus && previousFocusRef.current) {\n previousFocusRef.current.focus();\n\n // Validate focus restoration in dev\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n import('@a13y/devtools/runtime/validators').then(({ focusValidator }) => {\n if (previousFocusRef.current) {\n focusValidator.expectFocusRestoration(\n previousFocusRef.current,\n 'focus trap deactivation'\n );\n }\n });\n }\n }\n };\n }, [isActive, onEscape, restoreFocus, autoFocus]);\n\n return {\n trapRef,\n };\n};\n","/**\n * @a13y/react - useAccessibleDialog\n * Type-safe dialog/modal hook with full ARIA support\n */\n\nimport type { AriaRole } from 'react';\nimport { useEffect, useId, useRef } from 'react';\nimport { useFocusTrap } from './use-focus-trap';\n\n/**\n * Props for useAccessibleDialog\n */\nexport interface UseAccessibleDialogProps {\n /**\n * Whether the dialog is open\n */\n isOpen: boolean;\n\n /**\n * Callback when dialog should close\n * Called on Escape key or backdrop click\n */\n onClose: () => void;\n\n /**\n * Dialog title - REQUIRED for accessibility\n * This becomes the aria-labelledby target\n */\n title: string;\n\n /**\n * Optional dialog description\n * This becomes the aria-describedby target\n */\n description?: string;\n\n /**\n * ARIA role\n * @default 'dialog'\n */\n role?: Extract<AriaRole, 'dialog' | 'alertdialog'>;\n\n /**\n * Whether dialog is modal (blocking)\n * @default true\n */\n isModal?: boolean;\n\n /**\n * Whether clicking backdrop closes dialog\n * @default true\n */\n closeOnBackdropClick?: boolean;\n}\n\n/**\n * Dialog container props\n */\nexport interface DialogContainerProps {\n ref: React.RefObject<HTMLElement | null>;\n role: AriaRole;\n 'aria-labelledby': string;\n 'aria-describedby'?: string;\n 'aria-modal': boolean;\n tabIndex: -1;\n}\n\n/**\n * Title props\n */\nexport interface DialogTitleProps {\n id: string;\n}\n\n/**\n * Description props\n */\nexport interface DialogDescriptionProps {\n id: string;\n}\n\n/**\n * Backdrop props\n */\nexport interface DialogBackdropProps {\n onClick: () => void;\n 'aria-hidden': true;\n}\n\n/**\n * Return type\n */\nexport interface UseAccessibleDialogReturn {\n dialogProps: DialogContainerProps;\n titleProps: DialogTitleProps;\n descriptionProps: DialogDescriptionProps | null;\n backdropProps: DialogBackdropProps | null;\n close: () => void;\n}\n\n/**\n * Hook for creating accessible dialogs/modals\n *\n * Features:\n * - Focus trap with Tab/Shift+Tab cycling\n * - Escape key to close\n * - Focus restoration on close\n * - ARIA attributes (modal, labelledby, describedby)\n * - Backdrop click handling\n * - Development-time validation\n *\n * @example\n * ```tsx\n * const { dialogProps, titleProps, descriptionProps, backdropProps } =\n * useAccessibleDialog({\n * isOpen,\n * onClose: () => setIsOpen(false),\n * title: 'Delete Item',\n * description: 'This action cannot be undone',\n * });\n *\n * if (!isOpen) return null;\n *\n * return (\n * <>\n * <div {...backdropProps} />\n * <div {...dialogProps}>\n * <h2 {...titleProps}>Delete Item</h2>\n * <p {...descriptionProps}>This action cannot be undone</p>\n * <button onClick={close}>Cancel</button>\n * </div>\n * </>\n * );\n * ```\n */\nexport const useAccessibleDialog = (props: UseAccessibleDialogProps): UseAccessibleDialogReturn => {\n const {\n isOpen,\n onClose,\n title,\n description,\n role = 'dialog',\n isModal = true,\n closeOnBackdropClick = true,\n } = props;\n\n // Compile-time validation: title is required\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n if (!title || title.trim().length === 0) {\n throw new Error(\n '@a13y/react [useAccessibleDialog]: \"title\" prop is required for accessibility'\n );\n }\n }\n\n const dialogRef = useRef<HTMLElement>(null);\n const titleId = useId();\n const descriptionId = useId();\n\n // Focus trap\n const { trapRef } = useFocusTrap({\n isActive: isOpen,\n onEscape: onClose,\n restoreFocus: true,\n autoFocus: true,\n });\n\n // Sync refs (trapRef and dialogRef point to same element)\n useEffect(() => {\n if (dialogRef.current && trapRef.current !== dialogRef.current) {\n (trapRef as React.MutableRefObject<HTMLElement | null>).current = dialogRef.current;\n }\n }, [trapRef]);\n\n // Body scroll lock when modal is open\n useEffect(() => {\n if (!isOpen || !isModal) {\n return;\n }\n\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.body.style.overflow = originalOverflow;\n };\n }, [isOpen, isModal]);\n\n // Development-time validation\n useEffect(() => {\n if (typeof __DEV__ !== 'undefined' && __DEV__ && isOpen) {\n import('@a13y/devtools/runtime/invariants').then(\n ({ assertHasAccessibleName, assertValidAriaAttributes }) => {\n if (dialogRef.current) {\n assertHasAccessibleName(dialogRef.current, 'useAccessibleDialog');\n assertValidAriaAttributes(dialogRef.current);\n }\n }\n );\n }\n }, [isOpen]);\n\n const dialogProps: DialogContainerProps = {\n ref: dialogRef,\n role,\n 'aria-labelledby': titleId,\n 'aria-describedby': description ? descriptionId : undefined,\n 'aria-modal': isModal,\n tabIndex: -1,\n };\n\n const titleProps: DialogTitleProps = {\n id: titleId,\n };\n\n const descriptionProps: DialogDescriptionProps | null = description\n ? { id: descriptionId }\n : null;\n\n const backdropProps: DialogBackdropProps | null =\n closeOnBackdropClick && isModal\n ? {\n onClick: onClose,\n 'aria-hidden': true,\n }\n : null;\n\n return {\n dialogProps,\n titleProps,\n descriptionProps,\n backdropProps,\n close: onClose,\n };\n};\n","/**\n * @a13y/react - AccessibleDialog Component\n * Type-safe dialog component with enforced title\n */\n\nimport type { ReactNode } from 'react';\nimport { useAccessibleDialog } from '../hooks/use-accessible-dialog';\n\n/**\n * Props for AccessibleDialog\n */\nexport interface AccessibleDialogProps {\n /**\n * Whether dialog is open\n */\n isOpen: boolean;\n\n /**\n * Called when dialog should close\n */\n onClose: () => void;\n\n /**\n * Dialog title - REQUIRED for accessibility\n * This will be announced to screen readers\n */\n title: string;\n\n /**\n * Dialog content\n */\n children: ReactNode;\n\n /**\n * Optional description\n * Provides additional context to screen readers\n */\n description?: string;\n\n /**\n * ARIA role\n */\n role?: 'dialog' | 'alertdialog';\n\n /**\n * Whether to show close button\n */\n showCloseButton?: boolean;\n\n /**\n * Custom className for dialog container\n */\n className?: string;\n\n /**\n * Custom className for backdrop\n */\n backdropClassName?: string;\n}\n\n/**\n * Accessible Dialog Component\n *\n * Features:\n * - Focus trap with Tab/Shift+Tab cycling\n * - Escape key to close\n * - Focus restoration on close\n * - Click outside to close\n * - Required title for screen readers\n * - Body scroll lock when open\n *\n * @example\n * ```tsx\n * <AccessibleDialog\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * title=\"Confirm Action\"\n * description=\"This action cannot be undone\"\n * >\n * <p>Are you sure you want to delete this item?</p>\n * <button onClick={handleConfirm}>Confirm</button>\n * <button onClick={() => setIsOpen(false)}>Cancel</button>\n * </AccessibleDialog>\n * ```\n */\nexport const AccessibleDialog = (props: AccessibleDialogProps) => {\n const {\n isOpen,\n onClose,\n title,\n children,\n description,\n role = 'dialog',\n showCloseButton = true,\n className = '',\n backdropClassName = '',\n } = props;\n\n const { dialogProps, titleProps, descriptionProps, backdropProps, close } = useAccessibleDialog({\n isOpen,\n onClose,\n title,\n description,\n role,\n isModal: true,\n closeOnBackdropClick: true,\n });\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n {/* Backdrop */}\n {backdropProps && (\n <div\n {...backdropProps}\n className={backdropClassName}\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 50,\n }}\n />\n )}\n\n {/* Dialog */}\n <div\n ref={dialogProps.ref as React.RefObject<HTMLDivElement>}\n role={dialogProps.role}\n aria-labelledby={dialogProps['aria-labelledby']}\n aria-describedby={dialogProps['aria-describedby']}\n aria-modal={dialogProps['aria-modal']}\n tabIndex={dialogProps.tabIndex}\n className={className}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n backgroundColor: 'white',\n borderRadius: '0.5rem',\n boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1)',\n padding: '1.5rem',\n maxWidth: '32rem',\n width: '90vw',\n maxHeight: '90vh',\n overflow: 'auto',\n zIndex: 51,\n }}\n >\n {/* Close button */}\n {showCloseButton && (\n <button\n type=\"button\"\n onClick={close}\n aria-label=\"Close dialog\"\n style={{\n position: 'absolute',\n top: '1rem',\n right: '1rem',\n padding: '0.5rem',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n fontSize: '1.25rem',\n lineHeight: 1,\n color: '#6b7280',\n }}\n >\n ✕\n </button>\n )}\n\n {/* Title */}\n <h2\n {...titleProps}\n style={{\n fontSize: '1.25rem',\n fontWeight: 600,\n marginBottom: description ? '0.5rem' : '1rem',\n paddingRight: showCloseButton ? '2rem' : 0,\n }}\n >\n {title}\n </h2>\n\n {/* Description */}\n {descriptionProps && description && (\n <p\n {...descriptionProps}\n style={{\n fontSize: '0.875rem',\n color: '#6b7280',\n marginBottom: '1rem',\n }}\n >\n {description}\n </p>\n )}\n\n {/* Content */}\n <div>{children}</div>\n </div>\n </>\n );\n};\n","/**\n * @a13y/react - DialogStack Pattern\n * Manages nested modals with proper focus restoration and z-index layering\n */\n\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useEffect, useState } from 'react';\nimport { AccessibleDialog } from '../components/AccessibleDialog';\n\n/**\n * Dialog in the stack\n */\ninterface StackedDialog {\n id: string;\n title: string;\n content: ReactNode;\n description?: string;\n onClose: () => void;\n zIndex: number;\n}\n\n/**\n * Dialog stack context\n */\ninterface DialogStackContextValue {\n /**\n * Push a new dialog onto the stack\n */\n push: (dialog: Omit<StackedDialog, 'zIndex'>) => void;\n\n /**\n * Pop the topmost dialog\n */\n pop: () => void;\n\n /**\n * Close a specific dialog by ID\n */\n close: (id: string) => void;\n\n /**\n * Close all dialogs\n */\n closeAll: () => void;\n\n /**\n * Current stack depth\n */\n depth: number;\n}\n\nconst DialogStackContext = createContext<DialogStackContextValue | null>(null);\n\n/**\n * Hook to access dialog stack\n */\nexport const useDialogStack = (): DialogStackContextValue => {\n const context = useContext(DialogStackContext);\n if (!context) {\n throw new Error('useDialogStack must be used within DialogStackProvider');\n }\n return context;\n};\n\n/**\n * Props for DialogStackProvider\n */\nexport interface DialogStackProviderProps {\n children: ReactNode;\n /**\n * Base z-index for dialogs\n * @default 1000\n */\n baseZIndex?: number;\n /**\n * Z-index increment between layers\n * @default 10\n */\n zIndexIncrement?: number;\n}\n\n/**\n * Dialog Stack Provider\n *\n * Manages a stack of nested dialogs with:\n * - Automatic z-index management\n * - Focus restoration chain\n * - Escape key closes topmost dialog only\n * - Backdrop isolation per layer\n *\n * Pattern Explanation:\n * - Each dialog gets a unique z-index: base + (depth * increment)\n * - Focus is trapped in the topmost dialog\n * - When a dialog closes, focus returns to the previous dialog\n * - Escape key only affects the topmost dialog\n * - Body scroll is locked when any dialog is open\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <DialogStackProvider>\n * <MyComponent />\n * </DialogStackProvider>\n * );\n * }\n *\n * function MyComponent() {\n * const { push, pop } = useDialogStack();\n *\n * return (\n * <button onClick={() => push({\n * id: 'dialog1',\n * title: 'First Dialog',\n * content: <SecondLevelDialog />,\n * onClose: () => pop(),\n * })}>\n * Open Dialog\n * </button>\n * );\n * }\n *\n * function SecondLevelDialog() {\n * const { push, pop } = useDialogStack();\n *\n * return (\n * <button onClick={() => push({\n * id: 'dialog2',\n * title: 'Nested Dialog',\n * content: <p>This is nested!</p>,\n * onClose: () => pop(),\n * })}>\n * Open Nested Dialog\n * </button>\n * );\n * }\n * ```\n */\nexport const DialogStackProvider = (props: DialogStackProviderProps) => {\n const { children, baseZIndex = 1000, zIndexIncrement = 10 } = props;\n\n const [stack, setStack] = useState<StackedDialog[]>([]);\n\n const push = (dialog: Omit<StackedDialog, 'zIndex'>) => {\n const zIndex = baseZIndex + stack.length * zIndexIncrement;\n setStack((prev) => [...prev, { ...dialog, zIndex }]);\n };\n\n const pop = () => {\n setStack((prev) => {\n const newStack = [...prev];\n const dialog = newStack.pop();\n dialog?.onClose();\n return newStack;\n });\n };\n\n const close = (id: string) => {\n setStack((prev) => {\n const index = prev.findIndex((d) => d.id === id);\n if (index === -1) return prev;\n\n // Close this dialog and all dialogs above it\n const closedDialogs = prev.slice(index);\n for (const d of closedDialogs) {\n d.onClose();\n }\n\n return prev.slice(0, index);\n });\n };\n\n const closeAll = () => {\n for (const d of stack) {\n d.onClose();\n }\n setStack([]);\n };\n\n // Body scroll lock when stack is not empty\n useEffect(() => {\n if (stack.length > 0) {\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.body.style.overflow = originalOverflow;\n };\n }\n }, [stack.length]);\n\n const contextValue: DialogStackContextValue = {\n push,\n pop,\n close,\n closeAll,\n depth: stack.length,\n };\n\n return (\n <DialogStackContext.Provider value={contextValue}>\n {children}\n\n {/* Render all dialogs in the stack */}\n {stack.map((dialog) => (\n <div key={dialog.id} style={{ zIndex: dialog.zIndex }}>\n <AccessibleDialog\n isOpen={true}\n onClose={() => close(dialog.id)}\n title={dialog.title}\n description={dialog.description}\n backdropClassName=\"dialog-stack-backdrop\"\n >\n {dialog.content}\n </AccessibleDialog>\n </div>\n ))}\n </DialogStackContext.Provider>\n );\n};\n","/**\n * @a13y/react - InfiniteList Pattern\n * Accessible infinite scroll with lazy loading\n */\n\nimport { announce } from '@a13y/core/runtime/announce';\nimport type { ReactNode } from 'react';\nimport { useEffect, useRef, useState } from 'react';\n\n/**\n * Props for InfiniteList\n */\nexport interface InfiniteListProps<T> {\n /**\n * Current items in the list\n */\n items: T[];\n\n /**\n * Function to load more items\n * Should return a promise that resolves to new items\n */\n loadMore: () => Promise<T[]>;\n\n /**\n * Check if there are more items to load\n */\n hasMore: boolean;\n\n /**\n * Check if currently loading\n */\n isLoading: boolean;\n\n /**\n * Render function for each item\n */\n renderItem: (item: T, index: number) => ReactNode;\n\n /**\n * Unique key extractor\n */\n getItemKey: (item: T, index: number) => string;\n\n /**\n * Loading indicator\n */\n loadingIndicator?: ReactNode;\n\n /**\n * Empty state\n */\n emptyState?: ReactNode;\n\n /**\n * Accessible label for the list\n */\n 'aria-label': string;\n\n /**\n * Distance from bottom to trigger load (px)\n * @default 200\n */\n threshold?: number;\n\n /**\n * Custom className\n */\n className?: string;\n}\n\n/**\n * Infinite List Component\n *\n * Accessible infinite scroll with:\n * - Intersection Observer for lazy loading\n * - Screen reader announcements for new items\n * - Keyboard navigation (Tab through items)\n * - Loading states announced\n * - Total count announcements\n *\n * Pattern Explanation:\n * - Uses Intersection Observer to detect when user scrolls near bottom\n * - Announces new items loaded to screen readers\n * - Maintains focus position when new items are added\n * - Works with keyboard navigation (no mouse required)\n * - Provides loading and empty states\n *\n * @example\n * ```tsx\n * const [items, setItems] = useState<Item[]>([]);\n * const [hasMore, setHasMore] = useState(true);\n * const [isLoading, setIsLoading] = useState(false);\n *\n * const loadMore = async () => {\n * setIsLoading(true);\n * const newItems = await fetchItems(items.length, 20);\n * setItems([...items, ...newItems]);\n * setHasMore(newItems.length === 20);\n * setIsLoading(false);\n * return newItems;\n * };\n *\n * return (\n * <InfiniteList\n * items={items}\n * loadMore={loadMore}\n * hasMore={hasMore}\n * isLoading={isLoading}\n * renderItem={(item) => <ItemCard item={item} />}\n * getItemKey={(item) => item.id}\n * aria-label=\"Products list\"\n * />\n * );\n * ```\n */\nexport const InfiniteList = <T,>(props: InfiniteListProps<T>) => {\n const {\n items,\n loadMore,\n hasMore,\n isLoading,\n renderItem,\n getItemKey,\n loadingIndicator,\n emptyState,\n 'aria-label': ariaLabel,\n threshold = 200,\n className = '',\n } = props;\n\n const [previousCount, setPreviousCount] = useState(items.length);\n const sentinelRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n\n // Announce new items to screen readers\n useEffect(() => {\n if (items.length > previousCount && !isLoading) {\n const newItemsCount = items.length - previousCount;\n announce(\n `${newItemsCount} new item${newItemsCount === 1 ? '' : 's'} loaded. Total: ${items.length}`,\n { politeness: 'polite', delay: 500 }\n );\n setPreviousCount(items.length);\n }\n }, [items.length, previousCount, isLoading]);\n\n // Announce loading state\n useEffect(() => {\n if (isLoading) {\n announce('Loading more items', { politeness: 'polite' });\n }\n }, [isLoading]);\n\n // Intersection Observer for infinite scroll\n useEffect(() => {\n if (!hasMore || isLoading || !sentinelRef.current) {\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n const sentinel = entries[0];\n if (sentinel?.isIntersecting) {\n loadMore();\n }\n },\n {\n root: null,\n rootMargin: `${threshold}px`,\n threshold: 0,\n }\n );\n\n observer.observe(sentinelRef.current);\n\n return () => observer.disconnect();\n }, [hasMore, isLoading, loadMore, threshold]);\n\n // Empty state\n if (items.length === 0 && !isLoading) {\n return (\n <div role=\"status\" aria-live=\"polite\">\n {emptyState || <p>No items to display</p>}\n </div>\n );\n }\n\n return (\n <div ref={listRef} className={className}>\n {/* List */}\n <div role=\"list\" aria-label={ariaLabel} aria-busy={isLoading}>\n {items.map((item, index) => (\n <div key={getItemKey(item, index)} role=\"listitem\">\n {renderItem(item, index)}\n </div>\n ))}\n </div>\n\n {/* Loading indicator */}\n {isLoading && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading more items\"\n style={{\n padding: '1rem',\n textAlign: 'center',\n }}\n >\n {loadingIndicator || <span>Loading...</span>}\n </div>\n )}\n\n {/* Sentinel for intersection observer */}\n {hasMore && !isLoading && (\n <div ref={sentinelRef} aria-hidden=\"true\" style={{ height: '1px', visibility: 'hidden' }} />\n )}\n\n {/* End message */}\n {!hasMore && items.length > 0 && (\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{\n padding: '1rem',\n textAlign: 'center',\n color: '#6b7280',\n fontSize: '0.875rem',\n }}\n >\n End of list. Total: {items.length} items.\n </div>\n )}\n </div>\n );\n};\n","/**\n * @a13y/react - useAccessibleButton\n * Type-safe button hook with keyboard support\n */\n\nimport type { AriaRole } from 'react';\nimport { useCallback, useEffect, useRef } from 'react';\n\n/**\n * Button press event (mouse or keyboard)\n */\nexport interface PressEvent {\n type: 'mouse' | 'keyboard';\n key?: string;\n}\n\n/**\n * Props for useAccessibleButton\n */\nexport interface UseAccessibleButtonProps {\n /**\n * Accessible label for the button\n * Required if button content is not text (e.g., icon-only)\n */\n label?: string;\n\n /**\n * Press handler - called on click or Enter/Space\n */\n onPress: (event: PressEvent) => void;\n\n /**\n * Whether the button is disabled\n */\n isDisabled?: boolean;\n\n /**\n * ARIA role override\n * @default 'button'\n */\n role?: Extract<AriaRole, 'button' | 'link'>;\n\n /**\n * Element type - only 'button' or 'a' allowed\n * @default 'button'\n */\n elementType?: 'button' | 'a';\n}\n\n/**\n * Button props returned by the hook\n */\nexport interface AccessibleButtonProps {\n role: AriaRole;\n tabIndex: number;\n 'aria-label'?: string;\n 'aria-disabled'?: boolean;\n disabled?: boolean;\n onPointerDown: (event: React.PointerEvent) => void;\n onKeyDown: (event: React.KeyboardEvent) => void;\n}\n\n/**\n * Return type\n */\nexport interface UseAccessibleButtonReturn {\n buttonProps: AccessibleButtonProps;\n isPressed: boolean;\n}\n\n/**\n * Hook for creating accessible buttons\n *\n * Features:\n * - Keyboard support (Enter, Space)\n * - Disabled state handling\n * - Automatic ARIA attributes\n * - Development-time validation\n *\n * @example\n * ```tsx\n * const { buttonProps } = useAccessibleButton({\n * label: 'Delete item',\n * onPress: () => console.log('Pressed!'),\n * });\n *\n * return <button {...buttonProps}>🗑️</button>;\n * ```\n */\nexport const useAccessibleButton = (props: UseAccessibleButtonProps): UseAccessibleButtonReturn => {\n const { label, onPress, isDisabled = false, role = 'button', elementType = 'button' } = props;\n\n const buttonRef = useRef<HTMLElement | null>(null);\n const isPressedRef = useRef(false);\n\n // Development-time validation\n useEffect(() => {\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n import('@a13y/devtools/runtime/invariants').then(\n ({ assertHasAccessibleName, assertKeyboardAccessible }) => {\n if (buttonRef.current) {\n // Validate accessible name\n assertHasAccessibleName(buttonRef.current, 'useAccessibleButton');\n\n // Validate keyboard accessibility\n assertKeyboardAccessible(buttonRef.current, 'useAccessibleButton');\n }\n }\n );\n }\n }, []);\n\n const handlePress = useCallback(\n (event: PressEvent) => {\n if (isDisabled) {\n return;\n }\n onPress(event);\n },\n [onPress, isDisabled]\n );\n\n const handlePointerDown = useCallback(\n (event: React.PointerEvent) => {\n if (isDisabled) {\n event.preventDefault();\n return;\n }\n\n isPressedRef.current = true;\n handlePress({ type: 'mouse' });\n },\n [handlePress, isDisabled]\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (isDisabled) {\n return;\n }\n\n // Enter or Space activates button\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handlePress({ type: 'keyboard', key: event.key });\n }\n },\n [handlePress, isDisabled]\n );\n\n const buttonProps: AccessibleButtonProps = {\n role,\n tabIndex: isDisabled ? -1 : 0,\n 'aria-label': label,\n 'aria-disabled': isDisabled ? true : undefined,\n disabled: elementType === 'button' ? isDisabled : undefined,\n onPointerDown: handlePointerDown,\n onKeyDown: handleKeyDown,\n };\n\n return {\n buttonProps,\n isPressed: isPressedRef.current,\n };\n};\n","/**\n * @a13y/react - useKeyboardNavigation\n * Roving tabindex keyboard navigation hook\n */\n\nimport type { NavigationDirection } from '@a13y/core/runtime/keyboard';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n/**\n * Navigation orientation\n */\nexport type Orientation = 'horizontal' | 'vertical' | 'both';\n\n/**\n * Props for useKeyboardNavigation\n */\nexport interface UseKeyboardNavigationProps {\n /**\n * Navigation orientation\n * - 'horizontal': Arrow Left/Right\n * - 'vertical': Arrow Up/Down\n * - 'both': All arrow keys\n */\n orientation: Orientation;\n\n /**\n * Whether to loop at boundaries\n * @default false\n */\n loop?: boolean;\n\n /**\n * Callback when navigation occurs\n */\n onNavigate?: (index: number) => void;\n\n /**\n * Initial focused index\n * @default 0\n */\n defaultIndex?: number;\n\n /**\n * Controlled current index\n */\n currentIndex?: number;\n}\n\n/**\n * Item props for navigable items\n */\nexport interface NavigableItemProps {\n ref: (element: HTMLElement | null) => void;\n tabIndex: number;\n onKeyDown: (event: React.KeyboardEvent) => void;\n 'data-index': number;\n}\n\n/**\n * Return type\n */\nexport interface UseKeyboardNavigationReturn {\n /**\n * Current focused index\n */\n currentIndex: number;\n\n /**\n * Navigate to specific index\n */\n setCurrentIndex: (index: number) => void;\n\n /**\n * Get props for navigable item\n */\n getItemProps: (index: number) => NavigableItemProps;\n\n /**\n * Container props\n */\n containerProps: {\n role: 'toolbar' | 'listbox' | 'menu';\n 'aria-orientation': Orientation;\n };\n}\n\n/**\n * Hook for keyboard navigation with roving tabindex\n *\n * Features:\n * - Arrow key navigation\n * - Home/End navigation\n * - Roving tabindex pattern\n * - Automatic focus management\n * - Development-time validation\n *\n * @example\n * ```tsx\n * const { containerProps, getItemProps, currentIndex } =\n * useKeyboardNavigation({\n * orientation: 'horizontal',\n * loop: true,\n * });\n *\n * return (\n * <div {...containerProps}>\n * {items.map((item, index) => (\n * <button key={index} {...getItemProps(index)}>\n * {item.label}\n * </button>\n * ))}\n * </div>\n * );\n * ```\n */\nexport const useKeyboardNavigation = (\n props: UseKeyboardNavigationProps\n): UseKeyboardNavigationReturn => {\n const {\n orientation,\n loop = false,\n onNavigate,\n defaultIndex = 0,\n currentIndex: controlledIndex,\n } = props;\n\n const isControlled = controlledIndex !== undefined;\n const [uncontrolledIndex, setUncontrolledIndex] = useState(defaultIndex);\n const currentIndex = isControlled ? controlledIndex : uncontrolledIndex;\n\n const itemsRef = useRef<Map<number, HTMLElement>>(new Map());\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Update current index\n const setCurrentIndex = useCallback(\n (index: number) => {\n if (!isControlled) {\n setUncontrolledIndex(index);\n }\n onNavigate?.(index);\n\n // Focus the element\n const element = itemsRef.current.get(index);\n if (element) {\n element.focus();\n }\n },\n [isControlled, onNavigate]\n );\n\n // Navigate in direction\n const navigate = useCallback(\n (direction: NavigationDirection) => {\n const itemCount = itemsRef.current.size;\n if (itemCount === 0) {\n return;\n }\n\n let nextIndex = currentIndex;\n\n switch (direction) {\n case 'forward':\n nextIndex = currentIndex + 1;\n if (nextIndex >= itemCount) {\n nextIndex = loop ? 0 : itemCount - 1;\n }\n break;\n\n case 'backward':\n nextIndex = currentIndex - 1;\n if (nextIndex < 0) {\n nextIndex = loop ? itemCount - 1 : 0;\n }\n break;\n\n case 'first':\n nextIndex = 0;\n break;\n\n case 'last':\n nextIndex = itemCount - 1;\n break;\n }\n\n if (nextIndex !== currentIndex) {\n setCurrentIndex(nextIndex);\n }\n },\n [currentIndex, loop, setCurrentIndex]\n );\n\n // Handle keyboard events\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n const { key } = event;\n\n let direction: NavigationDirection | null = null;\n\n // Arrow keys\n if (key === 'ArrowRight') {\n if (orientation === 'horizontal' || orientation === 'both') {\n direction = 'forward';\n }\n } else if (key === 'ArrowLeft') {\n if (orientation === 'horizontal' || orientation === 'both') {\n direction = 'backward';\n }\n } else if (key === 'ArrowDown') {\n if (orientation === 'vertical' || orientation === 'both') {\n direction = 'forward';\n }\n } else if (key === 'ArrowUp') {\n if (orientation === 'vertical' || orientation === 'both') {\n direction = 'backward';\n }\n }\n\n // Home/End\n else if (key === 'Home') {\n direction = 'first';\n } else if (key === 'End') {\n direction = 'last';\n }\n\n if (direction) {\n event.preventDefault();\n navigate(direction);\n }\n },\n [orientation, navigate]\n );\n\n // Get props for individual item\n const getItemProps = useCallback(\n (index: number): NavigableItemProps => {\n return {\n ref: (element: HTMLElement | null) => {\n if (element) {\n itemsRef.current.set(index, element);\n } else {\n itemsRef.current.delete(index);\n }\n },\n tabIndex: index === currentIndex ? 0 : -1,\n onKeyDown: handleKeyDown,\n 'data-index': index,\n };\n },\n [currentIndex, handleKeyDown]\n );\n\n // Development-time validation\n useEffect(() => {\n if (typeof __DEV__ !== 'undefined' && __DEV__) {\n import('@a13y/devtools/runtime/validators').then(({ keyboardValidator }) => {\n // Validate container\n if (containerRef.current) {\n keyboardValidator.validateContainer(containerRef.current);\n }\n\n // Validate roving tabindex\n const container = Array.from(itemsRef.current.values())[0]?.parentElement;\n if (container) {\n keyboardValidator.validateRovingTabindex(container);\n }\n });\n }\n }, []);\n\n const containerProps = {\n role: 'toolbar' as const,\n 'aria-orientation': orientation,\n };\n\n return {\n currentIndex,\n setCurrentIndex,\n getItemProps,\n containerProps,\n };\n};\n","/**\n * @a13y/react - NestedMenu Pattern\n * Multi-level dropdown menu with keyboard navigation\n */\n\nimport type { ReactNode } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { useAccessibleButton } from '../hooks/use-accessible-button';\nimport { useKeyboardNavigation } from '../hooks/use-keyboard-navigation';\n\n/**\n * Menu item with optional submenu\n */\nexport interface NestedMenuItem {\n id: string;\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n /**\n * Action when item is selected\n * Omit for items with submenu\n */\n onPress?: () => void;\n /**\n * Submenu items\n */\n submenu?: NestedMenuItem[];\n}\n\n/**\n * Props for NestedMenu\n */\nexport interface NestedMenuProps {\n /**\n * Menu trigger label for screen readers\n */\n label: string;\n /**\n * Trigger content\n */\n trigger: ReactNode;\n /**\n * Menu items (can have nested submenus)\n */\n items: NestedMenuItem[];\n /**\n * Custom className for trigger\n */\n className?: string;\n}\n\n/**\n * Nested Menu Component\n *\n * Multi-level dropdown menu with full keyboard navigation:\n * - Arrow Up/Down: Navigate items\n * - Arrow Right: Open submenu\n * - Arrow Left: Close submenu and return to parent\n * - Enter/Space: Select item or open submenu\n * - Escape: Close current menu level\n *\n * Pattern Explanation:\n * - Each submenu level maintains its own navigation state\n * - Arrow Right on item with submenu opens it\n * - Arrow Left closes submenu and returns focus to parent item\n * - Screen readers announce submenu availability via aria-haspopup\n * - Submenus are positioned relative to parent items\n * - Focus is trapped within the active menu level\n *\n * @example\n * ```tsx\n * <NestedMenu\n * label=\"File menu\"\n * trigger=\"File ▼\"\n * items={[\n * {\n * id: 'new',\n * label: 'New',\n * submenu: [\n * { id: 'file', label: 'File', onPress: () => console.log('New File') },\n * { id: 'folder', label: 'Folder', onPress: () => console.log('New Folder') },\n * ],\n * },\n * { id: 'open', label: 'Open', onPress: () => console.log('Open') },\n * {\n * id: 'recent',\n * label: 'Open Recent',\n * submenu: [\n * { id: 'file1', label: 'document.txt', onPress: () => {} },\n * { id: 'file2', label: 'project.json', onPress: () => {} },\n * ],\n * },\n * ]}\n * />\n * ```\n */\nexport const NestedMenu = (props: NestedMenuProps) => {\n const { label, trigger, items, className = '' } = props;\n\n const [isOpen, setIsOpen] = useState(false);\n const [openSubmenuId, setOpenSubmenuId] = useState<string | null>(null);\n\n // Trigger button\n const { buttonProps } = useAccessibleButton({\n label,\n onPress: () => setIsOpen(!isOpen),\n });\n\n // Close menu on Escape\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen) {\n setIsOpen(false);\n setOpenSubmenuId(null);\n }\n };\n\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [isOpen]);\n\n return (\n <div style={{ position: 'relative', display: 'inline-block' }}>\n <button\n {...buttonProps}\n aria-expanded={isOpen}\n aria-haspopup=\"true\"\n className={className}\n style={{\n padding: '0.5rem 1rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: 'white',\n cursor: 'pointer',\n }}\n >\n {trigger}\n </button>\n\n {isOpen && (\n <MenuLevel\n items={items}\n onClose={() => setIsOpen(false)}\n openSubmenuId={openSubmenuId}\n onSubmenuChange={setOpenSubmenuId}\n depth={0}\n />\n )}\n </div>\n );\n};\n\n/**\n * Single menu level (supports recursion for submenus)\n */\ninterface MenuLevelProps {\n items: NestedMenuItem[];\n onClose: () => void;\n openSubmenuId: string | null;\n onSubmenuChange: (id: string | null) => void;\n depth: number;\n}\n\nconst MenuLevel = (props: MenuLevelProps) => {\n const { items, onClose, openSubmenuId, onSubmenuChange, depth } = props;\n\n const menuRef = useRef<HTMLDivElement>(null);\n\n // Keyboard navigation\n const { getItemProps, setCurrentIndex } = useKeyboardNavigation({\n orientation: 'vertical',\n loop: true,\n });\n\n const handleItemKeyDown = (e: React.KeyboardEvent, item: NestedMenuItem) => {\n // Arrow Right: Open submenu\n if (e.key === 'ArrowRight' && item.submenu) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuChange(item.id);\n }\n\n // Arrow Left: Close submenu (only if this is a submenu)\n if (e.key === 'ArrowLeft' && depth > 0) {\n e.preventDefault();\n e.stopPropagation();\n onSubmenuChange(null);\n }\n\n // Enter/Space: Execute action or open submenu\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n\n if (item.submenu) {\n onSubmenuChange(item.id);\n } else if (item.onPress && !item.disabled) {\n item.onPress();\n onClose();\n }\n }\n };\n\n const handleItemClick = (item: NestedMenuItem) => {\n if (item.disabled) return;\n\n if (item.submenu) {\n onSubmenuChange(openSubmenuId === item.id ? null : item.id);\n } else if (item.onPress) {\n item.onPress();\n onClose();\n }\n };\n\n return (\n <div\n ref={menuRef}\n role=\"menu\"\n aria-orientation=\"vertical\"\n style={{\n position: depth === 0 ? 'absolute' : 'absolute',\n top: depth === 0 ? 'calc(100% + 0.25rem)' : 0,\n left: depth === 0 ? 0 : '100%',\n minWidth: '12rem',\n backgroundColor: 'white',\n border: '1px solid #e5e7eb',\n borderRadius: '0.375rem',\n boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n padding: '0.25rem',\n zIndex: 50 + depth,\n }}\n >\n {items.map((item, index) => {\n const itemProps = getItemProps(index);\n const hasSubmenu = !!item.submenu;\n const isSubmenuOpen = openSubmenuId === item.id;\n\n return (\n <div key={item.id} style={{ position: 'relative' }}>\n <button\n {...itemProps}\n role=\"menuitem\"\n aria-haspopup={hasSubmenu ? 'true' : undefined}\n aria-expanded={hasSubmenu ? isSubmenuOpen : undefined}\n disabled={item.disabled}\n onClick={() => handleItemClick(item)}\n onKeyDown={(e) => handleItemKeyDown(e, item)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '0.75rem',\n width: '100%',\n padding: '0.5rem 0.75rem',\n border: 'none',\n background: 'transparent',\n textAlign: 'left',\n fontSize: '0.875rem',\n cursor: item.disabled ? 'not-allowed' : 'pointer',\n borderRadius: '0.25rem',\n color: item.disabled ? '#9ca3af' : '#111827',\n opacity: item.disabled ? 0.5 : 1,\n }}\n onMouseEnter={(e) => {\n if (!item.disabled) {\n e.currentTarget.style.backgroundColor = '#f3f4f6';\n setCurrentIndex(index);\n if (hasSubmenu) {\n onSubmenuChange(item.id);\n }\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>\n {item.icon && <span>{item.icon}</span>}\n <span>{item.label}</span>\n </span>\n {hasSubmenu && <span aria-hidden=\"true\">▶</span>}\n </button>\n\n {/* Render submenu recursively */}\n {hasSubmenu && isSubmenuOpen && item.submenu && (\n <MenuLevel\n items={item.submenu}\n onClose={onClose}\n openSubmenuId={null}\n onSubmenuChange={() => {}}\n depth={depth + 1}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n};\n","/**\n * @a13y/react - VirtualizedList Pattern\n * Accessible virtualized list with screen reader support\n */\n\nimport { announce } from '@a13y/core/runtime/announce';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useEffect, useRef, useState } from 'react';\n\n/**\n * Props for VirtualizedList\n */\nexport interface VirtualizedListProps<T> {\n /**\n * All items in the list\n */\n items: T[];\n\n /**\n * Height of each item (fixed)\n */\n itemHeight: number;\n\n /**\n * Height of the visible container\n */\n height: number;\n\n /**\n * Render function for each item\n */\n renderItem: (item: T, index: number) => ReactNode;\n\n /**\n * Unique key extractor\n */\n getItemKey: (item: T, index: number) => string;\n\n /**\n * Accessible label for the list\n */\n 'aria-label': string;\n\n /**\n * Number of items to render outside viewport (overscan)\n * @default 3\n */\n overscan?: number;\n\n /**\n * Custom className\n */\n className?: string;\n\n /**\n * Empty state\n */\n emptyState?: ReactNode;\n}\n\n/**\n * Virtualized List Component\n *\n * Accessible virtualized list that works with screen readers:\n * - Only renders visible items + overscan\n * - Maintains total height for scrollbar\n * - Announces visible range to screen readers\n * - Keyboard navigation works correctly\n * - Focus management when scrolling\n *\n * Pattern Explanation:\n * - Calculates visible range based on scroll position\n * - Renders only visible items + overscan buffer\n * - Uses absolute positioning to maintain item positions\n * - Announces visible range changes to screen readers\n * - Total height maintained for accurate scrollbar\n * - Works with keyboard navigation (Page Up/Down, Home/End)\n *\n * Screen Reader Strategy:\n * - aria-setsize and aria-posinset tell screen readers total count\n * - Visible range announced when user scrolls\n * - Focus is maintained when items are virtualized\n *\n * @example\n * ```tsx\n * const items = Array.from({ length: 10000 }, (_, i) => ({\n * id: i,\n * name: `Item ${i}`,\n * }));\n *\n * return (\n * <VirtualizedList\n * items={items}\n * itemHeight={48}\n * height={600}\n * renderItem={(item) => (\n * <div style={{ padding: '0.75rem' }}>\n * {item.name}\n * </div>\n * )}\n * getItemKey={(item) => item.id.toString()}\n * aria-label=\"Large list of items\"\n * />\n * );\n * ```\n */\nexport const VirtualizedList = <T,>(props: VirtualizedListProps<T>) => {\n const {\n items,\n itemHeight,\n height,\n renderItem,\n getItemKey,\n 'aria-label': ariaLabel,\n overscan = 3,\n className = '',\n emptyState,\n } = props;\n\n const [scrollTop, setScrollTop] = useState(0);\n const [visibleRange, setVisibleRange] = useState({ start: 0, end: 0 });\n const containerRef = useRef<HTMLDivElement>(null);\n const previousRangeRef = useRef({ start: 0, end: 0 });\n\n const totalHeight = items.length * itemHeight;\n const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);\n const endIndex = Math.min(\n items.length - 1,\n Math.ceil((scrollTop + height) / itemHeight) + overscan\n );\n\n const visibleItems = items.slice(startIndex, endIndex + 1);\n\n // Announce visible range to screen readers (throttled)\n useEffect(() => {\n const newRange = { start: startIndex, end: endIndex };\n\n // Only announce if range changed significantly (more than 10 items)\n const rangeChanged =\n Math.abs(newRange.start - previousRangeRef.current.start) > 10 ||\n Math.abs(newRange.end - previousRangeRef.current.end) > 10;\n\n if (rangeChanged && items.length > 0) {\n setVisibleRange(newRange);\n previousRangeRef.current = newRange;\n\n // Announce visible range\n const message = `Showing items ${newRange.start + 1} to ${newRange.end + 1} of ${items.length}`;\n announce(message, { politeness: 'polite', delay: 300 });\n }\n }, [startIndex, endIndex, items.length]);\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {\n setScrollTop(e.currentTarget.scrollTop);\n };\n\n // Keyboard navigation helpers\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!containerRef.current) return;\n\n const scrollAmount = itemHeight * 5; // Scroll 5 items at a time\n\n switch (e.key) {\n case 'PageDown':\n e.preventDefault();\n containerRef.current.scrollBy({ top: scrollAmount, behavior: 'smooth' });\n break;\n\n case 'PageUp':\n e.preventDefault();\n containerRef.current.scrollBy({ top: -scrollAmount, behavior: 'smooth' });\n break;\n\n case 'Home':\n e.preventDefault();\n containerRef.current.scrollTo({ top: 0, behavior: 'smooth' });\n break;\n\n case 'End':\n e.preventDefault();\n containerRef.current.scrollTo({ top: totalHeight, behavior: 'smooth' });\n break;\n }\n };\n\n // Empty state\n if (items.length === 0) {\n return (\n <div role=\"status\" aria-live=\"polite\">\n {emptyState || <p>No items to display</p>}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n role=\"list\"\n aria-label={ariaLabel}\n tabIndex={0}\n className={className}\n onScroll={handleScroll}\n onKeyDown={handleKeyDown}\n style={{\n height: `${height}px`,\n overflow: 'auto',\n position: 'relative',\n outline: 'none',\n }}\n >\n {/* Total height spacer */}\n <div style={{ height: `${totalHeight}px`, position: 'relative' }}>\n {/* Visible items */}\n {visibleItems.map((item, virtualIndex) => {\n const actualIndex = startIndex + virtualIndex;\n const itemStyle: CSSProperties = {\n position: 'absolute',\n top: `${actualIndex * itemHeight}px`,\n left: 0,\n right: 0,\n height: `${itemHeight}px`,\n };\n\n return (\n <div\n key={getItemKey(item, actualIndex)}\n role=\"listitem\"\n aria-setsize={items.length}\n aria-posinset={actualIndex + 1}\n style={itemStyle}\n >\n {renderItem(item, actualIndex)}\n </div>\n );\n })}\n </div>\n\n {/* Screen reader helper */}\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style={{\n position: 'absolute',\n left: '-10000px',\n width: '1px',\n height: '1px',\n overflow: 'hidden',\n }}\n >\n {`Showing items ${visibleRange.start + 1} to ${visibleRange.end + 1} of ${items.length}`}\n </div>\n </div>\n );\n};\n","/**\n * @a13y/react - Wizard Pattern\n * Multi-step form with validation and keyboard navigation\n */\n\nimport { announce } from '@a13y/core/runtime/announce';\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useState } from 'react';\n\n/**\n * Wizard step definition\n */\nexport interface WizardStep {\n /**\n * Unique step ID\n */\n id: string;\n\n /**\n * Step label (shown in progress indicator)\n */\n label: string;\n\n /**\n * Step content\n */\n content: ReactNode;\n\n /**\n * Optional validation before proceeding\n * Return true if valid, or error message if invalid\n */\n validate?: () => true | string;\n\n /**\n * Whether this step can be skipped\n */\n optional?: boolean;\n}\n\n/**\n * Wizard context value\n */\ninterface WizardContextValue {\n /**\n * Current step index\n */\n currentStep: number;\n\n /**\n * Total number of steps\n */\n totalSteps: number;\n\n /**\n * Current step data\n */\n step: WizardStep;\n\n /**\n * Navigate to next step\n */\n next: () => void;\n\n /**\n * Navigate to previous step\n */\n previous: () => void;\n\n /**\n * Navigate to specific step (if valid)\n */\n goToStep: (index: number) => void;\n\n /**\n * Check if can go to next step\n */\n canGoNext: boolean;\n\n /**\n * Check if can go to previous step\n */\n canGoPrevious: boolean;\n\n /**\n * Check if on last step\n */\n isLastStep: boolean;\n\n /**\n * Validation error (if any)\n */\n validationError: string | null;\n}\n\nconst WizardContext = createContext<WizardContextValue | null>(null);\n\n/**\n * Hook to access wizard context\n */\nexport const useWizard = (): WizardContextValue => {\n const context = useContext(WizardContext);\n if (!context) {\n throw new Error('useWizard must be used within Wizard component');\n }\n return context;\n};\n\n/**\n * Props for Wizard\n */\nexport interface WizardProps {\n /**\n * Wizard steps (must have at least one)\n */\n steps: [WizardStep, ...WizardStep[]];\n\n /**\n * Called when wizard is completed\n */\n onComplete: () => void;\n\n /**\n * Called when wizard is cancelled\n */\n onCancel?: () => void;\n\n /**\n * Initial step index\n */\n initialStep?: number;\n\n /**\n * Custom className\n */\n className?: string;\n}\n\n/**\n * Wizard Component\n *\n * Multi-step form with:\n * - Progress indicator\n * - Keyboard navigation (arrows, Home, End)\n * - Step validation\n * - Screen reader announcements\n * - Focus management between steps\n *\n * Pattern Explanation:\n * - Each step can have validation before proceeding\n * - Arrow keys navigate between steps (if valid)\n * - Progress indicator shows current position\n * - Screen readers announce step changes\n * - Optional steps can be skipped\n * - Validation errors are announced to screen readers\n *\n * @example\n * ```tsx\n * <Wizard\n * steps={[\n * {\n * id: 'account',\n * label: 'Account Info',\n * content: <AccountForm />,\n * validate: () => isValidEmail(email) || 'Invalid email',\n * },\n * {\n * id: 'preferences',\n * label: 'Preferences',\n * content: <PreferencesForm />,\n * optional: true,\n * },\n * {\n * id: 'review',\n * label: 'Review',\n * content: <ReviewScreen />,\n * },\n * ]}\n * onComplete={() => console.log('Wizard completed!')}\n * />\n * ```\n */\nexport const Wizard = (props: WizardProps) => {\n const { steps, onComplete, onCancel, initialStep = 0, className = '' } = props;\n\n const [currentStep, setCurrentStep] = useState(initialStep);\n const [validationError, setValidationError] = useState<string | null>(null);\n const [visitedSteps, setVisitedSteps] = useState<Set<number>>(new Set([initialStep]));\n\n const totalSteps = steps.length;\n const step = steps[currentStep] ?? steps[0];\n\n // Ensure currentStep is always within bounds\n if (currentStep < 0 || currentStep >= totalSteps) {\n setCurrentStep(0);\n }\n const isLastStep = currentStep === totalSteps - 1;\n const canGoPrevious = currentStep > 0;\n const canGoNext = currentStep < totalSteps - 1;\n\n const validateCurrentStep = (): boolean => {\n if (!step.validate) return true;\n\n const result = step.validate();\n if (result === true) {\n setValidationError(null);\n return true;\n }\n\n setValidationError(result);\n announce(`Validation error: ${result}`, { politeness: 'assertive' });\n return false;\n };\n\n const goToStep = (index: number) => {\n if (index < 0 || index >= totalSteps) return;\n\n // Can only go forward if current step is valid\n if (index > currentStep && !validateCurrentStep()) {\n return;\n }\n\n setCurrentStep(index);\n setVisitedSteps((prev) => new Set([...prev, index]));\n setValidationError(null);\n\n // Announce to screen readers\n const newStep = steps[index];\n if (newStep) {\n announce(\n `Step ${index + 1} of ${totalSteps}: ${newStep.label}${newStep.optional ? ' (optional)' : ''}`,\n { politeness: 'polite' }\n );\n }\n };\n\n const next = () => {\n if (!canGoNext) return;\n\n if (validateCurrentStep()) {\n goToStep(currentStep + 1);\n }\n };\n\n const previous = () => {\n if (!canGoPrevious) return;\n goToStep(currentStep - 1);\n };\n\n const handleComplete = () => {\n if (validateCurrentStep()) {\n announce('Wizard completed', { politeness: 'polite' });\n onComplete();\n }\n };\n\n const contextValue: WizardContextValue = {\n currentStep,\n totalSteps,\n step,\n next,\n previous,\n goToStep,\n canGoNext,\n canGoPrevious,\n isLastStep,\n validationError,\n };\n\n return (\n <WizardContext.Provider value={contextValue}>\n <div className={className} style={{ maxWidth: '48rem', margin: '0 auto' }}>\n {/* Progress Indicator */}\n <nav aria-label=\"Wizard progress\">\n <ol\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '2rem',\n padding: 0,\n listStyle: 'none',\n }}\n >\n {steps.map((s, index) => {\n const isActive = index === currentStep;\n const isCompleted = visitedSteps.has(index) && index < currentStep;\n const isClickable = visitedSteps.has(index) || index === currentStep;\n\n return (\n <li\n key={s.id}\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n }}\n >\n <button\n type=\"button\"\n onClick={() => isClickable && goToStep(index)}\n aria-current={isActive ? 'step' : undefined}\n disabled={!isClickable}\n style={{\n width: '2.5rem',\n height: '2.5rem',\n borderRadius: '50%',\n border: `2px solid ${isActive || isCompleted ? '#2563eb' : '#d1d5db'}`,\n backgroundColor: isCompleted ? '#2563eb' : isActive ? 'white' : '#f3f4f6',\n color: isCompleted ? 'white' : isActive ? '#2563eb' : '#9ca3af',\n fontWeight: 600,\n cursor: isClickable ? 'pointer' : 'not-allowed',\n marginBottom: '0.5rem',\n }}\n >\n {isCompleted ? '✓' : index + 1}\n </button>\n <span\n style={{\n fontSize: '0.875rem',\n color: isActive ? '#2563eb' : '#6b7280',\n fontWeight: isActive ? 600 : 400,\n textAlign: 'center',\n }}\n >\n {s.label}\n {s.optional && (\n <span style={{ display: 'block', fontSize: '0.75rem', color: '#9ca3af' }}>\n (Optional)\n </span>\n )}\n </span>\n </li>\n );\n })}\n </ol>\n </nav>\n\n {/* Validation Error */}\n {validationError && (\n <div\n role=\"alert\"\n aria-live=\"assertive\"\n style={{\n padding: '0.75rem',\n marginBottom: '1rem',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '0.375rem',\n color: '#991b1b',\n }}\n >\n {validationError}\n </div>\n )}\n\n {/* Step Content */}\n <div\n role=\"region\"\n aria-labelledby={`step-${step.id}-label`}\n style={{ marginBottom: '2rem' }}\n >\n <h2\n id={`step-${step.id}-label`}\n style={{ fontSize: '1.5rem', fontWeight: 600, marginBottom: '1rem' }}\n >\n {step.label}\n </h2>\n {step.content}\n </div>\n\n {/* Navigation Buttons */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n gap: '1rem',\n }}\n >\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n style={{\n padding: '0.5rem 1rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: 'white',\n cursor: 'pointer',\n }}\n >\n Cancel\n </button>\n )}\n\n {canGoPrevious && (\n <button\n type=\"button\"\n onClick={previous}\n style={{\n padding: '0.5rem 1rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: 'white',\n cursor: 'pointer',\n }}\n >\n ← Previous\n </button>\n )}\n </div>\n\n <div>\n {isLastStep ? (\n <button\n type=\"button\"\n onClick={handleComplete}\n style={{\n padding: '0.5rem 1.5rem',\n border: 'none',\n borderRadius: '0.375rem',\n backgroundColor: '#2563eb',\n color: 'white',\n fontWeight: 600,\n cursor: 'pointer',\n }}\n >\n Complete\n </button>\n ) : (\n <button\n type=\"button\"\n onClick={next}\n disabled={!canGoNext}\n style={{\n padding: '0.5rem 1.5rem',\n border: 'none',\n borderRadius: '0.375rem',\n backgroundColor: '#2563eb',\n color: 'white',\n fontWeight: 600,\n cursor: canGoNext ? 'pointer' : 'not-allowed',\n opacity: canGoNext ? 1 : 0.5,\n }}\n >\n Next →\n </button>\n )}\n </div>\n </div>\n </div>\n </WizardContext.Provider>\n );\n};\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { AriaRole } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @a13y/react - useAccessibleButton
|
|
5
|
+
* Type-safe button hook with keyboard support
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Button press event (mouse or keyboard)
|
|
10
|
+
*/
|
|
11
|
+
interface PressEvent {
|
|
12
|
+
type: 'mouse' | 'keyboard';
|
|
13
|
+
key?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Props for useAccessibleButton
|
|
17
|
+
*/
|
|
18
|
+
interface UseAccessibleButtonProps {
|
|
19
|
+
/**
|
|
20
|
+
* Accessible label for the button
|
|
21
|
+
* Required if button content is not text (e.g., icon-only)
|
|
22
|
+
*/
|
|
23
|
+
label?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Press handler - called on click or Enter/Space
|
|
26
|
+
*/
|
|
27
|
+
onPress: (event: PressEvent) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the button is disabled
|
|
30
|
+
*/
|
|
31
|
+
isDisabled?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* ARIA role override
|
|
34
|
+
* @default 'button'
|
|
35
|
+
*/
|
|
36
|
+
role?: Extract<AriaRole, 'button' | 'link'>;
|
|
37
|
+
/**
|
|
38
|
+
* Element type - only 'button' or 'a' allowed
|
|
39
|
+
* @default 'button'
|
|
40
|
+
*/
|
|
41
|
+
elementType?: 'button' | 'a';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Button props returned by the hook
|
|
45
|
+
*/
|
|
46
|
+
interface AccessibleButtonProps {
|
|
47
|
+
role: AriaRole;
|
|
48
|
+
tabIndex: number;
|
|
49
|
+
'aria-label'?: string;
|
|
50
|
+
'aria-disabled'?: boolean;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
onPointerDown: (event: React.PointerEvent) => void;
|
|
53
|
+
onKeyDown: (event: React.KeyboardEvent) => void;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Return type
|
|
57
|
+
*/
|
|
58
|
+
interface UseAccessibleButtonReturn {
|
|
59
|
+
buttonProps: AccessibleButtonProps;
|
|
60
|
+
isPressed: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Hook for creating accessible buttons
|
|
64
|
+
*
|
|
65
|
+
* Features:
|
|
66
|
+
* - Keyboard support (Enter, Space)
|
|
67
|
+
* - Disabled state handling
|
|
68
|
+
* - Automatic ARIA attributes
|
|
69
|
+
* - Development-time validation
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```tsx
|
|
73
|
+
* const { buttonProps } = useAccessibleButton({
|
|
74
|
+
* label: 'Delete item',
|
|
75
|
+
* onPress: () => console.log('Pressed!'),
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* return <button {...buttonProps}>🗑️</button>;
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
declare const useAccessibleButton: (props: UseAccessibleButtonProps) => UseAccessibleButtonReturn;
|
|
82
|
+
|
|
83
|
+
export { type AccessibleButtonProps as A, type PressEvent as P, type UseAccessibleButtonProps as U, type UseAccessibleButtonReturn as a, useAccessibleButton as u };
|
package/package.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a13y/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Runtime-enforced React hooks and components for accessibility",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Diego Aneli",
|
|
9
|
+
"url": "https://github.com/DiegoAneli"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/a13y/a13y.git",
|
|
14
|
+
"directory": "packages/react"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/a13y/a13y/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/a13y/a13y#readme",
|
|
20
|
+
"keywords": [
|
|
21
|
+
"accessibility",
|
|
22
|
+
"a11y",
|
|
23
|
+
"react",
|
|
24
|
+
"hooks",
|
|
25
|
+
"components",
|
|
26
|
+
"wcag",
|
|
27
|
+
"aria",
|
|
28
|
+
"focus-trap",
|
|
29
|
+
"keyboard-navigation",
|
|
30
|
+
"typescript",
|
|
31
|
+
"type-safe"
|
|
32
|
+
],
|
|
33
|
+
"sideEffects": false,
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./hooks": {
|
|
41
|
+
"types": "./dist/hooks/index.d.ts",
|
|
42
|
+
"import": "./dist/hooks/index.js",
|
|
43
|
+
"default": "./dist/hooks/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./components": {
|
|
46
|
+
"types": "./dist/components/index.d.ts",
|
|
47
|
+
"import": "./dist/components/index.js",
|
|
48
|
+
"default": "./dist/components/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./patterns": {
|
|
51
|
+
"types": "./dist/patterns/index.d.ts",
|
|
52
|
+
"import": "./dist/patterns/index.js",
|
|
53
|
+
"default": "./dist/patterns/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./package.json": "./package.json"
|
|
56
|
+
},
|
|
57
|
+
"main": "./dist/index.js",
|
|
58
|
+
"module": "./dist/index.js",
|
|
59
|
+
"types": "./dist/index.d.ts",
|
|
60
|
+
"files": [
|
|
61
|
+
"dist",
|
|
62
|
+
"README.md",
|
|
63
|
+
"LICENSE"
|
|
64
|
+
],
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "tsup",
|
|
67
|
+
"dev": "tsup --watch",
|
|
68
|
+
"test": "vitest",
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"prepublishOnly": "pnpm build"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@a13y/core": "workspace:*"
|
|
74
|
+
},
|
|
75
|
+
"peerDependencies": {
|
|
76
|
+
"@a13y/devtools": "^0.1.0",
|
|
77
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"@a13y/devtools": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=18.0.0"
|
|
86
|
+
},
|
|
87
|
+
"publishConfig": {
|
|
88
|
+
"access": "public",
|
|
89
|
+
"dependencies": {
|
|
90
|
+
"@a13y/core": "^0.1.0"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@a13y/devtools": "workspace:*",
|
|
95
|
+
"@types/node": "^25.0.3",
|
|
96
|
+
"@types/react": "^19.2.7",
|
|
97
|
+
"react": "^19.0.0",
|
|
98
|
+
"tsup": "^8.5.1",
|
|
99
|
+
"vitest": "^4.0.16"
|
|
100
|
+
}
|
|
101
|
+
}
|