@a11ypros/a11y-ui-components 1.0.0 → 1.0.1

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/.storybook/custom.css +69 -0
  2. package/.storybook/main.ts +46 -0
  3. package/.storybook/manager.ts +26 -0
  4. package/.storybook/package.json +6 -0
  5. package/.storybook/preview.tsx +31 -0
  6. package/.storybook/public/logo.png +0 -0
  7. package/.storybook/vite.config.ts +24 -0
  8. package/.storybook/welcome.mdx +97 -0
  9. package/DEPLOYMENT.md +154 -0
  10. package/README.md +227 -0
  11. package/apps/web/app/(docs)/audit/audit.css +269 -0
  12. package/apps/web/app/(docs)/audit/page.tsx +271 -0
  13. package/apps/web/app/(docs)/components/button/page.tsx +49 -0
  14. package/apps/web/app/(docs)/components/form/page.tsx +92 -0
  15. package/apps/web/app/(docs)/components/link/page.tsx +31 -0
  16. package/apps/web/app/(docs)/components/modal/page.tsx +41 -0
  17. package/apps/web/app/(docs)/components/page.tsx +37 -0
  18. package/apps/web/app/(docs)/components/table/page.tsx +54 -0
  19. package/apps/web/app/(docs)/components/tabs/page.tsx +61 -0
  20. package/apps/web/app/(docs)/components/toast/page.tsx +51 -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 +5 -0
  27. package/apps/web/next.config.js +21 -0
  28. package/apps/web/package.json +28 -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 +30 -58
  36. package/packages/design-system/README.md +252 -0
  37. package/packages/design-system/package.json +68 -0
  38. package/packages/design-system/scripts/copy-css.js +63 -0
  39. package/packages/design-system/src/components/Button/Button.stories.tsx +228 -0
  40. package/packages/design-system/src/components/Button/Button.tsx +137 -0
  41. package/packages/design-system/src/components/Button/index.ts +3 -0
  42. package/packages/design-system/src/components/DataTable/DataTable.stories.tsx +211 -0
  43. package/packages/design-system/src/components/DataTable/DataTable.tsx +293 -0
  44. package/packages/design-system/src/components/DataTable/index.ts +3 -0
  45. package/packages/design-system/src/components/Form/Checkbox.stories.tsx +252 -0
  46. package/packages/design-system/src/components/Form/Checkbox.tsx +114 -0
  47. package/packages/design-system/src/components/Form/Fieldset.stories.tsx +210 -0
  48. package/packages/design-system/src/components/Form/Fieldset.tsx +71 -0
  49. package/packages/design-system/src/components/Form/Input.stories.tsx +164 -0
  50. package/packages/design-system/src/components/Form/Input.tsx +113 -0
  51. package/packages/design-system/src/components/Form/Label.tsx +56 -0
  52. package/packages/design-system/src/components/Form/Radio.stories.tsx +265 -0
  53. package/packages/design-system/src/components/Form/Radio.tsx +147 -0
  54. package/packages/design-system/src/components/Form/Select.stories.tsx +295 -0
  55. package/packages/design-system/src/components/Form/Select.tsx +160 -0
  56. package/packages/design-system/src/components/Form/Textarea.stories.tsx +253 -0
  57. package/packages/design-system/src/components/Form/Textarea.tsx +145 -0
  58. package/packages/design-system/src/components/Form/index.ts +8 -0
  59. package/packages/design-system/src/components/Link/Link.stories.tsx +128 -0
  60. package/packages/design-system/src/components/Link/Link.tsx +117 -0
  61. package/packages/design-system/src/components/Link/index.ts +3 -0
  62. package/packages/design-system/src/components/Modal/Modal.stories.tsx +165 -0
  63. package/packages/design-system/src/components/Modal/Modal.tsx +202 -0
  64. package/packages/design-system/src/components/Modal/index.ts +3 -0
  65. package/packages/design-system/src/components/Tabs/Tabs.stories.tsx +213 -0
  66. package/packages/design-system/src/components/Tabs/Tabs.tsx +248 -0
  67. package/packages/design-system/src/components/Tabs/index.ts +3 -0
  68. package/packages/design-system/src/components/Toast/Toast.stories.tsx +153 -0
  69. package/packages/design-system/src/components/Toast/Toast.tsx +175 -0
  70. package/packages/design-system/src/components/Toast/ToastProvider.tsx +73 -0
  71. package/packages/design-system/src/components/Toast/index.ts +5 -0
  72. package/packages/design-system/src/hooks/useAriaLive.ts +51 -0
  73. package/packages/design-system/src/hooks/useFocusReturn.ts +40 -0
  74. package/packages/design-system/src/hooks/useFocusTrap.ts +82 -0
  75. package/{dist/index.js → packages/design-system/src/index.ts} +4 -0
  76. package/packages/design-system/src/styles/index.ts +3 -0
  77. package/packages/design-system/src/tokens/breakpoints.ts +28 -0
  78. package/packages/design-system/src/tokens/colors.ts +98 -0
  79. package/packages/design-system/src/tokens/index.ts +6 -0
  80. package/packages/design-system/src/tokens/motion.ts +41 -0
  81. package/packages/design-system/src/tokens/spacing.ts +24 -0
  82. package/packages/design-system/src/tokens/theme.ts +19 -0
  83. package/packages/design-system/src/tokens/typography.ts +64 -0
  84. package/packages/design-system/src/utils/aria.ts +108 -0
  85. package/packages/design-system/src/utils/focus.ts +87 -0
  86. package/packages/design-system/src/utils/index.ts +4 -0
  87. package/packages/design-system/src/utils/keyboard.ts +77 -0
  88. package/packages/design-system/tsconfig.json +17 -0
  89. package/public/logo.png +0 -0
  90. package/scripts/fix-storybook-paths.js +53 -0
  91. package/tsconfig.json +20 -0
  92. package/dist/components/Button/Button.d.ts +0 -37
  93. package/dist/components/Button/Button.d.ts.map +0 -1
  94. package/dist/components/Button/Button.js +0 -52
  95. package/dist/components/Button/index.d.ts +0 -3
  96. package/dist/components/Button/index.d.ts.map +0 -1
  97. package/dist/components/Button/index.js +0 -1
  98. package/dist/components/DataTable/DataTable.d.ts +0 -71
  99. package/dist/components/DataTable/DataTable.d.ts.map +0 -1
  100. package/dist/components/DataTable/DataTable.js +0 -122
  101. package/dist/components/DataTable/index.d.ts +0 -3
  102. package/dist/components/DataTable/index.d.ts.map +0 -1
  103. package/dist/components/DataTable/index.js +0 -1
  104. package/dist/components/Form/Checkbox.d.ts +0 -36
  105. package/dist/components/Form/Checkbox.d.ts.map +0 -1
  106. package/dist/components/Form/Checkbox.js +0 -39
  107. package/dist/components/Form/Fieldset.d.ts +0 -33
  108. package/dist/components/Form/Fieldset.d.ts.map +0 -1
  109. package/dist/components/Form/Fieldset.js +0 -34
  110. package/dist/components/Form/Input.d.ts +0 -37
  111. package/dist/components/Form/Input.d.ts.map +0 -1
  112. package/dist/components/Form/Input.js +0 -41
  113. package/dist/components/Form/Label.d.ts +0 -30
  114. package/dist/components/Form/Label.d.ts.map +0 -1
  115. package/dist/components/Form/Label.js +0 -30
  116. package/dist/components/Form/Radio.d.ts +0 -53
  117. package/dist/components/Form/Radio.d.ts.map +0 -1
  118. package/dist/components/Form/Radio.js +0 -39
  119. package/dist/components/Form/Select.d.ts +0 -51
  120. package/dist/components/Form/Select.d.ts.map +0 -1
  121. package/dist/components/Form/Select.js +0 -49
  122. package/dist/components/Form/Textarea.d.ts +0 -44
  123. package/dist/components/Form/Textarea.d.ts.map +0 -1
  124. package/dist/components/Form/Textarea.js +0 -43
  125. package/dist/components/Form/index.d.ts +0 -8
  126. package/dist/components/Form/index.d.ts.map +0 -1
  127. package/dist/components/Form/index.js +0 -7
  128. package/dist/components/Link/Link.d.ts +0 -34
  129. package/dist/components/Link/Link.d.ts.map +0 -1
  130. package/dist/components/Link/Link.js +0 -48
  131. package/dist/components/Link/index.d.ts +0 -3
  132. package/dist/components/Link/index.d.ts.map +0 -1
  133. package/dist/components/Link/index.js +0 -1
  134. package/dist/components/Modal/Modal.d.ts +0 -64
  135. package/dist/components/Modal/Modal.d.ts.map +0 -1
  136. package/dist/components/Modal/Modal.js +0 -108
  137. package/dist/components/Modal/index.d.ts +0 -3
  138. package/dist/components/Modal/index.d.ts.map +0 -1
  139. package/dist/components/Modal/index.js +0 -1
  140. package/dist/components/Tabs/Tabs.d.ts +0 -63
  141. package/dist/components/Tabs/Tabs.d.ts.map +0 -1
  142. package/dist/components/Tabs/Tabs.js +0 -134
  143. package/dist/components/Tabs/index.d.ts +0 -3
  144. package/dist/components/Tabs/index.d.ts.map +0 -1
  145. package/dist/components/Tabs/index.js +0 -1
  146. package/dist/components/Toast/Toast.d.ts +0 -59
  147. package/dist/components/Toast/Toast.d.ts.map +0 -1
  148. package/dist/components/Toast/Toast.js +0 -91
  149. package/dist/components/Toast/ToastProvider.d.ts +0 -22
  150. package/dist/components/Toast/ToastProvider.d.ts.map +0 -1
  151. package/dist/components/Toast/ToastProvider.js +0 -33
  152. package/dist/components/Toast/index.d.ts +0 -5
  153. package/dist/components/Toast/index.d.ts.map +0 -1
  154. package/dist/components/Toast/index.js +0 -2
  155. package/dist/hooks/useAriaLive.d.ts +0 -9
  156. package/dist/hooks/useAriaLive.d.ts.map +0 -1
  157. package/dist/hooks/useAriaLive.js +0 -39
  158. package/dist/hooks/useFocusReturn.d.ts +0 -9
  159. package/dist/hooks/useFocusReturn.d.ts.map +0 -1
  160. package/dist/hooks/useFocusReturn.js +0 -33
  161. package/dist/hooks/useFocusTrap.d.ts +0 -9
  162. package/dist/hooks/useFocusTrap.d.ts.map +0 -1
  163. package/dist/hooks/useFocusTrap.js +0 -68
  164. package/dist/index.d.ts +0 -22
  165. package/dist/index.d.ts.map +0 -1
  166. package/dist/styles/index.d.ts +0 -3
  167. package/dist/styles/index.d.ts.map +0 -1
  168. package/dist/styles/index.js +0 -1
  169. package/dist/tokens/breakpoints.d.ts +0 -25
  170. package/dist/tokens/breakpoints.d.ts.map +0 -1
  171. package/dist/tokens/breakpoints.js +0 -23
  172. package/dist/tokens/colors.d.ts +0 -81
  173. package/dist/tokens/colors.d.ts.map +0 -1
  174. package/dist/tokens/colors.js +0 -86
  175. package/dist/tokens/index.d.ts +0 -6
  176. package/dist/tokens/index.d.ts.map +0 -1
  177. package/dist/tokens/index.js +0 -5
  178. package/dist/tokens/motion.d.ts +0 -30
  179. package/dist/tokens/motion.d.ts.map +0 -1
  180. package/dist/tokens/motion.js +0 -34
  181. package/dist/tokens/spacing.d.ts +0 -22
  182. package/dist/tokens/spacing.d.ts.map +0 -1
  183. package/dist/tokens/spacing.js +0 -20
  184. package/dist/tokens/theme.d.ts +0 -159
  185. package/dist/tokens/theme.d.ts.map +0 -1
  186. package/dist/tokens/theme.js +0 -15
  187. package/dist/tokens/typography.d.ts +0 -45
  188. package/dist/tokens/typography.d.ts.map +0 -1
  189. package/dist/tokens/typography.js +0 -56
  190. package/dist/utils/aria.d.ts +0 -60
  191. package/dist/utils/aria.d.ts.map +0 -1
  192. package/dist/utils/aria.js +0 -86
  193. package/dist/utils/focus.d.ts +0 -30
  194. package/dist/utils/focus.d.ts.map +0 -1
  195. package/dist/utils/focus.js +0 -80
  196. package/dist/utils/index.d.ts +0 -4
  197. package/dist/utils/index.d.ts.map +0 -1
  198. package/dist/utils/index.js +0 -3
  199. package/dist/utils/keyboard.d.ts +0 -38
  200. package/dist/utils/keyboard.d.ts.map +0 -1
  201. package/dist/utils/keyboard.js +0 -59
  202. /package/{dist → packages/design-system/src}/components/Button/Button.css +0 -0
  203. /package/{dist → packages/design-system/src}/components/DataTable/DataTable.css +0 -0
  204. /package/{dist → packages/design-system/src}/components/Form/Checkbox.css +0 -0
  205. /package/{dist → packages/design-system/src}/components/Form/Fieldset.css +0 -0
  206. /package/{dist → packages/design-system/src}/components/Form/Input.css +0 -0
  207. /package/{dist → packages/design-system/src}/components/Form/Label.css +0 -0
  208. /package/{dist → packages/design-system/src}/components/Form/Radio.css +0 -0
  209. /package/{dist → packages/design-system/src}/components/Form/Select.css +0 -0
  210. /package/{dist → packages/design-system/src}/components/Form/Textarea.css +0 -0
  211. /package/{dist → packages/design-system/src}/components/Link/Link.css +0 -0
  212. /package/{dist → packages/design-system/src}/components/Modal/Modal.css +0 -0
  213. /package/{dist → packages/design-system/src}/components/Tabs/Tabs.css +0 -0
  214. /package/{dist → packages/design-system/src}/components/Toast/Toast.css +0 -0
  215. /package/{dist → packages/design-system/src}/components/Toast/ToastProvider.css +0 -0
  216. /package/{dist → packages/design-system/src}/styles/components.css +0 -0
  217. /package/{dist → packages/design-system/src}/styles/global.css +0 -0
@@ -0,0 +1,69 @@
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
+
@@ -0,0 +1,46 @@
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
+
@@ -0,0 +1,26 @@
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
+
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "storybook-config",
3
+ "version": "1.0.0",
4
+ "private": true
5
+ }
6
+
@@ -0,0 +1,31 @@
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
@@ -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,97 @@
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
+
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
+
package/README.md ADDED
@@ -0,0 +1,227 @@
1
+ # Accessible Design System + AI Audit Assistant
2
+
3
+ An opinionated, accessibility-first design system built with React, TypeScript, and Next.js, featuring an AI-powered accessibility audit assistant powered by Anthropic's Claude API.
4
+
5
+ ## Features
6
+
7
+ - **WCAG 2.1/2.2 Compliant Components**: All components follow accessibility best practices
8
+ - **Design Token System**: Consistent spacing, colors, typography, and motion tokens
9
+ - **Keyboard Navigation**: Full keyboard support for all interactive elements
10
+ - **Focus Management**: Proper focus trapping and return focus patterns
11
+ - **ARIA Support**: Semantic HTML with ARIA enhancements where needed
12
+ - **Reduced Motion**: Respects `prefers-reduced-motion` media query
13
+ - **High Contrast**: Supports `prefers-contrast` for better visibility
14
+ - **AI Audit Assistant**: Paste JSX code and get WCAG compliance reviews with code suggestions
15
+
16
+ ## Project Structure
17
+
18
+ ```
19
+ ├── packages/
20
+ │ └── design-system/ # Component library
21
+ │ ├── src/
22
+ │ │ ├── components/ # React components
23
+ │ │ ├── tokens/ # Design tokens
24
+ │ │ ├── hooks/ # Custom hooks
25
+ │ │ ├── utils/ # Utility functions
26
+ │ │ └── styles/ # Global styles
27
+ │ └── package.json
28
+ ├── apps/
29
+ │ └── web/ # Next.js app
30
+ │ ├── app/
31
+ │ │ ├── (docs)/ # Documentation pages
32
+ │ │ └── api/ # API routes
33
+ │ └── package.json
34
+ ├── .storybook/ # Storybook configuration
35
+ └── package.json # Root workspace config
36
+ ```
37
+
38
+ ## Getting Started
39
+
40
+ ### Prerequisites
41
+
42
+ - Node.js 18+
43
+ - npm or pnpm
44
+
45
+ ### Installation
46
+
47
+ 1. Clone the repository:
48
+ ```bash
49
+ git clone <repository-url>
50
+ cd PORTFOLIO
51
+ ```
52
+
53
+ 2. Install dependencies:
54
+ ```bash
55
+ npm install
56
+ ```
57
+
58
+ 3. Set up environment variables:
59
+ Create a `.env.local` file in `apps/web/`:
60
+ ```bash
61
+ ANTHROPIC_API_KEY=your_api_key_here
62
+ ```
63
+
64
+ ### Development
65
+
66
+ 1. Start the Next.js development server:
67
+ ```bash
68
+ npm run dev
69
+ ```
70
+
71
+ 2. Start Storybook (in a separate terminal):
72
+ ```bash
73
+ npm run storybook
74
+ ```
75
+
76
+ The Next.js app will be available at `http://localhost:3000` and Storybook at `http://localhost:6006`.
77
+
78
+ ## Component Library
79
+
80
+ ### Available Components
81
+
82
+ - **Button**: Accessible button with variants, sizes, and loading states
83
+ - **Link**: Semantic link component with external link detection
84
+ - **Modal**: Focus-trapped modal dialog with ARIA support
85
+ - **DataTable**: Accessible table with keyboard navigation and sorting
86
+ - **Toast**: Notification system with ARIA live regions
87
+ - **Tabs**: Tab component with arrow key navigation
88
+ - **Form Components**: Input, Textarea, Select, Checkbox, Radio, Fieldset, Label
89
+
90
+ ### Usage Example
91
+
92
+ ```tsx
93
+ import { Button, Input, Modal } from '@a11ypros/a11y-ui-components'
94
+
95
+ function MyComponent() {
96
+ const [isOpen, setIsOpen] = useState(false)
97
+
98
+ return (
99
+ <>
100
+ <Button variant="primary" onClick={() => setIsOpen(true)}>
101
+ Open Modal
102
+ </Button>
103
+
104
+ <Modal
105
+ isOpen={isOpen}
106
+ onClose={() => setIsOpen(false)}
107
+ title="Example Modal"
108
+ >
109
+ <Input label="Email" type="email" required />
110
+ </Modal>
111
+ </>
112
+ )
113
+ }
114
+ ```
115
+
116
+ ## WCAG Compliance
117
+
118
+ Each component documents its WCAG 2.1/2.2 compliance:
119
+
120
+ - **1.3.1** Info and Relationships (semantic HTML)
121
+ - **1.4.3** Contrast (Minimum) - via design tokens
122
+ - **2.1.1** Keyboard (all interactive elements)
123
+ - **2.4.7** Focus Visible
124
+ - **2.5.3** Label in Name
125
+ - **4.1.2** Name, Role, Value (ARIA)
126
+ - **4.1.3** Status Messages (for Toast)
127
+
128
+ ## AI Audit Assistant
129
+
130
+ The AI Audit Assistant analyzes JSX code snippets for accessibility issues:
131
+
132
+ 1. Navigate to `/audit` in the Next.js app
133
+ 2. Paste your JSX code
134
+ 3. Click "Run Accessibility Audit"
135
+ 4. Review issues grouped by WCAG Success Criteria
136
+ 5. See code suggestions for each issue
137
+
138
+ ### API Setup
139
+
140
+ The audit assistant requires an Anthropic API key:
141
+
142
+ 1. Get your API key from [Anthropic](https://console.anthropic.com/)
143
+ 2. Add it to `apps/web/.env.local`:
144
+ ```
145
+ ANTHROPIC_API_KEY=your_key_here
146
+ ```
147
+
148
+ ## Design Tokens
149
+
150
+ The design system uses CSS custom properties for theming:
151
+
152
+ ```css
153
+ /* Colors */
154
+ --color-primary-500: #0ea5e9;
155
+ --color-text-primary: #171717;
156
+
157
+ /* Spacing */
158
+ --spacing-4: 1rem;
159
+
160
+ /* Typography */
161
+ --font-size-base: 1rem;
162
+ --font-weight-semibold: 600;
163
+
164
+ /* Motion */
165
+ --motion-duration-normal: 200ms;
166
+ ```
167
+
168
+ ## Storybook
169
+
170
+ View all components and their documentation in Storybook:
171
+
172
+ ```bash
173
+ npm run storybook
174
+ ```
175
+
176
+ Each component story includes:
177
+ - Usage examples
178
+ - Accessibility notes
179
+ - Keyboard interaction tables
180
+ - WCAG compliance information
181
+
182
+ ## Building
183
+
184
+ Build the Next.js app:
185
+ ```bash
186
+ npm run build
187
+ ```
188
+
189
+ Build Storybook:
190
+ ```bash
191
+ npm run build-storybook
192
+ ```
193
+
194
+ ## Testing Accessibility
195
+
196
+ ### Automated Testing
197
+
198
+ Storybook includes the `@storybook/addon-a11y` addon for automated accessibility checks.
199
+
200
+ ### Manual Testing
201
+
202
+ 1. **Keyboard Navigation**: Test all components with keyboard only (Tab, Arrow keys, Enter/Space)
203
+ 2. **Screen Reader**: Test with NVDA (Windows), VoiceOver (macOS), or JAWS
204
+ 3. **Focus Indicators**: Ensure all interactive elements have visible focus styles
205
+ 4. **Color Contrast**: Verify text meets WCAG AA contrast ratios (4.5:1)
206
+
207
+ ## Contributing
208
+
209
+ When adding new components:
210
+
211
+ 1. Follow the existing component structure
212
+ 2. Include proper ARIA attributes
213
+ 3. Add keyboard navigation support
214
+ 4. Include focus management
215
+ 5. Add Storybook stories with accessibility documentation
216
+ 6. Test with keyboard and screen readers
217
+
218
+ ## License
219
+
220
+ MIT
221
+
222
+ ## Resources
223
+
224
+ - [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
225
+ - [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
226
+ - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
227
+