@zoyth/simple-site-framework 1.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 (166) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +572 -0
  3. package/bin/create-simple-site.js +390 -0
  4. package/bin/simple-site.js +664 -0
  5. package/dist/client.js +135 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/client.mjs +107 -0
  8. package/dist/client.mjs.map +1 -0
  9. package/dist/components/index.d.mts +3936 -0
  10. package/dist/components/index.d.ts +3936 -0
  11. package/dist/components/index.js +38265 -0
  12. package/dist/components/index.js.map +1 -0
  13. package/dist/components/index.mjs +38173 -0
  14. package/dist/components/index.mjs.map +1 -0
  15. package/dist/config/index.d.mts +298 -0
  16. package/dist/config/index.d.ts +298 -0
  17. package/dist/config/index.js +19 -0
  18. package/dist/config/index.js.map +1 -0
  19. package/dist/config/index.mjs +1 -0
  20. package/dist/config/index.mjs.map +1 -0
  21. package/dist/index.d.mts +2184 -0
  22. package/dist/index.d.ts +2184 -0
  23. package/dist/index.js +1713 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/index.mjs +1605 -0
  26. package/dist/index.mjs.map +1 -0
  27. package/dist/lib/i18n/index.js +665 -0
  28. package/dist/lib/i18n/index.js.map +1 -0
  29. package/dist/lib/i18n/index.mjs +621 -0
  30. package/dist/lib/i18n/index.mjs.map +1 -0
  31. package/docs/DOCUMENTATION-STRUCTURE.md +1156 -0
  32. package/docs/EXPORTS.md +125 -0
  33. package/docs/PERFORMANCE.md +757 -0
  34. package/docs/POLICY-PAGES.md +867 -0
  35. package/docs/ROADMAP.md +334 -0
  36. package/docs/SEO.md +455 -0
  37. package/docs/SITEMAP.md +708 -0
  38. package/docs/STRUCTURED-DATA.md +671 -0
  39. package/docs/accessibility/common-patterns.md +529 -0
  40. package/docs/accessibility/keyboard-navigation.md +263 -0
  41. package/docs/accessibility/overview.md +122 -0
  42. package/docs/accessibility/screen-readers.md +311 -0
  43. package/docs/accessibility/wcag-compliance.md +159 -0
  44. package/docs/api/README.md +164 -0
  45. package/docs/api/components/Accessibility.md +356 -0
  46. package/docs/api/components/Button.md +240 -0
  47. package/docs/api/components/HeroSection.md +306 -0
  48. package/docs/architecture/decisions.md +449 -0
  49. package/docs/components/AnalyticsTracker.md +58 -0
  50. package/docs/components/AnimatedCounter.md +48 -0
  51. package/docs/components/AnimatedSection.md +56 -0
  52. package/docs/components/BlogCard.md +42 -0
  53. package/docs/components/Checkbox.md +56 -0
  54. package/docs/components/CodeBlock.md +52 -0
  55. package/docs/components/ComparisonTable.md +40 -0
  56. package/docs/components/ComponentDemo.md +38 -0
  57. package/docs/components/CountdownTimer.md +51 -0
  58. package/docs/components/ExitIntentModal.md +56 -0
  59. package/docs/components/FAQAccordion.md +66 -0
  60. package/docs/components/FeaturesGrid.md +55 -0
  61. package/docs/components/FileUpload.md +54 -0
  62. package/docs/components/I18nMetaTags.md +55 -0
  63. package/docs/components/Icon.md +53 -0
  64. package/docs/components/LazySection.md +46 -0
  65. package/docs/components/LiveProof.md +53 -0
  66. package/docs/components/LoadingSpinner.md +46 -0
  67. package/docs/components/MultiStepForm.md +48 -0
  68. package/docs/components/PolicyLayout.md +55 -0
  69. package/docs/components/PricingTable.md +49 -0
  70. package/docs/components/Radio.md +59 -0
  71. package/docs/components/SEOMetaTags.md +58 -0
  72. package/docs/components/ScriptInjector.md +50 -0
  73. package/docs/components/Select.md +72 -0
  74. package/docs/components/Skeleton.md +47 -0
  75. package/docs/components/StatsSection.md +48 -0
  76. package/docs/components/StickyBar.md +62 -0
  77. package/docs/components/StructuredData.md +99 -0
  78. package/docs/components/StyleGuide.md +46 -0
  79. package/docs/components/TableOfContents.md +47 -0
  80. package/docs/components/TestimonialCarousel.md +42 -0
  81. package/docs/components/Timeline.md +51 -0
  82. package/docs/components/Toast.md +59 -0
  83. package/docs/components/TrackedLink.md +62 -0
  84. package/docs/components/TrustBadges.md +44 -0
  85. package/docs/components/conversion/MobileCTA.md +363 -0
  86. package/docs/components/forms/ContactForm.md +75 -0
  87. package/docs/components/forms/FormField.md +74 -0
  88. package/docs/components/layout/Footer.md +601 -0
  89. package/docs/components/layout/Header.md +549 -0
  90. package/docs/components/layout/LanguageSelector.md +54 -0
  91. package/docs/components/layout/LanguageSwitcher.md +24 -0
  92. package/docs/components/overview.md +447 -0
  93. package/docs/components/sections/AboutSection.md +48 -0
  94. package/docs/components/sections/CTASection.md +596 -0
  95. package/docs/components/sections/CaseStudySection.md +47 -0
  96. package/docs/components/sections/ContactSection.md +599 -0
  97. package/docs/components/sections/FeatureSection.md +44 -0
  98. package/docs/components/sections/HeroSection.md +404 -0
  99. package/docs/components/sections/LogosSection.md +47 -0
  100. package/docs/components/sections/PersonalTaxesSection.md +23 -0
  101. package/docs/components/sections/RecruitingSection.md +23 -0
  102. package/docs/components/sections/SecurePortalSection.md +23 -0
  103. package/docs/components/sections/ServicePageLayout.md +52 -0
  104. package/docs/components/sections/ServicesSection.md +49 -0
  105. package/docs/components/sections/TestimonialSection.md +44 -0
  106. package/docs/components/sections/WhyChooseUsSection.md +54 -0
  107. package/docs/components/ui/Breadcrumb.md +70 -0
  108. package/docs/components/ui/Button.md +514 -0
  109. package/docs/components/ui/Card.md +501 -0
  110. package/docs/components/ui/Input.md +54 -0
  111. package/docs/components/ui/MobileLinks.md +43 -0
  112. package/docs/components/ui/Modal.md +60 -0
  113. package/docs/components/ui/Tabs.md +62 -0
  114. package/docs/components/ui/Textarea.md +52 -0
  115. package/docs/core-concepts/configuration-driven.md +552 -0
  116. package/docs/core-concepts/overview.md +351 -0
  117. package/docs/features/accessibility/README.md +73 -0
  118. package/docs/features/accessibility/aria-support.md +177 -0
  119. package/docs/features/accessibility/color-contrast.md +155 -0
  120. package/docs/features/accessibility/focus-management.md +187 -0
  121. package/docs/features/accessibility/testing.md +196 -0
  122. package/docs/features/analytics/README.md +51 -0
  123. package/docs/features/analytics/ab-testing.md +171 -0
  124. package/docs/features/analytics/conversion-tracking.md +207 -0
  125. package/docs/features/analytics/custom-events.md +219 -0
  126. package/docs/features/analytics/privacy.md +198 -0
  127. package/docs/features/analytics/setup.md +114 -0
  128. package/docs/features/analytics/tracking-events.md +224 -0
  129. package/docs/features/i18n/README.md +51 -0
  130. package/docs/features/i18n/best-practices.md +273 -0
  131. package/docs/features/i18n/configuration.md +84 -0
  132. package/docs/features/i18n/formatting.md +133 -0
  133. package/docs/features/i18n/locale-detection.md +122 -0
  134. package/docs/features/i18n/routing.md +99 -0
  135. package/docs/features/i18n/rtl-support.md +191 -0
  136. package/docs/features/i18n/translations.md +129 -0
  137. package/docs/features/internationalization.md +595 -0
  138. package/docs/features/performance/README.md +77 -0
  139. package/docs/features/performance/bundle-size.md +134 -0
  140. package/docs/features/performance/caching.md +131 -0
  141. package/docs/features/performance/code-splitting.md +121 -0
  142. package/docs/features/performance/image-optimization.md +110 -0
  143. package/docs/features/performance/lazy-loading.md +92 -0
  144. package/docs/features/performance/monitoring.md +148 -0
  145. package/docs/features/seo/README.md +51 -0
  146. package/docs/features/seo/best-practices.md +184 -0
  147. package/docs/features/seo/canonical-urls.md +182 -0
  148. package/docs/features/seo/meta-tags.md +126 -0
  149. package/docs/features/seo/open-graph.md +166 -0
  150. package/docs/features/seo/robots-txt.md +146 -0
  151. package/docs/features/seo/sitemaps.md +162 -0
  152. package/docs/features/seo/structured-data.md +166 -0
  153. package/docs/getting-started/installation.md +292 -0
  154. package/docs/getting-started/introduction.md +195 -0
  155. package/docs/getting-started/quick-start.md +460 -0
  156. package/docs/guides/analytics-setup.md +616 -0
  157. package/docs/i18n/CONFIGURATION.md +353 -0
  158. package/docs/i18n/EXAMPLES.md +402 -0
  159. package/docs/i18n/MIGRATION.md +260 -0
  160. package/docs/i18n/SEO.md +392 -0
  161. package/docs/i18n/STATIC-GENERATION-FIX.md +71 -0
  162. package/docs/migration/changelog.md +136 -0
  163. package/docs/migration/overview.md +233 -0
  164. package/docs/recipes/adding-animations.md +475 -0
  165. package/docs/recipes/forms-with-validation.md +393 -0
  166. package/package.json +152 -0
@@ -0,0 +1,263 @@
1
+ # Keyboard Navigation Guide
2
+
3
+ All Simple Site Framework components support full keyboard navigation. This guide covers keyboard patterns and testing.
4
+
5
+ ## Standard Keyboard Controls
6
+
7
+ ### Tab Navigation
8
+ - **Tab**: Move focus forward through interactive elements
9
+ - **Shift + Tab**: Move focus backward
10
+ - **Enter/Space**: Activate buttons, links, and controls
11
+ - **Escape**: Close modals, menus, and dropdowns
12
+
13
+ ### Component-Specific
14
+ - **Arrow Keys**: Navigate within lists, menus, tabs, and carousels
15
+ - **Home/End**: Jump to first/last item in lists
16
+ - **Page Up/Down**: Scroll or navigate in long lists
17
+
18
+ ## Component Keyboard Patterns
19
+
20
+ ### Button
21
+ ```tsx
22
+ <Button onClick={handleClick}>
23
+ Submit
24
+ </Button>
25
+ ```
26
+ - **Tab**: Focus the button
27
+ - **Enter/Space**: Activate the button
28
+
29
+ ### Modal
30
+ ```tsx
31
+ <Modal isOpen={isOpen} onClose={handleClose}>
32
+ {/* Modal content */}
33
+ </Modal>
34
+ ```
35
+ - **Tab**: Cycle through focusable elements inside modal
36
+ - **Shift + Tab**: Cycle backward
37
+ - **Escape**: Close modal
38
+ - Focus is **trapped** inside modal while open
39
+ - Focus **returns** to trigger when closed
40
+
41
+ ### Tabs
42
+ ```tsx
43
+ <Tabs tabs={tabs} value={activeTab} onValueChange={setActiveTab} />
44
+ ```
45
+ - **Tab**: Focus the tab list
46
+ - **Arrow Left/Right**: Navigate between tabs
47
+ - **Home**: Jump to first tab
48
+ - **End**: Jump to last tab
49
+ - **Enter/Space**: Activate selected tab
50
+
51
+ ### Select/Dropdown
52
+ ```tsx
53
+ <Select options={options} value={value} onChange={setValue} />
54
+ ```
55
+ - **Tab**: Focus the select
56
+ - **Enter/Space/Arrow Down**: Open dropdown
57
+ - **Arrow Up/Down**: Navigate options
58
+ - **Home/End**: Jump to first/last option
59
+ - **Enter/Space**: Select option
60
+ - **Escape**: Close without selecting
61
+ - **Type ahead**: Jump to option starting with typed character
62
+
63
+ ### Accordion
64
+ ```tsx
65
+ <FAQAccordion items={faqItems} />
66
+ ```
67
+ - **Tab**: Focus accordion header
68
+ - **Enter/Space**: Toggle section
69
+ - **Arrow Down**: Move to next header
70
+ - **Arrow Up**: Move to previous header
71
+ - **Home**: Jump to first header
72
+ - **End**: Jump to last header
73
+
74
+ ### Carousel/Slider
75
+ ```tsx
76
+ <TestimonialCarousel testimonials={items} />
77
+ ```
78
+ - **Tab**: Focus carousel controls
79
+ - **Arrow Left/Right**: Navigate slides
80
+ - **Space/Enter**: Pause/play autoplay
81
+
82
+ ### Multi-Step Form
83
+ ```tsx
84
+ <MultiStepForm>
85
+ {/* Form steps */}
86
+ </MultiStepForm>
87
+ ```
88
+ - **Tab**: Navigate through form fields
89
+ - **Enter**: Submit step or form
90
+ - **Arrow Keys**: Navigate between radio buttons/checkboxes in groups
91
+
92
+ ## Focus Management
93
+
94
+ ### Skip Links
95
+ Allow keyboard users to skip repetitive navigation:
96
+
97
+ ```tsx
98
+ import { SkipLink } from '@zoyth/simple-site-framework'
99
+
100
+ <SkipLink href="#main">
101
+ Skip to main content
102
+ </SkipLink>
103
+ <SkipLink href="#nav">
104
+ Skip to navigation
105
+ </SkipLink>
106
+ ```
107
+
108
+ ### Focus Trap (Modals/Dialogs)
109
+ Keep focus inside modal until closed:
110
+
111
+ ```tsx
112
+ import { useFocusTrap } from '@zoyth/simple-site-framework'
113
+
114
+ function Modal({ isOpen, children }) {
115
+ const trapRef = useFocusTrap(isOpen)
116
+
117
+ return (
118
+ <div ref={trapRef} role="dialog">
119
+ {children}
120
+ </div>
121
+ )
122
+ }
123
+ ```
124
+
125
+ ### Focus Return
126
+ Return focus to trigger element after modal closes:
127
+
128
+ ```tsx
129
+ import { useFocusReturn } from '@zoyth/simple-site-framework'
130
+
131
+ function Modal() {
132
+ const returnRef = useFocusReturn()
133
+
134
+ return <div ref={returnRef}>{/* content */}</div>
135
+ }
136
+ ```
137
+
138
+ ## Testing Keyboard Navigation
139
+
140
+ ### Manual Testing Checklist
141
+ 1. **Unplug your mouse** (or don't touch it)
142
+ 2. **Tab through entire page**
143
+ - Can you reach all interactive elements?
144
+ - Is tab order logical?
145
+ - Is focus visible on all elements?
146
+ 3. **Open and close all modals/menus**
147
+ - Does Escape close them?
148
+ - Does focus stay trapped inside?
149
+ - Does focus return when closed?
150
+ 4. **Submit all forms**
151
+ - Can you fill out and submit with only keyboard?
152
+ - Are errors announced?
153
+ 5. **Navigate all components**
154
+ - Do tabs work with arrows?
155
+ - Do dropdowns work as expected?
156
+ - Do carousels respond to arrows?
157
+
158
+ ### Automated Testing
159
+ ```tsx
160
+ import { testKeyboardNav } from '@zoyth/simple-site-framework/testing'
161
+
162
+ describe('Button', () => {
163
+ it('should activate on Enter and Space', () => {
164
+ const onClick = jest.fn()
165
+ const { getByRole } = render(<Button onClick={onClick}>Click</Button>)
166
+
167
+ testKeyboardNav(getByRole('button'), {
168
+ enter: onClick,
169
+ space: onClick
170
+ })
171
+ })
172
+ })
173
+ ```
174
+
175
+ ## Common Keyboard Traps (and How to Avoid)
176
+
177
+ ### ❌ Keyboard Trap
178
+ ```tsx
179
+ // BAD: Focus gets stuck in modal
180
+ <div onClick={() => setOpen(false)}>
181
+ <input /> {/* Focus can't reach close button */}
182
+ </div>
183
+ ```
184
+
185
+ ### ✅ Proper Modal
186
+ ```tsx
187
+ // GOOD: Use framework Modal with focus trap
188
+ <Modal isOpen={isOpen} onClose={() => setOpen(false)}>
189
+ <input />
190
+ <Button onClick={() => setOpen(false)}>Close</Button>
191
+ </Modal>
192
+ ```
193
+
194
+ ### ❌ Missing Tab Index
195
+ ```tsx
196
+ // BAD: Custom div button not keyboard accessible
197
+ <div onClick={handleClick}>Click me</div>
198
+ ```
199
+
200
+ ### ✅ Semantic Button
201
+ ```tsx
202
+ // GOOD: Use semantic button or framework Button
203
+ <Button onClick={handleClick}>Click me</Button>
204
+ ```
205
+
206
+ ### ❌ No Escape to Close
207
+ ```tsx
208
+ // BAD: No way to close with keyboard
209
+ <div className="modal">
210
+ <button onClick={handleClose}>×</button>
211
+ </div>
212
+ ```
213
+
214
+ ### ✅ Escape Handler
215
+ ```tsx
216
+ // GOOD: Escape key closes modal
217
+ <Modal onClose={handleClose} isOpen={isOpen}>
218
+ {/* content */}
219
+ </Modal>
220
+ ```
221
+
222
+ ## Focus Indicator Best Practices
223
+
224
+ ### Visible Focus
225
+ All framework components have visible focus indicators:
226
+ ```css
227
+ /* Default focus ring */
228
+ .button:focus-visible {
229
+ outline: 2px solid var(--color-primary);
230
+ outline-offset: 2px;
231
+ }
232
+ ```
233
+
234
+ ### Custom Focus Styles
235
+ Override in your theme:
236
+ ```tsx
237
+ const theme = {
238
+ colors: {
239
+ focusRing: '#FF7800',
240
+ },
241
+ // ...
242
+ }
243
+ ```
244
+
245
+ ### Never Remove Focus
246
+ ```css
247
+ /* ❌ NEVER DO THIS */
248
+ *:focus {
249
+ outline: none;
250
+ }
251
+
252
+ /* ✅ Style it, but keep it visible */
253
+ *:focus-visible {
254
+ outline: 2px solid blue;
255
+ outline-offset: 2px;
256
+ }
257
+ ```
258
+
259
+ ## Resources
260
+
261
+ - [WebAIM Keyboard Testing](https://webaim.org/articles/keyboard/)
262
+ - [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
263
+ - [Framework Component Guides](./components/)
@@ -0,0 +1,122 @@
1
+ # Accessibility Overview
2
+
3
+ The Simple Site Framework is built with accessibility as a core principle, ensuring that all components meet WCAG 2.1 Level AA standards by default.
4
+
5
+ ## Our Commitment
6
+
7
+ - **Semantic HTML**: All components use proper HTML5 semantic elements
8
+ - **Keyboard Navigation**: Full keyboard support for all interactive elements
9
+ - **Screen Reader Support**: ARIA attributes and announcements where needed
10
+ - **Color Contrast**: AA-compliant color ratios (4.5:1 for text, 3:1 for UI)
11
+ - **Focus Management**: Clear focus indicators and logical focus order
12
+ - **Responsive**: Touch targets meet minimum 44x44px on mobile
13
+
14
+ ## WCAG 2.1 AA Compliance
15
+
16
+ All framework components are designed to meet:
17
+ - **Perceivable**: Content visible to all users
18
+ - **Operable**: Interface usable via keyboard and other input methods
19
+ - **Understandable**: Clear labels, instructions, and error messages
20
+ - **Robust**: Compatible with assistive technologies
21
+
22
+ ## Quick Start
23
+
24
+ ### 1. Use Semantic Components
25
+ ```tsx
26
+ // Good - semantic and accessible
27
+ <Button onClick={handleClick}>Submit</Button>
28
+
29
+ // Avoid - div buttons need extra work
30
+ <div onClick={handleClick}>Submit</div>
31
+ ```
32
+
33
+ ### 2. Add ARIA Labels
34
+ ```tsx
35
+ <Button
36
+ icon={<Icons.Search />}
37
+ iconOnly
38
+ aria-label="Search"
39
+ />
40
+ ```
41
+
42
+ ### 3. Test with Keyboard
43
+ All interactive elements should work with:
44
+ - `Tab` - Navigate forward
45
+ - `Shift + Tab` - Navigate backward
46
+ - `Enter/Space` - Activate buttons
47
+ - `Escape` - Close modals/menus
48
+ - `Arrow keys` - Navigate within components
49
+
50
+ ### 4. Check Color Contrast
51
+ Use our built-in utilities or browser DevTools to verify:
52
+ - Normal text: 4.5:1 minimum
53
+ - Large text (18pt+): 3:1 minimum
54
+ - UI components: 3:1 minimum
55
+
56
+ ## Testing Tools
57
+
58
+ ### Development
59
+ > **Note**: The `A11yChecker` component is planned for v0.2.0 and not yet available.
60
+
61
+ For now, use these external tools for accessibility testing:
62
+
63
+ ### Automated Testing
64
+ - **axe DevTools**: Browser extension for automated accessibility testing
65
+ - **WAVE**: Browser extension for manual testing
66
+ - **Lighthouse**: Chrome DevTools accessibility audit
67
+ - **axe-core**: Can be integrated into your test suite
68
+
69
+ ### Screen Reader Testing
70
+ - **Windows**: NVDA (free) or JAWS
71
+ - **macOS**: VoiceOver (built-in)
72
+ - **Mobile**: TalkBack (Android), VoiceOver (iOS)
73
+
74
+ ## Common Patterns
75
+
76
+ ### Skip Links
77
+ ```tsx
78
+ import { SkipLink } from '@zoyth/simple-site-framework'
79
+
80
+ <SkipLink href="#main">Skip to main content</SkipLink>
81
+ ```
82
+
83
+ ### Screen Reader Announcements
84
+ ```tsx
85
+ import { useA11y } from '@zoyth/simple-site-framework'
86
+
87
+ const { announce } = useA11y()
88
+
89
+ const handleSubmit = async () => {
90
+ await submitForm()
91
+ announce('Form submitted successfully')
92
+ }
93
+ ```
94
+
95
+ ### Focus Management
96
+ ```tsx
97
+ import { useFocusTrap } from '@zoyth/simple-site-framework'
98
+
99
+ function Modal({ isOpen }) {
100
+ const trapRef = useFocusTrap(isOpen)
101
+
102
+ return (
103
+ <div ref={trapRef} role="dialog" aria-modal="true">
104
+ {/* Modal content */}
105
+ </div>
106
+ )
107
+ }
108
+ ```
109
+
110
+ ## Resources
111
+
112
+ - [WCAG 2.1 Quick Reference](https://www.w3.org/WAI/WCAG21/quickref/)
113
+ - [A11y Project Checklist](https://www.a11yproject.com/checklist/)
114
+ - [WebAIM Resources](https://webaim.org/resources/)
115
+ - [Component A11y Guides](./components/)
116
+
117
+ ## Need Help?
118
+
119
+ - Review component-specific guides in [./components/](./components/)
120
+ - Check the [accessibility checklist](./wcag-compliance.md)
121
+ - Test with [keyboard navigation guide](./keyboard-navigation.md)
122
+ - Verify with [screen reader testing guide](./screen-readers.md)
@@ -0,0 +1,311 @@
1
+ # Screen Reader Testing Guide
2
+
3
+ Testing with screen readers is essential to ensure your site is accessible to users with visual impairments.
4
+
5
+ ## Screen Reader Software
6
+
7
+ ### Windows
8
+ **NVDA (Free, Open Source)**
9
+ - Download: https://www.nvaccess.org/
10
+ - Most popular free option
11
+ - Good compatibility with modern web standards
12
+
13
+ **JAWS (Commercial)**
14
+ - Most widely used by professionals
15
+ - Expensive ($1000+)
16
+ - Very thorough testing tool
17
+
18
+ ### macOS
19
+ **VoiceOver (Built-in)**
20
+ - Cmd + F5 to toggle on/off
21
+ - Free and pre-installed
22
+ - Good for basic testing
23
+
24
+ ### Mobile
25
+ **iOS VoiceOver**
26
+ - Settings → Accessibility → VoiceOver
27
+ - Triple-click home button shortcut
28
+
29
+ **Android TalkBack**
30
+ - Settings → Accessibility → TalkBack
31
+ - Volume keys shortcut
32
+
33
+ ## Quick Start with NVDA (Windows)
34
+
35
+ ### Basic Controls
36
+ - **NVDA + Space**: Toggle browse/focus mode
37
+ - **↓**: Read next item
38
+ - **↑**: Read previous item
39
+ - **Tab**: Navigate to next focusable element
40
+ - **NVDA + T**: Read window title
41
+ - **NVDA + B**: Read entire page
42
+ - **Insert**: NVDA modifier key
43
+
44
+ ### Testing Workflow
45
+ 1. Start NVDA
46
+ 2. Open your site
47
+ 3. Press **NVDA + B** to read entire page
48
+ 4. Use **↓** to navigate item by item
49
+ 5. Use **Tab** to jump between interactive elements
50
+ 6. Listen for:
51
+ - Clear labels and descriptions
52
+ - Proper heading hierarchy
53
+ - Form field labels
54
+ - Button text
55
+ - Image alt text
56
+ - Error messages
57
+
58
+ ## Quick Start with VoiceOver (macOS)
59
+
60
+ ### Basic Controls
61
+ - **Cmd + F5**: Toggle VoiceOver on/off
62
+ - **VO + →**: Next item (VO = Ctrl + Option)
63
+ - **VO + ←**: Previous item
64
+ - **VO + Cmd + H**: Next heading
65
+ - **VO + Cmd + Shift + H**: Previous heading
66
+ - **VO + U**: Open rotor (navigation menu)
67
+ - **Tab**: Next focusable element
68
+
69
+ ### Testing Workflow
70
+ 1. Press **Cmd + F5** to start
71
+ 2. Open your site
72
+ 3. Press **VO + A** to read entire page
73
+ 4. Use **VO + →** to navigate
74
+ 5. Press **VO + U** for rotor navigation
75
+ 6. Test interactions with **VO + Space**
76
+
77
+ ## What to Listen For
78
+
79
+ ### ✅ Good Screen Reader Experience
80
+ - **Descriptive labels**: "Submit contact form" not just "Submit"
81
+ - **Clear headings**: "Contact Us - heading level 2"
82
+ - **Form labels**: "Email address, edit text, required"
83
+ - **Error messages**: "Email address, invalid format, edit text"
84
+ - **State changes**: "Loading complete" announcements
85
+ - **Alt text**: "Company logo" not "image-logo-final-v2.png"
86
+
87
+ ### ❌ Poor Screen Reader Experience
88
+ - "Button" with no label
89
+ - "Image" with no alt text
90
+ - "Required" not announced
91
+ - "Edit text" with no label
92
+ - No headings or all h1s
93
+ - Silent state changes
94
+ - "Click here" links
95
+
96
+ ## Component Testing Examples
97
+
98
+ ### Button
99
+ ```tsx
100
+ <Button onClick={handleSubmit}>Submit Form</Button>
101
+ ```
102
+ **Reads**: "Submit Form, button"
103
+
104
+ ### Icon Button
105
+ ```tsx
106
+ <Button icon={<Icons.Search />} iconOnly aria-label="Search">
107
+ ```
108
+ **Reads**: "Search, button"
109
+
110
+ ### Form Field
111
+ ```tsx
112
+ <FormField
113
+ name="email"
114
+ label="Email Address"
115
+ required
116
+ error={errors.email}
117
+ >
118
+ <input type="email" {...register('email')} />
119
+ </FormField>
120
+ ```
121
+ **Reads**: "Email Address, edit text, required"
122
+ **If error**: "Email Address, invalid format, edit text, required"
123
+
124
+ ### Modal
125
+ ```tsx
126
+ <Modal isOpen={true} title="Confirm Action">
127
+ <p>Are you sure?</p>
128
+ </Modal>
129
+ ```
130
+ **Reads**: "Confirm Action, dialog"
131
+ **Announces**: When modal opens, focus moves and title is read
132
+
133
+ ### Live Region (Toast)
134
+ ```tsx
135
+ toast.success('Form submitted successfully')
136
+ ```
137
+ **Announces**: "Form submitted successfully" (polite)
138
+
139
+ ### Loading State
140
+ ```tsx
141
+ <Button loading={true}>Submit</Button>
142
+ ```
143
+ **Reads**: "Submit, button, busy"
144
+
145
+ ## ARIA Attributes and What They Do
146
+
147
+ ### aria-label
148
+ Provides accessible name when visible text isn't enough:
149
+ ```tsx
150
+ <Button icon={<Icons.Close />} aria-label="Close dialog" />
151
+ ```
152
+ **Reads**: "Close dialog, button"
153
+
154
+ ### aria-labelledby
155
+ References another element for label:
156
+ ```tsx
157
+ <div role="dialog" aria-labelledby="dialog-title">
158
+ <h2 id="dialog-title">Confirm Delete</h2>
159
+ </div>
160
+ ```
161
+ **Reads**: "Confirm Delete, dialog"
162
+
163
+ ### aria-describedby
164
+ Provides additional description:
165
+ ```tsx
166
+ <input
167
+ id="password"
168
+ type="password"
169
+ aria-describedby="password-hint"
170
+ />
171
+ <p id="password-hint">
172
+ Must be at least 8 characters
173
+ </p>
174
+ ```
175
+ **Reads**: "Password, edit text. Must be at least 8 characters"
176
+
177
+ ### aria-live
178
+ Announces dynamic content changes:
179
+ ```tsx
180
+ <div aria-live="polite" aria-atomic="true">
181
+ {statusMessage}
182
+ </div>
183
+ ```
184
+ **Announces**: When statusMessage changes
185
+
186
+ ### aria-hidden
187
+ Hides decorative content:
188
+ ```tsx
189
+ <span aria-hidden="true">★</span>
190
+ <span className="sr-only">5 out of 5 stars</span>
191
+ ```
192
+ **Reads**: "5 out of 5 stars" (star icon ignored)
193
+
194
+ ## Common Screen Reader Issues
195
+
196
+ ### Issue: Button Reads as "Button" Only
197
+ **Problem**: No accessible text
198
+ ```tsx
199
+ <button onClick={handleClick}>
200
+ <Icon name="trash" />
201
+ </button>
202
+ ```
203
+ **Fix**: Add aria-label
204
+ ```tsx
205
+ <Button
206
+ icon={<Icons.Trash />}
207
+ iconOnly
208
+ aria-label="Delete item"
209
+ />
210
+ ```
211
+
212
+ ### Issue: Form Field Not Associated with Label
213
+ **Problem**: Label not programmatically connected
214
+ ```tsx
215
+ <label>Email</label>
216
+ <input type="email" />
217
+ ```
218
+ **Fix**: Use for/id or nest input
219
+ ```tsx
220
+ <FormField name="email" label="Email">
221
+ <input type="email" />
222
+ </FormField>
223
+ ```
224
+
225
+ ### Issue: State Changes Not Announced
226
+ **Problem**: Loading/success state is visual only
227
+ ```tsx
228
+ <button disabled={isLoading}>
229
+ {isLoading ? 'Loading...' : 'Submit'}
230
+ </button>
231
+ ```
232
+ **Fix**: Use aria-busy or toast announcement
233
+ ```tsx
234
+ <Button loading={isLoading}>Submit</Button>
235
+ ```
236
+
237
+ ### Issue: Modal Focus Not Managed
238
+ **Problem**: Focus doesn't move to modal
239
+ ```tsx
240
+ <div className={isOpen ? 'modal' : 'modal hidden'}>
241
+ {/* content */}
242
+ </div>
243
+ ```
244
+ **Fix**: Use framework Modal
245
+ ```tsx
246
+ <Modal isOpen={isOpen} onClose={handleClose}>
247
+ {/* content */}
248
+ </Modal>
249
+ ```
250
+
251
+ ## Testing Checklist
252
+
253
+ - [ ] All buttons and links have accessible text
254
+ - [ ] All form fields have associated labels
255
+ - [ ] Required fields are announced as required
256
+ - [ ] Form errors are announced clearly
257
+ - [ ] Headings create logical document outline
258
+ - [ ] Images have descriptive alt text (or alt="" if decorative)
259
+ - [ ] Modals announce when opened
260
+ - [ ] Focus moves logically through page
261
+ - [ ] State changes (loading, success, error) are announced
262
+ - [ ] Skip links work
263
+ - [ ] Data tables have proper headers
264
+ - [ ] Live regions announce dynamic content
265
+
266
+ ## Framework Utilities for Screen Readers
267
+
268
+ ### useA11y Hook
269
+ ```tsx
270
+ import { useA11y } from '@zoyth/simple-site-framework'
271
+
272
+ const { announce } = useA11y()
273
+
274
+ const handleSubmit = async () => {
275
+ await submitForm()
276
+ announce('Form submitted successfully', 'polite')
277
+ }
278
+ ```
279
+
280
+ ### A11yAnnouncer Component
281
+ ```tsx
282
+ import { A11yAnnouncer } from '@zoyth/simple-site-framework'
283
+
284
+ <A11yAnnouncer
285
+ message={statusMessage}
286
+ politeness="polite" // or "assertive"
287
+ />
288
+ ```
289
+
290
+ ### Screen Reader Only Text
291
+ ```tsx
292
+ // Visible to screen readers, hidden visually
293
+ <span className="sr-only">Required field</span>
294
+ ```
295
+
296
+ ## Resources
297
+
298
+ - [NVDA User Guide](https://www.nvaccess.org/files/nvda/documentation/userGuide.html)
299
+ - [VoiceOver Guide](https://www.apple.com/voiceover/info/guide/)
300
+ - [WebAIM Screen Reader Testing](https://webaim.org/articles/screenreader_testing/)
301
+ - [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
302
+
303
+ ## Pro Tips
304
+
305
+ 1. **Test early and often** - Don't wait until the end
306
+ 2. **Listen to the full page** - Navigate start to finish
307
+ 3. **Test forms completely** - Fill out, submit, handle errors
308
+ 4. **Test all interactive elements** - Buttons, links, modals, etc.
309
+ 5. **Test with real users** - Nothing beats actual screen reader users
310
+ 6. **Keep it simple** - Don't over-use ARIA, semantic HTML is often enough
311
+ 7. **Test on mobile** - VoiceOver/TalkBack usage is common