(
+ ({ label, helperText, error, testId: customTestId, ...props }, ref) => {
+ const id = useId()
+ const helperTextId = `${id}-helper-text`
+
+ const accessible = useAccessible({
+ feature: 'form',
+ component: 'input',
+ identifier: customTestId || String(label)?.substring(0, 20),
+ ariaDescribedBy: helperText ? helperTextId : undefined,
+ })
+
+ return (
+
+
+
+ {helperText && (
+
+ {helperText}
+
+ )}
+
+ )
+ }
+)
+```
+
+**Result**:
+```html
+
+
+
+
+ Enter a valid email
+
+
+```
+
+## Using Accessibility Utilities
+
+### Hook: useAccessible()
+
+Generate test IDs and ARIA attributes for any component:
+
+```tsx
+import { useAccessible } from '@metabuilder/fakemui'
+
+export function MyComponent() {
+ const accessible = useAccessible({
+ feature: 'canvas', // canvas, settings, navigation, etc.
+ component: 'button', // button, input, select, etc.
+ action: 'delete', // Optional: click, drag, delete, etc.
+ identifier: 'item-123', // Optional: unique identifier
+ })
+
+ return (
+
+ )
+}
+```
+
+### Hook: useKeyboardNavigation()
+
+Handle keyboard events (Enter, Escape, Arrow keys, Tab):
+
+```tsx
+import { useKeyboardNavigation } from '@metabuilder/fakemui'
+
+export function ComboBox() {
+ const keyboardProps = useKeyboardNavigation({
+ onEnter: () => selectItem(),
+ onEscape: () => closeDropdown(),
+ onArrowUp: () => selectPrevious(),
+ onArrowDown: () => selectNext(),
+ })
+
+ return ComboBox content
+}
+```
+
+### Hook: useFocusManagement()
+
+Manage focus programmatically:
+
+```tsx
+import { useFocusManagement } from '@metabuilder/fakemui'
+
+export function SearchBox() {
+ const { focusRef, focus } = useFocusManagement()
+
+ return (
+ <>
+
+
+ >
+ )
+}
+```
+
+### Hook: useLiveRegion()
+
+Announce messages to screen readers:
+
+```tsx
+import { useLiveRegion } from '@metabuilder/fakemui'
+
+export function ItemList() {
+ const { announce, liveRegionProps, message } = useLiveRegion('polite')
+
+ const handleDelete = (item) => {
+ deleteItem(item)
+ announce(`${item.name} deleted`)
+ }
+
+ return (
+ <>
+ {message}
+
+ {items.map(item => (
+ -
+ {item.name}
+
+
+ ))}
+
+ >
+ )
+}
+```
+
+### Hook: useFocusTrap()
+
+Trap focus within modals/dialogs:
+
+```tsx
+import { useFocusTrap } from '@metabuilder/fakemui'
+
+export function Modal({ isOpen, onClose }) {
+ const { focusTrapRef } = useFocusTrap(isOpen)
+
+ return (
+ isOpen && (
+
+
Dialog Title
+
+
+
+
+ )
+ )
+}
+```
+
+## Test ID Patterns
+
+### Format
+```
+{feature}-{component}-{action?}-{identifier?}
+```
+
+### Examples
+```
+form-button-click-submit // Submit button in form
+settings-input-email // Email input in settings
+canvas-item-drag-123 // Drag action on canvas item with ID 123
+navigation-link-click-home // Home link in navigation
+table-row-row-123 // Row 123 in table
+modal-close-dialog-close // Close button in dialog
+```
+
+### Preset Generators
+
+The `testId` object provides 50+ preset generators:
+
+```tsx
+import { testId } from '@metabuilder/fakemui'
+
+// Form fields
+testId.button('Save') // form-button-click-save
+testId.input('email') // form-input-email
+testId.checkbox('remember') // form-checkbox-remember
+testId.select('language') // form-select-language
+
+// Canvas
+testId.canvasItem('item-1') // canvas-item-drag-item-1
+testId.canvasZoomIn() // canvas-button-click-zoom-in
+
+// Navigation
+testId.navLink('Dashboard') // navigation-button-click-dashboard
+testId.navTab('Projects') // navigation-tab-projects
+
+// Modals
+testId.modal('confirm') // modal-modal-confirm
+testId.modalButton('confirm', 'ok') // modal-button-click-confirm-ok
+
+// Tables
+testId.table('users') // table-table-users
+testId.tableRow('users', 'row-1') // table-item-users-row-1
+
+// And more...
+```
+
+## ARIA Attribute Patterns
+
+The `aria` object provides ARIA attribute patterns:
+
+```tsx
+import { aria } from '@metabuilder/fakemui'
+
+// Button
+
+
+// Toggle
+Toggle
+
+// Combobox
+Dropdown
+
+// Dialog
+Confirm?
+
+// Tab system
+
+
+
+
+// Status messages
+Loading...
+
+// Live regions
+Important update
+
+// And more...
+```
+
+## Keyboard Navigation
+
+Handle keyboard events:
+
+```tsx
+import { keyboard } from '@metabuilder/fakemui'
+
+function handleKeyDown(e: React.KeyboardEvent) {
+ if (keyboard.isActivation(e.key)) {
+ // Enter or Space pressed
+ }
+
+ if (keyboard.isArrow(e.key)) {
+ const direction = keyboard.getArrowDirection(e.key)
+ // -1, 0, or 1
+ }
+
+ if (keyboard.isEscape(e.key)) {
+ // Escape pressed
+ }
+
+ if (keyboard.isTab(e.key)) {
+ // Tab pressed
+ }
+}
+```
+
+## Testing with Accessibility Utilities
+
+### Example: Testing a Button
+
+```tsx
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import { Button } from '@metabuilder/fakemui'
+
+describe('Button', () => {
+ it('should render with data-testid', () => {
+ render()
+ const button = screen.getByTestId('form-button-click-submit')
+ expect(button).toBeInTheDocument()
+ })
+
+ it('should have accessible aria-label', () => {
+ render()
+ const button = screen.getByRole('button', { name: /save changes/i })
+ expect(button).toBeInTheDocument()
+ })
+
+ it('should be keyboard accessible', async () => {
+ const handleClick = jest.fn()
+ render()
+
+ const button = screen.getByRole('button')
+ await userEvent.keyboard('{Enter}')
+ expect(handleClick).toHaveBeenCalled()
+ })
+})
+```
+
+### Example: Testing a TextField
+
+```tsx
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import { TextField } from '@metabuilder/fakemui'
+
+describe('TextField', () => {
+ it('should have helper text announced', () => {
+ render(
+
+ )
+
+ const input = screen.getByRole('textbox', { name: /email/i })
+ const helper = screen.getByText('Enter a valid email')
+
+ expect(input).toHaveAttribute('aria-describedby')
+ expect(helper).toHaveAttribute('role', 'status')
+ })
+
+ it('should show error state accessibly', () => {
+ render(
+
+ )
+
+ const input = screen.getByRole('textbox', { name: /password/i })
+ expect(input).toHaveAttribute('aria-invalid', 'true')
+ })
+})
+```
+
+## Accessibility Checklist
+
+When integrating accessibility utilities into components:
+
+- [ ] Component has `data-testid` attribute (via `useAccessible`)
+- [ ] Component has proper `aria-label` or semantic HTML
+- [ ] Error states use `aria-invalid` and `aria-describedby`
+- [ ] Helper text uses `role="status"` for announcements
+- [ ] Buttons have semantic role (native `