@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.
@@ -1,4 +1,4 @@
1
- import { A as AnnouncerOptions } from '../types-DDSPmE8m.cjs';
1
+ import { A as AnnouncerOptions } from '../types-DpTUSAxr.cjs';
2
2
 
3
3
  /**
4
4
  * Live Announcer
@@ -1,4 +1,4 @@
1
- import { A as AnnouncerOptions } from '../types-DDSPmE8m.js';
1
+ import { A as AnnouncerOptions } from '../types-DpTUSAxr.js';
2
2
 
3
3
  /**
4
4
  * Live Announcer
@@ -1,4 +1,4 @@
1
- import { c as AriaRole } from '../types-DDSPmE8m.cjs';
1
+ import { c as AriaRole } from '../types-DpTUSAxr.cjs';
2
2
 
3
3
  /**
4
4
  * ARIA Utilities
@@ -1,4 +1,4 @@
1
- import { c as AriaRole } from '../types-DDSPmE8m.js';
1
+ import { c as AriaRole } from '../types-DpTUSAxr.js';
2
2
 
3
3
  /**
4
4
  * ARIA Utilities
@@ -1,4 +1,4 @@
1
- import { F as FocusTrapOptions } from '../types-DDSPmE8m.cjs';
1
+ import { F as FocusTrapOptions } from '../types-DpTUSAxr.cjs';
2
2
 
3
3
  /**
4
4
  * Focus Trap - Constrains focus within a container
@@ -1,4 +1,4 @@
1
- import { F as FocusTrapOptions } from '../types-DDSPmE8m.js';
1
+ import { F as FocusTrapOptions } from '../types-DpTUSAxr.js';
2
2
 
3
3
  /**
4
4
  * Focus Trap - Constrains focus within a container
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 initA11yKit() {
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.initA11yKit = initA11yKit;
563
+ exports.initCompa11y = initCompa11y;
569
564
  exports.resetIdCounter = resetIdCounter;
570
565
  exports.setWarningHandler = setWarningHandler;
571
566
  exports.warn = warn;
@@ -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-DDSPmE8m.cjs';
2
- export { A as AnnouncerOptions, b as AriaLivePoliteness, c as AriaRole, F as FocusTrapOptions, d as FocusableElement, K as KeyboardNavigationOptions } from './types-DDSPmE8m.cjs';
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 initA11yKit(): () => void;
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, initA11yKit, isAndroid, isBrowser, isFocusable, isIOS, isMac, isTabbable, isTouchDevice, isVisible, isWindows, isWithinContainer, prefersDarkMode, prefersHighContrast, prefersReducedMotion, resetIdCounter, resolveElement, setWarningHandler, warn };
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-DDSPmE8m.js';
2
- export { A as AnnouncerOptions, b as AriaLivePoliteness, c as AriaRole, F as FocusTrapOptions, d as FocusableElement, K as KeyboardNavigationOptions } from './types-DDSPmE8m.js';
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 initA11yKit(): () => void;
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, initA11yKit, isAndroid, isBrowser, isFocusable, isIOS, isMac, isTabbable, isTouchDevice, isVisible, isWindows, isWithinContainer, prefersDarkMode, prefersHighContrast, prefersReducedMotion, resetIdCounter, resolveElement, setWarningHandler, warn };
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 initA11yKit() {
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, initA11yKit, resetIdCounter, setWarningHandler, warn };
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' | 'checkbox' | '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' | 'menuitemcheckbox' | 'menuitemradio' | 'navigation' | 'none' | 'note' | 'option' | 'presentation' | 'progressbar' | 'radio' | 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';
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' | 'checkbox' | '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' | 'menuitemcheckbox' | 'menuitemradio' | 'navigation' | 'none' | 'note' | 'option' | 'presentation' | 'progressbar' | 'radio' | 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem';
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compa11y/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Framework-agnostic accessibility primitives",
5
5
  "author": "Ivan Trajkovski",
6
6
  "license": "MIT",