@a11ypros/a11y-ui-components 1.0.5 → 2.0.0

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 (236) hide show
  1. package/.storybook/custom.css +85 -0
  2. package/.storybook/main.ts +51 -0
  3. package/.storybook/manager-head.html +2 -0
  4. package/.storybook/manager.ts +31 -0
  5. package/.storybook/package.json +6 -0
  6. package/.storybook/preview.tsx +74 -0
  7. package/.storybook/public/logo.png +0 -0
  8. package/.storybook/vite.config.ts +24 -0
  9. package/.storybook/welcome.mdx +265 -0
  10. package/DEPLOYMENT.md +154 -0
  11. package/README.md +230 -287
  12. package/apps/web/app/(docs)/audit/audit.css +269 -0
  13. package/apps/web/app/(docs)/audit/page.tsx +271 -0
  14. package/apps/web/app/(docs)/components/button/page.tsx +49 -0
  15. package/apps/web/app/(docs)/components/form/page.tsx +92 -0
  16. package/apps/web/app/(docs)/components/link/page.tsx +31 -0
  17. package/apps/web/app/(docs)/components/modal/page.tsx +41 -0
  18. package/apps/web/app/(docs)/components/page.tsx +37 -0
  19. package/apps/web/app/(docs)/components/table/page.tsx +54 -0
  20. package/apps/web/app/(docs)/components/tabs/page.tsx +61 -0
  21. package/apps/web/app/api/audit/route.ts +128 -0
  22. package/apps/web/app/favicon.ico +0 -0
  23. package/apps/web/app/layout.tsx +20 -0
  24. package/apps/web/app/page.tsx +17 -0
  25. package/apps/web/app/styles/globals.css +5 -0
  26. package/apps/web/next-env.d.ts +6 -0
  27. package/apps/web/next.config.js +21 -0
  28. package/apps/web/package.json +29 -0
  29. package/apps/web/public/_headers +17 -0
  30. package/apps/web/public/_redirects +31 -0
  31. package/apps/web/public/logo.png +0 -0
  32. package/apps/web/tsconfig.json +29 -0
  33. package/netlify/functions/audit.ts +163 -0
  34. package/netlify.toml +37 -0
  35. package/package.json +28 -50
  36. package/packages/design-system/README.md +376 -0
  37. package/packages/design-system/create-tests.sh +215 -0
  38. package/packages/design-system/package.json +70 -0
  39. package/packages/design-system/scripts/copy-css.js +63 -0
  40. package/packages/design-system/src/components/Accordion/Accordion.stories.tsx +174 -0
  41. package/packages/design-system/src/components/Accordion/Accordion.tsx +211 -0
  42. package/packages/design-system/src/components/Accordion/index.ts +2 -0
  43. package/packages/design-system/src/components/Button/Button.stories.tsx +240 -0
  44. package/packages/design-system/src/components/Button/Button.test.tsx +148 -0
  45. package/packages/design-system/src/components/Button/Button.tsx +137 -0
  46. package/packages/design-system/src/components/Button/index.ts +3 -0
  47. package/packages/design-system/src/components/DataTable/DataTable.stories.tsx +220 -0
  48. package/packages/design-system/src/components/DataTable/DataTable.tsx +299 -0
  49. package/packages/design-system/src/components/DataTable/index.ts +3 -0
  50. package/packages/design-system/src/components/Form/Checkbox.stories.tsx +261 -0
  51. package/packages/design-system/src/components/Form/Checkbox.tsx +114 -0
  52. package/packages/design-system/src/components/Form/Fieldset.stories.tsx +219 -0
  53. package/packages/design-system/src/components/Form/Fieldset.tsx +71 -0
  54. package/packages/design-system/src/components/Form/Input.stories.tsx +173 -0
  55. package/packages/design-system/src/components/Form/Input.test.tsx +110 -0
  56. package/packages/design-system/src/components/Form/Input.tsx +113 -0
  57. package/packages/design-system/src/components/Form/Label.tsx +56 -0
  58. package/packages/design-system/src/components/Form/Radio.stories.tsx +274 -0
  59. package/packages/design-system/src/components/Form/Radio.tsx +147 -0
  60. package/packages/design-system/src/components/Form/Select.stories.tsx +304 -0
  61. package/packages/design-system/src/components/Form/Select.tsx +160 -0
  62. package/packages/design-system/src/components/Form/Textarea.stories.tsx +262 -0
  63. package/packages/design-system/src/components/Form/Textarea.tsx +145 -0
  64. package/packages/design-system/src/components/Form/index.ts +8 -0
  65. package/packages/design-system/src/components/Link/Link.stories.tsx +137 -0
  66. package/packages/design-system/src/components/Link/Link.tsx +112 -0
  67. package/packages/design-system/src/components/Link/index.ts +3 -0
  68. package/packages/design-system/src/components/Modal/Modal.stories.tsx +174 -0
  69. package/packages/design-system/src/components/Modal/Modal.test.tsx +173 -0
  70. package/packages/design-system/src/components/Modal/Modal.tsx +208 -0
  71. package/packages/design-system/src/components/Modal/index.ts +3 -0
  72. package/packages/design-system/src/components/Tabs/Tabs.stories.tsx +222 -0
  73. package/packages/design-system/src/components/Tabs/Tabs.tsx +254 -0
  74. package/packages/design-system/src/components/Tabs/index.ts +3 -0
  75. package/packages/design-system/src/hooks/useAriaLive.test.ts +110 -0
  76. package/packages/design-system/src/hooks/useAriaLive.ts +51 -0
  77. package/packages/design-system/src/hooks/useFocusReturn.test.ts +123 -0
  78. package/packages/design-system/src/hooks/useFocusReturn.ts +40 -0
  79. package/packages/design-system/src/hooks/useFocusTrap.test.ts +190 -0
  80. package/packages/design-system/src/hooks/useFocusTrap.ts +82 -0
  81. package/{dist/index.js → packages/design-system/src/index.ts} +4 -2
  82. package/{dist → packages/design-system/src}/styles/components.css +0 -4
  83. package/packages/design-system/src/styles/index.ts +3 -0
  84. package/packages/design-system/src/test-utils.tsx +71 -0
  85. package/packages/design-system/src/tokens/breakpoints.ts +28 -0
  86. package/packages/design-system/src/tokens/colors.ts +98 -0
  87. package/packages/design-system/src/tokens/index.ts +6 -0
  88. package/packages/design-system/src/tokens/motion.ts +41 -0
  89. package/packages/design-system/src/tokens/spacing.ts +24 -0
  90. package/packages/design-system/src/tokens/theme.ts +19 -0
  91. package/packages/design-system/src/tokens/typography.ts +64 -0
  92. package/packages/design-system/src/utils/aria.test.ts +215 -0
  93. package/packages/design-system/src/utils/aria.ts +108 -0
  94. package/packages/design-system/src/utils/focus.test.ts +175 -0
  95. package/packages/design-system/src/utils/focus.ts +87 -0
  96. package/packages/design-system/src/utils/index.ts +4 -0
  97. package/packages/design-system/src/utils/keyboard.test.ts +184 -0
  98. package/packages/design-system/src/utils/keyboard.ts +77 -0
  99. package/packages/design-system/tsconfig.json +17 -0
  100. package/packages/design-system/vitest.config +0 -0
  101. package/packages/design-system/vitest.config.ts +34 -0
  102. package/public/logo.png +0 -0
  103. package/scripts/fix-storybook-paths.js +53 -0
  104. package/tsconfig.json +20 -0
  105. package/dist/components/Accordion/Accordion.d.ts +0 -76
  106. package/dist/components/Accordion/Accordion.d.ts.map +0 -1
  107. package/dist/components/Accordion/Accordion.js +0 -91
  108. package/dist/components/Accordion/index.d.ts +0 -3
  109. package/dist/components/Accordion/index.d.ts.map +0 -1
  110. package/dist/components/Accordion/index.js +0 -1
  111. package/dist/components/Button/Button.d.ts +0 -37
  112. package/dist/components/Button/Button.d.ts.map +0 -1
  113. package/dist/components/Button/Button.js +0 -52
  114. package/dist/components/Button/index.d.ts +0 -3
  115. package/dist/components/Button/index.d.ts.map +0 -1
  116. package/dist/components/Button/index.js +0 -1
  117. package/dist/components/DataTable/DataTable.d.ts +0 -75
  118. package/dist/components/DataTable/DataTable.d.ts.map +0 -1
  119. package/dist/components/DataTable/DataTable.js +0 -122
  120. package/dist/components/DataTable/index.d.ts +0 -3
  121. package/dist/components/DataTable/index.d.ts.map +0 -1
  122. package/dist/components/DataTable/index.js +0 -1
  123. package/dist/components/Form/Checkbox.d.ts +0 -36
  124. package/dist/components/Form/Checkbox.d.ts.map +0 -1
  125. package/dist/components/Form/Checkbox.js +0 -39
  126. package/dist/components/Form/Fieldset.d.ts +0 -33
  127. package/dist/components/Form/Fieldset.d.ts.map +0 -1
  128. package/dist/components/Form/Fieldset.js +0 -34
  129. package/dist/components/Form/Input.d.ts +0 -37
  130. package/dist/components/Form/Input.d.ts.map +0 -1
  131. package/dist/components/Form/Input.js +0 -41
  132. package/dist/components/Form/Label.d.ts +0 -30
  133. package/dist/components/Form/Label.d.ts.map +0 -1
  134. package/dist/components/Form/Label.js +0 -30
  135. package/dist/components/Form/Radio.d.ts +0 -53
  136. package/dist/components/Form/Radio.d.ts.map +0 -1
  137. package/dist/components/Form/Radio.js +0 -39
  138. package/dist/components/Form/Select.d.ts +0 -51
  139. package/dist/components/Form/Select.d.ts.map +0 -1
  140. package/dist/components/Form/Select.js +0 -49
  141. package/dist/components/Form/Textarea.d.ts +0 -44
  142. package/dist/components/Form/Textarea.d.ts.map +0 -1
  143. package/dist/components/Form/Textarea.js +0 -43
  144. package/dist/components/Form/index.d.ts +0 -8
  145. package/dist/components/Form/index.d.ts.map +0 -1
  146. package/dist/components/Form/index.js +0 -7
  147. package/dist/components/Link/Link.d.ts +0 -34
  148. package/dist/components/Link/Link.d.ts.map +0 -1
  149. package/dist/components/Link/Link.js +0 -48
  150. package/dist/components/Link/index.d.ts +0 -3
  151. package/dist/components/Link/index.d.ts.map +0 -1
  152. package/dist/components/Link/index.js +0 -1
  153. package/dist/components/Modal/Modal.d.ts +0 -68
  154. package/dist/components/Modal/Modal.d.ts.map +0 -1
  155. package/dist/components/Modal/Modal.js +0 -108
  156. package/dist/components/Modal/index.d.ts +0 -3
  157. package/dist/components/Modal/index.d.ts.map +0 -1
  158. package/dist/components/Modal/index.js +0 -1
  159. package/dist/components/Tabs/Tabs.d.ts +0 -67
  160. package/dist/components/Tabs/Tabs.d.ts.map +0 -1
  161. package/dist/components/Tabs/Tabs.js +0 -134
  162. package/dist/components/Tabs/index.d.ts +0 -3
  163. package/dist/components/Tabs/index.d.ts.map +0 -1
  164. package/dist/components/Tabs/index.js +0 -1
  165. package/dist/components/Toast/Toast.css +0 -100
  166. package/dist/components/Toast/Toast.d.ts +0 -63
  167. package/dist/components/Toast/Toast.d.ts.map +0 -1
  168. package/dist/components/Toast/Toast.js +0 -92
  169. package/dist/components/Toast/ToastProvider.css +0 -48
  170. package/dist/components/Toast/ToastProvider.d.ts +0 -22
  171. package/dist/components/Toast/ToastProvider.d.ts.map +0 -1
  172. package/dist/components/Toast/ToastProvider.js +0 -33
  173. package/dist/components/Toast/index.d.ts +0 -5
  174. package/dist/components/Toast/index.d.ts.map +0 -1
  175. package/dist/components/Toast/index.js +0 -2
  176. package/dist/hooks/useAriaLive.d.ts +0 -9
  177. package/dist/hooks/useAriaLive.d.ts.map +0 -1
  178. package/dist/hooks/useAriaLive.js +0 -39
  179. package/dist/hooks/useFocusReturn.d.ts +0 -9
  180. package/dist/hooks/useFocusReturn.d.ts.map +0 -1
  181. package/dist/hooks/useFocusReturn.js +0 -33
  182. package/dist/hooks/useFocusTrap.d.ts +0 -9
  183. package/dist/hooks/useFocusTrap.d.ts.map +0 -1
  184. package/dist/hooks/useFocusTrap.js +0 -68
  185. package/dist/index.d.ts +0 -23
  186. package/dist/index.d.ts.map +0 -1
  187. package/dist/styles/index.d.ts +0 -3
  188. package/dist/styles/index.d.ts.map +0 -1
  189. package/dist/styles/index.js +0 -1
  190. package/dist/tokens/breakpoints.d.ts +0 -25
  191. package/dist/tokens/breakpoints.d.ts.map +0 -1
  192. package/dist/tokens/breakpoints.js +0 -23
  193. package/dist/tokens/colors.d.ts +0 -81
  194. package/dist/tokens/colors.d.ts.map +0 -1
  195. package/dist/tokens/colors.js +0 -86
  196. package/dist/tokens/index.d.ts +0 -6
  197. package/dist/tokens/index.d.ts.map +0 -1
  198. package/dist/tokens/index.js +0 -5
  199. package/dist/tokens/motion.d.ts +0 -30
  200. package/dist/tokens/motion.d.ts.map +0 -1
  201. package/dist/tokens/motion.js +0 -34
  202. package/dist/tokens/spacing.d.ts +0 -22
  203. package/dist/tokens/spacing.d.ts.map +0 -1
  204. package/dist/tokens/spacing.js +0 -20
  205. package/dist/tokens/theme.d.ts +0 -159
  206. package/dist/tokens/theme.d.ts.map +0 -1
  207. package/dist/tokens/theme.js +0 -15
  208. package/dist/tokens/typography.d.ts +0 -45
  209. package/dist/tokens/typography.d.ts.map +0 -1
  210. package/dist/tokens/typography.js +0 -56
  211. package/dist/utils/aria.d.ts +0 -60
  212. package/dist/utils/aria.d.ts.map +0 -1
  213. package/dist/utils/aria.js +0 -86
  214. package/dist/utils/focus.d.ts +0 -30
  215. package/dist/utils/focus.d.ts.map +0 -1
  216. package/dist/utils/focus.js +0 -80
  217. package/dist/utils/index.d.ts +0 -4
  218. package/dist/utils/index.d.ts.map +0 -1
  219. package/dist/utils/index.js +0 -3
  220. package/dist/utils/keyboard.d.ts +0 -38
  221. package/dist/utils/keyboard.d.ts.map +0 -1
  222. package/dist/utils/keyboard.js +0 -59
  223. /package/{dist → packages/design-system/src}/components/Accordion/Accordion.css +0 -0
  224. /package/{dist → packages/design-system/src}/components/Button/Button.css +0 -0
  225. /package/{dist → packages/design-system/src}/components/DataTable/DataTable.css +0 -0
  226. /package/{dist → packages/design-system/src}/components/Form/Checkbox.css +0 -0
  227. /package/{dist → packages/design-system/src}/components/Form/Fieldset.css +0 -0
  228. /package/{dist → packages/design-system/src}/components/Form/Input.css +0 -0
  229. /package/{dist → packages/design-system/src}/components/Form/Label.css +0 -0
  230. /package/{dist → packages/design-system/src}/components/Form/Radio.css +0 -0
  231. /package/{dist → packages/design-system/src}/components/Form/Select.css +0 -0
  232. /package/{dist → packages/design-system/src}/components/Form/Textarea.css +0 -0
  233. /package/{dist → packages/design-system/src}/components/Link/Link.css +0 -0
  234. /package/{dist → packages/design-system/src}/components/Modal/Modal.css +0 -0
  235. /package/{dist → packages/design-system/src}/components/Tabs/Tabs.css +0 -0
  236. /package/{dist → packages/design-system/src}/styles/global.css +0 -0
@@ -0,0 +1,85 @@
1
+ /* Custom Storybook styles */
2
+
3
+ /* Theme backgrounds for docs view */
4
+ [data-theme="dark"] .docs-story,
5
+ [data-theme="dark"] .sbdocs-preview {
6
+ background-color: #171717 !important;
7
+ }
8
+
9
+ [data-theme="light"] .docs-story,
10
+ [data-theme="light"] .sbdocs-preview {
11
+ background-color: #ffffff !important;
12
+ }
13
+
14
+ /* Override Storybook's default bright blue link color */
15
+ .sbdocs a,
16
+ .sbdocs a:link,
17
+ .docs-story a,
18
+ .docs-story a:link {
19
+ color: #0e8168 !important;
20
+ }
21
+
22
+ .sbdocs a:hover,
23
+ .docs-story a:hover {
24
+ color: #075985 !important;
25
+ }
26
+
27
+ .sbdocs a:visited,
28
+ .docs-story a:visited {
29
+ color: #0369a1 !important;
30
+ }
31
+
32
+ /* Fix controls pane button hover states - ensure text is visible */
33
+ .sb-controls button:hover,
34
+ .sb-controls button:focus,
35
+ [data-testid="control-buttons-container"] button:hover,
36
+ [data-testid="control-buttons-container"] button:focus,
37
+ button[aria-label*="Set"]:hover,
38
+ button[aria-label*="Set"]:focus,
39
+ button[aria-label*="Reset"]:hover,
40
+ button[aria-label*="Reset"]:focus,
41
+ [id*="storybook-panel"] button:hover,
42
+ [id*="storybook-panel"] button:focus {
43
+ color: #171717 !important;
44
+ background-color: #f5f5f5 !important;
45
+ }
46
+
47
+ /* Ensure button text is visible in all states */
48
+ .sb-controls button,
49
+ [data-testid="control-buttons-container"] button,
50
+ button[aria-label*="Set"],
51
+ button[aria-label*="Reset"],
52
+ [id*="storybook-panel"] button {
53
+ color: #171717 !important;
54
+ }
55
+
56
+ /* Override left sidebar navigation hover colors to match color scheme */
57
+ .sidebar-container [role="menuitem"]:hover,
58
+ .sidebar-container [role="menuitem"]:focus,
59
+ .sidebar-container a:hover,
60
+ .sidebar-container a:focus,
61
+ [data-nodetype="story"]:hover,
62
+ [data-nodetype="story"]:focus,
63
+ [data-nodetype="component"]:hover,
64
+ [data-nodetype="component"]:focus,
65
+ [data-nodetype="group"]:hover,
66
+ [data-nodetype="group"]:focus {
67
+ background-color: #f5f5f5 !important;
68
+ color: #0e8168 !important;
69
+ }
70
+
71
+ /* Override selected state to use primary color */
72
+ .sidebar-container [role="menuitem"][aria-selected="true"],
73
+ .sidebar-container [role="menuitem"][aria-current="true"],
74
+ [data-nodetype="story"][aria-selected="true"],
75
+ [data-nodetype="component"][aria-selected="true"] {
76
+ background-color: #f0f9ff !important;
77
+ color: #0e8168 !important;
78
+ border-left-color: #0e8168 !important;
79
+ }
80
+
81
+ .sb-bar button:hover {
82
+ color: #000000 !important;
83
+ background-color: #f5f5f5;;
84
+ }
85
+
@@ -0,0 +1,51 @@
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
+ managerHead: (head) => `
42
+ ${head}
43
+ <title>A11Y Pros Accessible Design System</title>
44
+ <meta name="description" content="Accessibility-first React UI component library - WCAG 2.1/2.2 compliant components" />
45
+ `,
46
+ // Base path is configured in vite.config.ts to use /storybook-static/
47
+ // This ensures assets use absolute paths that match where files are located
48
+ }
49
+
50
+ export default config
51
+
@@ -0,0 +1,2 @@
1
+ <title>A11Y Pros Accessible Design System - Storybook</title>
2
+ <meta name="description" content="Accessibility-first React UI component library - WCAG 2.1/2.2 compliant components" />
@@ -0,0 +1,31 @@
1
+ import { addons } from 'storybook/internal/manager-api'
2
+ import { create } from 'storybook/internal/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
+
27
+ // Explicitly set document title
28
+ if (typeof window !== 'undefined') {
29
+ window.document.title = 'A11Y Pros Accessible Design System'
30
+ }
31
+
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "storybook-config",
3
+ "version": "1.0.0",
4
+ "private": true
5
+ }
6
+
@@ -0,0 +1,74 @@
1
+ import type { Preview } from '@storybook/react'
2
+ import React, { useEffect } from 'react'
3
+ import '../packages/design-system/src/styles/global.css'
4
+ import './custom.css'
5
+
6
+ const withTheme = (Story, context) => {
7
+ const theme = context.globals.theme || 'light'
8
+
9
+ useEffect(() => {
10
+ document.documentElement.setAttribute('data-theme', theme)
11
+ // Also update Storybook's docs background
12
+ const docsStory = document.querySelector('.docs-story')
13
+ if (docsStory) {
14
+ docsStory.setAttribute('data-theme', theme)
15
+ }
16
+ }, [theme])
17
+
18
+ return (
19
+ <div data-theme={theme} style={{
20
+ backgroundColor: theme === 'dark' ? '#171717' : '#ffffff',
21
+ minHeight: '100%',
22
+ padding: '1rem'
23
+ }}>
24
+ <Story />
25
+ </div>
26
+ )
27
+ }
28
+
29
+ const preview: Preview = {
30
+ decorators: [withTheme],
31
+ globalTypes: {
32
+ theme: {
33
+ description: 'Global theme for components',
34
+ defaultValue: 'light',
35
+ toolbar: {
36
+ title: 'Theme',
37
+ icon: 'circlehollow',
38
+ items: [
39
+ { value: 'light', title: 'Light', icon: 'sun' },
40
+ { value: 'dark', title: 'Dark', icon: 'moon' },
41
+ ],
42
+ dynamicTitle: true,
43
+ },
44
+ },
45
+ },
46
+ parameters: {
47
+ actions: { argTypesRegex: '^on[A-Z].*' },
48
+ backgrounds: {
49
+ disable: true, // Disable since we're handling it with theme
50
+ },
51
+ controls: {
52
+ matchers: {
53
+ color: /(background|color)$/i,
54
+ date: /Date$/i,
55
+ },
56
+ },
57
+ a11y: {
58
+ config: {
59
+ rules: [
60
+ {
61
+ id: 'color-contrast',
62
+ enabled: true,
63
+ },
64
+ ],
65
+ },
66
+ },
67
+ docs: {
68
+ toc: false,
69
+ },
70
+ },
71
+ }
72
+
73
+ export default preview
74
+
Binary file
@@ -0,0 +1,24 @@
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
+
@@ -0,0 +1,265 @@
1
+ export const meta = {
2
+ title: 'Welcome',
3
+ };
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) • [Npm Package](https://www.npmjs.com/package/@a11ypros/a11y-ui-components)
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
+ ### Exploring Components
18
+
19
+ Browse the component stories in the sidebar to explore each component's:
20
+
21
+ ### Key Features
22
+
23
+ - **React 18+ Support**: Compatible with React 18.2.0 and React 19.0.0+
24
+ - **Light & Dark Mode**: Built-in theming support with semantic color tokens for light and dark modes
25
+ - **Fully Accessible Components**: All React UI components are fully accessible, featuring proper ARIA attributes, keyboard navigation, and screen reader support
26
+ - **WCAG 2.1/2.2 Compliant**: Components follow accessibility best practices and meet WCAG Level AA standards
27
+ - **Keyboard Navigation**: Complete keyboard support for all interactive elements
28
+ - **Focus Management**: Proper focus trapping and return focus patterns for modals and dialogs
29
+ - **Semantic HTML**: Components use semantic HTML with ARIA enhancements where needed
30
+ - **Reduced Motion Support**: Respects `prefers-reduced-motion` media query
31
+ - **High Contrast Support**: Supports `prefers-contrast` for better visibility
32
+ - **Design Token System**: Consistent spacing, colors, typography, and motion tokens
33
+
34
+ ## Available Components
35
+
36
+ Our component library includes:
37
+
38
+ - **Button**: Accessible button with variants, sizes, and loading states
39
+ - **Link**: Semantic link component with external link detection
40
+ - **Modal**: Focus-trapped modal dialog with ARIA support
41
+ - **DataTable**: Accessible table with keyboard navigation and sorting
42
+ - **Tabs**: Tab component with arrow key navigation
43
+ - **Form Components**: Input, Textarea, Select, Checkbox, Radio, Fieldset, Label
44
+
45
+ ## Coming Soon
46
+
47
+ The following components are currently in development and will be available soon:
48
+
49
+ - **DatePicker**: Accessible date selection component with keyboard navigation
50
+ - **Banner**: Alert banner component with ARIA live region support
51
+ - **Phone Text Field**: Specialized input field for phone numbers with formatting
52
+ - **Combobox**: Accessible autocomplete/combobox component with ARIA 1.2 patterns
53
+
54
+ ## Getting Started
55
+
56
+ ### Installation
57
+
58
+ Install the component library via npm:
59
+
60
+ ```bash
61
+ npm i @a11ypros/a11y-ui-components
62
+ ```
63
+
64
+ Or using yarn:
65
+
66
+ ```bash
67
+ yarn add @a11ypros/a11y-ui-components
68
+ ```
69
+
70
+ Or using pnpm:
71
+
72
+ ```bash
73
+ pnpm add @a11ypros/a11y-ui-components
74
+ ```
75
+
76
+ ### Usage
77
+
78
+ Once installed, you can import and use components in your React application:
79
+
80
+ ```tsx
81
+ import { Button, Modal, DataTable } from '@a11ypros/a11y-ui-components';
82
+
83
+ function App() {
84
+ return (
85
+ <Button variant="primary" size="medium">
86
+ Click me
87
+ </Button>
88
+ );
89
+ }
90
+ ```
91
+
92
+ Browse the component stories in the sidebar to explore each component's:
93
+ - Usage examples
94
+ - Accessibility features
95
+ - Keyboard interaction patterns
96
+ - WCAG compliance information
97
+ - Props and API documentation
98
+
99
+ ### Customization with Design Tokens
100
+
101
+ The library exports design tokens and utility functions for customizing your theme:
102
+
103
+ ```tsx
104
+ import { colors, spacing, typography, breakpoints, motion } from '@a11ypros/a11y-ui-components';
105
+ import { generateFocusRing, trapFocus, announceToScreenReader } from '@a11ypros/a11y-ui-components';
106
+
107
+ // Use design tokens in your custom components
108
+ const MyComponent = () => (
109
+ <div style={{
110
+ color: colors.primary[600],
111
+ padding: spacing[4],
112
+ fontSize: typography.size.base
113
+ }}>
114
+ Custom styled component with design tokens
115
+ </div>
116
+ );
117
+
118
+ // Use accessibility utilities
119
+ const MyModal = () => {
120
+ const modalRef = useRef(null);
121
+
122
+ useEffect(() => {
123
+ if (modalRef.current) {
124
+ trapFocus(modalRef.current);
125
+ announceToScreenReader('Modal opened');
126
+ }
127
+ }, []);
128
+
129
+ return <div ref={modalRef}>...</div>;
130
+ };
131
+ ```
132
+
133
+ **Available Tokens:**
134
+ - **Colors**: WCAG AA compliant color palettes (primary, neutral, success, warning, error)
135
+ - **Spacing**: Consistent spacing scale based on 4px/8px grid
136
+ - **Typography**: Font sizes, weights, and line heights
137
+ - **Breakpoints**: Responsive design breakpoints
138
+ - **Motion**: Animation durations respecting `prefers-reduced-motion`
139
+
140
+ **Utility Functions:**
141
+ - **ARIA helpers**: `announceToScreenReader`, `generateAriaLabel`
142
+ - **Focus management**: `trapFocus`, `restoreFocus`, `generateFocusRing`
143
+ - **Keyboard**: `handleEscape`, `handleArrowKeys`
144
+
145
+ All tokens maintain WCAG 2.1/2.2 Level AA compliance for color contrast and spacing.
146
+
147
+ ### Overriding Design Tokens
148
+
149
+ You can override the default design tokens by customizing CSS custom properties in your application:
150
+
151
+ ```css
152
+ /* In your global CSS file */
153
+ :root {
154
+ /* Override primary color */
155
+ --color-primary-500: #your-brand-color;
156
+ --color-primary-600: #your-darker-shade;
157
+ --color-primary-700: #your-darkest-shade;
158
+
159
+ /* Override spacing */
160
+ --spacing-4: 1.5rem; /* default is 1rem */
161
+
162
+ /* Override typography */
163
+ --font-size-base: 1.125rem; /* default is 1rem */
164
+ --font-weight-bold: 600; /* default is 700 */
165
+
166
+ /* Override motion */
167
+ --duration-normal: 250ms; /* default is 200ms */
168
+ }
169
+ ```
170
+
171
+ ### Light & Dark Mode Theming
172
+
173
+ The design system includes built-in support for light and dark modes using semantic color tokens. Toggle between themes by setting the `data-theme` attribute:
174
+
175
+ ```html
176
+ <!-- Light mode (default) -->
177
+ <html data-theme="light">
178
+
179
+ <!-- Dark mode -->
180
+ <html data-theme="dark">
181
+ ```
182
+
183
+ Implement a theme toggle in your application:
184
+
185
+ ```tsx
186
+ const ThemeToggle = () => {
187
+ const [theme, setTheme] = useState('light');
188
+
189
+ const toggleTheme = () => {
190
+ const newTheme = theme === 'light' ? 'dark' : 'light';
191
+ setTheme(newTheme);
192
+ document.documentElement.setAttribute('data-theme', newTheme);
193
+ };
194
+
195
+ return (
196
+ <button onClick={toggleTheme}>
197
+ Switch to {theme === 'light' ? 'dark' : 'light'} mode
198
+ </button>
199
+ );
200
+ };
201
+ ```
202
+
203
+ **Theme-Aware Semantic Colors:**
204
+
205
+ The system uses semantic color variables that automatically adapt to the current theme:
206
+ - `--color-text-primary`: Main text color (dark in light mode, light in dark mode)
207
+ - `--color-text-secondary`: Secondary text color
208
+ - `--color-background-default`: Primary background
209
+ - `--color-background-secondary`: Secondary background (cards, hover states)
210
+ - `--color-link`: Link color (maintains WCAG AA contrast in both themes)
211
+ - `--color-border-default`: Border colors
212
+
213
+ All color combinations are tested to meet WCAG AA contrast requirements (4.5:1) in both light and dark modes.
214
+
215
+ **Important**: When overriding colors, ensure your custom colors maintain WCAG AA contrast ratios:
216
+ - **4.5:1** minimum for normal text
217
+ - **3:1** minimum for large text (18pt+) and UI components
218
+
219
+ **Available CSS Custom Properties:**
220
+ - Semantic Colors (theme-aware): `--color-text-primary`, `--color-text-secondary`, `--color-background-default`, `--color-background-secondary`, `--color-link`, `--color-border-default`, `--color-border-hover`, `--color-border-focus`
221
+ - Base Colors: `--color-primary-[50-900]`, `--color-neutral-[50-900]`, `--color-success-[500-700]`, etc.
222
+ - Spacing: `--spacing-[0,1,2,3,4,5,6,8,10,12,16,20,24,32]`
223
+ - Typography: `--font-size-[xs,sm,base,lg,xl,2xl,3xl,4xl]`, `--font-weight-[normal,medium,semibold,bold]`
224
+ - Motion: `--duration-[fast,normal,slow]`
225
+
226
+ ## Accessibility First
227
+
228
+ As a **certified WAS web accessibility specialist**, I've ensured that every component in this library:
229
+
230
+ - Uses semantic HTML elements
231
+ - Implements proper ARIA attributes
232
+ - Supports full keyboard navigation
233
+ - Provides visible focus indicators
234
+ - Meets WCAG contrast requirements
235
+ - Works seamlessly with screen readers
236
+ - Handles focus management appropriately
237
+
238
+ Each component story includes detailed accessibility documentation, so you can understand how to use these components in an accessible way.
239
+
240
+ ## Important Note on Accessibility
241
+
242
+ > **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.
243
+
244
+ To ensure your application is truly accessible, consider:
245
+
246
+ - **Proper Implementation**: Use components according to their documented patterns and accessibility guidelines
247
+ - **Application-Level Considerations**: Ensure proper page structure, heading hierarchy, and landmark regions
248
+ - **Content Accessibility**: Write clear, descriptive text and provide alternative text for images
249
+ - **Testing**: Regularly test your application with keyboard navigation and screen readers
250
+ - **User Experience**: Consider the full user journey and how components work together
251
+
252
+ These components provide a solid foundation, but accessibility is achieved through thoughtful implementation across your entire application.
253
+
254
+ ## Design Tokens
255
+
256
+ The design system uses CSS custom properties for theming, ensuring consistency across your application while maintaining accessibility standards for color contrast and spacing.
257
+
258
+ ## Need Help?
259
+
260
+ 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.
261
+
262
+ ---
263
+
264
+ **Built with accessibility in mind by a certified WAS web accessibility specialist.**
265
+
package/DEPLOYMENT.md ADDED
@@ -0,0 +1,154 @@
1
+ # Deployment Guide for ui.a11ypros.com
2
+
3
+ This guide covers deploying the component library and Storybook to Netlify at `ui.a11ypros.com`.
4
+
5
+ ## What's Configured
6
+
7
+ ✅ **Netlify Configuration** (`netlify.toml`)
8
+ - Builds Storybook and Next.js app
9
+ - Serves Storybook at `/storybook`
10
+ - Routes API calls to Netlify Functions
11
+
12
+ ✅ **Next.js Static Export**
13
+ - Configured for static site generation
14
+ - Outputs to `apps/web/out`
15
+
16
+ ✅ **Storybook Build**
17
+ - Builds to `apps/web/public/storybook-static`
18
+ - Accessible at `ui.a11ypros.com/storybook`
19
+
20
+ ✅ **Netlify Function**
21
+ - Audit API converted to serverless function
22
+ - Located at `netlify/functions/audit.ts`
23
+ - Accessible via `/api/audit` (auto-redirected)
24
+
25
+ ## Deployment Steps
26
+
27
+ ### 1. Connect Repository to Netlify
28
+
29
+ 1. Go to [Netlify Dashboard](https://app.netlify.com)
30
+ 2. Click "Add new site" → "Import an existing project"
31
+ 3. Connect your Git provider and select this repository
32
+
33
+ ### 2. Configure Build Settings
34
+
35
+ Netlify should auto-detect `netlify.toml`, but verify:
36
+ - **Base directory:** `.` (root)
37
+ - **Build command:** `npm install && npm run build-storybook && npm run build --workspace=apps/web`
38
+ - **Publish directory:** `apps/web/out`
39
+
40
+ ### 3. Set Environment Variables
41
+
42
+ Go to **Site settings → Environment variables** and add:
43
+ - `ANTHROPIC_API_KEY` - Your Anthropic API key for the audit function
44
+
45
+ ### 4. Configure Custom Domain
46
+
47
+ 1. Go to **Site settings → Domain management**
48
+ 2. Click "Add custom domain"
49
+ 3. Enter `ui.a11ypros.com`
50
+ 4. Follow Netlify's DNS instructions:
51
+ - Add a **CNAME** record at your domain provider:
52
+ ```
53
+ Type: CNAME
54
+ Name: ui
55
+ Value: [your-netlify-site-name].netlify.app
56
+ ```
57
+ 5. Wait for DNS propagation (5-60 minutes)
58
+
59
+ ### 5. Deploy
60
+
61
+ - Netlify will automatically deploy on every push to your main branch
62
+ - Or click "Deploy site" to deploy manually
63
+
64
+ ## URLs After Deployment
65
+
66
+ - **Main App:** `https://ui.a11ypros.com`
67
+ - **Storybook:** `https://ui.a11ypros.com/storybook`
68
+ - **Audit API:** `https://ui.a11ypros.com/api/audit` (POST)
69
+
70
+ ## How It Works
71
+
72
+ 1. **Build Process:**
73
+ - Installs dependencies
74
+ - Builds Storybook → `apps/web/public/storybook-static`
75
+ - Builds Next.js app → `apps/web/out` (includes Storybook from public/)
76
+
77
+ 2. **Routing:**
78
+ - `/storybook/*` → Served from `/storybook-static/*`
79
+ - `/api/audit` → Redirected to `/.netlify/functions/audit`
80
+ - `/*` → Next.js SPA routes
81
+
82
+ 3. **Netlify Function:**
83
+ - Serverless function handles the audit API
84
+ - Uses `ANTHROPIC_API_KEY` environment variable
85
+ - Supports CORS for cross-origin requests
86
+
87
+ ## Troubleshooting
88
+
89
+ ### Build Fails
90
+
91
+ - Check Node.js version (should be 18+)
92
+ - Verify all dependencies are in `package.json`
93
+ - Check build logs in Netlify dashboard
94
+
95
+ ### Storybook Not Loading
96
+
97
+ - Verify Storybook build completed successfully
98
+ - Check that `apps/web/public/storybook-static` exists
99
+ - Verify redirect rules in `netlify.toml`
100
+
101
+ ### API Not Working
102
+
103
+ - Ensure `ANTHROPIC_API_KEY` is set in Netlify environment variables
104
+ - Check Netlify Function logs in dashboard
105
+ - Verify the function is deployed (check Functions tab)
106
+
107
+ ### DNS Issues
108
+
109
+ - Wait for DNS propagation (can take up to 48 hours, usually 5-60 minutes)
110
+ - Verify CNAME record is correct
111
+ - Check DNS propagation with `dig ui.a11ypros.com`
112
+
113
+ ## Local Testing
114
+
115
+ Test the build locally before deploying:
116
+
117
+ ```bash
118
+ # Install dependencies
119
+ npm install
120
+
121
+ # Build Storybook
122
+ npm run build-storybook
123
+
124
+ # Build Next.js app
125
+ npm run build --workspace=apps/web
126
+
127
+ # Test locally (optional)
128
+ npx serve apps/web/out
129
+ ```
130
+
131
+ Visit `http://localhost:3000` for the app and `http://localhost:3000/storybook` for Storybook.
132
+
133
+ ## File Structure
134
+
135
+ ```
136
+ ├── netlify.toml # Netlify configuration
137
+ ├── netlify/
138
+ │ └── functions/
139
+ │ └── audit.ts # Netlify Function for audit API
140
+ ├── apps/
141
+ │ └── web/
142
+ │ ├── public/
143
+ │ │ └── storybook-static/ # Storybook build output
144
+ │ └── out/ # Next.js build output
145
+ └── package.json # Root dependencies
146
+ ```
147
+
148
+ ## Notes
149
+
150
+ - The Next.js app uses static export, so no server-side features
151
+ - API routes are converted to Netlify Functions
152
+ - Storybook is served as static files alongside the app
153
+ - All routes are client-side (SPA mode)
154
+