@a11ypros/a11y-ui-components 1.0.1 → 1.0.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.
Files changed (217) hide show
  1. package/README.md +182 -157
  2. package/dist/components/Button/Button.d.ts +37 -0
  3. package/dist/components/Button/Button.d.ts.map +1 -0
  4. package/dist/components/Button/Button.js +52 -0
  5. package/dist/components/Button/index.d.ts +3 -0
  6. package/dist/components/Button/index.d.ts.map +1 -0
  7. package/dist/components/Button/index.js +1 -0
  8. package/dist/components/DataTable/DataTable.d.ts +71 -0
  9. package/dist/components/DataTable/DataTable.d.ts.map +1 -0
  10. package/dist/components/DataTable/DataTable.js +122 -0
  11. package/dist/components/DataTable/index.d.ts +3 -0
  12. package/dist/components/DataTable/index.d.ts.map +1 -0
  13. package/dist/components/DataTable/index.js +1 -0
  14. package/dist/components/Form/Checkbox.d.ts +36 -0
  15. package/dist/components/Form/Checkbox.d.ts.map +1 -0
  16. package/dist/components/Form/Checkbox.js +39 -0
  17. package/dist/components/Form/Fieldset.d.ts +33 -0
  18. package/dist/components/Form/Fieldset.d.ts.map +1 -0
  19. package/dist/components/Form/Fieldset.js +34 -0
  20. package/dist/components/Form/Input.d.ts +37 -0
  21. package/dist/components/Form/Input.d.ts.map +1 -0
  22. package/dist/components/Form/Input.js +41 -0
  23. package/dist/components/Form/Label.d.ts +30 -0
  24. package/dist/components/Form/Label.d.ts.map +1 -0
  25. package/dist/components/Form/Label.js +30 -0
  26. package/dist/components/Form/Radio.d.ts +53 -0
  27. package/dist/components/Form/Radio.d.ts.map +1 -0
  28. package/dist/components/Form/Radio.js +39 -0
  29. package/dist/components/Form/Select.d.ts +51 -0
  30. package/dist/components/Form/Select.d.ts.map +1 -0
  31. package/dist/components/Form/Select.js +49 -0
  32. package/dist/components/Form/Textarea.d.ts +44 -0
  33. package/dist/components/Form/Textarea.d.ts.map +1 -0
  34. package/dist/components/Form/Textarea.js +43 -0
  35. package/dist/components/Form/index.d.ts +8 -0
  36. package/dist/components/Form/index.d.ts.map +1 -0
  37. package/dist/components/Form/index.js +7 -0
  38. package/dist/components/Link/Link.d.ts +34 -0
  39. package/dist/components/Link/Link.d.ts.map +1 -0
  40. package/dist/components/Link/Link.js +48 -0
  41. package/dist/components/Link/index.d.ts +3 -0
  42. package/dist/components/Link/index.d.ts.map +1 -0
  43. package/dist/components/Link/index.js +1 -0
  44. package/dist/components/Modal/Modal.d.ts +64 -0
  45. package/dist/components/Modal/Modal.d.ts.map +1 -0
  46. package/dist/components/Modal/Modal.js +108 -0
  47. package/dist/components/Modal/index.d.ts +3 -0
  48. package/dist/components/Modal/index.d.ts.map +1 -0
  49. package/dist/components/Modal/index.js +1 -0
  50. package/dist/components/Tabs/Tabs.d.ts +63 -0
  51. package/dist/components/Tabs/Tabs.d.ts.map +1 -0
  52. package/dist/components/Tabs/Tabs.js +134 -0
  53. package/dist/components/Tabs/index.d.ts +3 -0
  54. package/dist/components/Tabs/index.d.ts.map +1 -0
  55. package/dist/components/Tabs/index.js +1 -0
  56. package/dist/components/Toast/Toast.d.ts +59 -0
  57. package/dist/components/Toast/Toast.d.ts.map +1 -0
  58. package/dist/components/Toast/Toast.js +91 -0
  59. package/dist/components/Toast/ToastProvider.d.ts +22 -0
  60. package/dist/components/Toast/ToastProvider.d.ts.map +1 -0
  61. package/dist/components/Toast/ToastProvider.js +33 -0
  62. package/dist/components/Toast/index.d.ts +5 -0
  63. package/dist/components/Toast/index.d.ts.map +1 -0
  64. package/dist/components/Toast/index.js +2 -0
  65. package/dist/hooks/useAriaLive.d.ts +9 -0
  66. package/dist/hooks/useAriaLive.d.ts.map +1 -0
  67. package/dist/hooks/useAriaLive.js +39 -0
  68. package/dist/hooks/useFocusReturn.d.ts +9 -0
  69. package/dist/hooks/useFocusReturn.d.ts.map +1 -0
  70. package/dist/hooks/useFocusReturn.js +33 -0
  71. package/dist/hooks/useFocusTrap.d.ts +9 -0
  72. package/dist/hooks/useFocusTrap.d.ts.map +1 -0
  73. package/dist/hooks/useFocusTrap.js +68 -0
  74. package/dist/index.d.ts +22 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/{packages/design-system/src/index.ts → dist/index.js} +0 -4
  77. package/dist/styles/index.d.ts +3 -0
  78. package/dist/styles/index.d.ts.map +1 -0
  79. package/dist/styles/index.js +1 -0
  80. package/dist/tokens/breakpoints.d.ts +25 -0
  81. package/dist/tokens/breakpoints.d.ts.map +1 -0
  82. package/dist/tokens/breakpoints.js +23 -0
  83. package/dist/tokens/colors.d.ts +81 -0
  84. package/dist/tokens/colors.d.ts.map +1 -0
  85. package/dist/tokens/colors.js +86 -0
  86. package/dist/tokens/index.d.ts +6 -0
  87. package/dist/tokens/index.d.ts.map +1 -0
  88. package/dist/tokens/index.js +5 -0
  89. package/dist/tokens/motion.d.ts +30 -0
  90. package/dist/tokens/motion.d.ts.map +1 -0
  91. package/dist/tokens/motion.js +34 -0
  92. package/dist/tokens/spacing.d.ts +22 -0
  93. package/dist/tokens/spacing.d.ts.map +1 -0
  94. package/dist/tokens/spacing.js +20 -0
  95. package/dist/tokens/theme.d.ts +159 -0
  96. package/dist/tokens/theme.d.ts.map +1 -0
  97. package/dist/tokens/theme.js +15 -0
  98. package/dist/tokens/typography.d.ts +45 -0
  99. package/dist/tokens/typography.d.ts.map +1 -0
  100. package/dist/tokens/typography.js +56 -0
  101. package/dist/utils/aria.d.ts +60 -0
  102. package/dist/utils/aria.d.ts.map +1 -0
  103. package/dist/utils/aria.js +86 -0
  104. package/dist/utils/focus.d.ts +30 -0
  105. package/dist/utils/focus.d.ts.map +1 -0
  106. package/dist/utils/focus.js +80 -0
  107. package/dist/utils/index.d.ts +4 -0
  108. package/dist/utils/index.d.ts.map +1 -0
  109. package/dist/utils/index.js +3 -0
  110. package/dist/utils/keyboard.d.ts +38 -0
  111. package/dist/utils/keyboard.d.ts.map +1 -0
  112. package/dist/utils/keyboard.js +59 -0
  113. package/package.json +58 -31
  114. package/.storybook/custom.css +0 -69
  115. package/.storybook/main.ts +0 -46
  116. package/.storybook/manager.ts +0 -26
  117. package/.storybook/package.json +0 -6
  118. package/.storybook/preview.tsx +0 -31
  119. package/.storybook/public/logo.png +0 -0
  120. package/.storybook/vite.config.ts +0 -24
  121. package/.storybook/welcome.mdx +0 -97
  122. package/DEPLOYMENT.md +0 -154
  123. package/apps/web/app/(docs)/audit/audit.css +0 -269
  124. package/apps/web/app/(docs)/audit/page.tsx +0 -271
  125. package/apps/web/app/(docs)/components/button/page.tsx +0 -49
  126. package/apps/web/app/(docs)/components/form/page.tsx +0 -92
  127. package/apps/web/app/(docs)/components/link/page.tsx +0 -31
  128. package/apps/web/app/(docs)/components/modal/page.tsx +0 -41
  129. package/apps/web/app/(docs)/components/page.tsx +0 -37
  130. package/apps/web/app/(docs)/components/table/page.tsx +0 -54
  131. package/apps/web/app/(docs)/components/tabs/page.tsx +0 -61
  132. package/apps/web/app/(docs)/components/toast/page.tsx +0 -51
  133. package/apps/web/app/api/audit/route.ts +0 -128
  134. package/apps/web/app/favicon.ico +0 -0
  135. package/apps/web/app/layout.tsx +0 -20
  136. package/apps/web/app/page.tsx +0 -17
  137. package/apps/web/app/styles/globals.css +0 -5
  138. package/apps/web/next-env.d.ts +0 -5
  139. package/apps/web/next.config.js +0 -21
  140. package/apps/web/package.json +0 -28
  141. package/apps/web/public/_headers +0 -17
  142. package/apps/web/public/_redirects +0 -31
  143. package/apps/web/public/logo.png +0 -0
  144. package/apps/web/tsconfig.json +0 -29
  145. package/netlify/functions/audit.ts +0 -163
  146. package/netlify.toml +0 -37
  147. package/packages/design-system/README.md +0 -252
  148. package/packages/design-system/package.json +0 -68
  149. package/packages/design-system/scripts/copy-css.js +0 -63
  150. package/packages/design-system/src/components/Button/Button.stories.tsx +0 -228
  151. package/packages/design-system/src/components/Button/Button.tsx +0 -137
  152. package/packages/design-system/src/components/Button/index.ts +0 -3
  153. package/packages/design-system/src/components/DataTable/DataTable.stories.tsx +0 -211
  154. package/packages/design-system/src/components/DataTable/DataTable.tsx +0 -293
  155. package/packages/design-system/src/components/DataTable/index.ts +0 -3
  156. package/packages/design-system/src/components/Form/Checkbox.stories.tsx +0 -252
  157. package/packages/design-system/src/components/Form/Checkbox.tsx +0 -114
  158. package/packages/design-system/src/components/Form/Fieldset.stories.tsx +0 -210
  159. package/packages/design-system/src/components/Form/Fieldset.tsx +0 -71
  160. package/packages/design-system/src/components/Form/Input.stories.tsx +0 -164
  161. package/packages/design-system/src/components/Form/Input.tsx +0 -113
  162. package/packages/design-system/src/components/Form/Label.tsx +0 -56
  163. package/packages/design-system/src/components/Form/Radio.stories.tsx +0 -265
  164. package/packages/design-system/src/components/Form/Radio.tsx +0 -147
  165. package/packages/design-system/src/components/Form/Select.stories.tsx +0 -295
  166. package/packages/design-system/src/components/Form/Select.tsx +0 -160
  167. package/packages/design-system/src/components/Form/Textarea.stories.tsx +0 -253
  168. package/packages/design-system/src/components/Form/Textarea.tsx +0 -145
  169. package/packages/design-system/src/components/Form/index.ts +0 -8
  170. package/packages/design-system/src/components/Link/Link.stories.tsx +0 -128
  171. package/packages/design-system/src/components/Link/Link.tsx +0 -117
  172. package/packages/design-system/src/components/Link/index.ts +0 -3
  173. package/packages/design-system/src/components/Modal/Modal.stories.tsx +0 -165
  174. package/packages/design-system/src/components/Modal/Modal.tsx +0 -202
  175. package/packages/design-system/src/components/Modal/index.ts +0 -3
  176. package/packages/design-system/src/components/Tabs/Tabs.stories.tsx +0 -213
  177. package/packages/design-system/src/components/Tabs/Tabs.tsx +0 -248
  178. package/packages/design-system/src/components/Tabs/index.ts +0 -3
  179. package/packages/design-system/src/components/Toast/Toast.stories.tsx +0 -153
  180. package/packages/design-system/src/components/Toast/Toast.tsx +0 -175
  181. package/packages/design-system/src/components/Toast/ToastProvider.tsx +0 -73
  182. package/packages/design-system/src/components/Toast/index.ts +0 -5
  183. package/packages/design-system/src/hooks/useAriaLive.ts +0 -51
  184. package/packages/design-system/src/hooks/useFocusReturn.ts +0 -40
  185. package/packages/design-system/src/hooks/useFocusTrap.ts +0 -82
  186. package/packages/design-system/src/styles/index.ts +0 -3
  187. package/packages/design-system/src/tokens/breakpoints.ts +0 -28
  188. package/packages/design-system/src/tokens/colors.ts +0 -98
  189. package/packages/design-system/src/tokens/index.ts +0 -6
  190. package/packages/design-system/src/tokens/motion.ts +0 -41
  191. package/packages/design-system/src/tokens/spacing.ts +0 -24
  192. package/packages/design-system/src/tokens/theme.ts +0 -19
  193. package/packages/design-system/src/tokens/typography.ts +0 -64
  194. package/packages/design-system/src/utils/aria.ts +0 -108
  195. package/packages/design-system/src/utils/focus.ts +0 -87
  196. package/packages/design-system/src/utils/index.ts +0 -4
  197. package/packages/design-system/src/utils/keyboard.ts +0 -77
  198. package/packages/design-system/tsconfig.json +0 -17
  199. package/public/logo.png +0 -0
  200. package/scripts/fix-storybook-paths.js +0 -53
  201. package/tsconfig.json +0 -20
  202. /package/{packages/design-system/src → dist}/components/Button/Button.css +0 -0
  203. /package/{packages/design-system/src → dist}/components/DataTable/DataTable.css +0 -0
  204. /package/{packages/design-system/src → dist}/components/Form/Checkbox.css +0 -0
  205. /package/{packages/design-system/src → dist}/components/Form/Fieldset.css +0 -0
  206. /package/{packages/design-system/src → dist}/components/Form/Input.css +0 -0
  207. /package/{packages/design-system/src → dist}/components/Form/Label.css +0 -0
  208. /package/{packages/design-system/src → dist}/components/Form/Radio.css +0 -0
  209. /package/{packages/design-system/src → dist}/components/Form/Select.css +0 -0
  210. /package/{packages/design-system/src → dist}/components/Form/Textarea.css +0 -0
  211. /package/{packages/design-system/src → dist}/components/Link/Link.css +0 -0
  212. /package/{packages/design-system/src → dist}/components/Modal/Modal.css +0 -0
  213. /package/{packages/design-system/src → dist}/components/Tabs/Tabs.css +0 -0
  214. /package/{packages/design-system/src → dist}/components/Toast/Toast.css +0 -0
  215. /package/{packages/design-system/src → dist}/components/Toast/ToastProvider.css +0 -0
  216. /package/{packages/design-system/src → dist}/styles/components.css +0 -0
  217. /package/{packages/design-system/src → dist}/styles/global.css +0 -0
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Focus management utilities
3
+ * Helpers for programmatic focus control
4
+ */
5
+ /**
6
+ * Get all focusable elements within a container
7
+ */
8
+ export declare function getFocusableElements(container: HTMLElement): HTMLElement[];
9
+ /**
10
+ * Get the first focusable element in a container
11
+ */
12
+ export declare function getFirstFocusable(container: HTMLElement): HTMLElement | null;
13
+ /**
14
+ * Get the last focusable element in a container
15
+ */
16
+ export declare function getLastFocusable(container: HTMLElement): HTMLElement | null;
17
+ /**
18
+ * Check if an element is focusable
19
+ */
20
+ export declare function isFocusable(element: HTMLElement): boolean;
21
+ export declare function saveFocus(): void;
22
+ /**
23
+ * Restore focus to the previously saved element
24
+ */
25
+ export declare function restoreFocus(): void;
26
+ /**
27
+ * Focus an element safely (with error handling)
28
+ */
29
+ export declare function safeFocus(element: HTMLElement | null): void;
30
+ //# sourceMappingURL=focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus.d.ts","sourceRoot":"","sources":["../../src/utils/focus.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,WAAW,GACrB,WAAW,EAAE,CAWf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAG5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAG3E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAQzD;AAOD,wBAAgB,SAAS,IAAI,IAAI,CAIhC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAKnC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAS3D"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Focus management utilities
3
+ * Helpers for programmatic focus control
4
+ */
5
+ /**
6
+ * Get all focusable elements within a container
7
+ */
8
+ export function getFocusableElements(container) {
9
+ const focusableSelectors = [
10
+ 'a[href]',
11
+ 'button:not([disabled])',
12
+ 'textarea:not([disabled])',
13
+ 'input:not([disabled])',
14
+ 'select:not([disabled])',
15
+ '[tabindex]:not([tabindex="-1"])',
16
+ ].join(', ');
17
+ return Array.from(container.querySelectorAll(focusableSelectors));
18
+ }
19
+ /**
20
+ * Get the first focusable element in a container
21
+ */
22
+ export function getFirstFocusable(container) {
23
+ const focusable = getFocusableElements(container);
24
+ return focusable[0] || null;
25
+ }
26
+ /**
27
+ * Get the last focusable element in a container
28
+ */
29
+ export function getLastFocusable(container) {
30
+ const focusable = getFocusableElements(container);
31
+ return focusable[focusable.length - 1] || null;
32
+ }
33
+ /**
34
+ * Check if an element is focusable
35
+ */
36
+ export function isFocusable(element) {
37
+ if (element.tabIndex < 0)
38
+ return false;
39
+ if (element.hasAttribute('disabled'))
40
+ return false;
41
+ if (element.hasAttribute('hidden'))
42
+ return false;
43
+ if (element.style.display === 'none')
44
+ return false;
45
+ if (element.style.visibility === 'hidden')
46
+ return false;
47
+ return true;
48
+ }
49
+ /**
50
+ * Save the currently focused element
51
+ */
52
+ let savedFocusElement = null;
53
+ export function saveFocus() {
54
+ if (document.activeElement instanceof HTMLElement) {
55
+ savedFocusElement = document.activeElement;
56
+ }
57
+ }
58
+ /**
59
+ * Restore focus to the previously saved element
60
+ */
61
+ export function restoreFocus() {
62
+ if (savedFocusElement) {
63
+ savedFocusElement.focus();
64
+ savedFocusElement = null;
65
+ }
66
+ }
67
+ /**
68
+ * Focus an element safely (with error handling)
69
+ */
70
+ export function safeFocus(element) {
71
+ if (element && typeof element.focus === 'function') {
72
+ try {
73
+ element.focus();
74
+ }
75
+ catch (error) {
76
+ // Silently fail if focus fails
77
+ console.warn('Failed to focus element:', error);
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,4 @@
1
+ export * from './aria';
2
+ export * from './keyboard';
3
+ export * from './focus';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './aria';
2
+ export * from './keyboard';
3
+ export * from './focus';
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Keyboard event utilities
3
+ * Helpers for handling keyboard interactions
4
+ */
5
+ export type KeyboardHandler = (event: React.KeyboardEvent) => void;
6
+ /**
7
+ * Check if a key is an activation key (Enter or Space)
8
+ */
9
+ export declare function isActivationKey(key: string): boolean;
10
+ /**
11
+ * Check if a key is an arrow key
12
+ */
13
+ export declare function isArrowKey(key: string): boolean;
14
+ /**
15
+ * Check if a key is a navigation key (Home, End, PageUp, PageDown)
16
+ */
17
+ export declare function isNavigationKey(key: string): boolean;
18
+ /**
19
+ * Check if a key is an escape key
20
+ */
21
+ export declare function isEscapeKey(key: string): boolean;
22
+ /**
23
+ * Check if modifier keys are pressed
24
+ */
25
+ export declare function hasModifierKey(event: React.KeyboardEvent): boolean;
26
+ /**
27
+ * Create a keyboard handler that only fires on specific keys
28
+ */
29
+ export declare function createKeyHandler(keys: string[], handler: KeyboardHandler): KeyboardHandler;
30
+ /**
31
+ * Create a keyboard handler for activation keys (Enter/Space)
32
+ */
33
+ export declare function createActivationHandler(handler: KeyboardHandler): KeyboardHandler;
34
+ /**
35
+ * Create a keyboard handler for arrow keys
36
+ */
37
+ export declare function createArrowKeyHandler(handler: KeyboardHandler): KeyboardHandler;
38
+ //# sourceMappingURL=keyboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/utils/keyboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAA;AAElE;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,GAAG,OAAO,CAElE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,eAAe,GACvB,eAAe,CAMjB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,eAAe,GACvB,eAAe,CAKjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,GACvB,eAAe,CAEjB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Keyboard event utilities
3
+ * Helpers for handling keyboard interactions
4
+ */
5
+ /**
6
+ * Check if a key is an activation key (Enter or Space)
7
+ */
8
+ export function isActivationKey(key) {
9
+ return key === 'Enter' || key === ' ';
10
+ }
11
+ /**
12
+ * Check if a key is an arrow key
13
+ */
14
+ export function isArrowKey(key) {
15
+ return ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(key);
16
+ }
17
+ /**
18
+ * Check if a key is a navigation key (Home, End, PageUp, PageDown)
19
+ */
20
+ export function isNavigationKey(key) {
21
+ return ['Home', 'End', 'PageUp', 'PageDown'].includes(key);
22
+ }
23
+ /**
24
+ * Check if a key is an escape key
25
+ */
26
+ export function isEscapeKey(key) {
27
+ return key === 'Escape';
28
+ }
29
+ /**
30
+ * Check if modifier keys are pressed
31
+ */
32
+ export function hasModifierKey(event) {
33
+ return event.ctrlKey || event.metaKey || event.altKey || event.shiftKey;
34
+ }
35
+ /**
36
+ * Create a keyboard handler that only fires on specific keys
37
+ */
38
+ export function createKeyHandler(keys, handler) {
39
+ return (event) => {
40
+ if (keys.includes(event.key)) {
41
+ handler(event);
42
+ }
43
+ };
44
+ }
45
+ /**
46
+ * Create a keyboard handler for activation keys (Enter/Space)
47
+ */
48
+ export function createActivationHandler(handler) {
49
+ return createKeyHandler(['Enter', ' '], (event) => {
50
+ event.preventDefault();
51
+ handler(event);
52
+ });
53
+ }
54
+ /**
55
+ * Create a keyboard handler for arrow keys
56
+ */
57
+ export function createArrowKeyHandler(handler) {
58
+ return createKeyHandler(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'], handler);
59
+ }
package/package.json CHANGED
@@ -1,40 +1,67 @@
1
1
  {
2
2
  "name": "@a11ypros/a11y-ui-components",
3
- "version": "1.0.1",
4
- "private": false,
5
- "workspaces": [
6
- "packages/*",
7
- "apps/*"
3
+ "version": "1.0.2",
4
+ "description": "An accessibility-first React UI component library built with WCAG 2.1/2.2 compliance",
5
+ "keywords": [
6
+ "react",
7
+ "accessibility",
8
+ "a11y",
9
+ "wcag",
10
+ "design-system",
11
+ "components",
12
+ "typescript"
8
13
  ],
14
+ "author": "Ryan Mack <ryan@a11ypros.com>",
15
+ "license": "MIT",
16
+ "type": "module",
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "module": "./dist/index.js",
20
+ "sideEffects": false,
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ },
30
+ "./styles": {
31
+ "import": "./dist/styles/global.css"
32
+ },
33
+ "./styles/components": {
34
+ "import": "./dist/styles/components.css"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/ryan0122/a11ypros-components.git",
41
+ "directory": "packages/design-system"
42
+ },
9
43
  "scripts": {
10
- "dev": "yarn workspace @apps/web dev",
11
- "build": "yarn workspace @apps/web build",
12
- "build:netlify": "netlify build --offline",
13
- "build:netlify:debug": "netlify build --debug --offline",
14
- "build:local": "mv apps/web/app/api apps/web/app/api.disabled 2>/dev/null || true && yarn install && yarn build-storybook && yarn workspace @apps/web build && mv apps/web/app/api.disabled apps/web/app/api 2>/dev/null || true",
15
- "build:local:clean": "rm -rf apps/web/.next apps/web/out apps/web/public/storybook-static node_modules/.cache && yarn build:local",
16
- "build:simulate": "netlify build --offline",
17
- "storybook": "storybook dev -p 6006 --config-dir .storybook",
18
- "build-storybook": "storybook build --config-dir .storybook --output-dir apps/web/public/storybook-static && node scripts/fix-storybook-paths.js"
44
+ "build": "tsc && node scripts/copy-css.js",
45
+ "prepublishOnly": "npm run build",
46
+ "storybook": "cd ../.. && npm run storybook",
47
+ "build-storybook": "cd ../.. && npm run build-storybook"
19
48
  },
20
- "dependencies": {
21
- "@anthropic-ai/sdk": "^0.20.0",
22
- "@netlify/functions": "^2.4.1"
49
+ "peerDependencies": {
50
+ "react": "^18.0.0",
51
+ "react-dom": "^18.0.0"
23
52
  },
24
53
  "devDependencies": {
25
- "@storybook/addon-a11y": "9.1.17",
26
- "@storybook/addon-docs": "9.1.17",
27
- "@storybook/addon-links": "9.1.17",
28
- "@storybook/react": "9.1.17",
29
- "@storybook/react-vite": "9.1.17",
30
- "react": "^18.2.0",
31
- "react-dom": "^18.2.0",
32
- "storybook": "9.1.17",
33
- "typescript": "^5.3.3",
34
- "vite": "^5.0.0"
35
- },
36
- "engines": {
37
- "node": ">=18.0.0"
54
+ "@storybook/addon-a11y": "^7.6.17",
55
+ "@storybook/addon-docs": "^7.6.17",
56
+ "@storybook/addon-essentials": "^7.6.17",
57
+ "@storybook/addon-interactions": "^7.6.17",
58
+ "@storybook/addon-links": "^7.6.17",
59
+ "@storybook/blocks": "^7.6.17",
60
+ "@storybook/react": "^7.6.17",
61
+ "@storybook/react-webpack5": "^7.6.17",
62
+ "@storybook/test": "^7.6.17",
63
+ "@types/react": "^18.2.48",
64
+ "@types/react-dom": "^18.2.18",
65
+ "typescript": "^5.3.3"
38
66
  }
39
67
  }
40
-
@@ -1,69 +0,0 @@
1
- /* Custom Storybook styles */
2
-
3
- /* Override Storybook's default bright blue link color */
4
- .sbdocs a,
5
- .sbdocs a:link,
6
- .docs-story a,
7
- .docs-story a:link {
8
- color: #0e8168 !important;
9
- }
10
-
11
- .sbdocs a:hover,
12
- .docs-story a:hover {
13
- color: #075985 !important;
14
- }
15
-
16
- .sbdocs a:visited,
17
- .docs-story a:visited {
18
- color: #0369a1 !important;
19
- }
20
-
21
- /* Fix controls pane button hover states - ensure text is visible */
22
- .sb-controls button:hover,
23
- .sb-controls button:focus,
24
- [data-testid="control-buttons-container"] button:hover,
25
- [data-testid="control-buttons-container"] button:focus,
26
- button[aria-label*="Set"]:hover,
27
- button[aria-label*="Set"]:focus,
28
- button[aria-label*="Reset"]:hover,
29
- button[aria-label*="Reset"]:focus,
30
- [id*="storybook-panel"] button:hover,
31
- [id*="storybook-panel"] button:focus {
32
- color: #171717 !important;
33
- background-color: #f5f5f5 !important;
34
- }
35
-
36
- /* Ensure button text is visible in all states */
37
- .sb-controls button,
38
- [data-testid="control-buttons-container"] button,
39
- button[aria-label*="Set"],
40
- button[aria-label*="Reset"],
41
- [id*="storybook-panel"] button {
42
- color: #171717 !important;
43
- }
44
-
45
- /* Override left sidebar navigation hover colors to match color scheme */
46
- .sidebar-container [role="menuitem"]:hover,
47
- .sidebar-container [role="menuitem"]:focus,
48
- .sidebar-container a:hover,
49
- .sidebar-container a:focus,
50
- [data-nodetype="story"]:hover,
51
- [data-nodetype="story"]:focus,
52
- [data-nodetype="component"]:hover,
53
- [data-nodetype="component"]:focus,
54
- [data-nodetype="group"]:hover,
55
- [data-nodetype="group"]:focus {
56
- background-color: #f5f5f5 !important;
57
- color: #0e8168 !important;
58
- }
59
-
60
- /* Override selected state to use primary color */
61
- .sidebar-container [role="menuitem"][aria-selected="true"],
62
- .sidebar-container [role="menuitem"][aria-current="true"],
63
- [data-nodetype="story"][aria-selected="true"],
64
- [data-nodetype="component"][aria-selected="true"] {
65
- background-color: #f0f9ff !important;
66
- color: #0e8168 !important;
67
- border-left-color: #0e8168 !important;
68
- }
69
-
@@ -1,46 +0,0 @@
1
- import type { StorybookConfig } from '@storybook/react-vite'
2
-
3
- const config: StorybookConfig = {
4
- stories: [
5
- '../.storybook/welcome.mdx',
6
- '../packages/design-system/src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
7
- addons: [
8
- '@storybook/addon-links',
9
- '@storybook/addon-a11y',
10
- '@storybook/addon-docs',
11
- ],
12
- framework: {
13
- name: '@storybook/react-vite',
14
- options: {
15
- viteConfigPath: '.storybook/vite.config.ts',
16
- },
17
- },
18
- viteFinal: async (config) => {
19
- config.define = {
20
- ...config.define,
21
- 'process.env': {},
22
- 'process': { env: {} },
23
- }
24
- return config
25
- },
26
- docs: {
27
- autodocs: 'tag',
28
- },
29
- typescript: {
30
- check: false,
31
- reactDocgen: 'react-docgen-typescript',
32
- reactDocgenTypescriptOptions: {
33
- shouldExtractLiteralValuesFromEnum: true,
34
- propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
35
- },
36
- },
37
- core: {
38
- disableTelemetry: true,
39
- },
40
- staticDirs: ['../public'],
41
- // Base path is configured in vite.config.ts to use /storybook-static/
42
- // This ensures assets use absolute paths that match where files are located
43
- }
44
-
45
- export default config
46
-
@@ -1,26 +0,0 @@
1
- import { addons } from '@storybook/manager-api'
2
- import { create } from '@storybook/theming'
3
- import './custom.css'
4
-
5
- const theme = create({
6
- base: 'light',
7
- brandTitle: 'A11y Pros Design System',
8
- brandUrl: '/storybook',
9
- brandImage: '/storybook-static/logo.png', // Path to your logo file (served from staticDirs)
10
- brandTarget: '_self',
11
-
12
- colorPrimary: '#0e8168',
13
- colorSecondary: '#001d2f',
14
-
15
- // Toolbar colors
16
- barTextColor: '#171717',
17
- barSelectedColor: '#0e8168', // Selected nav item color (matches colorPrimary)
18
- barHoverColor: '#f5f5f5', // Hover color for nav items in left sidebar
19
- barBg: '#ffffff',
20
-
21
- })
22
-
23
- addons.setConfig({
24
- theme,
25
- })
26
-
@@ -1,6 +0,0 @@
1
- {
2
- "name": "storybook-config",
3
- "version": "1.0.0",
4
- "private": true
5
- }
6
-
@@ -1,31 +0,0 @@
1
- import type { Preview } from '@storybook/react'
2
- import '../packages/design-system/src/styles/global.css'
3
- import './custom.css'
4
-
5
- const preview: Preview = {
6
- parameters: {
7
- actions: { argTypesRegex: '^on[A-Z].*' },
8
- controls: {
9
- matchers: {
10
- color: /(background|color)$/i,
11
- date: /Date$/i,
12
- },
13
- },
14
- a11y: {
15
- config: {
16
- rules: [
17
- {
18
- id: 'color-contrast',
19
- enabled: true,
20
- },
21
- ],
22
- },
23
- },
24
- docs: {
25
- toc: false,
26
- },
27
- },
28
- }
29
-
30
- export default preview
31
-
Binary file
@@ -1,24 +0,0 @@
1
- import { defineConfig } from 'vite'
2
-
3
- export default defineConfig({
4
- base: '/storybook-static/',
5
- define: {
6
- 'process.env': {},
7
- 'process': {
8
- env: {},
9
- },
10
- },
11
- build: {
12
- // Ensure assets use absolute paths
13
- assetsDir: 'assets',
14
- // Disable source maps in production to avoid eval issues
15
- sourcemap: false,
16
- // Ensure proper minification
17
- minify: 'esbuild',
18
- },
19
- // Ensure proper module resolution
20
- resolve: {
21
- preserveSymlinks: false,
22
- },
23
- })
24
-
@@ -1,97 +0,0 @@
1
- import { Meta } from '@storybook/blocks';
2
-
3
- <Meta title="Welcome" />
4
-
5
- # Welcome to the A11y Pros Accessible Design System
6
-
7
- Welcome to our **accessibility-first React UI component library**. This design system provides a comprehensive collection of fully accessible components built with React, TypeScript, and modern web standards.
8
-
9
- [View on GitHub](https://github.com/ryan0122/a11ypros-components) • [Live Documentation](https://ui.a11ypros.com)
10
-
11
- ## About This Design System
12
-
13
- This design system is **authored with accessibility in mind by a certified WAS (Web Accessibility Specialist)**. Every component has been carefully crafted to meet WCAG 2.1/2.2 Level AA standards, ensuring that your applications are usable by everyone, regardless of their abilities or the assistive technologies they use.
14
-
15
- **Note**: Currently, English is the only supported language for screen reader text and ARIA labels. Internationalization (i18n) support is coming soon.
16
-
17
- ### Key Features
18
-
19
- - **Fully Accessible Components**: All React UI components are fully accessible, featuring proper ARIA attributes, keyboard navigation, and screen reader support
20
- - **WCAG 2.1/2.2 Compliant**: Components follow accessibility best practices and meet WCAG Level AA standards
21
- - **Keyboard Navigation**: Complete keyboard support for all interactive elements
22
- - **Focus Management**: Proper focus trapping and return focus patterns for modals and dialogs
23
- - **Semantic HTML**: Components use semantic HTML with ARIA enhancements where needed
24
- - **Reduced Motion Support**: Respects `prefers-reduced-motion` media query
25
- - **High Contrast Support**: Supports `prefers-contrast` for better visibility
26
- - **Design Token System**: Consistent spacing, colors, typography, and motion tokens
27
-
28
- ## Available Components
29
-
30
- Our component library includes:
31
-
32
- - **Button**: Accessible button with variants, sizes, and loading states
33
- - **Link**: Semantic link component with external link detection
34
- - **Modal**: Focus-trapped modal dialog with ARIA support
35
- - **DataTable**: Accessible table with keyboard navigation and sorting
36
- - **Toast**: Notification system with ARIA live regions
37
- - **Tabs**: Tab component with arrow key navigation
38
- - **Form Components**: Input, Textarea, Select, Checkbox, Radio, Fieldset, Label
39
-
40
- ## Coming Soon
41
-
42
- The following components are currently in development and will be available soon:
43
-
44
- - **DatePicker**: Accessible date selection component with keyboard navigation
45
- - **Banner**: Alert banner component with ARIA live region support
46
- - **Phone Text Field**: Specialized input field for phone numbers with formatting
47
- - **Combobox**: Accessible autocomplete/combobox component with ARIA 1.2 patterns
48
-
49
- ## Getting Started
50
-
51
- Browse the component stories in the sidebar to explore each component's:
52
- - Usage examples
53
- - Accessibility features
54
- - Keyboard interaction patterns
55
- - WCAG compliance information
56
- - Props and API documentation
57
-
58
- ## Accessibility First
59
-
60
- As a **certified WAS web accessibility specialist**, I've ensured that every component in this library:
61
-
62
- - Uses semantic HTML elements
63
- - Implements proper ARIA attributes
64
- - Supports full keyboard navigation
65
- - Provides visible focus indicators
66
- - Meets WCAG contrast requirements
67
- - Works seamlessly with screen readers
68
- - Handles focus management appropriately
69
-
70
- Each component story includes detailed accessibility documentation, so you can understand how to use these components in an accessible way.
71
-
72
- ## Important Note on Accessibility
73
-
74
- > **Note**: While these components are built with accessibility in mind and meet WCAG 2.1/2.2 Level AA standards, **simply using these components does not guarantee an accessible application**. These components are foundational building blocks that must be used properly within the larger consuming application with accessibility in mind.
75
-
76
- To ensure your application is truly accessible, consider:
77
-
78
- - **Proper Implementation**: Use components according to their documented patterns and accessibility guidelines
79
- - **Application-Level Considerations**: Ensure proper page structure, heading hierarchy, and landmark regions
80
- - **Content Accessibility**: Write clear, descriptive text and provide alternative text for images
81
- - **Testing**: Regularly test your application with keyboard navigation and screen readers
82
- - **User Experience**: Consider the full user journey and how components work together
83
-
84
- These components provide a solid foundation, but accessibility is achieved through thoughtful implementation across your entire application.
85
-
86
- ## Design Tokens
87
-
88
- The design system uses CSS custom properties for theming, ensuring consistency across your application while maintaining accessibility standards for color contrast and spacing.
89
-
90
- ## Need Help?
91
-
92
- Explore the component stories to see examples, accessibility notes, and implementation details. Each component is documented with its WCAG compliance information and keyboard interaction patterns.
93
-
94
- ---
95
-
96
- **Built with accessibility in mind by a certified WAS web accessibility specialist.**
97
-