@fpkit/acss 0.5.11 → 0.5.13
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.
- package/README.md +514 -18
- package/libs/chunk-23ANBDCR.js +8 -0
- package/libs/chunk-23ANBDCR.js.map +1 -0
- package/libs/chunk-2LTJ7HHX.cjs +18 -0
- package/libs/chunk-2LTJ7HHX.cjs.map +1 -0
- package/libs/chunk-2Y7W75TT.js +9 -0
- package/libs/chunk-2Y7W75TT.js.map +1 -0
- package/libs/chunk-3MKLDCKQ.cjs +31 -0
- package/libs/chunk-3MKLDCKQ.cjs.map +1 -0
- package/libs/chunk-5M57K4SW.js +8 -0
- package/libs/chunk-5M57K4SW.js.map +1 -0
- package/libs/chunk-5S4ORA4C.cjs +15 -0
- package/libs/chunk-5S4ORA4C.cjs.map +1 -0
- package/libs/chunk-772NRB75.js +9 -0
- package/libs/chunk-772NRB75.js.map +1 -0
- package/libs/chunk-AHDJGCG5.cjs +15 -0
- package/libs/chunk-AHDJGCG5.cjs.map +1 -0
- package/libs/chunk-B7F5FS6D.cjs +16 -0
- package/libs/chunk-B7F5FS6D.cjs.map +1 -0
- package/libs/chunk-BHRQBJRY.js +8 -0
- package/libs/chunk-BHRQBJRY.js.map +1 -0
- package/libs/chunk-D4YLRWAO.cjs +18 -0
- package/libs/chunk-D4YLRWAO.cjs.map +1 -0
- package/libs/chunk-ETFLFC2S.js +10 -0
- package/libs/chunk-ETFLFC2S.js.map +1 -0
- package/libs/chunk-G55UJ53G.cjs +16 -0
- package/libs/chunk-G55UJ53G.cjs.map +1 -0
- package/libs/chunk-GZ4QFPRY.js +9 -0
- package/libs/chunk-GZ4QFPRY.js.map +1 -0
- package/libs/chunk-IYUN2EW3.cjs +15 -0
- package/libs/chunk-IYUN2EW3.cjs.map +1 -0
- package/libs/chunk-J32EZPYD.cjs +15 -0
- package/libs/chunk-J32EZPYD.cjs.map +1 -0
- package/libs/chunk-JJ43O4Y5.js +8 -0
- package/libs/chunk-JJ43O4Y5.js.map +1 -0
- package/libs/chunk-KUKIVRC2.js +7 -0
- package/libs/chunk-KUKIVRC2.js.map +1 -0
- package/libs/chunk-L75OQKEI.cjs +13 -0
- package/libs/chunk-L75OQKEI.cjs.map +1 -0
- package/libs/chunk-LT5KZ2QW.cjs +22 -0
- package/libs/chunk-LT5KZ2QW.cjs.map +1 -0
- package/libs/chunk-M5RRNTVX.cjs +15 -0
- package/libs/chunk-M5RRNTVX.cjs.map +1 -0
- package/libs/chunk-NGTJDDFO.js +8 -0
- package/libs/chunk-NGTJDDFO.js.map +1 -0
- package/libs/chunk-OK5QEIMD.cjs +17 -0
- package/libs/chunk-OK5QEIMD.cjs.map +1 -0
- package/libs/chunk-P2DC76ZZ.cjs +18 -0
- package/libs/chunk-P2DC76ZZ.cjs.map +1 -0
- package/libs/chunk-P7TTEYCD.js +7 -0
- package/libs/chunk-P7TTEYCD.js.map +1 -0
- package/libs/chunk-PQ2K3BM6.cjs +17 -0
- package/libs/chunk-PQ2K3BM6.cjs.map +1 -0
- package/libs/chunk-QLZWHAMK.js +8 -0
- package/libs/chunk-QLZWHAMK.js.map +1 -0
- package/libs/chunk-RIVUMPOG.js +8 -0
- package/libs/chunk-RIVUMPOG.js.map +1 -0
- package/libs/chunk-ROZI23GS.cjs +15 -0
- package/libs/chunk-ROZI23GS.cjs.map +1 -0
- package/libs/chunk-S7BABR7Z.cjs +13 -0
- package/libs/chunk-S7BABR7Z.cjs.map +1 -0
- package/libs/chunk-SMYRLO3E.js +8 -0
- package/libs/chunk-SMYRLO3E.js.map +1 -0
- package/libs/chunk-TYRCEX2L.js +8 -0
- package/libs/chunk-TYRCEX2L.js.map +1 -0
- package/libs/chunk-VUH3FXGJ.js +11 -0
- package/libs/chunk-VUH3FXGJ.js.map +1 -0
- package/libs/chunk-XBA562WW.js +8 -0
- package/libs/chunk-XBA562WW.js.map +1 -0
- package/libs/chunk-XTQKWY7W.cjs +32 -0
- package/libs/chunk-XTQKWY7W.cjs.map +1 -0
- package/libs/chunk-ZANSFMTD.js +9 -0
- package/libs/chunk-ZANSFMTD.js.map +1 -0
- package/libs/component-props-a8a2f97e.d.ts +38 -0
- package/libs/components/alert/alert.css +1 -1
- package/libs/components/alert/alert.css.map +1 -1
- package/libs/components/alert/alert.min.css +2 -2
- package/libs/components/badge/badge.css +1 -1
- package/libs/components/badge/badge.css.map +1 -1
- package/libs/components/badge/badge.min.css +2 -2
- package/libs/components/breadcrumbs/breadcrumb.cjs +24 -0
- package/libs/components/breadcrumbs/breadcrumb.cjs.map +1 -0
- package/libs/components/breadcrumbs/breadcrumb.d.cts +290 -0
- package/libs/components/breadcrumbs/breadcrumb.d.ts +290 -0
- package/libs/components/breadcrumbs/breadcrumb.js +5 -0
- package/libs/components/breadcrumbs/breadcrumb.js.map +1 -0
- package/libs/components/button.cjs +19 -0
- package/libs/components/button.cjs.map +1 -0
- package/libs/components/button.d.cts +16 -0
- package/libs/components/button.d.ts +16 -0
- package/libs/components/button.js +4 -0
- package/libs/components/button.js.map +1 -0
- package/libs/components/buttons/button.css +1 -1
- package/libs/components/buttons/button.css.map +1 -1
- package/libs/components/buttons/button.min.css +2 -2
- package/libs/components/card.cjs +31 -0
- package/libs/components/card.cjs.map +1 -0
- package/libs/components/card.d.cts +302 -0
- package/libs/components/card.d.ts +302 -0
- package/libs/components/card.js +4 -0
- package/libs/components/card.js.map +1 -0
- package/libs/components/cards/card.css +1 -1
- package/libs/components/cards/card.css.map +1 -1
- package/libs/components/cards/card.min.css +2 -2
- package/libs/components/details/details.css +1 -1
- package/libs/components/details/details.css.map +1 -1
- package/libs/components/details/details.min.css +2 -2
- package/libs/components/dialog/dialog.cjs +22 -0
- package/libs/components/dialog/dialog.cjs.map +1 -0
- package/libs/components/dialog/dialog.css +1 -1
- package/libs/components/dialog/dialog.css.map +1 -1
- package/libs/components/dialog/dialog.d.cts +105 -0
- package/libs/components/dialog/dialog.d.ts +105 -0
- package/libs/components/dialog/dialog.js +7 -0
- package/libs/components/dialog/dialog.js.map +1 -0
- package/libs/components/dialog/dialog.min.css +2 -2
- package/libs/components/form/fields.cjs +19 -0
- package/libs/components/form/fields.cjs.map +1 -0
- package/libs/components/form/fields.d.cts +24 -0
- package/libs/components/form/fields.d.ts +24 -0
- package/libs/components/form/fields.js +4 -0
- package/libs/components/form/fields.js.map +1 -0
- package/libs/components/form/inputs.cjs +19 -0
- package/libs/components/form/inputs.cjs.map +1 -0
- package/libs/components/form/inputs.d.cts +2 -0
- package/libs/components/form/inputs.d.ts +2 -0
- package/libs/components/form/inputs.js +4 -0
- package/libs/components/form/inputs.js.map +1 -0
- package/libs/components/form/textarea.cjs +19 -0
- package/libs/components/form/textarea.cjs.map +1 -0
- package/libs/components/form/textarea.d.cts +29 -0
- package/libs/components/form/textarea.d.ts +29 -0
- package/libs/components/form/textarea.js +4 -0
- package/libs/components/form/textarea.js.map +1 -0
- package/libs/components/heading/heading.cjs +10 -0
- package/libs/components/heading/heading.cjs.map +1 -0
- package/libs/components/heading/heading.d.cts +3 -0
- package/libs/components/heading/heading.d.ts +3 -0
- package/libs/components/heading/heading.js +4 -0
- package/libs/components/heading/heading.js.map +1 -0
- package/libs/components/icons/icon.cjs +19 -0
- package/libs/components/icons/icon.cjs.map +1 -0
- package/libs/{icons-31ace3de.d.ts → components/icons/icon.d.cts} +151 -61
- package/libs/components/icons/icon.d.ts +445 -0
- package/libs/components/icons/icon.js +4 -0
- package/libs/components/icons/icon.js.map +1 -0
- package/libs/components/images/img.css +1 -1
- package/libs/components/images/img.css.map +1 -1
- package/libs/components/images/img.min.css +2 -2
- package/libs/components/link/link.cjs +19 -0
- package/libs/components/link/link.cjs.map +1 -0
- package/libs/components/link/link.d.cts +19 -0
- package/libs/components/link/link.d.ts +19 -0
- package/libs/components/link/link.js +4 -0
- package/libs/components/link/link.js.map +1 -0
- package/libs/components/list/list.cjs +23 -0
- package/libs/components/list/list.cjs.map +1 -0
- package/libs/components/list/list.d.cts +39 -0
- package/libs/components/list/list.d.ts +39 -0
- package/libs/components/list/list.js +4 -0
- package/libs/components/list/list.js.map +1 -0
- package/libs/components/modal.cjs +14 -0
- package/libs/components/modal.cjs.map +1 -0
- package/libs/components/modal.d.cts +35 -0
- package/libs/components/modal.d.ts +35 -0
- package/libs/components/modal.js +5 -0
- package/libs/components/modal.js.map +1 -0
- package/libs/components/nav/nav.cjs +28 -0
- package/libs/components/nav/nav.cjs.map +1 -0
- package/libs/components/nav/nav.d.cts +44 -0
- package/libs/components/nav/nav.d.ts +44 -0
- package/libs/components/nav/nav.js +5 -0
- package/libs/components/nav/nav.js.map +1 -0
- package/libs/components/popover/popover.cjs +23 -0
- package/libs/components/popover/popover.cjs.map +1 -0
- package/libs/components/popover/popover.d.cts +40 -0
- package/libs/components/popover/popover.d.ts +40 -0
- package/libs/components/popover/popover.js +4 -0
- package/libs/components/popover/popover.js.map +1 -0
- package/libs/components/tables/table.cjs +21 -0
- package/libs/components/tables/table.cjs.map +1 -0
- package/libs/components/tables/table.d.cts +36 -0
- package/libs/components/tables/table.d.ts +36 -0
- package/libs/components/tables/table.js +4 -0
- package/libs/components/tables/table.js.map +1 -0
- package/libs/components/text/text.cjs +23 -0
- package/libs/components/text/text.cjs.map +1 -0
- package/libs/components/text/text.d.cts +30 -0
- package/libs/components/text/text.d.ts +30 -0
- package/libs/components/text/text.js +4 -0
- package/libs/components/text/text.js.map +1 -0
- package/libs/heading-3648c538.d.ts +250 -0
- package/libs/hooks.cjs +7 -0
- package/libs/hooks.d.cts +5 -0
- package/libs/hooks.d.ts +5 -0
- package/libs/hooks.js +3 -0
- package/libs/icons.cjs +3 -2
- package/libs/icons.d.cts +3 -1
- package/libs/icons.d.ts +3 -1
- package/libs/icons.js +2 -1
- package/libs/index.cjs +174 -62
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +529 -446
- package/libs/index.d.ts +529 -446
- package/libs/index.js +36 -7
- package/libs/index.js.map +1 -1
- package/libs/inputs-f3a216db.d.ts +45 -0
- package/libs/ui-645f95b5.d.ts +285 -0
- package/package.json +2 -2
- package/src/components/README-UI.mdx +416 -0
- package/src/components/alert/ACCESSIBILITY.md +319 -0
- package/src/components/alert/README.mdx +475 -19
- package/src/components/alert/alert.scss +113 -6
- package/src/components/alert/alert.stories.tsx +372 -0
- package/src/components/alert/alert.test.tsx +762 -0
- package/src/components/alert/alert.tsx +331 -66
- package/src/components/alert/views/alert-actions.tsx +13 -0
- package/src/components/alert/views/alert-content.tsx +17 -0
- package/src/components/alert/views/alert-icon.tsx +53 -0
- package/src/components/alert/views/alert-screen-reader-text.tsx +30 -0
- package/src/components/alert/views/alert-title.tsx +23 -0
- package/src/components/alert/views/alert-view.tsx +158 -0
- package/src/components/alert/views/index.ts +12 -0
- package/src/components/badge/badge.mdx +186 -49
- package/src/components/badge/badge.scss +20 -2
- package/src/components/badge/badge.stories.tsx +160 -14
- package/src/components/badge/badge.test.tsx +179 -0
- package/src/components/badge/badge.tsx +97 -4
- package/src/components/breadcrumbs/README.mdx +364 -45
- package/src/components/breadcrumbs/__snapshots__/breadcrumb.test.tsx.snap +152 -0
- package/src/components/breadcrumbs/breadcrumb.stories.tsx +7 -3
- package/src/components/breadcrumbs/breadcrumb.test.tsx +490 -0
- package/src/components/breadcrumbs/breadcrumb.tsx +427 -170
- package/src/components/button.ts +2 -0
- package/src/components/buttons/button.scss +34 -31
- package/src/components/buttons/button.stories.tsx +35 -0
- package/src/components/card.ts +2 -0
- package/src/components/cards/README.mdx +657 -0
- package/src/components/cards/card.scss +22 -0
- package/src/components/cards/card.stories.tsx +167 -5
- package/src/components/cards/card.test.tsx +360 -20
- package/src/components/cards/card.tsx +200 -79
- package/src/components/cards/card.types.ts +135 -0
- package/src/components/cards/card.utils.ts +79 -0
- package/src/components/details/ACCESSIBILITY-REVIEW-LIVE.md +1050 -0
- package/src/components/details/ACCESSIBILITY-REVIEW.md +502 -0
- package/src/components/details/README.mdx +437 -69
- package/src/components/details/details.scss +16 -0
- package/src/components/details/details.test.tsx +385 -0
- package/src/components/details/details.tsx +101 -69
- package/src/components/details/details.types.ts +76 -0
- package/src/components/dialog/README.mdx +513 -110
- package/src/components/dialog/dialog-modal.tsx +79 -56
- package/src/components/dialog/dialog.scss +53 -3
- package/src/components/dialog/dialog.stories.tsx +10 -7
- package/src/components/dialog/dialog.test.tsx +450 -0
- package/src/components/dialog/dialog.tsx +69 -59
- package/src/components/dialog/dialog.types.ts +133 -0
- package/src/components/dialog/views/dialog-footer.tsx +54 -11
- package/src/components/dialog/views/dialog-header.tsx +20 -15
- package/src/components/heading/heading.stories.tsx +44 -4
- package/src/components/heading/heading.tsx +89 -23
- package/src/components/icons/README.mdx +332 -0
- package/src/components/icons/icon.stories.tsx +74 -1
- package/src/components/icons/icon.tsx +89 -1
- package/src/components/icons/types.ts +47 -0
- package/src/components/images/README.mdx +340 -24
- package/src/components/images/img.scss +19 -3
- package/src/components/images/img.stories.tsx +424 -15
- package/src/components/images/img.test.tsx +354 -25
- package/src/components/images/img.tsx +186 -63
- package/src/components/images/img.types.ts +211 -0
- package/src/components/modal.ts +1 -0
- package/src/components/title/MIGRATION.md +199 -0
- package/src/components/title/README.md +326 -0
- package/src/components/title/README.mdx +452 -0
- package/src/components/title/title.stories.tsx +393 -0
- package/src/components/title/title.test.tsx +251 -0
- package/src/components/title/title.tsx +219 -0
- package/src/components/ui.stories.tsx +894 -0
- package/src/components/ui.test.tsx +559 -0
- package/src/components/ui.tsx +266 -15
- package/src/components/word-count/README.md +240 -0
- package/src/hooks.ts +1 -0
- package/src/index.ts +51 -19
- package/src/sass/_properties.scss +1 -0
- package/src/styles/alert/alert.css +94 -4
- package/src/styles/alert/alert.css.map +1 -1
- package/src/styles/badge/badge.css +20 -2
- package/src/styles/badge/badge.css.map +1 -1
- package/src/styles/buttons/button.css +31 -31
- package/src/styles/buttons/button.css.map +1 -1
- package/src/styles/cards/card.css +16 -0
- package/src/styles/cards/card.css.map +1 -1
- package/src/styles/details/details.css +19 -0
- package/src/styles/details/details.css.map +1 -1
- package/src/styles/dialog/dialog.css +43 -2
- package/src/styles/dialog/dialog.css.map +1 -1
- package/src/styles/images/img.css +15 -3
- package/src/styles/images/img.css.map +1 -1
- package/src/styles/index.css +240 -43
- package/src/styles/index.css.map +1 -1
- package/src/test/setup.d.ts +9 -0
- package/src/test/setup.ts +53 -1
- package/libs/chunk-PWVRDQ3R.js +0 -8
- package/libs/chunk-PWVRDQ3R.js.map +0 -1
- package/libs/chunk-SVS4MX3U.cjs +0 -31
- package/libs/chunk-SVS4MX3U.cjs.map +0 -1
- package/src/components/cards/README.md +0 -80
- package/src/components/dialog/hooks/useClickOutside.ts +0 -33
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Alert Component - Accessibility Documentation
|
|
2
|
+
|
|
3
|
+
This document outlines the accessibility features of the Alert component and its compliance with WCAG 2.1 Level AA standards.
|
|
4
|
+
|
|
5
|
+
## WCAG 2.1 Compliance
|
|
6
|
+
|
|
7
|
+
The Alert component has been designed and tested to meet WCAG 2.1 Level AA standards.
|
|
8
|
+
|
|
9
|
+
### 1.1.1 Non-text Content (Level A)
|
|
10
|
+
|
|
11
|
+
**Implementation:**
|
|
12
|
+
- Icons are marked with `aria-hidden="true"` to prevent redundant announcements
|
|
13
|
+
- Visually hidden text announces severity level to screen readers
|
|
14
|
+
- Severity announcements: "Information:", "Success:", "Warning:", "Error:"
|
|
15
|
+
|
|
16
|
+
**Example:**
|
|
17
|
+
```tsx
|
|
18
|
+
<Alert severity="error">System error occurred</Alert>
|
|
19
|
+
// Screen reader hears: "Error: System error occurred"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 1.3.1 Info and Relationships (Level A)
|
|
23
|
+
|
|
24
|
+
**Implementation:**
|
|
25
|
+
- `titleLevel` prop allows configurable heading levels (h2-h6)
|
|
26
|
+
- Maintains proper document heading hierarchy
|
|
27
|
+
- Default uses `<strong>` element when titleLevel is undefined
|
|
28
|
+
|
|
29
|
+
**Example:**
|
|
30
|
+
```tsx
|
|
31
|
+
<h1>Page Title</h1>
|
|
32
|
+
<Alert titleLevel={2} title="Section Alert">Content</Alert>
|
|
33
|
+
<Alert titleLevel={3} title="Subsection Alert">Content</Alert>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 1.4.1 Use of Color (Level A)
|
|
37
|
+
|
|
38
|
+
**Implementation:**
|
|
39
|
+
- Severity is conveyed through multiple channels:
|
|
40
|
+
- Text labels (visually hidden for screen readers)
|
|
41
|
+
- Icons (visual indicator)
|
|
42
|
+
- Color (supplementary indicator)
|
|
43
|
+
- Does not rely solely on color to convey meaning
|
|
44
|
+
|
|
45
|
+
### 1.4.3 Contrast (Minimum) (Level AA)
|
|
46
|
+
|
|
47
|
+
**Implementation:**
|
|
48
|
+
- All text meets 4.5:1 contrast ratio against backgrounds
|
|
49
|
+
- Tested across all severity levels and variants
|
|
50
|
+
- Color combinations:
|
|
51
|
+
- **Success**: Dark green text (#1e4620) on light green bg (#e6f4ea) ✓
|
|
52
|
+
- **Error**: Dark red text (#5f2120) on light red bg (#fdeded) ✓
|
|
53
|
+
- **Warning**: Dark orange text (#663c00) on light yellow bg (#fff4e5) ✓
|
|
54
|
+
- **Info**: Dark blue text (#084154) on light blue bg (#e5f6fd) ✓
|
|
55
|
+
- **Filled variants**: White text on solid colors (>7:1 ratio) ✓
|
|
56
|
+
|
|
57
|
+
### 2.2.1 Timing Adjustable (Level A)
|
|
58
|
+
|
|
59
|
+
**Implementation:**
|
|
60
|
+
- Auto-dismiss can be paused by hovering over or focusing the alert
|
|
61
|
+
- `pauseOnHover` prop (default: true) enables this behavior
|
|
62
|
+
- Timer restarts when mouse leaves or focus is lost
|
|
63
|
+
|
|
64
|
+
**Example:**
|
|
65
|
+
```tsx
|
|
66
|
+
<Alert autoHideDuration={5000} pauseOnHover={true}>
|
|
67
|
+
Hover or focus to pause auto-dismiss
|
|
68
|
+
</Alert>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 2.4.7 Focus Visible (Level AA)
|
|
72
|
+
|
|
73
|
+
**Implementation:**
|
|
74
|
+
- Visible focus indicator (2px solid outline with 2px offset)
|
|
75
|
+
- Uses `:focus-visible` to show outline only for keyboard navigation
|
|
76
|
+
- Focus outline color uses `currentColor` for adequate contrast
|
|
77
|
+
- Alert container is focusable when `autoFocus={true}`
|
|
78
|
+
|
|
79
|
+
**CSS:**
|
|
80
|
+
```scss
|
|
81
|
+
&:focus {
|
|
82
|
+
outline: 2px solid currentColor;
|
|
83
|
+
outline-offset: 2px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&:focus:not(:focus-visible) {
|
|
87
|
+
outline: none;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2.5.5 Target Size (Level AAA - Implemented)
|
|
92
|
+
|
|
93
|
+
**Implementation:**
|
|
94
|
+
- Dismiss button meets minimum 44×44px touch target size
|
|
95
|
+
- Adequate padding ensures comfortable touch interaction
|
|
96
|
+
- Tested on mobile devices (iOS Safari, Chrome Android)
|
|
97
|
+
|
|
98
|
+
**CSS:**
|
|
99
|
+
```scss
|
|
100
|
+
&.alert-dismiss {
|
|
101
|
+
min-width: 2.75rem; /* 44px */
|
|
102
|
+
min-height: 2.75rem; /* 44px */
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
justify-content: center;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## ARIA Attributes
|
|
110
|
+
|
|
111
|
+
### role="alert"
|
|
112
|
+
|
|
113
|
+
All alert instances use `role="alert"` which causes screen readers to announce the content immediately.
|
|
114
|
+
|
|
115
|
+
### aria-live
|
|
116
|
+
|
|
117
|
+
- **error** severity: `aria-live="assertive"` (interrupts screen reader)
|
|
118
|
+
- **All other severities**: `aria-live="polite"` (waits for screen reader to finish)
|
|
119
|
+
|
|
120
|
+
### aria-atomic="true"
|
|
121
|
+
|
|
122
|
+
Ensures screen readers announce the entire alert content, not just changes.
|
|
123
|
+
|
|
124
|
+
### aria-hidden="true"
|
|
125
|
+
|
|
126
|
+
Applied to decorative icons to prevent redundant announcements.
|
|
127
|
+
|
|
128
|
+
### aria-label
|
|
129
|
+
|
|
130
|
+
Dismiss button includes `aria-label="Close alert"` for clear screen reader announcement.
|
|
131
|
+
|
|
132
|
+
## Keyboard Support
|
|
133
|
+
|
|
134
|
+
| Key | Action |
|
|
135
|
+
|-----|--------|
|
|
136
|
+
| `Escape` | Dismisses the alert (when `dismissible={true}`) |
|
|
137
|
+
| `Tab` | Moves focus to dismiss button (if present) |
|
|
138
|
+
| `Enter`/`Space` | Activates dismiss button when focused |
|
|
139
|
+
|
|
140
|
+
## Screen Reader Behavior
|
|
141
|
+
|
|
142
|
+
### Expected Announcements
|
|
143
|
+
|
|
144
|
+
**Error Alert:**
|
|
145
|
+
```
|
|
146
|
+
"Error: System error occurred. Close alert, button."
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Success Alert with Title:**
|
|
150
|
+
```
|
|
151
|
+
"Success: Operation completed. Success message. Close alert, button."
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Info Alert with Heading:**
|
|
155
|
+
```
|
|
156
|
+
"Information. Important update, heading level 2. Please review the changes."
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Screen Reader Testing
|
|
160
|
+
|
|
161
|
+
Tested with:
|
|
162
|
+
- ✓ VoiceOver (macOS Safari)
|
|
163
|
+
- ✓ NVDA (Windows Firefox/Chrome)
|
|
164
|
+
- ⚠ JAWS (Manual testing recommended)
|
|
165
|
+
- ⚠ TalkBack (Android - Manual testing recommended)
|
|
166
|
+
- ⚠ VoiceOver iOS (Manual testing recommended)
|
|
167
|
+
|
|
168
|
+
## Motion and Animation
|
|
169
|
+
|
|
170
|
+
**Implementation:**
|
|
171
|
+
- Respects `prefers-reduced-motion` user preference
|
|
172
|
+
- When reduced motion is preferred, transition duration is set to 0.01ms
|
|
173
|
+
- Exit animations use opacity and transform for smooth visual feedback
|
|
174
|
+
|
|
175
|
+
**CSS:**
|
|
176
|
+
```scss
|
|
177
|
+
@media (prefers-reduced-motion: reduce) {
|
|
178
|
+
transition-duration: 0.01ms;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Best Practices
|
|
183
|
+
|
|
184
|
+
### When to Use autoFocus
|
|
185
|
+
|
|
186
|
+
Use `autoFocus={true}` sparingly and only for:
|
|
187
|
+
- ✓ Critical error messages that require immediate attention
|
|
188
|
+
- ✓ Security alerts or warnings
|
|
189
|
+
- ✗ Success confirmations (use `autoFocus={false}`)
|
|
190
|
+
- ✗ Informational messages (use `autoFocus={false}`)
|
|
191
|
+
|
|
192
|
+
### Heading Hierarchy
|
|
193
|
+
|
|
194
|
+
Always maintain proper heading hierarchy:
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<h1>Dashboard</h1>
|
|
198
|
+
|
|
199
|
+
<section>
|
|
200
|
+
<h2>Recent Activity</h2>
|
|
201
|
+
<Alert titleLevel={3} title="Updates Available">
|
|
202
|
+
New features are available
|
|
203
|
+
</Alert>
|
|
204
|
+
</section>
|
|
205
|
+
|
|
206
|
+
<section>
|
|
207
|
+
<h2>Notifications</h2>
|
|
208
|
+
<Alert titleLevel={3} title="System Maintenance">
|
|
209
|
+
Scheduled for tonight
|
|
210
|
+
</Alert>
|
|
211
|
+
</section>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Auto-Dismiss Timing
|
|
215
|
+
|
|
216
|
+
Recommended durations based on content:
|
|
217
|
+
- Short messages (< 20 words): 4-5 seconds
|
|
218
|
+
- Medium messages (20-40 words): 6-8 seconds
|
|
219
|
+
- Long messages (> 40 words): 10+ seconds
|
|
220
|
+
- Always enable `pauseOnHover={true}` (default)
|
|
221
|
+
|
|
222
|
+
### Color Contrast Verification
|
|
223
|
+
|
|
224
|
+
All alert variants have been tested with WebAIM Contrast Checker:
|
|
225
|
+
- Use **outlined** variant for most cases (default)
|
|
226
|
+
- Use **filled** variant for high-emphasis alerts
|
|
227
|
+
- Use **soft** variant for subtle, low-priority messages
|
|
228
|
+
|
|
229
|
+
### Content Type Selection
|
|
230
|
+
|
|
231
|
+
The `contentType` prop determines how alert children are rendered and affects semantic HTML structure:
|
|
232
|
+
|
|
233
|
+
**Use contentType="text" (default) when:**
|
|
234
|
+
- ✓ Displaying simple text messages (single sentence or paragraph)
|
|
235
|
+
- ✓ Content is purely informational without complex structure
|
|
236
|
+
- ✓ You want automatic paragraph wrapping for semantic correctness
|
|
237
|
+
|
|
238
|
+
**Use contentType="node" when:**
|
|
239
|
+
- ✓ Displaying lists (ordered or unordered)
|
|
240
|
+
- ✓ Including multiple paragraphs with different styling
|
|
241
|
+
- ✓ Rendering custom components or complex layouts
|
|
242
|
+
- ✓ Need fine-grained control over HTML structure
|
|
243
|
+
- ✓ Content includes interactive elements beyond actions
|
|
244
|
+
|
|
245
|
+
**Examples:**
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
// Simple text - use default "text" mode
|
|
249
|
+
<Alert severity="info">
|
|
250
|
+
Your session will expire in 5 minutes.
|
|
251
|
+
</Alert>
|
|
252
|
+
|
|
253
|
+
// Complex content with list - use "node" mode
|
|
254
|
+
<Alert severity="warning" contentType="node">
|
|
255
|
+
<p>Complete these steps:</p>
|
|
256
|
+
<ul>
|
|
257
|
+
<li>Update your password</li>
|
|
258
|
+
<li>Enable 2FA</li>
|
|
259
|
+
</ul>
|
|
260
|
+
</Alert>
|
|
261
|
+
|
|
262
|
+
// Multiple paragraphs - use "node" mode
|
|
263
|
+
<Alert severity="info" contentType="node">
|
|
264
|
+
<p>We've updated our privacy policy.</p>
|
|
265
|
+
<p>Review the changes by January 1, 2026.</p>
|
|
266
|
+
</Alert>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Accessibility Considerations:**
|
|
270
|
+
- Both modes maintain proper ARIA structure and screen reader compatibility
|
|
271
|
+
- `contentType="node"` allows for better semantic HTML when content is complex
|
|
272
|
+
- Use meaningful headings within node content for screen reader navigation
|
|
273
|
+
- Ensure custom layouts maintain logical reading order
|
|
274
|
+
|
|
275
|
+
## Testing Checklist
|
|
276
|
+
|
|
277
|
+
Use this checklist when implementing or modifying the Alert component:
|
|
278
|
+
|
|
279
|
+
- [ ] Keyboard navigation works (Tab, Escape)
|
|
280
|
+
- [ ] Screen reader announces severity correctly
|
|
281
|
+
- [ ] Focus indicator is visible on keyboard focus
|
|
282
|
+
- [ ] Dismiss button is at least 44×44px
|
|
283
|
+
- [ ] Auto-dismiss pauses on hover/focus
|
|
284
|
+
- [ ] Color contrast meets 4.5:1 ratio
|
|
285
|
+
- [ ] Heading hierarchy is maintained (if using titleLevel)
|
|
286
|
+
- [ ] Works with browser zoom at 200%
|
|
287
|
+
- [ ] Respects prefers-reduced-motion
|
|
288
|
+
- [ ] Works in high contrast mode (Windows)
|
|
289
|
+
|
|
290
|
+
## Browser Support
|
|
291
|
+
|
|
292
|
+
Tested and verified in:
|
|
293
|
+
- ✓ Chrome 90+
|
|
294
|
+
- ✓ Firefox 88+
|
|
295
|
+
- ✓ Safari 14+
|
|
296
|
+
- ✓ Edge 90+
|
|
297
|
+
- ⚠ IE 11 (Not supported - missing focus-visible)
|
|
298
|
+
|
|
299
|
+
## References
|
|
300
|
+
|
|
301
|
+
- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
|
|
302
|
+
- [WAI-ARIA Practices - Alert](https://www.w3.org/WAI/ARIA/apg/patterns/alert/)
|
|
303
|
+
- [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
|
|
304
|
+
- [Mozilla Accessibility Guidelines](https://developer.mozilla.org/en-US/docs/Web/Accessibility)
|
|
305
|
+
|
|
306
|
+
## Support
|
|
307
|
+
|
|
308
|
+
For accessibility-related issues or questions:
|
|
309
|
+
1. Check this documentation first
|
|
310
|
+
2. Review the component's Storybook examples
|
|
311
|
+
3. Consult WCAG 2.1 guidelines
|
|
312
|
+
4. Test with actual assistive technologies
|
|
313
|
+
5. File an issue if you discover an accessibility bug
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
**Last Updated:** October 2025
|
|
318
|
+
**WCAG Version:** 2.1 Level AA
|
|
319
|
+
**Component Version:** Phase 4 (Enhanced Accessibility)
|