@opensourceframework/react-a11y-utils
Advanced tools
+4
-5
| { | ||
| "name": "@opensourceframework/react-a11y-utils", | ||
| "version": "0.1.1", | ||
| "version": "0.1.2", | ||
| "description": "React accessibility utility functions and hooks for building accessible user interfaces", | ||
@@ -68,9 +68,8 @@ "keywords": [ | ||
| "type": "git", | ||
| "url": "git+https://github.com/riceharvest/opensourceframework.git", | ||
| "directory": "packages/react-a11y-utils" | ||
| "url": "git+https://github.com/riceharvest/react-a11y-utils.git" | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/riceharvest/opensourceframework/issues?q=is%3Aissue+is%3Aopen+react-a11y-utils" | ||
| "url": "https://github.com/riceharvest/react-a11y-utils/issues" | ||
| }, | ||
| "homepage": "https://github.com/riceharvest/opensourceframework/tree/main/packages/react-a11y-utils#readme", | ||
| "homepage": "https://github.com/riceharvest/react-a11y-utils#readme", | ||
| "publishConfig": { | ||
@@ -77,0 +76,0 @@ "access": "public" |
-136
| 'use strict'; | ||
| /** | ||
| * @opensourceframework/react-a11y-utils | ||
| * React accessibility utility functions and hooks | ||
| * | ||
| * @license MIT | ||
| */ | ||
| // src/index.ts | ||
| var srOnly = { | ||
| position: "absolute", | ||
| width: "1px", | ||
| height: "1px", | ||
| padding: "0", | ||
| margin: "-1px", | ||
| overflow: "hidden", | ||
| clip: "rect(0, 0, 0, 0)", | ||
| whiteSpace: "nowrap", | ||
| borderWidth: "0" | ||
| }; | ||
| var srOnlyFocusable = { | ||
| position: "absolute", | ||
| width: "auto", | ||
| height: "auto", | ||
| padding: "1rem", | ||
| margin: "0", | ||
| overflow: "visible", | ||
| clip: "auto", | ||
| whiteSpace: "normal" | ||
| }; | ||
| var decorative = { | ||
| "aria-hidden": "true" | ||
| }; | ||
| var disabledProps = { | ||
| "aria-disabled": "true", | ||
| tabIndex: -1 | ||
| }; | ||
| var statusMessageProps = { | ||
| role: "status", | ||
| "aria-live": "polite" | ||
| }; | ||
| var alertMessageProps = { | ||
| role: "alert", | ||
| "aria-live": "assertive" | ||
| }; | ||
| function createLiveRegion(options = {}) { | ||
| const { | ||
| atomic = false, | ||
| relevant = "additions", | ||
| busy = false, | ||
| live = "polite" | ||
| } = options; | ||
| return { | ||
| "aria-live": live, | ||
| "aria-atomic": atomic ? "true" : "false", | ||
| "aria-relevant": relevant, | ||
| "aria-busy": busy ? "true" : "false" | ||
| }; | ||
| } | ||
| function createSkipLinkProps(targetId) { | ||
| return { | ||
| href: `#${targetId}`, | ||
| tabIndex: 0 | ||
| }; | ||
| } | ||
| function createDisclosureProps(expanded, controlsId) { | ||
| return { | ||
| "aria-expanded": expanded ? "true" : "false", | ||
| "aria-controls": controlsId | ||
| }; | ||
| } | ||
| function createPressedProps(pressed) { | ||
| return { | ||
| "aria-pressed": pressed ? "true" : "false" | ||
| }; | ||
| } | ||
| function createSelectedProps(selected) { | ||
| return { | ||
| "aria-selected": selected ? "true" : "false" | ||
| }; | ||
| } | ||
| function createCheckedProps(checked) { | ||
| return { | ||
| "aria-checked": typeof checked === "string" ? checked : checked ? "true" : "false" | ||
| }; | ||
| } | ||
| function mergeA11yProps(...props) { | ||
| return Object.assign({}, ...props); | ||
| } | ||
| function createDialogTriggerProps(dialogId, isOpen) { | ||
| return { | ||
| "aria-haspopup": "dialog", | ||
| "aria-controls": dialogId, | ||
| "aria-expanded": isOpen ? "true" : "false" | ||
| }; | ||
| } | ||
| function createFormFieldProps(required, invalid = false) { | ||
| const props = { | ||
| "aria-required": required ? "true" : "false" | ||
| }; | ||
| if (invalid) { | ||
| props["aria-invalid"] = "true"; | ||
| } | ||
| return props; | ||
| } | ||
| function createDescribedByProps(describedById) { | ||
| return { | ||
| "aria-describedby": describedById | ||
| }; | ||
| } | ||
| function createLabelledByProps(labelledById) { | ||
| return { | ||
| "aria-labelledby": labelledById | ||
| }; | ||
| } | ||
| exports.alertMessageProps = alertMessageProps; | ||
| exports.createCheckedProps = createCheckedProps; | ||
| exports.createDescribedByProps = createDescribedByProps; | ||
| exports.createDialogTriggerProps = createDialogTriggerProps; | ||
| exports.createDisclosureProps = createDisclosureProps; | ||
| exports.createFormFieldProps = createFormFieldProps; | ||
| exports.createLabelledByProps = createLabelledByProps; | ||
| exports.createLiveRegion = createLiveRegion; | ||
| exports.createPressedProps = createPressedProps; | ||
| exports.createSelectedProps = createSelectedProps; | ||
| exports.createSkipLinkProps = createSkipLinkProps; | ||
| exports.decorative = decorative; | ||
| exports.disabledProps = disabledProps; | ||
| exports.mergeA11yProps = mergeA11yProps; | ||
| exports.srOnly = srOnly; | ||
| exports.srOnlyFocusable = srOnlyFocusable; | ||
| exports.statusMessageProps = statusMessageProps; | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
| {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * React Accessibility Utilities\n * Helper functions and hooks for building accessible React applications\n * @module @opensourceframework/react-a11y-utils\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Standard accessibility props that can be spread onto elements\n */\nexport interface AccessibilityProps {\n 'aria-activedescendant'?: string;\n 'aria-atomic'?: 'true' | 'false';\n 'aria-autocomplete'?: 'inline' | 'list' | 'both' | 'none';\n 'aria-busy'?: 'true' | 'false';\n 'aria-checked'?: 'true' | 'false' | 'mixed';\n 'aria-colcount'?: number;\n 'aria-colindex'?: number;\n 'aria-colspan'?: number;\n 'aria-controls'?: string;\n 'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false';\n 'aria-describedby'?: string;\n 'aria-details'?: string;\n 'aria-disabled'?: 'true' | 'false';\n 'aria-dropeffect'?: 'copy' | 'execute' | 'link' | 'move' | 'none' | 'popup';\n 'aria-errormessage'?: string;\n 'aria-expanded'?: 'true' | 'false';\n 'aria-flowto'?: string;\n 'aria-grabbed'?: 'true' | 'false';\n 'aria-haspopup'?: 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';\n 'aria-hidden'?: 'true' | 'false';\n 'aria-invalid'?: 'true' | 'false' | 'grammar' | 'spelling';\n 'aria-keyshortcuts'?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-level'?: number;\n 'aria-live'?: 'off' | 'polite' | 'assertive';\n 'aria-modal'?: 'true' | 'false';\n 'aria-multiline'?: 'true' | 'false';\n 'aria-multiselectable'?: 'true' | 'false';\n 'aria-orientation'?: 'horizontal' | 'vertical';\n 'aria-owns'?: string;\n 'aria-placeholder'?: string;\n 'aria-posinset'?: number;\n 'aria-pressed'?: 'true' | 'false' | 'mixed';\n 'aria-readonly'?: 'true' | 'false';\n 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all';\n 'aria-required'?: 'true' | 'false';\n 'aria-roledescription'?: string;\n 'aria-rowcount'?: number;\n 'aria-rowindex'?: number;\n 'aria-rowspan'?: number;\n 'aria-selected'?: 'true' | 'false';\n 'aria-setsize'?: number;\n 'aria-sort'?: 'ascending' | 'descending' | 'none' | 'other';\n 'aria-valuemax'?: number;\n 'aria-valuemin'?: number;\n 'aria-valuenow'?: number;\n 'aria-valuetext'?: string;\n role?: string;\n tabIndex?: number;\n}\n\n/**\n * Props for live region elements\n */\nexport interface LiveRegionProps extends AccessibilityProps {\n 'aria-live'?: 'off' | 'polite' | 'assertive';\n 'aria-atomic'?: 'true' | 'false';\n 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all';\n 'aria-busy'?: 'true' | 'false';\n}\n\n/**\n * Options for creating live region props\n */\nexport interface LiveRegionOptions {\n /** Whether the entire region should be announced (true) or just changes (false) */\n atomic?: boolean;\n /** What types of changes are relevant */\n relevant?: 'additions' | 'removals' | 'text' | 'all';\n /** Whether the region is currently being updated */\n busy?: boolean;\n /** How assertive the announcement should be */\n live?: 'polite' | 'assertive';\n}\n\n/**\n * Props for disclosure elements (expand/collapse)\n */\nexport interface DisclosureProps extends AccessibilityProps {\n 'aria-expanded': 'true' | 'false';\n 'aria-controls': string;\n}\n\n/**\n * Props for toggle buttons with pressed state\n */\nexport interface PressedProps extends AccessibilityProps {\n 'aria-pressed': 'true' | 'false' | 'mixed';\n}\n\n/**\n * Props for selectable elements\n */\nexport interface SelectedProps extends AccessibilityProps {\n 'aria-selected': 'true' | 'false';\n}\n\n/**\n * Props for checkable elements\n */\nexport interface CheckedProps extends AccessibilityProps {\n 'aria-checked': 'true' | 'false' | 'mixed';\n}\n\n/**\n * CSS Properties type for style objects\n */\nexport type A11yCSSProperties = Record<string, string | number | undefined>;\n\n// ============================================================================\n// Screen Reader Utilities\n// ============================================================================\n\n/**\n * CSS styles for screen-reader-only content\n * Elements with these styles are visually hidden but accessible to screen readers\n *\n * @example\n * ```tsx\n * <span style={srOnly}>Skip to main content</span>\n * ```\n */\nexport const srOnly: A11yCSSProperties = {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n};\n\n/**\n * CSS styles for making hidden content visible when focused\n * Use for skip links that should appear on focus\n *\n * @example\n * ```tsx\n * <a href=\"#main\" style={srOnlyFocusable}>Skip to main content</a>\n * ```\n */\nexport const srOnlyFocusable: A11yCSSProperties = {\n position: 'absolute',\n width: 'auto',\n height: 'auto',\n padding: '1rem',\n margin: '0',\n overflow: 'visible',\n clip: 'auto',\n whiteSpace: 'normal',\n};\n\n// ============================================================================\n// ARIA Props Factories\n// ============================================================================\n\n/**\n * Props for decorative elements that should be hidden from screen readers\n *\n * @example\n * ```tsx\n * <img src=\"decoration.png\" alt=\"\" {...decorative} />\n * ```\n */\nexport const decorative: AccessibilityProps = {\n 'aria-hidden': 'true',\n};\n\n/**\n * Props for disabled interactive elements\n * Provides proper accessibility for disabled elements\n *\n * @example\n * ```tsx\n * <button {...disabledProps} onClick={handleClick}>Disabled</button>\n * ```\n */\nexport const disabledProps: AccessibilityProps = {\n 'aria-disabled': 'true',\n tabIndex: -1,\n};\n\n/**\n * Props for status messages (polite announcements)\n *\n * @example\n * ```tsx\n * <div {...statusMessageProps}>Changes saved successfully</div>\n * ```\n */\nexport const statusMessageProps: AccessibilityProps = {\n role: 'status',\n 'aria-live': 'polite',\n};\n\n/**\n * Props for alert messages (assertive announcements)\n *\n * @example\n * ```tsx\n * <div {...alertMessageProps}>Error: Please fill in all required fields</div>\n * ```\n */\nexport const alertMessageProps: AccessibilityProps = {\n role: 'alert',\n 'aria-live': 'assertive',\n};\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Creates props for live regions\n * Live regions announce changes to screen readers\n *\n * @param options - Configuration options for the live region\n * @returns Accessibility props for the live region\n *\n * @example\n * ```tsx\n * <div {...createLiveRegion({ atomic: true, live: 'polite' })}>\n * {message}\n * </div>\n * ```\n */\nexport function createLiveRegion(\n options: LiveRegionOptions = {}\n): LiveRegionProps {\n const {\n atomic = false,\n relevant = 'additions',\n busy = false,\n live = 'polite',\n } = options;\n\n return {\n 'aria-live': live,\n 'aria-atomic': atomic ? 'true' : 'false',\n 'aria-relevant': relevant,\n 'aria-busy': busy ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for skip links\n * Skip links allow keyboard users to bypass navigation\n *\n * @param targetId - The ID of the target element to skip to\n * @returns Props for the skip link element\n *\n * @example\n * ```tsx\n * <a {...createSkipLinkProps('main-content')}>Skip to main content</a>\n * // ...\n * <main id=\"main-content\">...</main>\n * ```\n */\nexport function createSkipLinkProps(targetId: string): {\n href: string;\n tabIndex: number;\n} {\n return {\n href: `#${targetId}`,\n tabIndex: 0,\n };\n}\n\n/**\n * Creates props for elements that expand/collapse content\n *\n * @param expanded - Whether the content is currently expanded\n * @param controlsId - The ID of the element being controlled\n * @returns Accessibility props for the disclosure trigger\n *\n * @example\n * ```tsx\n * <button {...createDisclosureProps(isOpen, 'panel-id')} onClick={toggle}>\n * Toggle Panel\n * </button>\n * <div id=\"panel-id\" hidden={!isOpen}>Panel content</div>\n * ```\n */\nexport function createDisclosureProps(\n expanded: boolean,\n controlsId: string\n): DisclosureProps {\n return {\n 'aria-expanded': expanded ? 'true' : 'false',\n 'aria-controls': controlsId,\n };\n}\n\n/**\n * Creates props for toggle buttons with pressed state\n *\n * @param pressed - Whether the button is currently pressed\n * @returns Accessibility props for the toggle button\n *\n * @example\n * ```tsx\n * <button {...createPressedProps(isActive)} onClick={toggle}>\n * Toggle Feature\n * </button>\n * ```\n */\nexport function createPressedProps(pressed: boolean): PressedProps {\n return {\n 'aria-pressed': pressed ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for elements with selected state\n *\n * @param selected - Whether the element is currently selected\n * @returns Accessibility props for the selectable element\n *\n * @example\n * ```tsx\n * <li {...createSelectedProps(isSelected)} role=\"option\">\n * Option 1\n * </li>\n * ```\n */\nexport function createSelectedProps(selected: boolean): SelectedProps {\n return {\n 'aria-selected': selected ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for elements with checked state\n *\n * @param checked - Whether the element is checked (true), unchecked (false), or indeterminate ('mixed')\n * @returns Accessibility props for the checkable element\n *\n * @example\n * ```tsx\n * <div {...createCheckedProps(checked)} role=\"checkbox\" tabIndex={0}>\n * {checked ? '✓' : ''}\n * </div>\n * ```\n */\nexport function createCheckedProps(\n checked: boolean | 'mixed'\n): CheckedProps {\n return {\n 'aria-checked': typeof checked === 'string' ? checked : (checked ? 'true' : 'false'),\n };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Combines multiple accessibility props objects\n * Later props override earlier ones for the same keys\n *\n * @param props - Array of accessibility props to merge\n * @returns Combined accessibility props\n *\n * @example\n * ```tsx\n * <div {...mergeA11yProps(statusMessageProps, { 'aria-label': 'Status' })}>\n * {message}\n * </div>\n * ```\n */\nexport function mergeA11yProps(\n ...props: AccessibilityProps[]\n): AccessibilityProps {\n return Object.assign({}, ...props);\n}\n\n/**\n * Creates props for a dialog/modal trigger\n *\n * @param dialogId - The ID of the dialog element\n * @param isOpen - Whether the dialog is currently open\n * @returns Accessibility props for the dialog trigger\n *\n * @example\n * ```tsx\n * <button {...createDialogTriggerProps('my-dialog', isOpen)}>\n * Open Dialog\n * </button>\n * ```\n */\nexport function createDialogTriggerProps(\n dialogId: string,\n isOpen: boolean\n): AccessibilityProps {\n return {\n 'aria-haspopup': 'dialog',\n 'aria-controls': dialogId,\n 'aria-expanded': isOpen ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for a required form field\n *\n * @param required - Whether the field is required\n * @param invalid - Whether the field value is invalid\n * @returns Accessibility props for the form field\n *\n * @example\n * ```tsx\n * <input {...createFormFieldProps(true, hasError)} />\n * ```\n */\nexport function createFormFieldProps(\n required: boolean,\n invalid: boolean = false\n): AccessibilityProps {\n const props: AccessibilityProps = {\n 'aria-required': required ? 'true' : 'false',\n };\n \n if (invalid) {\n props['aria-invalid'] = 'true';\n }\n \n return props;\n}\n\n/**\n * Creates props for describing an element with another element\n *\n * @param describedById - The ID of the element that describes this element\n * @returns Accessibility props with aria-describedby\n *\n * @example\n * ```tsx\n * <input {...createDescribedByProps('error-message')} />\n * <span id=\"error-message\">This field is required</span>\n * ```\n */\nexport function createDescribedByProps(\n describedById: string\n): AccessibilityProps {\n return {\n 'aria-describedby': describedById,\n };\n}\n\n/**\n * Creates props for labeling an element with another element\n *\n * @param labelledById - The ID of the element that labels this element\n * @returns Accessibility props with aria-labelledby\n *\n * @example\n * ```tsx\n * <div {...createLabelledByProps('panel-title')} role=\"region\">\n * <h2 id=\"panel-title\">Panel Title</h2>\n * Panel content\n * </div>\n * ```\n */\nexport function createLabelledByProps(\n labelledById: string\n): AccessibilityProps {\n return {\n 'aria-labelledby': labelledById,\n };\n}\n"]} |
-332
| /** | ||
| * React Accessibility Utilities | ||
| * Helper functions and hooks for building accessible React applications | ||
| * @module @opensourceframework/react-a11y-utils | ||
| */ | ||
| /** | ||
| * Standard accessibility props that can be spread onto elements | ||
| */ | ||
| interface AccessibilityProps { | ||
| 'aria-activedescendant'?: string; | ||
| 'aria-atomic'?: 'true' | 'false'; | ||
| 'aria-autocomplete'?: 'inline' | 'list' | 'both' | 'none'; | ||
| 'aria-busy'?: 'true' | 'false'; | ||
| 'aria-checked'?: 'true' | 'false' | 'mixed'; | ||
| 'aria-colcount'?: number; | ||
| 'aria-colindex'?: number; | ||
| 'aria-colspan'?: number; | ||
| 'aria-controls'?: string; | ||
| 'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false'; | ||
| 'aria-describedby'?: string; | ||
| 'aria-details'?: string; | ||
| 'aria-disabled'?: 'true' | 'false'; | ||
| 'aria-dropeffect'?: 'copy' | 'execute' | 'link' | 'move' | 'none' | 'popup'; | ||
| 'aria-errormessage'?: string; | ||
| 'aria-expanded'?: 'true' | 'false'; | ||
| 'aria-flowto'?: string; | ||
| 'aria-grabbed'?: 'true' | 'false'; | ||
| 'aria-haspopup'?: 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'; | ||
| 'aria-hidden'?: 'true' | 'false'; | ||
| 'aria-invalid'?: 'true' | 'false' | 'grammar' | 'spelling'; | ||
| 'aria-keyshortcuts'?: string; | ||
| 'aria-label'?: string; | ||
| 'aria-labelledby'?: string; | ||
| 'aria-level'?: number; | ||
| 'aria-live'?: 'off' | 'polite' | 'assertive'; | ||
| 'aria-modal'?: 'true' | 'false'; | ||
| 'aria-multiline'?: 'true' | 'false'; | ||
| 'aria-multiselectable'?: 'true' | 'false'; | ||
| 'aria-orientation'?: 'horizontal' | 'vertical'; | ||
| 'aria-owns'?: string; | ||
| 'aria-placeholder'?: string; | ||
| 'aria-posinset'?: number; | ||
| 'aria-pressed'?: 'true' | 'false' | 'mixed'; | ||
| 'aria-readonly'?: 'true' | 'false'; | ||
| 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all'; | ||
| 'aria-required'?: 'true' | 'false'; | ||
| 'aria-roledescription'?: string; | ||
| 'aria-rowcount'?: number; | ||
| 'aria-rowindex'?: number; | ||
| 'aria-rowspan'?: number; | ||
| 'aria-selected'?: 'true' | 'false'; | ||
| 'aria-setsize'?: number; | ||
| 'aria-sort'?: 'ascending' | 'descending' | 'none' | 'other'; | ||
| 'aria-valuemax'?: number; | ||
| 'aria-valuemin'?: number; | ||
| 'aria-valuenow'?: number; | ||
| 'aria-valuetext'?: string; | ||
| role?: string; | ||
| tabIndex?: number; | ||
| } | ||
| /** | ||
| * Props for live region elements | ||
| */ | ||
| interface LiveRegionProps extends AccessibilityProps { | ||
| 'aria-live'?: 'off' | 'polite' | 'assertive'; | ||
| 'aria-atomic'?: 'true' | 'false'; | ||
| 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all'; | ||
| 'aria-busy'?: 'true' | 'false'; | ||
| } | ||
| /** | ||
| * Options for creating live region props | ||
| */ | ||
| interface LiveRegionOptions { | ||
| /** Whether the entire region should be announced (true) or just changes (false) */ | ||
| atomic?: boolean; | ||
| /** What types of changes are relevant */ | ||
| relevant?: 'additions' | 'removals' | 'text' | 'all'; | ||
| /** Whether the region is currently being updated */ | ||
| busy?: boolean; | ||
| /** How assertive the announcement should be */ | ||
| live?: 'polite' | 'assertive'; | ||
| } | ||
| /** | ||
| * Props for disclosure elements (expand/collapse) | ||
| */ | ||
| interface DisclosureProps extends AccessibilityProps { | ||
| 'aria-expanded': 'true' | 'false'; | ||
| 'aria-controls': string; | ||
| } | ||
| /** | ||
| * Props for toggle buttons with pressed state | ||
| */ | ||
| interface PressedProps extends AccessibilityProps { | ||
| 'aria-pressed': 'true' | 'false' | 'mixed'; | ||
| } | ||
| /** | ||
| * Props for selectable elements | ||
| */ | ||
| interface SelectedProps extends AccessibilityProps { | ||
| 'aria-selected': 'true' | 'false'; | ||
| } | ||
| /** | ||
| * Props for checkable elements | ||
| */ | ||
| interface CheckedProps extends AccessibilityProps { | ||
| 'aria-checked': 'true' | 'false' | 'mixed'; | ||
| } | ||
| /** | ||
| * CSS Properties type for style objects | ||
| */ | ||
| type A11yCSSProperties = Record<string, string | number | undefined>; | ||
| /** | ||
| * CSS styles for screen-reader-only content | ||
| * Elements with these styles are visually hidden but accessible to screen readers | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <span style={srOnly}>Skip to main content</span> | ||
| * ``` | ||
| */ | ||
| declare const srOnly: A11yCSSProperties; | ||
| /** | ||
| * CSS styles for making hidden content visible when focused | ||
| * Use for skip links that should appear on focus | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <a href="#main" style={srOnlyFocusable}>Skip to main content</a> | ||
| * ``` | ||
| */ | ||
| declare const srOnlyFocusable: A11yCSSProperties; | ||
| /** | ||
| * Props for decorative elements that should be hidden from screen readers | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <img src="decoration.png" alt="" {...decorative} /> | ||
| * ``` | ||
| */ | ||
| declare const decorative: AccessibilityProps; | ||
| /** | ||
| * Props for disabled interactive elements | ||
| * Provides proper accessibility for disabled elements | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...disabledProps} onClick={handleClick}>Disabled</button> | ||
| * ``` | ||
| */ | ||
| declare const disabledProps: AccessibilityProps; | ||
| /** | ||
| * Props for status messages (polite announcements) | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...statusMessageProps}>Changes saved successfully</div> | ||
| * ``` | ||
| */ | ||
| declare const statusMessageProps: AccessibilityProps; | ||
| /** | ||
| * Props for alert messages (assertive announcements) | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...alertMessageProps}>Error: Please fill in all required fields</div> | ||
| * ``` | ||
| */ | ||
| declare const alertMessageProps: AccessibilityProps; | ||
| /** | ||
| * Creates props for live regions | ||
| * Live regions announce changes to screen readers | ||
| * | ||
| * @param options - Configuration options for the live region | ||
| * @returns Accessibility props for the live region | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...createLiveRegion({ atomic: true, live: 'polite' })}> | ||
| * {message} | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function createLiveRegion(options?: LiveRegionOptions): LiveRegionProps; | ||
| /** | ||
| * Creates props for skip links | ||
| * Skip links allow keyboard users to bypass navigation | ||
| * | ||
| * @param targetId - The ID of the target element to skip to | ||
| * @returns Props for the skip link element | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <a {...createSkipLinkProps('main-content')}>Skip to main content</a> | ||
| * // ... | ||
| * <main id="main-content">...</main> | ||
| * ``` | ||
| */ | ||
| declare function createSkipLinkProps(targetId: string): { | ||
| href: string; | ||
| tabIndex: number; | ||
| }; | ||
| /** | ||
| * Creates props for elements that expand/collapse content | ||
| * | ||
| * @param expanded - Whether the content is currently expanded | ||
| * @param controlsId - The ID of the element being controlled | ||
| * @returns Accessibility props for the disclosure trigger | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...createDisclosureProps(isOpen, 'panel-id')} onClick={toggle}> | ||
| * Toggle Panel | ||
| * </button> | ||
| * <div id="panel-id" hidden={!isOpen}>Panel content</div> | ||
| * ``` | ||
| */ | ||
| declare function createDisclosureProps(expanded: boolean, controlsId: string): DisclosureProps; | ||
| /** | ||
| * Creates props for toggle buttons with pressed state | ||
| * | ||
| * @param pressed - Whether the button is currently pressed | ||
| * @returns Accessibility props for the toggle button | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...createPressedProps(isActive)} onClick={toggle}> | ||
| * Toggle Feature | ||
| * </button> | ||
| * ``` | ||
| */ | ||
| declare function createPressedProps(pressed: boolean): PressedProps; | ||
| /** | ||
| * Creates props for elements with selected state | ||
| * | ||
| * @param selected - Whether the element is currently selected | ||
| * @returns Accessibility props for the selectable element | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <li {...createSelectedProps(isSelected)} role="option"> | ||
| * Option 1 | ||
| * </li> | ||
| * ``` | ||
| */ | ||
| declare function createSelectedProps(selected: boolean): SelectedProps; | ||
| /** | ||
| * Creates props for elements with checked state | ||
| * | ||
| * @param checked - Whether the element is checked (true), unchecked (false), or indeterminate ('mixed') | ||
| * @returns Accessibility props for the checkable element | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...createCheckedProps(checked)} role="checkbox" tabIndex={0}> | ||
| * {checked ? '✓' : ''} | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function createCheckedProps(checked: boolean | 'mixed'): CheckedProps; | ||
| /** | ||
| * Combines multiple accessibility props objects | ||
| * Later props override earlier ones for the same keys | ||
| * | ||
| * @param props - Array of accessibility props to merge | ||
| * @returns Combined accessibility props | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...mergeA11yProps(statusMessageProps, { 'aria-label': 'Status' })}> | ||
| * {message} | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function mergeA11yProps(...props: AccessibilityProps[]): AccessibilityProps; | ||
| /** | ||
| * Creates props for a dialog/modal trigger | ||
| * | ||
| * @param dialogId - The ID of the dialog element | ||
| * @param isOpen - Whether the dialog is currently open | ||
| * @returns Accessibility props for the dialog trigger | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...createDialogTriggerProps('my-dialog', isOpen)}> | ||
| * Open Dialog | ||
| * </button> | ||
| * ``` | ||
| */ | ||
| declare function createDialogTriggerProps(dialogId: string, isOpen: boolean): AccessibilityProps; | ||
| /** | ||
| * Creates props for a required form field | ||
| * | ||
| * @param required - Whether the field is required | ||
| * @param invalid - Whether the field value is invalid | ||
| * @returns Accessibility props for the form field | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <input {...createFormFieldProps(true, hasError)} /> | ||
| * ``` | ||
| */ | ||
| declare function createFormFieldProps(required: boolean, invalid?: boolean): AccessibilityProps; | ||
| /** | ||
| * Creates props for describing an element with another element | ||
| * | ||
| * @param describedById - The ID of the element that describes this element | ||
| * @returns Accessibility props with aria-describedby | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <input {...createDescribedByProps('error-message')} /> | ||
| * <span id="error-message">This field is required</span> | ||
| * ``` | ||
| */ | ||
| declare function createDescribedByProps(describedById: string): AccessibilityProps; | ||
| /** | ||
| * Creates props for labeling an element with another element | ||
| * | ||
| * @param labelledById - The ID of the element that labels this element | ||
| * @returns Accessibility props with aria-labelledby | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...createLabelledByProps('panel-title')} role="region"> | ||
| * <h2 id="panel-title">Panel Title</h2> | ||
| * Panel content | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function createLabelledByProps(labelledById: string): AccessibilityProps; | ||
| export { type A11yCSSProperties, type AccessibilityProps, type CheckedProps, type DisclosureProps, type LiveRegionOptions, type LiveRegionProps, type PressedProps, type SelectedProps, alertMessageProps, createCheckedProps, createDescribedByProps, createDialogTriggerProps, createDisclosureProps, createFormFieldProps, createLabelledByProps, createLiveRegion, createPressedProps, createSelectedProps, createSkipLinkProps, decorative, disabledProps, mergeA11yProps, srOnly, srOnlyFocusable, statusMessageProps }; |
-332
| /** | ||
| * React Accessibility Utilities | ||
| * Helper functions and hooks for building accessible React applications | ||
| * @module @opensourceframework/react-a11y-utils | ||
| */ | ||
| /** | ||
| * Standard accessibility props that can be spread onto elements | ||
| */ | ||
| interface AccessibilityProps { | ||
| 'aria-activedescendant'?: string; | ||
| 'aria-atomic'?: 'true' | 'false'; | ||
| 'aria-autocomplete'?: 'inline' | 'list' | 'both' | 'none'; | ||
| 'aria-busy'?: 'true' | 'false'; | ||
| 'aria-checked'?: 'true' | 'false' | 'mixed'; | ||
| 'aria-colcount'?: number; | ||
| 'aria-colindex'?: number; | ||
| 'aria-colspan'?: number; | ||
| 'aria-controls'?: string; | ||
| 'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false'; | ||
| 'aria-describedby'?: string; | ||
| 'aria-details'?: string; | ||
| 'aria-disabled'?: 'true' | 'false'; | ||
| 'aria-dropeffect'?: 'copy' | 'execute' | 'link' | 'move' | 'none' | 'popup'; | ||
| 'aria-errormessage'?: string; | ||
| 'aria-expanded'?: 'true' | 'false'; | ||
| 'aria-flowto'?: string; | ||
| 'aria-grabbed'?: 'true' | 'false'; | ||
| 'aria-haspopup'?: 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog'; | ||
| 'aria-hidden'?: 'true' | 'false'; | ||
| 'aria-invalid'?: 'true' | 'false' | 'grammar' | 'spelling'; | ||
| 'aria-keyshortcuts'?: string; | ||
| 'aria-label'?: string; | ||
| 'aria-labelledby'?: string; | ||
| 'aria-level'?: number; | ||
| 'aria-live'?: 'off' | 'polite' | 'assertive'; | ||
| 'aria-modal'?: 'true' | 'false'; | ||
| 'aria-multiline'?: 'true' | 'false'; | ||
| 'aria-multiselectable'?: 'true' | 'false'; | ||
| 'aria-orientation'?: 'horizontal' | 'vertical'; | ||
| 'aria-owns'?: string; | ||
| 'aria-placeholder'?: string; | ||
| 'aria-posinset'?: number; | ||
| 'aria-pressed'?: 'true' | 'false' | 'mixed'; | ||
| 'aria-readonly'?: 'true' | 'false'; | ||
| 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all'; | ||
| 'aria-required'?: 'true' | 'false'; | ||
| 'aria-roledescription'?: string; | ||
| 'aria-rowcount'?: number; | ||
| 'aria-rowindex'?: number; | ||
| 'aria-rowspan'?: number; | ||
| 'aria-selected'?: 'true' | 'false'; | ||
| 'aria-setsize'?: number; | ||
| 'aria-sort'?: 'ascending' | 'descending' | 'none' | 'other'; | ||
| 'aria-valuemax'?: number; | ||
| 'aria-valuemin'?: number; | ||
| 'aria-valuenow'?: number; | ||
| 'aria-valuetext'?: string; | ||
| role?: string; | ||
| tabIndex?: number; | ||
| } | ||
| /** | ||
| * Props for live region elements | ||
| */ | ||
| interface LiveRegionProps extends AccessibilityProps { | ||
| 'aria-live'?: 'off' | 'polite' | 'assertive'; | ||
| 'aria-atomic'?: 'true' | 'false'; | ||
| 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all'; | ||
| 'aria-busy'?: 'true' | 'false'; | ||
| } | ||
| /** | ||
| * Options for creating live region props | ||
| */ | ||
| interface LiveRegionOptions { | ||
| /** Whether the entire region should be announced (true) or just changes (false) */ | ||
| atomic?: boolean; | ||
| /** What types of changes are relevant */ | ||
| relevant?: 'additions' | 'removals' | 'text' | 'all'; | ||
| /** Whether the region is currently being updated */ | ||
| busy?: boolean; | ||
| /** How assertive the announcement should be */ | ||
| live?: 'polite' | 'assertive'; | ||
| } | ||
| /** | ||
| * Props for disclosure elements (expand/collapse) | ||
| */ | ||
| interface DisclosureProps extends AccessibilityProps { | ||
| 'aria-expanded': 'true' | 'false'; | ||
| 'aria-controls': string; | ||
| } | ||
| /** | ||
| * Props for toggle buttons with pressed state | ||
| */ | ||
| interface PressedProps extends AccessibilityProps { | ||
| 'aria-pressed': 'true' | 'false' | 'mixed'; | ||
| } | ||
| /** | ||
| * Props for selectable elements | ||
| */ | ||
| interface SelectedProps extends AccessibilityProps { | ||
| 'aria-selected': 'true' | 'false'; | ||
| } | ||
| /** | ||
| * Props for checkable elements | ||
| */ | ||
| interface CheckedProps extends AccessibilityProps { | ||
| 'aria-checked': 'true' | 'false' | 'mixed'; | ||
| } | ||
| /** | ||
| * CSS Properties type for style objects | ||
| */ | ||
| type A11yCSSProperties = Record<string, string | number | undefined>; | ||
| /** | ||
| * CSS styles for screen-reader-only content | ||
| * Elements with these styles are visually hidden but accessible to screen readers | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <span style={srOnly}>Skip to main content</span> | ||
| * ``` | ||
| */ | ||
| declare const srOnly: A11yCSSProperties; | ||
| /** | ||
| * CSS styles for making hidden content visible when focused | ||
| * Use for skip links that should appear on focus | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <a href="#main" style={srOnlyFocusable}>Skip to main content</a> | ||
| * ``` | ||
| */ | ||
| declare const srOnlyFocusable: A11yCSSProperties; | ||
| /** | ||
| * Props for decorative elements that should be hidden from screen readers | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <img src="decoration.png" alt="" {...decorative} /> | ||
| * ``` | ||
| */ | ||
| declare const decorative: AccessibilityProps; | ||
| /** | ||
| * Props for disabled interactive elements | ||
| * Provides proper accessibility for disabled elements | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...disabledProps} onClick={handleClick}>Disabled</button> | ||
| * ``` | ||
| */ | ||
| declare const disabledProps: AccessibilityProps; | ||
| /** | ||
| * Props for status messages (polite announcements) | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...statusMessageProps}>Changes saved successfully</div> | ||
| * ``` | ||
| */ | ||
| declare const statusMessageProps: AccessibilityProps; | ||
| /** | ||
| * Props for alert messages (assertive announcements) | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...alertMessageProps}>Error: Please fill in all required fields</div> | ||
| * ``` | ||
| */ | ||
| declare const alertMessageProps: AccessibilityProps; | ||
| /** | ||
| * Creates props for live regions | ||
| * Live regions announce changes to screen readers | ||
| * | ||
| * @param options - Configuration options for the live region | ||
| * @returns Accessibility props for the live region | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...createLiveRegion({ atomic: true, live: 'polite' })}> | ||
| * {message} | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function createLiveRegion(options?: LiveRegionOptions): LiveRegionProps; | ||
| /** | ||
| * Creates props for skip links | ||
| * Skip links allow keyboard users to bypass navigation | ||
| * | ||
| * @param targetId - The ID of the target element to skip to | ||
| * @returns Props for the skip link element | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <a {...createSkipLinkProps('main-content')}>Skip to main content</a> | ||
| * // ... | ||
| * <main id="main-content">...</main> | ||
| * ``` | ||
| */ | ||
| declare function createSkipLinkProps(targetId: string): { | ||
| href: string; | ||
| tabIndex: number; | ||
| }; | ||
| /** | ||
| * Creates props for elements that expand/collapse content | ||
| * | ||
| * @param expanded - Whether the content is currently expanded | ||
| * @param controlsId - The ID of the element being controlled | ||
| * @returns Accessibility props for the disclosure trigger | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...createDisclosureProps(isOpen, 'panel-id')} onClick={toggle}> | ||
| * Toggle Panel | ||
| * </button> | ||
| * <div id="panel-id" hidden={!isOpen}>Panel content</div> | ||
| * ``` | ||
| */ | ||
| declare function createDisclosureProps(expanded: boolean, controlsId: string): DisclosureProps; | ||
| /** | ||
| * Creates props for toggle buttons with pressed state | ||
| * | ||
| * @param pressed - Whether the button is currently pressed | ||
| * @returns Accessibility props for the toggle button | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...createPressedProps(isActive)} onClick={toggle}> | ||
| * Toggle Feature | ||
| * </button> | ||
| * ``` | ||
| */ | ||
| declare function createPressedProps(pressed: boolean): PressedProps; | ||
| /** | ||
| * Creates props for elements with selected state | ||
| * | ||
| * @param selected - Whether the element is currently selected | ||
| * @returns Accessibility props for the selectable element | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <li {...createSelectedProps(isSelected)} role="option"> | ||
| * Option 1 | ||
| * </li> | ||
| * ``` | ||
| */ | ||
| declare function createSelectedProps(selected: boolean): SelectedProps; | ||
| /** | ||
| * Creates props for elements with checked state | ||
| * | ||
| * @param checked - Whether the element is checked (true), unchecked (false), or indeterminate ('mixed') | ||
| * @returns Accessibility props for the checkable element | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...createCheckedProps(checked)} role="checkbox" tabIndex={0}> | ||
| * {checked ? '✓' : ''} | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function createCheckedProps(checked: boolean | 'mixed'): CheckedProps; | ||
| /** | ||
| * Combines multiple accessibility props objects | ||
| * Later props override earlier ones for the same keys | ||
| * | ||
| * @param props - Array of accessibility props to merge | ||
| * @returns Combined accessibility props | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...mergeA11yProps(statusMessageProps, { 'aria-label': 'Status' })}> | ||
| * {message} | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function mergeA11yProps(...props: AccessibilityProps[]): AccessibilityProps; | ||
| /** | ||
| * Creates props for a dialog/modal trigger | ||
| * | ||
| * @param dialogId - The ID of the dialog element | ||
| * @param isOpen - Whether the dialog is currently open | ||
| * @returns Accessibility props for the dialog trigger | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <button {...createDialogTriggerProps('my-dialog', isOpen)}> | ||
| * Open Dialog | ||
| * </button> | ||
| * ``` | ||
| */ | ||
| declare function createDialogTriggerProps(dialogId: string, isOpen: boolean): AccessibilityProps; | ||
| /** | ||
| * Creates props for a required form field | ||
| * | ||
| * @param required - Whether the field is required | ||
| * @param invalid - Whether the field value is invalid | ||
| * @returns Accessibility props for the form field | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <input {...createFormFieldProps(true, hasError)} /> | ||
| * ``` | ||
| */ | ||
| declare function createFormFieldProps(required: boolean, invalid?: boolean): AccessibilityProps; | ||
| /** | ||
| * Creates props for describing an element with another element | ||
| * | ||
| * @param describedById - The ID of the element that describes this element | ||
| * @returns Accessibility props with aria-describedby | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <input {...createDescribedByProps('error-message')} /> | ||
| * <span id="error-message">This field is required</span> | ||
| * ``` | ||
| */ | ||
| declare function createDescribedByProps(describedById: string): AccessibilityProps; | ||
| /** | ||
| * Creates props for labeling an element with another element | ||
| * | ||
| * @param labelledById - The ID of the element that labels this element | ||
| * @returns Accessibility props with aria-labelledby | ||
| * | ||
| * @example | ||
| * ```tsx | ||
| * <div {...createLabelledByProps('panel-title')} role="region"> | ||
| * <h2 id="panel-title">Panel Title</h2> | ||
| * Panel content | ||
| * </div> | ||
| * ``` | ||
| */ | ||
| declare function createLabelledByProps(labelledById: string): AccessibilityProps; | ||
| export { type A11yCSSProperties, type AccessibilityProps, type CheckedProps, type DisclosureProps, type LiveRegionOptions, type LiveRegionProps, type PressedProps, type SelectedProps, alertMessageProps, createCheckedProps, createDescribedByProps, createDialogTriggerProps, createDisclosureProps, createFormFieldProps, createLabelledByProps, createLiveRegion, createPressedProps, createSelectedProps, createSkipLinkProps, decorative, disabledProps, mergeA11yProps, srOnly, srOnlyFocusable, statusMessageProps }; |
-118
| /** | ||
| * @opensourceframework/react-a11y-utils | ||
| * React accessibility utility functions and hooks | ||
| * | ||
| * @license MIT | ||
| */ | ||
| // src/index.ts | ||
| var srOnly = { | ||
| position: "absolute", | ||
| width: "1px", | ||
| height: "1px", | ||
| padding: "0", | ||
| margin: "-1px", | ||
| overflow: "hidden", | ||
| clip: "rect(0, 0, 0, 0)", | ||
| whiteSpace: "nowrap", | ||
| borderWidth: "0" | ||
| }; | ||
| var srOnlyFocusable = { | ||
| position: "absolute", | ||
| width: "auto", | ||
| height: "auto", | ||
| padding: "1rem", | ||
| margin: "0", | ||
| overflow: "visible", | ||
| clip: "auto", | ||
| whiteSpace: "normal" | ||
| }; | ||
| var decorative = { | ||
| "aria-hidden": "true" | ||
| }; | ||
| var disabledProps = { | ||
| "aria-disabled": "true", | ||
| tabIndex: -1 | ||
| }; | ||
| var statusMessageProps = { | ||
| role: "status", | ||
| "aria-live": "polite" | ||
| }; | ||
| var alertMessageProps = { | ||
| role: "alert", | ||
| "aria-live": "assertive" | ||
| }; | ||
| function createLiveRegion(options = {}) { | ||
| const { | ||
| atomic = false, | ||
| relevant = "additions", | ||
| busy = false, | ||
| live = "polite" | ||
| } = options; | ||
| return { | ||
| "aria-live": live, | ||
| "aria-atomic": atomic ? "true" : "false", | ||
| "aria-relevant": relevant, | ||
| "aria-busy": busy ? "true" : "false" | ||
| }; | ||
| } | ||
| function createSkipLinkProps(targetId) { | ||
| return { | ||
| href: `#${targetId}`, | ||
| tabIndex: 0 | ||
| }; | ||
| } | ||
| function createDisclosureProps(expanded, controlsId) { | ||
| return { | ||
| "aria-expanded": expanded ? "true" : "false", | ||
| "aria-controls": controlsId | ||
| }; | ||
| } | ||
| function createPressedProps(pressed) { | ||
| return { | ||
| "aria-pressed": pressed ? "true" : "false" | ||
| }; | ||
| } | ||
| function createSelectedProps(selected) { | ||
| return { | ||
| "aria-selected": selected ? "true" : "false" | ||
| }; | ||
| } | ||
| function createCheckedProps(checked) { | ||
| return { | ||
| "aria-checked": typeof checked === "string" ? checked : checked ? "true" : "false" | ||
| }; | ||
| } | ||
| function mergeA11yProps(...props) { | ||
| return Object.assign({}, ...props); | ||
| } | ||
| function createDialogTriggerProps(dialogId, isOpen) { | ||
| return { | ||
| "aria-haspopup": "dialog", | ||
| "aria-controls": dialogId, | ||
| "aria-expanded": isOpen ? "true" : "false" | ||
| }; | ||
| } | ||
| function createFormFieldProps(required, invalid = false) { | ||
| const props = { | ||
| "aria-required": required ? "true" : "false" | ||
| }; | ||
| if (invalid) { | ||
| props["aria-invalid"] = "true"; | ||
| } | ||
| return props; | ||
| } | ||
| function createDescribedByProps(describedById) { | ||
| return { | ||
| "aria-describedby": describedById | ||
| }; | ||
| } | ||
| function createLabelledByProps(labelledById) { | ||
| return { | ||
| "aria-labelledby": labelledById | ||
| }; | ||
| } | ||
| export { alertMessageProps, createCheckedProps, createDescribedByProps, createDialogTriggerProps, createDisclosureProps, createFormFieldProps, createLabelledByProps, createLiveRegion, createPressedProps, createSelectedProps, createSkipLinkProps, decorative, disabledProps, mergeA11yProps, srOnly, srOnlyFocusable, statusMessageProps }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * React Accessibility Utilities\n * Helper functions and hooks for building accessible React applications\n * @module @opensourceframework/react-a11y-utils\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Standard accessibility props that can be spread onto elements\n */\nexport interface AccessibilityProps {\n 'aria-activedescendant'?: string;\n 'aria-atomic'?: 'true' | 'false';\n 'aria-autocomplete'?: 'inline' | 'list' | 'both' | 'none';\n 'aria-busy'?: 'true' | 'false';\n 'aria-checked'?: 'true' | 'false' | 'mixed';\n 'aria-colcount'?: number;\n 'aria-colindex'?: number;\n 'aria-colspan'?: number;\n 'aria-controls'?: string;\n 'aria-current'?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false';\n 'aria-describedby'?: string;\n 'aria-details'?: string;\n 'aria-disabled'?: 'true' | 'false';\n 'aria-dropeffect'?: 'copy' | 'execute' | 'link' | 'move' | 'none' | 'popup';\n 'aria-errormessage'?: string;\n 'aria-expanded'?: 'true' | 'false';\n 'aria-flowto'?: string;\n 'aria-grabbed'?: 'true' | 'false';\n 'aria-haspopup'?: 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';\n 'aria-hidden'?: 'true' | 'false';\n 'aria-invalid'?: 'true' | 'false' | 'grammar' | 'spelling';\n 'aria-keyshortcuts'?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-level'?: number;\n 'aria-live'?: 'off' | 'polite' | 'assertive';\n 'aria-modal'?: 'true' | 'false';\n 'aria-multiline'?: 'true' | 'false';\n 'aria-multiselectable'?: 'true' | 'false';\n 'aria-orientation'?: 'horizontal' | 'vertical';\n 'aria-owns'?: string;\n 'aria-placeholder'?: string;\n 'aria-posinset'?: number;\n 'aria-pressed'?: 'true' | 'false' | 'mixed';\n 'aria-readonly'?: 'true' | 'false';\n 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all';\n 'aria-required'?: 'true' | 'false';\n 'aria-roledescription'?: string;\n 'aria-rowcount'?: number;\n 'aria-rowindex'?: number;\n 'aria-rowspan'?: number;\n 'aria-selected'?: 'true' | 'false';\n 'aria-setsize'?: number;\n 'aria-sort'?: 'ascending' | 'descending' | 'none' | 'other';\n 'aria-valuemax'?: number;\n 'aria-valuemin'?: number;\n 'aria-valuenow'?: number;\n 'aria-valuetext'?: string;\n role?: string;\n tabIndex?: number;\n}\n\n/**\n * Props for live region elements\n */\nexport interface LiveRegionProps extends AccessibilityProps {\n 'aria-live'?: 'off' | 'polite' | 'assertive';\n 'aria-atomic'?: 'true' | 'false';\n 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all';\n 'aria-busy'?: 'true' | 'false';\n}\n\n/**\n * Options for creating live region props\n */\nexport interface LiveRegionOptions {\n /** Whether the entire region should be announced (true) or just changes (false) */\n atomic?: boolean;\n /** What types of changes are relevant */\n relevant?: 'additions' | 'removals' | 'text' | 'all';\n /** Whether the region is currently being updated */\n busy?: boolean;\n /** How assertive the announcement should be */\n live?: 'polite' | 'assertive';\n}\n\n/**\n * Props for disclosure elements (expand/collapse)\n */\nexport interface DisclosureProps extends AccessibilityProps {\n 'aria-expanded': 'true' | 'false';\n 'aria-controls': string;\n}\n\n/**\n * Props for toggle buttons with pressed state\n */\nexport interface PressedProps extends AccessibilityProps {\n 'aria-pressed': 'true' | 'false' | 'mixed';\n}\n\n/**\n * Props for selectable elements\n */\nexport interface SelectedProps extends AccessibilityProps {\n 'aria-selected': 'true' | 'false';\n}\n\n/**\n * Props for checkable elements\n */\nexport interface CheckedProps extends AccessibilityProps {\n 'aria-checked': 'true' | 'false' | 'mixed';\n}\n\n/**\n * CSS Properties type for style objects\n */\nexport type A11yCSSProperties = Record<string, string | number | undefined>;\n\n// ============================================================================\n// Screen Reader Utilities\n// ============================================================================\n\n/**\n * CSS styles for screen-reader-only content\n * Elements with these styles are visually hidden but accessible to screen readers\n *\n * @example\n * ```tsx\n * <span style={srOnly}>Skip to main content</span>\n * ```\n */\nexport const srOnly: A11yCSSProperties = {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n};\n\n/**\n * CSS styles for making hidden content visible when focused\n * Use for skip links that should appear on focus\n *\n * @example\n * ```tsx\n * <a href=\"#main\" style={srOnlyFocusable}>Skip to main content</a>\n * ```\n */\nexport const srOnlyFocusable: A11yCSSProperties = {\n position: 'absolute',\n width: 'auto',\n height: 'auto',\n padding: '1rem',\n margin: '0',\n overflow: 'visible',\n clip: 'auto',\n whiteSpace: 'normal',\n};\n\n// ============================================================================\n// ARIA Props Factories\n// ============================================================================\n\n/**\n * Props for decorative elements that should be hidden from screen readers\n *\n * @example\n * ```tsx\n * <img src=\"decoration.png\" alt=\"\" {...decorative} />\n * ```\n */\nexport const decorative: AccessibilityProps = {\n 'aria-hidden': 'true',\n};\n\n/**\n * Props for disabled interactive elements\n * Provides proper accessibility for disabled elements\n *\n * @example\n * ```tsx\n * <button {...disabledProps} onClick={handleClick}>Disabled</button>\n * ```\n */\nexport const disabledProps: AccessibilityProps = {\n 'aria-disabled': 'true',\n tabIndex: -1,\n};\n\n/**\n * Props for status messages (polite announcements)\n *\n * @example\n * ```tsx\n * <div {...statusMessageProps}>Changes saved successfully</div>\n * ```\n */\nexport const statusMessageProps: AccessibilityProps = {\n role: 'status',\n 'aria-live': 'polite',\n};\n\n/**\n * Props for alert messages (assertive announcements)\n *\n * @example\n * ```tsx\n * <div {...alertMessageProps}>Error: Please fill in all required fields</div>\n * ```\n */\nexport const alertMessageProps: AccessibilityProps = {\n role: 'alert',\n 'aria-live': 'assertive',\n};\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Creates props for live regions\n * Live regions announce changes to screen readers\n *\n * @param options - Configuration options for the live region\n * @returns Accessibility props for the live region\n *\n * @example\n * ```tsx\n * <div {...createLiveRegion({ atomic: true, live: 'polite' })}>\n * {message}\n * </div>\n * ```\n */\nexport function createLiveRegion(\n options: LiveRegionOptions = {}\n): LiveRegionProps {\n const {\n atomic = false,\n relevant = 'additions',\n busy = false,\n live = 'polite',\n } = options;\n\n return {\n 'aria-live': live,\n 'aria-atomic': atomic ? 'true' : 'false',\n 'aria-relevant': relevant,\n 'aria-busy': busy ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for skip links\n * Skip links allow keyboard users to bypass navigation\n *\n * @param targetId - The ID of the target element to skip to\n * @returns Props for the skip link element\n *\n * @example\n * ```tsx\n * <a {...createSkipLinkProps('main-content')}>Skip to main content</a>\n * // ...\n * <main id=\"main-content\">...</main>\n * ```\n */\nexport function createSkipLinkProps(targetId: string): {\n href: string;\n tabIndex: number;\n} {\n return {\n href: `#${targetId}`,\n tabIndex: 0,\n };\n}\n\n/**\n * Creates props for elements that expand/collapse content\n *\n * @param expanded - Whether the content is currently expanded\n * @param controlsId - The ID of the element being controlled\n * @returns Accessibility props for the disclosure trigger\n *\n * @example\n * ```tsx\n * <button {...createDisclosureProps(isOpen, 'panel-id')} onClick={toggle}>\n * Toggle Panel\n * </button>\n * <div id=\"panel-id\" hidden={!isOpen}>Panel content</div>\n * ```\n */\nexport function createDisclosureProps(\n expanded: boolean,\n controlsId: string\n): DisclosureProps {\n return {\n 'aria-expanded': expanded ? 'true' : 'false',\n 'aria-controls': controlsId,\n };\n}\n\n/**\n * Creates props for toggle buttons with pressed state\n *\n * @param pressed - Whether the button is currently pressed\n * @returns Accessibility props for the toggle button\n *\n * @example\n * ```tsx\n * <button {...createPressedProps(isActive)} onClick={toggle}>\n * Toggle Feature\n * </button>\n * ```\n */\nexport function createPressedProps(pressed: boolean): PressedProps {\n return {\n 'aria-pressed': pressed ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for elements with selected state\n *\n * @param selected - Whether the element is currently selected\n * @returns Accessibility props for the selectable element\n *\n * @example\n * ```tsx\n * <li {...createSelectedProps(isSelected)} role=\"option\">\n * Option 1\n * </li>\n * ```\n */\nexport function createSelectedProps(selected: boolean): SelectedProps {\n return {\n 'aria-selected': selected ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for elements with checked state\n *\n * @param checked - Whether the element is checked (true), unchecked (false), or indeterminate ('mixed')\n * @returns Accessibility props for the checkable element\n *\n * @example\n * ```tsx\n * <div {...createCheckedProps(checked)} role=\"checkbox\" tabIndex={0}>\n * {checked ? '✓' : ''}\n * </div>\n * ```\n */\nexport function createCheckedProps(\n checked: boolean | 'mixed'\n): CheckedProps {\n return {\n 'aria-checked': typeof checked === 'string' ? checked : (checked ? 'true' : 'false'),\n };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Combines multiple accessibility props objects\n * Later props override earlier ones for the same keys\n *\n * @param props - Array of accessibility props to merge\n * @returns Combined accessibility props\n *\n * @example\n * ```tsx\n * <div {...mergeA11yProps(statusMessageProps, { 'aria-label': 'Status' })}>\n * {message}\n * </div>\n * ```\n */\nexport function mergeA11yProps(\n ...props: AccessibilityProps[]\n): AccessibilityProps {\n return Object.assign({}, ...props);\n}\n\n/**\n * Creates props for a dialog/modal trigger\n *\n * @param dialogId - The ID of the dialog element\n * @param isOpen - Whether the dialog is currently open\n * @returns Accessibility props for the dialog trigger\n *\n * @example\n * ```tsx\n * <button {...createDialogTriggerProps('my-dialog', isOpen)}>\n * Open Dialog\n * </button>\n * ```\n */\nexport function createDialogTriggerProps(\n dialogId: string,\n isOpen: boolean\n): AccessibilityProps {\n return {\n 'aria-haspopup': 'dialog',\n 'aria-controls': dialogId,\n 'aria-expanded': isOpen ? 'true' : 'false',\n };\n}\n\n/**\n * Creates props for a required form field\n *\n * @param required - Whether the field is required\n * @param invalid - Whether the field value is invalid\n * @returns Accessibility props for the form field\n *\n * @example\n * ```tsx\n * <input {...createFormFieldProps(true, hasError)} />\n * ```\n */\nexport function createFormFieldProps(\n required: boolean,\n invalid: boolean = false\n): AccessibilityProps {\n const props: AccessibilityProps = {\n 'aria-required': required ? 'true' : 'false',\n };\n \n if (invalid) {\n props['aria-invalid'] = 'true';\n }\n \n return props;\n}\n\n/**\n * Creates props for describing an element with another element\n *\n * @param describedById - The ID of the element that describes this element\n * @returns Accessibility props with aria-describedby\n *\n * @example\n * ```tsx\n * <input {...createDescribedByProps('error-message')} />\n * <span id=\"error-message\">This field is required</span>\n * ```\n */\nexport function createDescribedByProps(\n describedById: string\n): AccessibilityProps {\n return {\n 'aria-describedby': describedById,\n };\n}\n\n/**\n * Creates props for labeling an element with another element\n *\n * @param labelledById - The ID of the element that labels this element\n * @returns Accessibility props with aria-labelledby\n *\n * @example\n * ```tsx\n * <div {...createLabelledByProps('panel-title')} role=\"region\">\n * <h2 id=\"panel-title\">Panel Title</h2>\n * Panel content\n * </div>\n * ```\n */\nexport function createLabelledByProps(\n labelledById: string\n): AccessibilityProps {\n return {\n 'aria-labelledby': labelledById,\n };\n}\n"]} |
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
12312
-82.47%4
-60%0
-100%1
Infinity%2
100%2
Infinity%