@compa11y/core 0.1.0 → 0.1.2
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/dist/announcer/index.d.cts +1 -1
- package/dist/announcer/index.d.ts +1 -1
- package/dist/aria/index.d.cts +1 -1
- package/dist/aria/index.d.ts +1 -1
- package/dist/focus/index.d.cts +1 -1
- package/dist/focus/index.d.ts +1 -1
- package/dist/index.cjs +2 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -7
- package/dist/index.js.map +1 -1
- package/dist/{types-DDSPmE8m.d.cts → types-DpTUSAxr.d.cts} +1 -1
- package/dist/{types-DDSPmE8m.d.ts → types-DpTUSAxr.d.ts} +1 -1
- package/package.json +1 -1
package/dist/aria/index.d.cts
CHANGED
package/dist/aria/index.d.ts
CHANGED
package/dist/focus/index.d.cts
CHANGED
package/dist/focus/index.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -135,7 +135,6 @@ var checks = {
|
|
|
135
135
|
"banner",
|
|
136
136
|
"button",
|
|
137
137
|
"cell",
|
|
138
|
-
"checkbox",
|
|
139
138
|
"columnheader",
|
|
140
139
|
"combobox",
|
|
141
140
|
"complementary",
|
|
@@ -163,16 +162,12 @@ var checks = {
|
|
|
163
162
|
"menu",
|
|
164
163
|
"menubar",
|
|
165
164
|
"menuitem",
|
|
166
|
-
"menuitemcheckbox",
|
|
167
|
-
"menuitemradio",
|
|
168
165
|
"navigation",
|
|
169
166
|
"none",
|
|
170
167
|
"note",
|
|
171
168
|
"option",
|
|
172
169
|
"presentation",
|
|
173
170
|
"progressbar",
|
|
174
|
-
"radio",
|
|
175
|
-
"radiogroup",
|
|
176
171
|
"region",
|
|
177
172
|
"row",
|
|
178
173
|
"rowgroup",
|
|
@@ -326,7 +321,7 @@ function createComponentWarnings(componentName) {
|
|
|
326
321
|
}
|
|
327
322
|
|
|
328
323
|
// src/index.ts
|
|
329
|
-
function
|
|
324
|
+
function initCompa11y() {
|
|
330
325
|
const cleanups = [];
|
|
331
326
|
import('./focus/index.cjs').then(({ initFocusVisible: initFocusVisible2 }) => {
|
|
332
327
|
cleanups.push(initFocusVisible2());
|
|
@@ -565,7 +560,7 @@ exports.createComponentWarnings = createComponentWarnings;
|
|
|
565
560
|
exports.createIdScope = createIdScope;
|
|
566
561
|
exports.generateId = generateId;
|
|
567
562
|
exports.generateIds = generateIds;
|
|
568
|
-
exports.
|
|
563
|
+
exports.initCompa11y = initCompa11y;
|
|
569
564
|
exports.resetIdCounter = resetIdCounter;
|
|
570
565
|
exports.setWarningHandler = setWarningHandler;
|
|
571
566
|
exports.warn = warn;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/id.ts","../src/dev/warnings.ts","../src/index.ts"],"names":["hasAccessibleName","initFocusVisible","initAnnouncer"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ID generation utilities for accessible components\n *\n * Generates unique, predictable IDs for ARIA relationships\n */\n\nlet idCounter = 0;\n\nconst PREFIX = 'compa11y';\n\n/**\n * Generate a unique ID with optional prefix\n */\nexport function generateId(prefix?: string): string {\n const id = ++idCounter;\n return prefix ? `${PREFIX}-${prefix}-${id}` : `${PREFIX}-${id}`;\n}\n\n/**\n * Generate a set of related IDs for a component\n * Useful for complex components with multiple ARIA relationships\n */\nexport function generateIds<T extends readonly string[]>(\n parts: T,\n prefix?: string\n): Record<T[number], string> {\n const baseId = generateId(prefix);\n const ids = {} as Record<string, string>;\n\n for (const part of parts) {\n ids[part] = `${baseId}-${part}`;\n }\n\n return ids as Record<T[number], string>;\n}\n\n/**\n * Reset the ID counter (useful for testing)\n */\nexport function resetIdCounter(): void {\n idCounter = 0;\n}\n\n/**\n * Create a scoped ID generator for a component instance\n */\nexport function createIdScope(componentName: string) {\n const scopeId = generateId(componentName);\n\n return {\n id: scopeId,\n generate: (suffix: string) => `${scopeId}-${suffix}`,\n generateMultiple: <T extends readonly string[]>(parts: T) => {\n const ids = {} as Record<string, string>;\n for (const part of parts) {\n ids[part] = `${scopeId}-${part}`;\n }\n return ids as Record<T[number], string>;\n },\n };\n}\n","/**\n * Developer Warnings System\n *\n * Provides development-time feedback for accessibility issues\n */\n\nimport type { DevWarning, DevWarningHandler } from '../types';\nimport { hasAccessibleName } from '../aria/aria-utils';\n\n// Global warning handler\nlet warningHandler: DevWarningHandler | null = null;\n\n// Track issued warnings to avoid duplicates\nconst issuedWarnings = new Set<string>();\n\n// Check if we're in development mode\nfunction isDev(): boolean {\n return (\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n );\n}\n\n/**\n * Set a custom warning handler\n */\nexport function setWarningHandler(handler: DevWarningHandler | null): void {\n warningHandler = handler;\n}\n\n/**\n * Create a warning key for deduplication\n */\nfunction createWarningKey(warning: DevWarning): string {\n return `${warning.component}:${warning.message}`;\n}\n\n/**\n * Issue a development warning\n */\nexport function warn(warning: DevWarning): void {\n if (!isDev()) return;\n\n const key = createWarningKey(warning);\n if (issuedWarnings.has(key)) return;\n issuedWarnings.add(key);\n\n if (warningHandler) {\n warningHandler(warning);\n return;\n }\n\n const prefix = `[compa11y/${warning.component}]`;\n const style = getConsoleStyle(warning.type);\n\n const message = warning.suggestion\n ? `${warning.message}\\n\\n💡 Suggestion: ${warning.suggestion}`\n : warning.message;\n\n switch (warning.type) {\n case 'error':\n console.error(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'warning':\n console.warn(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'info':\n console.info(`%c${prefix}%c ${message}`, style, '');\n break;\n }\n\n if (warning.element) {\n console.log('Element:', warning.element);\n }\n}\n\n/**\n * Get console style for warning type\n */\nfunction getConsoleStyle(type: DevWarning['type']): string {\n switch (type) {\n case 'error':\n return 'background: #ff5555; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'warning':\n return 'background: #ffaa00; color: black; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'info':\n return 'background: #5555ff; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n }\n}\n\n/**\n * Clear issued warnings (useful for testing)\n */\nexport function clearWarnings(): void {\n issuedWarnings.clear();\n}\n\n/**\n * Pre-built warning checks\n */\nexport const checks = {\n /**\n * Check for missing accessible label\n */\n accessibleLabel(\n element: HTMLElement | null,\n component: string,\n propName = 'aria-label'\n ): void {\n if (!element) return;\n\n if (!hasAccessibleName(element)) {\n warn({\n type: 'error',\n component,\n message: `Missing accessible label. Screen reader users will not be able to understand this element.`,\n suggestion: `Add ${propName}, aria-labelledby, or visible text content.`,\n element,\n });\n }\n },\n\n /**\n * Check for missing required prop\n */\n requiredProp(value: unknown, propName: string, component: string): void {\n if (value === undefined || value === null || value === '') {\n warn({\n type: 'error',\n component,\n message: `Missing required prop \"${propName}\".`,\n suggestion: `Provide a value for the \"${propName}\" prop.`,\n });\n }\n },\n\n /**\n * Check for invalid ARIA role\n */\n validRole(\n role: string | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (!role) return;\n\n const validRoles = new Set([\n 'alert',\n 'alertdialog',\n 'application',\n 'article',\n 'banner',\n 'button',\n 'cell',\n 'checkbox',\n 'columnheader',\n 'combobox',\n 'complementary',\n 'contentinfo',\n 'definition',\n 'dialog',\n 'directory',\n 'document',\n 'feed',\n 'figure',\n 'form',\n 'grid',\n 'gridcell',\n 'group',\n 'heading',\n 'img',\n 'link',\n 'list',\n 'listbox',\n 'listitem',\n 'log',\n 'main',\n 'marquee',\n 'math',\n 'menu',\n 'menubar',\n 'menuitem',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'navigation',\n 'none',\n 'note',\n 'option',\n 'presentation',\n 'progressbar',\n 'radio',\n 'radiogroup',\n 'region',\n 'row',\n 'rowgroup',\n 'rowheader',\n 'scrollbar',\n 'search',\n 'searchbox',\n 'separator',\n 'slider',\n 'spinbutton',\n 'status',\n 'switch',\n 'tab',\n 'table',\n 'tablist',\n 'tabpanel',\n 'term',\n 'textbox',\n 'timer',\n 'toolbar',\n 'tooltip',\n 'tree',\n 'treegrid',\n 'treeitem',\n ]);\n\n if (!validRoles.has(role)) {\n warn({\n type: 'warning',\n component,\n message: `Invalid ARIA role \"${role}\".`,\n suggestion: 'Use a valid ARIA role from the WAI-ARIA specification.',\n element,\n });\n }\n },\n\n /**\n * Check for interactive element without keyboard support\n */\n keyboardAccessible(\n element: HTMLElement | null,\n component: string,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ): void {\n if (!element) return;\n\n if (handlers.onClick && !handlers.onKeyDown) {\n const tagName = element.tagName.toLowerCase();\n const role = element.getAttribute('role');\n\n // Native interactive elements are fine\n if (['button', 'a', 'input', 'select', 'textarea'].includes(tagName)) {\n return;\n }\n\n // Elements with interactive roles need keyboard handling\n const interactiveRoles = ['button', 'link', 'menuitem', 'option', 'tab'];\n if (role && interactiveRoles.includes(role)) {\n warn({\n type: 'warning',\n component,\n message: `Element has onClick but no onKeyDown handler.`,\n suggestion: 'Add keyboard event handling for Enter and Space keys.',\n element,\n });\n }\n }\n },\n\n /**\n * Check tabIndex usage\n */\n tabIndex(\n tabIndex: number | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (tabIndex === undefined) return;\n\n if (tabIndex > 0) {\n warn({\n type: 'warning',\n component,\n message: `Positive tabIndex (${tabIndex}) disrupts natural tab order.`,\n suggestion:\n 'Use tabIndex={0} or tabIndex={-1} instead. Rely on DOM order for tab sequence.',\n element,\n });\n }\n },\n\n /**\n * Check for autofocus in dialogs\n */\n dialogAutoFocus(hasAutoFocus: boolean, component: string): void {\n if (!hasAutoFocus) {\n warn({\n type: 'info',\n component,\n message: 'No initial focus element specified for dialog.',\n suggestion: 'Consider setting initialFocus to guide keyboard users.',\n });\n }\n },\n\n /**\n * Check for missing form labels\n */\n formLabel(\n inputElement: HTMLElement | null,\n labelId: string | undefined,\n component: string\n ): void {\n if (!inputElement) return;\n\n const hasLabel =\n labelId ||\n inputElement.getAttribute('aria-label') ||\n inputElement.getAttribute('aria-labelledby') ||\n (inputElement as HTMLInputElement).labels?.length;\n\n if (!hasLabel) {\n warn({\n type: 'error',\n component,\n message: 'Form input is missing an accessible label.',\n suggestion: 'Add a <label>, aria-label, or aria-labelledby.',\n element: inputElement,\n });\n }\n },\n\n /**\n * Check for missing alt text on images\n */\n imageAlt(element: HTMLElement | null, component: string): void {\n if (!element || element.tagName !== 'IMG') return;\n\n const alt = element.getAttribute('alt');\n const role = element.getAttribute('role');\n\n if (alt === null && role !== 'presentation' && role !== 'none') {\n warn({\n type: 'error',\n component,\n message: 'Image is missing alt attribute.',\n suggestion:\n 'Add alt=\"\" for decorative images or descriptive alt text for meaningful images.',\n element,\n });\n }\n },\n};\n\n/**\n * Create a component-scoped warning function\n */\nexport function createComponentWarnings(componentName: string) {\n return {\n error: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'error',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n warning: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'warning',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n info: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'info',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n checks: {\n accessibleLabel: (element: HTMLElement | null, propName?: string) =>\n checks.accessibleLabel(element, componentName, propName),\n requiredProp: (value: unknown, propName: string) =>\n checks.requiredProp(value, propName, componentName),\n keyboardAccessible: (\n element: HTMLElement | null,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ) => checks.keyboardAccessible(element, componentName, handlers),\n tabIndex: (tabIndex: number | undefined, element?: HTMLElement) =>\n checks.tabIndex(tabIndex, componentName, element),\n },\n };\n}\n","/**\n * @compa11y/core\n *\n * Framework-agnostic accessibility primitives\n *\n * This package provides the foundational utilities used by all\n * compa11y packages (React, Web Components, etc.)\n */\n\n// Types\nexport * from './types';\n\n// Utilities\nexport * from './utils/id';\nexport * from './utils/dom';\nexport * from './utils/platform';\n\n// Focus Management\nexport * from './focus';\n\n// Keyboard Navigation\nexport * from './keyboard';\n\n// Screen Reader Announcements\nexport * from './announcer';\n\n// ARIA Utilities\nexport * from './aria';\n\n// Development Tools\nexport * from './dev';\n\n/**\n * Initialize all compa11y systems\n * Call this once at app startup for optimal behavior\n */\nexport function initA11yKit(): () => void {\n const cleanups: Array<() => void> = [];\n\n // Dynamic imports to support tree-shaking\n // These are safe because they're from this package\n import('./focus').then(({ initFocusVisible }) => {\n cleanups.push(initFocusVisible());\n });\n\n import('./announcer').then(({ initAnnouncer }) => {\n cleanups.push(initAnnouncer());\n });\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/id.ts","../src/dev/warnings.ts","../src/index.ts"],"names":["hasAccessibleName","initFocusVisible","initAnnouncer"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ID generation utilities for accessible components\n *\n * Generates unique, predictable IDs for ARIA relationships\n */\n\nlet idCounter = 0;\n\nconst PREFIX = 'compa11y';\n\n/**\n * Generate a unique ID with optional prefix\n */\nexport function generateId(prefix?: string): string {\n const id = ++idCounter;\n return prefix ? `${PREFIX}-${prefix}-${id}` : `${PREFIX}-${id}`;\n}\n\n/**\n * Generate a set of related IDs for a component\n * Useful for complex components with multiple ARIA relationships\n */\nexport function generateIds<T extends readonly string[]>(\n parts: T,\n prefix?: string\n): Record<T[number], string> {\n const baseId = generateId(prefix);\n const ids = {} as Record<string, string>;\n\n for (const part of parts) {\n ids[part] = `${baseId}-${part}`;\n }\n\n return ids as Record<T[number], string>;\n}\n\n/**\n * Reset the ID counter (useful for testing)\n */\nexport function resetIdCounter(): void {\n idCounter = 0;\n}\n\n/**\n * Create a scoped ID generator for a component instance\n */\nexport function createIdScope(componentName: string) {\n const scopeId = generateId(componentName);\n\n return {\n id: scopeId,\n generate: (suffix: string) => `${scopeId}-${suffix}`,\n generateMultiple: <T extends readonly string[]>(parts: T) => {\n const ids = {} as Record<string, string>;\n for (const part of parts) {\n ids[part] = `${scopeId}-${part}`;\n }\n return ids as Record<T[number], string>;\n },\n };\n}\n","/**\n * Developer Warnings System\n *\n * Provides development-time feedback for accessibility issues\n */\n\nimport type { DevWarning, DevWarningHandler } from '../types';\nimport { hasAccessibleName } from '../aria/aria-utils';\n\n// Global warning handler\nlet warningHandler: DevWarningHandler | null = null;\n\n// Track issued warnings to avoid duplicates\nconst issuedWarnings = new Set<string>();\n\n// Check if we're in development mode\nfunction isDev(): boolean {\n return (\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n );\n}\n\n/**\n * Set a custom warning handler\n */\nexport function setWarningHandler(handler: DevWarningHandler | null): void {\n warningHandler = handler;\n}\n\n/**\n * Create a warning key for deduplication\n */\nfunction createWarningKey(warning: DevWarning): string {\n return `${warning.component}:${warning.message}`;\n}\n\n/**\n * Issue a development warning\n */\nexport function warn(warning: DevWarning): void {\n if (!isDev()) return;\n\n const key = createWarningKey(warning);\n if (issuedWarnings.has(key)) return;\n issuedWarnings.add(key);\n\n if (warningHandler) {\n warningHandler(warning);\n return;\n }\n\n const prefix = `[compa11y/${warning.component}]`;\n const style = getConsoleStyle(warning.type);\n\n const message = warning.suggestion\n ? `${warning.message}\\n\\n💡 Suggestion: ${warning.suggestion}`\n : warning.message;\n\n switch (warning.type) {\n case 'error':\n console.error(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'warning':\n console.warn(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'info':\n console.info(`%c${prefix}%c ${message}`, style, '');\n break;\n }\n\n if (warning.element) {\n console.log('Element:', warning.element);\n }\n}\n\n/**\n * Get console style for warning type\n */\nfunction getConsoleStyle(type: DevWarning['type']): string {\n switch (type) {\n case 'error':\n return 'background: #ff5555; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'warning':\n return 'background: #ffaa00; color: black; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'info':\n return 'background: #5555ff; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n }\n}\n\n/**\n * Clear issued warnings (useful for testing)\n */\nexport function clearWarnings(): void {\n issuedWarnings.clear();\n}\n\n/**\n * Pre-built warning checks\n */\nexport const checks = {\n /**\n * Check for missing accessible label\n */\n accessibleLabel(\n element: HTMLElement | null,\n component: string,\n propName = 'aria-label'\n ): void {\n if (!element) return;\n\n if (!hasAccessibleName(element)) {\n warn({\n type: 'error',\n component,\n message: `Missing accessible label. Screen reader users will not be able to understand this element.`,\n suggestion: `Add ${propName}, aria-labelledby, or visible text content.`,\n element,\n });\n }\n },\n\n /**\n * Check for missing required prop\n */\n requiredProp(value: unknown, propName: string, component: string): void {\n if (value === undefined || value === null || value === '') {\n warn({\n type: 'error',\n component,\n message: `Missing required prop \"${propName}\".`,\n suggestion: `Provide a value for the \"${propName}\" prop.`,\n });\n }\n },\n\n /**\n * Check for invalid ARIA role\n */\n validRole(\n role: string | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (!role) return;\n\n const validRoles = new Set([\n 'alert',\n 'alertdialog',\n 'application',\n 'article',\n 'banner',\n 'button',\n 'cell',\n 'columnheader',\n 'combobox',\n 'complementary',\n 'contentinfo',\n 'definition',\n 'dialog',\n 'directory',\n 'document',\n 'feed',\n 'figure',\n 'form',\n 'grid',\n 'gridcell',\n 'group',\n 'heading',\n 'img',\n 'link',\n 'list',\n 'listbox',\n 'listitem',\n 'log',\n 'main',\n 'marquee',\n 'math',\n 'menu',\n 'menubar',\n 'menuitem',\n 'navigation',\n 'none',\n 'note',\n 'option',\n 'presentation',\n 'progressbar',\n 'region',\n 'row',\n 'rowgroup',\n 'rowheader',\n 'scrollbar',\n 'search',\n 'searchbox',\n 'separator',\n 'slider',\n 'spinbutton',\n 'status',\n 'switch',\n 'tab',\n 'table',\n 'tablist',\n 'tabpanel',\n 'term',\n 'textbox',\n 'timer',\n 'toolbar',\n 'tooltip',\n 'tree',\n 'treegrid',\n 'treeitem',\n ]);\n\n if (!validRoles.has(role)) {\n warn({\n type: 'warning',\n component,\n message: `Invalid ARIA role \"${role}\".`,\n suggestion: 'Use a valid ARIA role from the WAI-ARIA specification.',\n element,\n });\n }\n },\n\n /**\n * Check for interactive element without keyboard support\n */\n keyboardAccessible(\n element: HTMLElement | null,\n component: string,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ): void {\n if (!element) return;\n\n if (handlers.onClick && !handlers.onKeyDown) {\n const tagName = element.tagName.toLowerCase();\n const role = element.getAttribute('role');\n\n // Native interactive elements are fine\n if (['button', 'a', 'input', 'select', 'textarea'].includes(tagName)) {\n return;\n }\n\n // Elements with interactive roles need keyboard handling\n const interactiveRoles = ['button', 'link', 'menuitem', 'option', 'tab'];\n if (role && interactiveRoles.includes(role)) {\n warn({\n type: 'warning',\n component,\n message: `Element has onClick but no onKeyDown handler.`,\n suggestion: 'Add keyboard event handling for Enter and Space keys.',\n element,\n });\n }\n }\n },\n\n /**\n * Check tabIndex usage\n */\n tabIndex(\n tabIndex: number | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (tabIndex === undefined) return;\n\n if (tabIndex > 0) {\n warn({\n type: 'warning',\n component,\n message: `Positive tabIndex (${tabIndex}) disrupts natural tab order.`,\n suggestion:\n 'Use tabIndex={0} or tabIndex={-1} instead. Rely on DOM order for tab sequence.',\n element,\n });\n }\n },\n\n /**\n * Check for autofocus in dialogs\n */\n dialogAutoFocus(hasAutoFocus: boolean, component: string): void {\n if (!hasAutoFocus) {\n warn({\n type: 'info',\n component,\n message: 'No initial focus element specified for dialog.',\n suggestion: 'Consider setting initialFocus to guide keyboard users.',\n });\n }\n },\n\n /**\n * Check for missing form labels\n */\n formLabel(\n inputElement: HTMLElement | null,\n labelId: string | undefined,\n component: string\n ): void {\n if (!inputElement) return;\n\n const hasLabel =\n labelId ||\n inputElement.getAttribute('aria-label') ||\n inputElement.getAttribute('aria-labelledby') ||\n (inputElement as HTMLInputElement).labels?.length;\n\n if (!hasLabel) {\n warn({\n type: 'error',\n component,\n message: 'Form input is missing an accessible label.',\n suggestion: 'Add a <label>, aria-label, or aria-labelledby.',\n element: inputElement,\n });\n }\n },\n\n /**\n * Check for missing alt text on images\n */\n imageAlt(element: HTMLElement | null, component: string): void {\n if (!element || element.tagName !== 'IMG') return;\n\n const alt = element.getAttribute('alt');\n const role = element.getAttribute('role');\n\n if (alt === null && role !== 'presentation' && role !== 'none') {\n warn({\n type: 'error',\n component,\n message: 'Image is missing alt attribute.',\n suggestion:\n 'Add alt=\"\" for decorative images or descriptive alt text for meaningful images.',\n element,\n });\n }\n },\n};\n\n/**\n * Create a component-scoped warning function\n */\nexport function createComponentWarnings(componentName: string) {\n return {\n error: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'error',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n warning: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'warning',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n info: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'info',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n checks: {\n accessibleLabel: (element: HTMLElement | null, propName?: string) =>\n checks.accessibleLabel(element, componentName, propName),\n requiredProp: (value: unknown, propName: string) =>\n checks.requiredProp(value, propName, componentName),\n keyboardAccessible: (\n element: HTMLElement | null,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ) => checks.keyboardAccessible(element, componentName, handlers),\n tabIndex: (tabIndex: number | undefined, element?: HTMLElement) =>\n checks.tabIndex(tabIndex, componentName, element),\n },\n };\n}\n","/**\n * @compa11y/core\n *\n * Framework-agnostic accessibility primitives\n *\n * This package provides the foundational utilities used by all\n * compa11y packages (React, Web Components, etc.)\n */\n\n// Types\nexport * from './types';\n\n// Utilities\nexport * from './utils/id';\nexport * from './utils/dom';\nexport * from './utils/platform';\n\n// Focus Management\nexport * from './focus';\n\n// Keyboard Navigation\nexport * from './keyboard';\n\n// Screen Reader Announcements\nexport * from './announcer';\n\n// ARIA Utilities\nexport * from './aria';\n\n// Development Tools\nexport * from './dev';\n\n/**\n * Initialize all compa11y systems\n * Call this once at app startup for optimal behavior\n */\nexport function initCompa11y(): () => void {\n const cleanups: Array<() => void> = [];\n\n // Dynamic imports to support tree-shaking\n // These are safe because they're from this package\n import('./focus').then(({ initFocusVisible }) => {\n cleanups.push(initFocusVisible());\n });\n\n import('./announcer').then(({ initAnnouncer }) => {\n cleanups.push(initAnnouncer());\n });\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DevWarningHandler, a as DevWarning } from './types-
|
|
2
|
-
export { A as AnnouncerOptions, b as AriaLivePoliteness, c as AriaRole, F as FocusTrapOptions, d as FocusableElement, K as KeyboardNavigationOptions } from './types-
|
|
1
|
+
import { D as DevWarningHandler, a as DevWarning } from './types-DpTUSAxr.cjs';
|
|
2
|
+
export { A as AnnouncerOptions, b as AriaLivePoliteness, c as AriaRole, F as FocusTrapOptions, d as FocusableElement, K as KeyboardNavigationOptions } from './types-DpTUSAxr.cjs';
|
|
3
3
|
export { FocusScope, FocusScopeOptions, RovingTabindex, RovingTabindexOptions, createFocusScope, createFocusTrap, createRovingTabindex, focusWithVisibleRing, getActiveFocusTrap, getLastFocusSource, hasFocusTrap, hasVisibleFocus, initFocusVisible, isFocusVisible, setFocusVisible } from './focus/index.cjs';
|
|
4
4
|
export { KeyboardHandler, KeyboardHandlers, KeyboardManager, KeyboardManagerOptions, KeyboardPatterns, TypeAhead, createKeyboardManager, createTypeAhead, getKeyCombo, normalizeKey } from './keyboard/index.cjs';
|
|
5
5
|
export { announce, announceAssertive, announceError, announcePolite, announceProgress, announceStatus, clearAnnouncements, createAnnouncer, initAnnouncer, queueAnnouncement } from './announcer/index.cjs';
|
|
@@ -236,6 +236,6 @@ declare function createComponentWarnings(componentName: string): {
|
|
|
236
236
|
* Initialize all compa11y systems
|
|
237
237
|
* Call this once at app startup for optimal behavior
|
|
238
238
|
*/
|
|
239
|
-
declare function
|
|
239
|
+
declare function initCompa11y(): () => void;
|
|
240
240
|
|
|
241
|
-
export { DevWarning, DevWarningHandler, FOCUSABLE_SELECTORS, TABBABLE_SELECTORS, checks, clearWarnings, containsFocus, createComponentWarnings, createIdScope, createMediaQueryListener, generateId, generateIds, getFirstFocusable, getFocusableElements, getLastFocusable, getNextFocusable, getPreviousFocusable, getScreenReaderHints, getTabbableElements,
|
|
241
|
+
export { DevWarning, DevWarningHandler, FOCUSABLE_SELECTORS, TABBABLE_SELECTORS, checks, clearWarnings, containsFocus, createComponentWarnings, createIdScope, createMediaQueryListener, generateId, generateIds, getFirstFocusable, getFocusableElements, getLastFocusable, getNextFocusable, getPreviousFocusable, getScreenReaderHints, getTabbableElements, initCompa11y, isAndroid, isBrowser, isFocusable, isIOS, isMac, isTabbable, isTouchDevice, isVisible, isWindows, isWithinContainer, prefersDarkMode, prefersHighContrast, prefersReducedMotion, resetIdCounter, resolveElement, setWarningHandler, warn };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DevWarningHandler, a as DevWarning } from './types-
|
|
2
|
-
export { A as AnnouncerOptions, b as AriaLivePoliteness, c as AriaRole, F as FocusTrapOptions, d as FocusableElement, K as KeyboardNavigationOptions } from './types-
|
|
1
|
+
import { D as DevWarningHandler, a as DevWarning } from './types-DpTUSAxr.js';
|
|
2
|
+
export { A as AnnouncerOptions, b as AriaLivePoliteness, c as AriaRole, F as FocusTrapOptions, d as FocusableElement, K as KeyboardNavigationOptions } from './types-DpTUSAxr.js';
|
|
3
3
|
export { FocusScope, FocusScopeOptions, RovingTabindex, RovingTabindexOptions, createFocusScope, createFocusTrap, createRovingTabindex, focusWithVisibleRing, getActiveFocusTrap, getLastFocusSource, hasFocusTrap, hasVisibleFocus, initFocusVisible, isFocusVisible, setFocusVisible } from './focus/index.js';
|
|
4
4
|
export { KeyboardHandler, KeyboardHandlers, KeyboardManager, KeyboardManagerOptions, KeyboardPatterns, TypeAhead, createKeyboardManager, createTypeAhead, getKeyCombo, normalizeKey } from './keyboard/index.js';
|
|
5
5
|
export { announce, announceAssertive, announceError, announcePolite, announceProgress, announceStatus, clearAnnouncements, createAnnouncer, initAnnouncer, queueAnnouncement } from './announcer/index.js';
|
|
@@ -236,6 +236,6 @@ declare function createComponentWarnings(componentName: string): {
|
|
|
236
236
|
* Initialize all compa11y systems
|
|
237
237
|
* Call this once at app startup for optimal behavior
|
|
238
238
|
*/
|
|
239
|
-
declare function
|
|
239
|
+
declare function initCompa11y(): () => void;
|
|
240
240
|
|
|
241
|
-
export { DevWarning, DevWarningHandler, FOCUSABLE_SELECTORS, TABBABLE_SELECTORS, checks, clearWarnings, containsFocus, createComponentWarnings, createIdScope, createMediaQueryListener, generateId, generateIds, getFirstFocusable, getFocusableElements, getLastFocusable, getNextFocusable, getPreviousFocusable, getScreenReaderHints, getTabbableElements,
|
|
241
|
+
export { DevWarning, DevWarningHandler, FOCUSABLE_SELECTORS, TABBABLE_SELECTORS, checks, clearWarnings, containsFocus, createComponentWarnings, createIdScope, createMediaQueryListener, generateId, generateIds, getFirstFocusable, getFocusableElements, getLastFocusable, getNextFocusable, getPreviousFocusable, getScreenReaderHints, getTabbableElements, initCompa11y, isAndroid, isBrowser, isFocusable, isIOS, isMac, isTabbable, isTouchDevice, isVisible, isWindows, isWithinContainer, prefersDarkMode, prefersHighContrast, prefersReducedMotion, resetIdCounter, resolveElement, setWarningHandler, warn };
|
package/dist/index.js
CHANGED
|
@@ -134,7 +134,6 @@ var checks = {
|
|
|
134
134
|
"banner",
|
|
135
135
|
"button",
|
|
136
136
|
"cell",
|
|
137
|
-
"checkbox",
|
|
138
137
|
"columnheader",
|
|
139
138
|
"combobox",
|
|
140
139
|
"complementary",
|
|
@@ -162,16 +161,12 @@ var checks = {
|
|
|
162
161
|
"menu",
|
|
163
162
|
"menubar",
|
|
164
163
|
"menuitem",
|
|
165
|
-
"menuitemcheckbox",
|
|
166
|
-
"menuitemradio",
|
|
167
164
|
"navigation",
|
|
168
165
|
"none",
|
|
169
166
|
"note",
|
|
170
167
|
"option",
|
|
171
168
|
"presentation",
|
|
172
169
|
"progressbar",
|
|
173
|
-
"radio",
|
|
174
|
-
"radiogroup",
|
|
175
170
|
"region",
|
|
176
171
|
"row",
|
|
177
172
|
"rowgroup",
|
|
@@ -325,7 +320,7 @@ function createComponentWarnings(componentName) {
|
|
|
325
320
|
}
|
|
326
321
|
|
|
327
322
|
// src/index.ts
|
|
328
|
-
function
|
|
323
|
+
function initCompa11y() {
|
|
329
324
|
const cleanups = [];
|
|
330
325
|
import('./focus/index.js').then(({ initFocusVisible: initFocusVisible2 }) => {
|
|
331
326
|
cleanups.push(initFocusVisible2());
|
|
@@ -338,6 +333,6 @@ function initA11yKit() {
|
|
|
338
333
|
};
|
|
339
334
|
}
|
|
340
335
|
|
|
341
|
-
export { checks, clearWarnings, createComponentWarnings, createIdScope, generateId, generateIds,
|
|
336
|
+
export { checks, clearWarnings, createComponentWarnings, createIdScope, generateId, generateIds, initCompa11y, resetIdCounter, setWarningHandler, warn };
|
|
342
337
|
//# sourceMappingURL=index.js.map
|
|
343
338
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/id.ts","../src/dev/warnings.ts","../src/index.ts"],"names":["initFocusVisible","initAnnouncer"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ID generation utilities for accessible components\n *\n * Generates unique, predictable IDs for ARIA relationships\n */\n\nlet idCounter = 0;\n\nconst PREFIX = 'compa11y';\n\n/**\n * Generate a unique ID with optional prefix\n */\nexport function generateId(prefix?: string): string {\n const id = ++idCounter;\n return prefix ? `${PREFIX}-${prefix}-${id}` : `${PREFIX}-${id}`;\n}\n\n/**\n * Generate a set of related IDs for a component\n * Useful for complex components with multiple ARIA relationships\n */\nexport function generateIds<T extends readonly string[]>(\n parts: T,\n prefix?: string\n): Record<T[number], string> {\n const baseId = generateId(prefix);\n const ids = {} as Record<string, string>;\n\n for (const part of parts) {\n ids[part] = `${baseId}-${part}`;\n }\n\n return ids as Record<T[number], string>;\n}\n\n/**\n * Reset the ID counter (useful for testing)\n */\nexport function resetIdCounter(): void {\n idCounter = 0;\n}\n\n/**\n * Create a scoped ID generator for a component instance\n */\nexport function createIdScope(componentName: string) {\n const scopeId = generateId(componentName);\n\n return {\n id: scopeId,\n generate: (suffix: string) => `${scopeId}-${suffix}`,\n generateMultiple: <T extends readonly string[]>(parts: T) => {\n const ids = {} as Record<string, string>;\n for (const part of parts) {\n ids[part] = `${scopeId}-${part}`;\n }\n return ids as Record<T[number], string>;\n },\n };\n}\n","/**\n * Developer Warnings System\n *\n * Provides development-time feedback for accessibility issues\n */\n\nimport type { DevWarning, DevWarningHandler } from '../types';\nimport { hasAccessibleName } from '../aria/aria-utils';\n\n// Global warning handler\nlet warningHandler: DevWarningHandler | null = null;\n\n// Track issued warnings to avoid duplicates\nconst issuedWarnings = new Set<string>();\n\n// Check if we're in development mode\nfunction isDev(): boolean {\n return (\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n );\n}\n\n/**\n * Set a custom warning handler\n */\nexport function setWarningHandler(handler: DevWarningHandler | null): void {\n warningHandler = handler;\n}\n\n/**\n * Create a warning key for deduplication\n */\nfunction createWarningKey(warning: DevWarning): string {\n return `${warning.component}:${warning.message}`;\n}\n\n/**\n * Issue a development warning\n */\nexport function warn(warning: DevWarning): void {\n if (!isDev()) return;\n\n const key = createWarningKey(warning);\n if (issuedWarnings.has(key)) return;\n issuedWarnings.add(key);\n\n if (warningHandler) {\n warningHandler(warning);\n return;\n }\n\n const prefix = `[compa11y/${warning.component}]`;\n const style = getConsoleStyle(warning.type);\n\n const message = warning.suggestion\n ? `${warning.message}\\n\\n💡 Suggestion: ${warning.suggestion}`\n : warning.message;\n\n switch (warning.type) {\n case 'error':\n console.error(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'warning':\n console.warn(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'info':\n console.info(`%c${prefix}%c ${message}`, style, '');\n break;\n }\n\n if (warning.element) {\n console.log('Element:', warning.element);\n }\n}\n\n/**\n * Get console style for warning type\n */\nfunction getConsoleStyle(type: DevWarning['type']): string {\n switch (type) {\n case 'error':\n return 'background: #ff5555; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'warning':\n return 'background: #ffaa00; color: black; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'info':\n return 'background: #5555ff; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n }\n}\n\n/**\n * Clear issued warnings (useful for testing)\n */\nexport function clearWarnings(): void {\n issuedWarnings.clear();\n}\n\n/**\n * Pre-built warning checks\n */\nexport const checks = {\n /**\n * Check for missing accessible label\n */\n accessibleLabel(\n element: HTMLElement | null,\n component: string,\n propName = 'aria-label'\n ): void {\n if (!element) return;\n\n if (!hasAccessibleName(element)) {\n warn({\n type: 'error',\n component,\n message: `Missing accessible label. Screen reader users will not be able to understand this element.`,\n suggestion: `Add ${propName}, aria-labelledby, or visible text content.`,\n element,\n });\n }\n },\n\n /**\n * Check for missing required prop\n */\n requiredProp(value: unknown, propName: string, component: string): void {\n if (value === undefined || value === null || value === '') {\n warn({\n type: 'error',\n component,\n message: `Missing required prop \"${propName}\".`,\n suggestion: `Provide a value for the \"${propName}\" prop.`,\n });\n }\n },\n\n /**\n * Check for invalid ARIA role\n */\n validRole(\n role: string | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (!role) return;\n\n const validRoles = new Set([\n 'alert',\n 'alertdialog',\n 'application',\n 'article',\n 'banner',\n 'button',\n 'cell',\n 'checkbox',\n 'columnheader',\n 'combobox',\n 'complementary',\n 'contentinfo',\n 'definition',\n 'dialog',\n 'directory',\n 'document',\n 'feed',\n 'figure',\n 'form',\n 'grid',\n 'gridcell',\n 'group',\n 'heading',\n 'img',\n 'link',\n 'list',\n 'listbox',\n 'listitem',\n 'log',\n 'main',\n 'marquee',\n 'math',\n 'menu',\n 'menubar',\n 'menuitem',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'navigation',\n 'none',\n 'note',\n 'option',\n 'presentation',\n 'progressbar',\n 'radio',\n 'radiogroup',\n 'region',\n 'row',\n 'rowgroup',\n 'rowheader',\n 'scrollbar',\n 'search',\n 'searchbox',\n 'separator',\n 'slider',\n 'spinbutton',\n 'status',\n 'switch',\n 'tab',\n 'table',\n 'tablist',\n 'tabpanel',\n 'term',\n 'textbox',\n 'timer',\n 'toolbar',\n 'tooltip',\n 'tree',\n 'treegrid',\n 'treeitem',\n ]);\n\n if (!validRoles.has(role)) {\n warn({\n type: 'warning',\n component,\n message: `Invalid ARIA role \"${role}\".`,\n suggestion: 'Use a valid ARIA role from the WAI-ARIA specification.',\n element,\n });\n }\n },\n\n /**\n * Check for interactive element without keyboard support\n */\n keyboardAccessible(\n element: HTMLElement | null,\n component: string,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ): void {\n if (!element) return;\n\n if (handlers.onClick && !handlers.onKeyDown) {\n const tagName = element.tagName.toLowerCase();\n const role = element.getAttribute('role');\n\n // Native interactive elements are fine\n if (['button', 'a', 'input', 'select', 'textarea'].includes(tagName)) {\n return;\n }\n\n // Elements with interactive roles need keyboard handling\n const interactiveRoles = ['button', 'link', 'menuitem', 'option', 'tab'];\n if (role && interactiveRoles.includes(role)) {\n warn({\n type: 'warning',\n component,\n message: `Element has onClick but no onKeyDown handler.`,\n suggestion: 'Add keyboard event handling for Enter and Space keys.',\n element,\n });\n }\n }\n },\n\n /**\n * Check tabIndex usage\n */\n tabIndex(\n tabIndex: number | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (tabIndex === undefined) return;\n\n if (tabIndex > 0) {\n warn({\n type: 'warning',\n component,\n message: `Positive tabIndex (${tabIndex}) disrupts natural tab order.`,\n suggestion:\n 'Use tabIndex={0} or tabIndex={-1} instead. Rely on DOM order for tab sequence.',\n element,\n });\n }\n },\n\n /**\n * Check for autofocus in dialogs\n */\n dialogAutoFocus(hasAutoFocus: boolean, component: string): void {\n if (!hasAutoFocus) {\n warn({\n type: 'info',\n component,\n message: 'No initial focus element specified for dialog.',\n suggestion: 'Consider setting initialFocus to guide keyboard users.',\n });\n }\n },\n\n /**\n * Check for missing form labels\n */\n formLabel(\n inputElement: HTMLElement | null,\n labelId: string | undefined,\n component: string\n ): void {\n if (!inputElement) return;\n\n const hasLabel =\n labelId ||\n inputElement.getAttribute('aria-label') ||\n inputElement.getAttribute('aria-labelledby') ||\n (inputElement as HTMLInputElement).labels?.length;\n\n if (!hasLabel) {\n warn({\n type: 'error',\n component,\n message: 'Form input is missing an accessible label.',\n suggestion: 'Add a <label>, aria-label, or aria-labelledby.',\n element: inputElement,\n });\n }\n },\n\n /**\n * Check for missing alt text on images\n */\n imageAlt(element: HTMLElement | null, component: string): void {\n if (!element || element.tagName !== 'IMG') return;\n\n const alt = element.getAttribute('alt');\n const role = element.getAttribute('role');\n\n if (alt === null && role !== 'presentation' && role !== 'none') {\n warn({\n type: 'error',\n component,\n message: 'Image is missing alt attribute.',\n suggestion:\n 'Add alt=\"\" for decorative images or descriptive alt text for meaningful images.',\n element,\n });\n }\n },\n};\n\n/**\n * Create a component-scoped warning function\n */\nexport function createComponentWarnings(componentName: string) {\n return {\n error: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'error',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n warning: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'warning',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n info: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'info',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n checks: {\n accessibleLabel: (element: HTMLElement | null, propName?: string) =>\n checks.accessibleLabel(element, componentName, propName),\n requiredProp: (value: unknown, propName: string) =>\n checks.requiredProp(value, propName, componentName),\n keyboardAccessible: (\n element: HTMLElement | null,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ) => checks.keyboardAccessible(element, componentName, handlers),\n tabIndex: (tabIndex: number | undefined, element?: HTMLElement) =>\n checks.tabIndex(tabIndex, componentName, element),\n },\n };\n}\n","/**\n * @compa11y/core\n *\n * Framework-agnostic accessibility primitives\n *\n * This package provides the foundational utilities used by all\n * compa11y packages (React, Web Components, etc.)\n */\n\n// Types\nexport * from './types';\n\n// Utilities\nexport * from './utils/id';\nexport * from './utils/dom';\nexport * from './utils/platform';\n\n// Focus Management\nexport * from './focus';\n\n// Keyboard Navigation\nexport * from './keyboard';\n\n// Screen Reader Announcements\nexport * from './announcer';\n\n// ARIA Utilities\nexport * from './aria';\n\n// Development Tools\nexport * from './dev';\n\n/**\n * Initialize all compa11y systems\n * Call this once at app startup for optimal behavior\n */\nexport function initA11yKit(): () => void {\n const cleanups: Array<() => void> = [];\n\n // Dynamic imports to support tree-shaking\n // These are safe because they're from this package\n import('./focus').then(({ initFocusVisible }) => {\n cleanups.push(initFocusVisible());\n });\n\n import('./announcer').then(({ initAnnouncer }) => {\n cleanups.push(initAnnouncer());\n });\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/id.ts","../src/dev/warnings.ts","../src/index.ts"],"names":["initFocusVisible","initAnnouncer"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ID generation utilities for accessible components\n *\n * Generates unique, predictable IDs for ARIA relationships\n */\n\nlet idCounter = 0;\n\nconst PREFIX = 'compa11y';\n\n/**\n * Generate a unique ID with optional prefix\n */\nexport function generateId(prefix?: string): string {\n const id = ++idCounter;\n return prefix ? `${PREFIX}-${prefix}-${id}` : `${PREFIX}-${id}`;\n}\n\n/**\n * Generate a set of related IDs for a component\n * Useful for complex components with multiple ARIA relationships\n */\nexport function generateIds<T extends readonly string[]>(\n parts: T,\n prefix?: string\n): Record<T[number], string> {\n const baseId = generateId(prefix);\n const ids = {} as Record<string, string>;\n\n for (const part of parts) {\n ids[part] = `${baseId}-${part}`;\n }\n\n return ids as Record<T[number], string>;\n}\n\n/**\n * Reset the ID counter (useful for testing)\n */\nexport function resetIdCounter(): void {\n idCounter = 0;\n}\n\n/**\n * Create a scoped ID generator for a component instance\n */\nexport function createIdScope(componentName: string) {\n const scopeId = generateId(componentName);\n\n return {\n id: scopeId,\n generate: (suffix: string) => `${scopeId}-${suffix}`,\n generateMultiple: <T extends readonly string[]>(parts: T) => {\n const ids = {} as Record<string, string>;\n for (const part of parts) {\n ids[part] = `${scopeId}-${part}`;\n }\n return ids as Record<T[number], string>;\n },\n };\n}\n","/**\n * Developer Warnings System\n *\n * Provides development-time feedback for accessibility issues\n */\n\nimport type { DevWarning, DevWarningHandler } from '../types';\nimport { hasAccessibleName } from '../aria/aria-utils';\n\n// Global warning handler\nlet warningHandler: DevWarningHandler | null = null;\n\n// Track issued warnings to avoid duplicates\nconst issuedWarnings = new Set<string>();\n\n// Check if we're in development mode\nfunction isDev(): boolean {\n return (\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n );\n}\n\n/**\n * Set a custom warning handler\n */\nexport function setWarningHandler(handler: DevWarningHandler | null): void {\n warningHandler = handler;\n}\n\n/**\n * Create a warning key for deduplication\n */\nfunction createWarningKey(warning: DevWarning): string {\n return `${warning.component}:${warning.message}`;\n}\n\n/**\n * Issue a development warning\n */\nexport function warn(warning: DevWarning): void {\n if (!isDev()) return;\n\n const key = createWarningKey(warning);\n if (issuedWarnings.has(key)) return;\n issuedWarnings.add(key);\n\n if (warningHandler) {\n warningHandler(warning);\n return;\n }\n\n const prefix = `[compa11y/${warning.component}]`;\n const style = getConsoleStyle(warning.type);\n\n const message = warning.suggestion\n ? `${warning.message}\\n\\n💡 Suggestion: ${warning.suggestion}`\n : warning.message;\n\n switch (warning.type) {\n case 'error':\n console.error(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'warning':\n console.warn(`%c${prefix}%c ${message}`, style, '');\n break;\n case 'info':\n console.info(`%c${prefix}%c ${message}`, style, '');\n break;\n }\n\n if (warning.element) {\n console.log('Element:', warning.element);\n }\n}\n\n/**\n * Get console style for warning type\n */\nfunction getConsoleStyle(type: DevWarning['type']): string {\n switch (type) {\n case 'error':\n return 'background: #ff5555; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'warning':\n return 'background: #ffaa00; color: black; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n case 'info':\n return 'background: #5555ff; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold;';\n }\n}\n\n/**\n * Clear issued warnings (useful for testing)\n */\nexport function clearWarnings(): void {\n issuedWarnings.clear();\n}\n\n/**\n * Pre-built warning checks\n */\nexport const checks = {\n /**\n * Check for missing accessible label\n */\n accessibleLabel(\n element: HTMLElement | null,\n component: string,\n propName = 'aria-label'\n ): void {\n if (!element) return;\n\n if (!hasAccessibleName(element)) {\n warn({\n type: 'error',\n component,\n message: `Missing accessible label. Screen reader users will not be able to understand this element.`,\n suggestion: `Add ${propName}, aria-labelledby, or visible text content.`,\n element,\n });\n }\n },\n\n /**\n * Check for missing required prop\n */\n requiredProp(value: unknown, propName: string, component: string): void {\n if (value === undefined || value === null || value === '') {\n warn({\n type: 'error',\n component,\n message: `Missing required prop \"${propName}\".`,\n suggestion: `Provide a value for the \"${propName}\" prop.`,\n });\n }\n },\n\n /**\n * Check for invalid ARIA role\n */\n validRole(\n role: string | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (!role) return;\n\n const validRoles = new Set([\n 'alert',\n 'alertdialog',\n 'application',\n 'article',\n 'banner',\n 'button',\n 'cell',\n 'columnheader',\n 'combobox',\n 'complementary',\n 'contentinfo',\n 'definition',\n 'dialog',\n 'directory',\n 'document',\n 'feed',\n 'figure',\n 'form',\n 'grid',\n 'gridcell',\n 'group',\n 'heading',\n 'img',\n 'link',\n 'list',\n 'listbox',\n 'listitem',\n 'log',\n 'main',\n 'marquee',\n 'math',\n 'menu',\n 'menubar',\n 'menuitem',\n 'navigation',\n 'none',\n 'note',\n 'option',\n 'presentation',\n 'progressbar',\n 'region',\n 'row',\n 'rowgroup',\n 'rowheader',\n 'scrollbar',\n 'search',\n 'searchbox',\n 'separator',\n 'slider',\n 'spinbutton',\n 'status',\n 'switch',\n 'tab',\n 'table',\n 'tablist',\n 'tabpanel',\n 'term',\n 'textbox',\n 'timer',\n 'toolbar',\n 'tooltip',\n 'tree',\n 'treegrid',\n 'treeitem',\n ]);\n\n if (!validRoles.has(role)) {\n warn({\n type: 'warning',\n component,\n message: `Invalid ARIA role \"${role}\".`,\n suggestion: 'Use a valid ARIA role from the WAI-ARIA specification.',\n element,\n });\n }\n },\n\n /**\n * Check for interactive element without keyboard support\n */\n keyboardAccessible(\n element: HTMLElement | null,\n component: string,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ): void {\n if (!element) return;\n\n if (handlers.onClick && !handlers.onKeyDown) {\n const tagName = element.tagName.toLowerCase();\n const role = element.getAttribute('role');\n\n // Native interactive elements are fine\n if (['button', 'a', 'input', 'select', 'textarea'].includes(tagName)) {\n return;\n }\n\n // Elements with interactive roles need keyboard handling\n const interactiveRoles = ['button', 'link', 'menuitem', 'option', 'tab'];\n if (role && interactiveRoles.includes(role)) {\n warn({\n type: 'warning',\n component,\n message: `Element has onClick but no onKeyDown handler.`,\n suggestion: 'Add keyboard event handling for Enter and Space keys.',\n element,\n });\n }\n }\n },\n\n /**\n * Check tabIndex usage\n */\n tabIndex(\n tabIndex: number | undefined,\n component: string,\n element?: HTMLElement\n ): void {\n if (tabIndex === undefined) return;\n\n if (tabIndex > 0) {\n warn({\n type: 'warning',\n component,\n message: `Positive tabIndex (${tabIndex}) disrupts natural tab order.`,\n suggestion:\n 'Use tabIndex={0} or tabIndex={-1} instead. Rely on DOM order for tab sequence.',\n element,\n });\n }\n },\n\n /**\n * Check for autofocus in dialogs\n */\n dialogAutoFocus(hasAutoFocus: boolean, component: string): void {\n if (!hasAutoFocus) {\n warn({\n type: 'info',\n component,\n message: 'No initial focus element specified for dialog.',\n suggestion: 'Consider setting initialFocus to guide keyboard users.',\n });\n }\n },\n\n /**\n * Check for missing form labels\n */\n formLabel(\n inputElement: HTMLElement | null,\n labelId: string | undefined,\n component: string\n ): void {\n if (!inputElement) return;\n\n const hasLabel =\n labelId ||\n inputElement.getAttribute('aria-label') ||\n inputElement.getAttribute('aria-labelledby') ||\n (inputElement as HTMLInputElement).labels?.length;\n\n if (!hasLabel) {\n warn({\n type: 'error',\n component,\n message: 'Form input is missing an accessible label.',\n suggestion: 'Add a <label>, aria-label, or aria-labelledby.',\n element: inputElement,\n });\n }\n },\n\n /**\n * Check for missing alt text on images\n */\n imageAlt(element: HTMLElement | null, component: string): void {\n if (!element || element.tagName !== 'IMG') return;\n\n const alt = element.getAttribute('alt');\n const role = element.getAttribute('role');\n\n if (alt === null && role !== 'presentation' && role !== 'none') {\n warn({\n type: 'error',\n component,\n message: 'Image is missing alt attribute.',\n suggestion:\n 'Add alt=\"\" for decorative images or descriptive alt text for meaningful images.',\n element,\n });\n }\n },\n};\n\n/**\n * Create a component-scoped warning function\n */\nexport function createComponentWarnings(componentName: string) {\n return {\n error: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'error',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n warning: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'warning',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n info: (message: string, suggestion?: string, element?: Element) =>\n warn({\n type: 'info',\n component: componentName,\n message,\n suggestion,\n element,\n }),\n checks: {\n accessibleLabel: (element: HTMLElement | null, propName?: string) =>\n checks.accessibleLabel(element, componentName, propName),\n requiredProp: (value: unknown, propName: string) =>\n checks.requiredProp(value, propName, componentName),\n keyboardAccessible: (\n element: HTMLElement | null,\n handlers: { onClick?: unknown; onKeyDown?: unknown }\n ) => checks.keyboardAccessible(element, componentName, handlers),\n tabIndex: (tabIndex: number | undefined, element?: HTMLElement) =>\n checks.tabIndex(tabIndex, componentName, element),\n },\n };\n}\n","/**\n * @compa11y/core\n *\n * Framework-agnostic accessibility primitives\n *\n * This package provides the foundational utilities used by all\n * compa11y packages (React, Web Components, etc.)\n */\n\n// Types\nexport * from './types';\n\n// Utilities\nexport * from './utils/id';\nexport * from './utils/dom';\nexport * from './utils/platform';\n\n// Focus Management\nexport * from './focus';\n\n// Keyboard Navigation\nexport * from './keyboard';\n\n// Screen Reader Announcements\nexport * from './announcer';\n\n// ARIA Utilities\nexport * from './aria';\n\n// Development Tools\nexport * from './dev';\n\n/**\n * Initialize all compa11y systems\n * Call this once at app startup for optimal behavior\n */\nexport function initCompa11y(): () => void {\n const cleanups: Array<() => void> = [];\n\n // Dynamic imports to support tree-shaking\n // These are safe because they're from this package\n import('./focus').then(({ initFocusVisible }) => {\n cleanups.push(initFocusVisible());\n });\n\n import('./announcer').then(({ initAnnouncer }) => {\n cleanups.push(initAnnouncer());\n });\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core types used across compa11y
|
|
3
3
|
*/
|
|
4
|
-
type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'button' | 'cell' | '
|
|
4
|
+
type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'button' | 'cell' | 'columnheader' | 'combobox' | 'complementary' | 'contentinfo' | 'definition' | 'dialog' | 'directory' | 'document' | 'feed' | 'figure' | 'form' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main' | 'marquee' | 'math' | 'menu' | 'menubar' | 'menuitem' | 'menuitemradio' | 'navigation' | 'none' | 'note' | 'option' | 'presentation' | 'progressbar' | 'radio' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';
|
|
5
5
|
type AriaLivePoliteness = 'off' | 'polite' | 'assertive';
|
|
6
6
|
interface FocusableElement extends HTMLElement {
|
|
7
7
|
focus(options?: FocusOptions): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core types used across compa11y
|
|
3
3
|
*/
|
|
4
|
-
type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'button' | 'cell' | '
|
|
4
|
+
type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'button' | 'cell' | 'columnheader' | 'combobox' | 'complementary' | 'contentinfo' | 'definition' | 'dialog' | 'directory' | 'document' | 'feed' | 'figure' | 'form' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main' | 'marquee' | 'math' | 'menu' | 'menubar' | 'menuitem' | 'menuitemradio' | 'navigation' | 'none' | 'note' | 'option' | 'presentation' | 'progressbar' | 'radio' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';
|
|
5
5
|
type AriaLivePoliteness = 'off' | 'polite' | 'assertive';
|
|
6
6
|
interface FocusableElement extends HTMLElement {
|
|
7
7
|
focus(options?: FocusOptions): void;
|