@fpkit/acss 0.5.13 → 0.6.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.
- package/libs/{chunk-PQ2K3BM6.cjs → chunk-2NRIP6RB.cjs} +3 -3
- package/libs/chunk-33PNJ4LO.cjs +15 -0
- package/libs/chunk-33PNJ4LO.cjs.map +1 -0
- package/libs/chunk-4BZKFPEC.cjs +17 -0
- package/libs/chunk-4BZKFPEC.cjs.map +1 -0
- package/libs/{chunk-772NRB75.js → chunk-5QD3DWFI.js} +2 -2
- package/libs/chunk-6SAHIYCZ.js +7 -0
- package/libs/chunk-6SAHIYCZ.js.map +1 -0
- package/libs/{chunk-3MKLDCKQ.cjs → chunk-6WTC4JXH.cjs} +3 -3
- package/libs/chunk-75QHTLFO.js +7 -0
- package/libs/chunk-75QHTLFO.js.map +1 -0
- package/libs/{chunk-ZANSFMTD.js → chunk-7XPFW7CB.js} +3 -3
- package/libs/chunk-BFK62VX5.js +5 -0
- package/libs/chunk-BFK62VX5.js.map +1 -0
- package/libs/{chunk-ROZI23GS.cjs → chunk-DKTHCQ5P.cjs} +4 -4
- package/libs/chunk-E2AJURUW.cjs +13 -0
- package/libs/chunk-E2AJURUW.cjs.map +1 -0
- package/libs/{chunk-L75OQKEI.cjs → chunk-ENTCUJ3A.cjs} +3 -3
- package/libs/chunk-ENTCUJ3A.cjs.map +1 -0
- package/libs/chunk-F5EYMVQM.js +10 -0
- package/libs/chunk-F5EYMVQM.js.map +1 -0
- package/libs/chunk-FVROL3V5.js +9 -0
- package/libs/chunk-FVROL3V5.js.map +1 -0
- package/libs/chunk-GT77BX4L.cjs +17 -0
- package/libs/chunk-GT77BX4L.cjs.map +1 -0
- package/libs/chunk-GUJSMQ3V.cjs +16 -0
- package/libs/chunk-GUJSMQ3V.cjs.map +1 -0
- package/libs/chunk-HHLNOC5T.js +7 -0
- package/libs/chunk-HHLNOC5T.js.map +1 -0
- package/libs/chunk-HRRHPLER.js +8 -0
- package/libs/chunk-HRRHPLER.js.map +1 -0
- package/libs/chunk-IEB64SWY.js +8 -0
- package/libs/chunk-IEB64SWY.js.map +1 -0
- package/libs/{chunk-NGTJDDFO.js → chunk-IQ76HGVP.js} +2 -2
- package/libs/chunk-IRLFZ3OL.js +9 -0
- package/libs/chunk-IRLFZ3OL.js.map +1 -0
- package/libs/{chunk-JJ43O4Y5.js → chunk-KK47SYZI.js} +2 -2
- package/libs/chunk-O3JIHC5M.cjs +15 -0
- package/libs/chunk-O3JIHC5M.cjs.map +1 -0
- package/libs/chunk-O5XAJ7BY.cjs +18 -0
- package/libs/chunk-O5XAJ7BY.cjs.map +1 -0
- package/libs/chunk-OVWLQYMK.js +10 -0
- package/libs/chunk-OVWLQYMK.js.map +1 -0
- package/libs/chunk-PNWIRCG3.cjs +7 -0
- package/libs/chunk-PNWIRCG3.cjs.map +1 -0
- package/libs/{chunk-D4YLRWAO.cjs → chunk-QVW6W76L.cjs} +6 -6
- package/libs/chunk-T4T6GWYQ.cjs +17 -0
- package/libs/chunk-T4T6GWYQ.cjs.map +1 -0
- package/libs/chunk-TON2YGMD.cjs +9 -0
- package/libs/chunk-TON2YGMD.cjs.map +1 -0
- package/libs/chunk-UEPAWMDF.js +8 -0
- package/libs/chunk-UEPAWMDF.js.map +1 -0
- package/libs/{chunk-LT5KZ2QW.cjs → chunk-US2I5GI7.cjs} +3 -3
- package/libs/{chunk-B7F5FS6D.cjs → chunk-W2UIN7EV.cjs} +3 -3
- package/libs/{chunk-P2DC76ZZ.cjs → chunk-W5TKWBFC.cjs} +3 -3
- package/libs/chunk-WXBFBWYF.cjs +16 -0
- package/libs/chunk-WXBFBWYF.cjs.map +1 -0
- package/libs/{chunk-VUH3FXGJ.js → chunk-X3JCTEPD.js} +5 -5
- package/libs/chunk-X5LGFCWG.js +9 -0
- package/libs/chunk-X5LGFCWG.js.map +1 -0
- package/libs/{chunk-5M57K4SW.js → chunk-Y2PFDELK.js} +2 -2
- package/libs/{chunk-ETFLFC2S.js → chunk-ZFJ4U45S.js} +2 -2
- package/libs/{component-props-a8a2f97e.d.ts → component-props-67d978a2.d.ts} +4 -4
- 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/breadcrumbs/breadcrumb.cjs +6 -6
- package/libs/components/breadcrumbs/breadcrumb.d.cts +11 -11
- package/libs/components/breadcrumbs/breadcrumb.d.ts +11 -11
- package/libs/components/breadcrumbs/breadcrumb.js +3 -3
- package/libs/components/button.cjs +6 -4
- package/libs/components/button.d.cts +97 -4
- package/libs/components/button.d.ts +97 -4
- package/libs/components/button.js +4 -2
- package/libs/components/card.cjs +7 -7
- package/libs/components/card.d.cts +14 -14
- package/libs/components/card.d.ts +14 -14
- package/libs/components/card.js +2 -2
- package/libs/components/dialog/dialog.cjs +9 -7
- package/libs/components/dialog/dialog.d.cts +3 -3
- package/libs/components/dialog/dialog.d.ts +3 -3
- package/libs/components/dialog/dialog.js +7 -5
- package/libs/components/form/fields.cjs +4 -4
- package/libs/components/form/fields.d.cts +16 -7
- package/libs/components/form/fields.d.ts +16 -7
- package/libs/components/form/fields.js +2 -2
- package/libs/components/form/inputs.cjs +6 -4
- package/libs/components/form/inputs.d.cts +50 -2
- package/libs/components/form/inputs.d.ts +50 -2
- package/libs/components/form/inputs.js +4 -2
- package/libs/components/form/textarea.cjs +5 -4
- package/libs/components/form/textarea.d.cts +32 -23
- package/libs/components/form/textarea.d.ts +32 -23
- package/libs/components/form/textarea.js +3 -2
- package/libs/components/heading/heading.cjs +3 -3
- package/libs/components/heading/heading.d.cts +2 -2
- package/libs/components/heading/heading.d.ts +2 -2
- package/libs/components/heading/heading.js +2 -2
- package/libs/components/icons/icon.cjs +4 -4
- package/libs/components/icons/icon.d.cts +38 -38
- package/libs/components/icons/icon.d.ts +38 -38
- package/libs/components/icons/icon.js +2 -2
- package/libs/components/link/link.cjs +4 -4
- package/libs/components/link/link.css +1 -1
- package/libs/components/link/link.css.map +1 -1
- package/libs/components/link/link.d.cts +3 -19
- package/libs/components/link/link.d.ts +3 -19
- package/libs/components/link/link.js +2 -2
- package/libs/components/link/link.min.css +2 -2
- package/libs/components/list/list.cjs +5 -5
- package/libs/components/list/list.css +1 -0
- package/libs/components/list/list.css.map +1 -0
- package/libs/components/list/list.d.cts +120 -33
- package/libs/components/list/list.d.ts +120 -33
- package/libs/components/list/list.js +2 -2
- package/libs/components/list/list.min.css +3 -0
- package/libs/components/modal.cjs +6 -4
- package/libs/components/modal.d.cts +8 -8
- package/libs/components/modal.d.ts +8 -8
- package/libs/components/modal.js +5 -3
- package/libs/components/nav/nav.cjs +7 -7
- package/libs/components/nav/nav.css +1 -1
- package/libs/components/nav/nav.css.map +1 -1
- package/libs/components/nav/nav.d.cts +550 -34
- package/libs/components/nav/nav.d.ts +550 -34
- package/libs/components/nav/nav.js +3 -3
- package/libs/components/nav/nav.min.css +2 -2
- package/libs/components/popover/popover.d.cts +5 -5
- package/libs/components/popover/popover.d.ts +5 -5
- package/libs/components/tables/table.cjs +5 -5
- package/libs/components/tables/table.d.cts +8 -8
- package/libs/components/tables/table.d.ts +8 -8
- package/libs/components/tables/table.js +2 -2
- package/libs/components/tag/tag.css +1 -1
- package/libs/components/tag/tag.css.map +1 -1
- package/libs/components/tag/tag.min.css +2 -2
- package/libs/components/text/text.cjs +5 -5
- package/libs/components/text/text.d.cts +5 -5
- package/libs/components/text/text.d.ts +5 -5
- package/libs/components/text/text.js +2 -2
- package/libs/form.types-d25ebfac.d.ts +233 -0
- package/libs/{heading-3648c538.d.ts → heading-7446cb46.d.ts} +8 -8
- package/libs/hooks.cjs +9 -4
- package/libs/hooks.d.cts +137 -3
- package/libs/hooks.d.ts +137 -3
- package/libs/hooks.js +4 -3
- package/libs/icons.cjs +3 -3
- package/libs/icons.d.cts +2 -2
- package/libs/icons.d.ts +2 -2
- package/libs/icons.js +2 -2
- package/libs/index.cjs +53 -51
- 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 +338 -49
- package/libs/index.d.ts +338 -49
- package/libs/index.js +24 -22
- package/libs/index.js.map +1 -1
- package/libs/link-5192f411.d.ts +323 -0
- package/libs/list.types-d26de310.d.ts +245 -0
- package/libs/{ui-645f95b5.d.ts → ui-d01b50d4.d.ts} +16 -12
- package/package.json +4 -6
- package/src/components/alert/alert.scss +1 -4
- package/src/components/breadcrumbs/breadcrumb.tsx +4 -1
- package/src/components/buttons/README.mdx +102 -1
- package/src/components/buttons/button.stories.tsx +106 -0
- package/src/components/buttons/button.tsx +82 -52
- package/src/components/dialog/dialog-a11y-review.md +653 -0
- package/src/components/form/README.mdx +725 -43
- package/src/components/form/WCAG-REVIEW.md +654 -0
- package/src/components/form/fields.tsx +10 -1
- package/src/components/form/form.stories.tsx +604 -23
- package/src/components/form/form.tsx +204 -63
- package/src/components/form/form.types.ts +378 -0
- package/src/components/form/input.stories.tsx +71 -3
- package/src/components/form/inputs.tsx +159 -67
- package/src/components/form/select.tsx +122 -66
- package/src/components/form/textarea.tsx +120 -73
- package/src/components/fp.tsx +86 -11
- package/src/components/link/README.mdx +923 -0
- package/src/components/link/link.scss +79 -26
- package/src/components/link/link.stories.tsx +383 -30
- package/src/components/link/link.test.tsx +677 -0
- package/src/components/link/link.tsx +163 -57
- package/src/components/link/link.types.ts +261 -0
- package/src/components/list/README.mdx +764 -0
- package/src/components/list/list.scss +285 -0
- package/src/components/list/list.stories.tsx +514 -27
- package/src/components/list/list.test.tsx +554 -0
- package/src/components/list/list.tsx +153 -51
- package/src/components/list/list.types.ts +255 -0
- package/src/components/nav/ACCESSIBILITY.md +649 -0
- package/src/components/nav/README.mdx +782 -0
- package/src/components/nav/nav.scss +32 -1
- package/src/components/nav/nav.stories.tsx +44 -6
- package/src/components/nav/nav.tsx +302 -51
- package/src/components/nav/nav.types.ts +308 -0
- package/src/components/tag/README.mdx +426 -0
- package/src/components/tag/tag.scss +101 -27
- package/src/components/tag/tag.stories.tsx +384 -10
- package/src/components/tag/tag.test.tsx +210 -0
- package/src/components/tag/tag.tsx +106 -9
- package/src/components/tag/tag.types.ts +107 -0
- package/src/components/ui.tsx +8 -3
- package/src/hooks/use-disabled-state.test.tsx +536 -0
- package/src/hooks/use-disabled-state.ts +246 -0
- package/src/hooks/useDisabledState.md +393 -0
- package/src/hooks.ts +6 -0
- package/src/index.scss +2 -0
- package/src/index.ts +2 -1
- package/src/sass/_globals.scss +2 -7
- package/src/styles/alert/alert.css +1 -3
- package/src/styles/alert/alert.css.map +1 -1
- package/src/styles/index.css +450 -76
- package/src/styles/index.css.map +1 -1
- package/src/styles/link/link.css +45 -28
- package/src/styles/link/link.css.map +1 -1
- package/src/styles/list/list.css +214 -0
- package/src/styles/list/list.css.map +1 -0
- package/src/styles/nav/nav.css +21 -1
- package/src/styles/nav/nav.css.map +1 -1
- package/src/styles/tag/tag.css +113 -35
- package/src/styles/tag/tag.css.map +1 -1
- package/src/styles/utilities/_disabled.scss +58 -0
- package/src/types/shared.ts +43 -6
- package/src/utils/accessibility.ts +109 -0
- package/libs/chunk-2LTJ7HHX.cjs +0 -18
- package/libs/chunk-2LTJ7HHX.cjs.map +0 -1
- package/libs/chunk-2Y7W75TT.js +0 -9
- package/libs/chunk-2Y7W75TT.js.map +0 -1
- package/libs/chunk-5S4ORA4C.cjs +0 -15
- package/libs/chunk-5S4ORA4C.cjs.map +0 -1
- package/libs/chunk-AHDJGCG5.cjs +0 -15
- package/libs/chunk-AHDJGCG5.cjs.map +0 -1
- package/libs/chunk-BHRQBJRY.js +0 -8
- package/libs/chunk-BHRQBJRY.js.map +0 -1
- package/libs/chunk-GZ4QFPRY.js +0 -9
- package/libs/chunk-GZ4QFPRY.js.map +0 -1
- package/libs/chunk-IYUN2EW3.cjs +0 -15
- package/libs/chunk-IYUN2EW3.cjs.map +0 -1
- package/libs/chunk-J32EZPYD.cjs +0 -15
- package/libs/chunk-J32EZPYD.cjs.map +0 -1
- package/libs/chunk-KUKIVRC2.js +0 -7
- package/libs/chunk-KUKIVRC2.js.map +0 -1
- package/libs/chunk-L75OQKEI.cjs.map +0 -1
- package/libs/chunk-M5RRNTVX.cjs +0 -15
- package/libs/chunk-M5RRNTVX.cjs.map +0 -1
- package/libs/chunk-OK5QEIMD.cjs +0 -17
- package/libs/chunk-OK5QEIMD.cjs.map +0 -1
- package/libs/chunk-P7TTEYCD.js +0 -7
- package/libs/chunk-P7TTEYCD.js.map +0 -1
- package/libs/chunk-QLZWHAMK.js +0 -8
- package/libs/chunk-QLZWHAMK.js.map +0 -1
- package/libs/chunk-RIVUMPOG.js +0 -8
- package/libs/chunk-RIVUMPOG.js.map +0 -1
- package/libs/chunk-S7BABR7Z.cjs +0 -13
- package/libs/chunk-S7BABR7Z.cjs.map +0 -1
- package/libs/chunk-SMYRLO3E.js +0 -8
- package/libs/chunk-SMYRLO3E.js.map +0 -1
- package/libs/chunk-TYRCEX2L.js +0 -8
- package/libs/chunk-TYRCEX2L.js.map +0 -1
- package/libs/chunk-XBA562WW.js +0 -8
- package/libs/chunk-XBA562WW.js.map +0 -1
- package/libs/chunk-XTQKWY7W.cjs +0 -32
- package/libs/chunk-XTQKWY7W.cjs.map +0 -1
- package/libs/inputs-f3a216db.d.ts +0 -45
- /package/libs/{chunk-PQ2K3BM6.cjs.map → chunk-2NRIP6RB.cjs.map} +0 -0
- /package/libs/{chunk-772NRB75.js.map → chunk-5QD3DWFI.js.map} +0 -0
- /package/libs/{chunk-3MKLDCKQ.cjs.map → chunk-6WTC4JXH.cjs.map} +0 -0
- /package/libs/{chunk-ZANSFMTD.js.map → chunk-7XPFW7CB.js.map} +0 -0
- /package/libs/{chunk-ROZI23GS.cjs.map → chunk-DKTHCQ5P.cjs.map} +0 -0
- /package/libs/{chunk-NGTJDDFO.js.map → chunk-IQ76HGVP.js.map} +0 -0
- /package/libs/{chunk-JJ43O4Y5.js.map → chunk-KK47SYZI.js.map} +0 -0
- /package/libs/{chunk-D4YLRWAO.cjs.map → chunk-QVW6W76L.cjs.map} +0 -0
- /package/libs/{chunk-LT5KZ2QW.cjs.map → chunk-US2I5GI7.cjs.map} +0 -0
- /package/libs/{chunk-B7F5FS6D.cjs.map → chunk-W2UIN7EV.cjs.map} +0 -0
- /package/libs/{chunk-P2DC76ZZ.cjs.map → chunk-W5TKWBFC.cjs.map} +0 -0
- /package/libs/{chunk-VUH3FXGJ.js.map → chunk-X3JCTEPD.js.map} +0 -0
- /package/libs/{chunk-5M57K4SW.js.map → chunk-Y2PFDELK.js.map} +0 -0
- /package/libs/{chunk-ETFLFC2S.js.map → chunk-ZFJ4U45S.js.map} +0 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { Meta } from "@storybook/addon-docs/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.React Components/Tag/Readme" />
|
|
4
|
+
|
|
5
|
+
# Tag Component
|
|
6
|
+
|
|
7
|
+
A small inline label component for displaying status indicators, version labels, and environment markers with WCAG 2.1 AA accessibility compliance.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The Tag component serves as a visual and semantic indicator for highlighting supplementary information such as:
|
|
12
|
+
|
|
13
|
+
- **Release stages** (alpha, beta, stable)
|
|
14
|
+
- **Environment indicators** (production, development)
|
|
15
|
+
- **Version labels** (v1.0.0, v2.0-beta)
|
|
16
|
+
- **Status markers** (new, updated, deprecated)
|
|
17
|
+
|
|
18
|
+
Tags are designed to be lightweight, accessible, and easily customizable through CSS custom properties.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
The Tag component is part of the `@fpkit/acss` package.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @fpkit/acss
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Basic Usage
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { Tag } from '@fpkit/acss'
|
|
32
|
+
|
|
33
|
+
function App() {
|
|
34
|
+
return <Tag variant="beta">Beta Feature</Tag>
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Variants
|
|
39
|
+
|
|
40
|
+
The Tag component includes four predefined variants, each with semantic color schemes:
|
|
41
|
+
|
|
42
|
+
### Alpha
|
|
43
|
+
|
|
44
|
+
Early development stage indicator with warning colors.
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<Tag variant="alpha">Alpha v0.1.0</Tag>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Beta
|
|
51
|
+
|
|
52
|
+
Pre-release version indicator with warning colors.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<Tag variant="beta">Beta</Tag>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Stable
|
|
59
|
+
|
|
60
|
+
Production-ready release indicator with success colors.
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
<Tag variant="stable">Stable v1.0</Tag>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Production
|
|
67
|
+
|
|
68
|
+
Live production environment indicator with primary colors.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<Tag variant="production">Production</Tag>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## API Reference
|
|
75
|
+
|
|
76
|
+
### Props
|
|
77
|
+
|
|
78
|
+
| Prop | Type | Default | Description |
|
|
79
|
+
|------|------|---------|-------------|
|
|
80
|
+
| `variant` | `'alpha' \| 'beta' \| 'stable' \| 'production'` | `undefined` | Visual variant with predefined color schemes |
|
|
81
|
+
| `elm` | `'span' \| 'p'` | `'span'` | HTML element to render (span for inline, p for block) |
|
|
82
|
+
| `role` | `'note' \| 'status'` | `'note'` | ARIA role for semantic meaning and screen reader behavior |
|
|
83
|
+
| `children` | `React.ReactNode` | `undefined` | Content to display inside the tag |
|
|
84
|
+
| `id` | `string` | `undefined` | HTML id attribute |
|
|
85
|
+
| `styles` | `React.CSSProperties` | `undefined` | Inline styles to apply |
|
|
86
|
+
| `classes` | `string` | `undefined` | CSS class names to apply |
|
|
87
|
+
| `aria-label` | `string` | `undefined` | Accessible label for screen readers |
|
|
88
|
+
| `aria-describedby` | `string` | `undefined` | Reference to element(s) that describe the tag |
|
|
89
|
+
|
|
90
|
+
### TypeScript Types
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import type { TagProps, TagVariant } from '@fpkit/acss'
|
|
94
|
+
|
|
95
|
+
type TagVariant = 'alpha' | 'beta' | 'stable' | 'production'
|
|
96
|
+
|
|
97
|
+
interface TagProps {
|
|
98
|
+
variant?: TagVariant
|
|
99
|
+
elm?: 'span' | 'p'
|
|
100
|
+
role?: 'note' | 'status'
|
|
101
|
+
children?: React.ReactNode
|
|
102
|
+
// ... extends UI component props
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Accessibility (WCAG 2.1 AA Compliance)
|
|
107
|
+
|
|
108
|
+
### ARIA Roles
|
|
109
|
+
|
|
110
|
+
The Tag component supports two ARIA roles to ensure proper semantic meaning and screen reader announcements:
|
|
111
|
+
|
|
112
|
+
#### `role="note"` (Default)
|
|
113
|
+
|
|
114
|
+
Use for **static tags** that provide informational labels:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
<Tag variant="stable" role="note">v1.0.0</Tag>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Characteristics:**
|
|
121
|
+
- Screen readers read content once when encountered
|
|
122
|
+
- Suitable for version numbers, feature labels, static indicators
|
|
123
|
+
- Does not announce changes to users
|
|
124
|
+
|
|
125
|
+
#### `role="status"`
|
|
126
|
+
|
|
127
|
+
Use for **dynamic tags** that update and require announcements:
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<Tag role="status" variant="beta">
|
|
131
|
+
{isDeploying ? 'Deploying...' : 'Deployed'}
|
|
132
|
+
</Tag>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Characteristics:**
|
|
136
|
+
- Creates a live region for screen reader announcements
|
|
137
|
+
- Screen readers announce updates when content changes
|
|
138
|
+
- Suitable for real-time status, deployment states, dynamic flags
|
|
139
|
+
|
|
140
|
+
### Color Independence
|
|
141
|
+
|
|
142
|
+
Don't rely solely on color to convey meaning. Always include descriptive text:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
{/* ✅ Good: Text provides meaning independent of color */}
|
|
146
|
+
<Tag variant="production">Production Environment</Tag>
|
|
147
|
+
|
|
148
|
+
{/* ❌ Bad: Relies only on color */}
|
|
149
|
+
<Tag variant="production" />
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Accessible Labels
|
|
153
|
+
|
|
154
|
+
Provide `aria-label` when tag content needs additional context:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<Tag variant="beta" aria-label="Beta version - feedback welcome">
|
|
158
|
+
Beta
|
|
159
|
+
</Tag>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Contrast Ratios
|
|
163
|
+
|
|
164
|
+
All predefined variants meet WCAG AA contrast requirements (4.5:1 for normal text). When using custom styles, ensure adequate contrast:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
{/* Ensure sufficient contrast when customizing */}
|
|
168
|
+
<Tag styles={{ backgroundColor: '#0066cc', color: '#ffffff' }}>
|
|
169
|
+
Custom Tag
|
|
170
|
+
</Tag>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Usage Examples
|
|
174
|
+
|
|
175
|
+
### Inline Tags
|
|
176
|
+
|
|
177
|
+
Display tags inline within text content:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
<p>
|
|
181
|
+
This feature is currently in{' '}
|
|
182
|
+
<Tag variant="beta">Beta</Tag>{' '}
|
|
183
|
+
and will be moved to{' '}
|
|
184
|
+
<Tag variant="stable">Stable</Tag>{' '}
|
|
185
|
+
after testing.
|
|
186
|
+
</p>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Block-Level Tags
|
|
190
|
+
|
|
191
|
+
Render tags as block elements using the `p` element:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
<Tag elm="p" variant="production">
|
|
195
|
+
Production Environment
|
|
196
|
+
</Tag>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Version Labels
|
|
200
|
+
|
|
201
|
+
Use tags for semantic versioning:
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<div>
|
|
205
|
+
<Tag variant="alpha">v0.1.0-alpha</Tag>
|
|
206
|
+
<Tag variant="beta">v0.9.0-beta</Tag>
|
|
207
|
+
<Tag variant="stable">v1.0.0</Tag>
|
|
208
|
+
<Tag variant="production">v2.0.0</Tag>
|
|
209
|
+
</div>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Dynamic Status Indicators
|
|
213
|
+
|
|
214
|
+
Update tags dynamically with proper ARIA role:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
function DeploymentStatus() {
|
|
218
|
+
const [status, setStatus] = useState('deploying')
|
|
219
|
+
|
|
220
|
+
return (
|
|
221
|
+
<Tag
|
|
222
|
+
role="status"
|
|
223
|
+
variant={status === 'deployed' ? 'stable' : 'beta'}
|
|
224
|
+
>
|
|
225
|
+
{status === 'deploying' ? 'Deploying...' : 'Deployed'}
|
|
226
|
+
</Tag>
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Custom Styling
|
|
232
|
+
|
|
233
|
+
Override default styles with inline CSS or custom properties:
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
<Tag
|
|
237
|
+
variant="beta"
|
|
238
|
+
styles={{
|
|
239
|
+
fontSize: '0.75rem',
|
|
240
|
+
padding: '0.25rem 0.5rem',
|
|
241
|
+
fontWeight: 'bold'
|
|
242
|
+
}}
|
|
243
|
+
>
|
|
244
|
+
Small Beta
|
|
245
|
+
</Tag>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Styling & Theming
|
|
249
|
+
|
|
250
|
+
The Tag component uses CSS custom properties for theming. You can customize the appearance by overriding these variables:
|
|
251
|
+
|
|
252
|
+
### CSS Custom Properties
|
|
253
|
+
|
|
254
|
+
```css
|
|
255
|
+
[data-tag] {
|
|
256
|
+
/* Spacing */
|
|
257
|
+
--tag-px: 0.7rem; /* Horizontal padding */
|
|
258
|
+
--tag-py: 0.2rem; /* Vertical padding */
|
|
259
|
+
|
|
260
|
+
/* Typography */
|
|
261
|
+
--tag-fs: 0.8rem; /* Font size */
|
|
262
|
+
--tag-fw: 500; /* Font weight */
|
|
263
|
+
--tag-color: currentColor; /* Text color */
|
|
264
|
+
|
|
265
|
+
/* Appearance */
|
|
266
|
+
--tag-bg: lightgray; /* Background color */
|
|
267
|
+
--tag-radius: 99rem; /* Border radius */
|
|
268
|
+
--tag-display: inline-block;/* Display type */
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Variant Color Tokens
|
|
273
|
+
|
|
274
|
+
```css
|
|
275
|
+
/* Override variant colors */
|
|
276
|
+
[data-tag] {
|
|
277
|
+
--beta: var(--warning-500, orange);
|
|
278
|
+
--stable: var(--success-500, green);
|
|
279
|
+
--production: rgb(44, 71, 151);
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Custom Theme Example
|
|
284
|
+
|
|
285
|
+
```css
|
|
286
|
+
/* Create a custom dark theme for tags */
|
|
287
|
+
[data-tag] {
|
|
288
|
+
--tag-bg: #1a1a1a;
|
|
289
|
+
--tag-color: #ffffff;
|
|
290
|
+
--tag-radius: 0.25rem;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
[data-tag~='beta'] {
|
|
294
|
+
--tag-bg: #ff6b00;
|
|
295
|
+
--tag-color: #ffffff;
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Best Practices
|
|
300
|
+
|
|
301
|
+
### ✅ Do
|
|
302
|
+
|
|
303
|
+
- **Use semantic variants** that match the content meaning
|
|
304
|
+
- **Include descriptive text** independent of color
|
|
305
|
+
- **Use `role="status"`** for dynamic content that updates
|
|
306
|
+
- **Use `role="note"`** for static informational labels
|
|
307
|
+
- **Provide `aria-label`** for additional screen reader context when needed
|
|
308
|
+
- **Keep tag content concise** (typically 1-3 words)
|
|
309
|
+
|
|
310
|
+
### ❌ Don't
|
|
311
|
+
|
|
312
|
+
- **Don't rely on color alone** to convey meaning
|
|
313
|
+
- **Don't use `role="status"`** for static content
|
|
314
|
+
- **Don't use empty tags** without accessible labels
|
|
315
|
+
- **Don't nest interactive elements** inside tags
|
|
316
|
+
- **Don't use tags for critical information** without text alternatives
|
|
317
|
+
|
|
318
|
+
## Common Patterns
|
|
319
|
+
|
|
320
|
+
### Feature Release Stages
|
|
321
|
+
|
|
322
|
+
```tsx
|
|
323
|
+
<div>
|
|
324
|
+
<h3>New Features</h3>
|
|
325
|
+
<ul>
|
|
326
|
+
<li>
|
|
327
|
+
Dark Mode <Tag variant="alpha">Alpha</Tag>
|
|
328
|
+
</li>
|
|
329
|
+
<li>
|
|
330
|
+
API v2 <Tag variant="beta">Beta</Tag>
|
|
331
|
+
</li>
|
|
332
|
+
<li>
|
|
333
|
+
OAuth Login <Tag variant="stable">Stable</Tag>
|
|
334
|
+
</li>
|
|
335
|
+
</ul>
|
|
336
|
+
</div>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Environment Indicators
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
function EnvironmentBanner() {
|
|
343
|
+
const env = process.env.NODE_ENV
|
|
344
|
+
|
|
345
|
+
return (
|
|
346
|
+
<Tag
|
|
347
|
+
variant={env === 'production' ? 'production' : 'beta'}
|
|
348
|
+
aria-label={`Current environment: ${env}`}
|
|
349
|
+
>
|
|
350
|
+
{env}
|
|
351
|
+
</Tag>
|
|
352
|
+
)
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Version Comparison
|
|
357
|
+
|
|
358
|
+
```tsx
|
|
359
|
+
<table>
|
|
360
|
+
<tr>
|
|
361
|
+
<td>Current</td>
|
|
362
|
+
<td><Tag variant="stable">v1.2.0</Tag></td>
|
|
363
|
+
</tr>
|
|
364
|
+
<tr>
|
|
365
|
+
<td>Latest</td>
|
|
366
|
+
<td><Tag variant="production">v2.0.0</Tag></td>
|
|
367
|
+
</tr>
|
|
368
|
+
</table>
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Testing
|
|
372
|
+
|
|
373
|
+
The Tag component includes comprehensive test coverage. Example test cases:
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
import { render, screen } from '@testing-library/react'
|
|
377
|
+
import Tag from './tag'
|
|
378
|
+
|
|
379
|
+
test('renders with default props', () => {
|
|
380
|
+
render(<Tag>Test Tag</Tag>)
|
|
381
|
+
expect(screen.getByRole('note')).toBeInTheDocument()
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
test('applies variant styling', () => {
|
|
385
|
+
render(<Tag variant="beta">Beta</Tag>)
|
|
386
|
+
const tag = screen.getByText('Beta')
|
|
387
|
+
expect(tag).toHaveAttribute('data-tag', 'beta')
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
test('supports dynamic status updates', () => {
|
|
391
|
+
const { rerender } = render(
|
|
392
|
+
<Tag role="status">Deploying</Tag>
|
|
393
|
+
)
|
|
394
|
+
expect(screen.getByRole('status')).toHaveTextContent('Deploying')
|
|
395
|
+
|
|
396
|
+
rerender(<Tag role="status">Deployed</Tag>)
|
|
397
|
+
expect(screen.getByRole('status')).toHaveTextContent('Deployed')
|
|
398
|
+
})
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Browser Support
|
|
402
|
+
|
|
403
|
+
The Tag component supports all modern browsers that support:
|
|
404
|
+
- CSS Custom Properties
|
|
405
|
+
- CSS Logical Properties (`padding-inline`, `padding-block`)
|
|
406
|
+
- ARIA roles and attributes
|
|
407
|
+
|
|
408
|
+
For legacy browser support, consider using PostCSS with appropriate plugins.
|
|
409
|
+
|
|
410
|
+
## Related Components
|
|
411
|
+
|
|
412
|
+
- **Badge**: For numerical indicators and notification counts
|
|
413
|
+
- **Chip**: For interactive, removable labels
|
|
414
|
+
- **Label**: For form field labels
|
|
415
|
+
|
|
416
|
+
## Changelog
|
|
417
|
+
|
|
418
|
+
See the [component changelog](../../CHANGELOG.md) for version history and updates.
|
|
419
|
+
|
|
420
|
+
## Contributing
|
|
421
|
+
|
|
422
|
+
Contributions are welcome! Please read our [contributing guidelines](../../CONTRIBUTING.md) before submitting pull requests.
|
|
423
|
+
|
|
424
|
+
## License
|
|
425
|
+
|
|
426
|
+
MIT License - see [LICENSE](../../LICENSE) for details.
|
|
@@ -1,19 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag Component Styles - WCAG 2.1 AA Compliant
|
|
3
|
+
*
|
|
4
|
+
* Provides visual styling for the Tag component with CSS custom properties
|
|
5
|
+
* for easy theming and variant support. All measurements use rem units
|
|
6
|
+
* for scalability and accessibility.
|
|
7
|
+
*
|
|
8
|
+
* Accessibility Features:
|
|
9
|
+
* - Color contrast ratios meet WCAG AA 4.5:1 minimum (WCAG 1.4.3)
|
|
10
|
+
* - Visual indicators beyond color (symbols via ::before) (WCAG 1.4.1)
|
|
11
|
+
* - Visible focus indicators with 3:1 contrast (WCAG 2.4.7)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Base Tag Styles
|
|
16
|
+
* Applied to all tag elements via role and data-tag attributes
|
|
17
|
+
*/
|
|
1
18
|
p[role='note'],
|
|
2
19
|
[role='note'],
|
|
3
20
|
small > span,
|
|
4
21
|
[data-tag] {
|
|
5
|
-
|
|
6
|
-
--
|
|
7
|
-
--
|
|
8
|
-
--
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
--tag-
|
|
12
|
-
--tag-
|
|
13
|
-
--tag-
|
|
14
|
-
--tag-
|
|
15
|
-
--tag-
|
|
22
|
+
/* Variant color tokens - WCAG AA compliant colors */
|
|
23
|
+
--beta: #fbbf24; /* Amber: 6.94:1 contrast with black */
|
|
24
|
+
--stable: #0f7c3e; /* Dark green: 4.56:1 contrast with white */
|
|
25
|
+
--production: #1e3a8a; /* Dark blue: 8.59:1 contrast with white */
|
|
26
|
+
|
|
27
|
+
/* Tag component tokens */
|
|
28
|
+
--tag-px: 0.7rem; /* Horizontal padding (11.2px at 16px base) */
|
|
29
|
+
--tag-py: 0.2rem; /* Vertical padding (3.2px at 16px base) */
|
|
30
|
+
--tag-fs: 0.8rem; /* Font size (12.8px at 16px base) */
|
|
31
|
+
--tag-radius: 99rem; /* Fully rounded pill shape */
|
|
32
|
+
--tag-bg: lightgray; /* Default background color */
|
|
33
|
+
--tag-fw: 500; /* Medium font weight */
|
|
34
|
+
--tag-color: currentColor; /* Default text color (inherits) */
|
|
35
|
+
--tag-display: inline-block;/* Display type */
|
|
16
36
|
|
|
37
|
+
/* Apply CSS custom properties */
|
|
17
38
|
display: var(--tag-display);
|
|
18
39
|
padding-inline: var(--tag-px);
|
|
19
40
|
padding-block: var(--tag-py);
|
|
@@ -22,35 +43,88 @@ small > span,
|
|
|
22
43
|
background-color: var(--tag-bg);
|
|
23
44
|
border-radius: var(--tag-radius);
|
|
24
45
|
|
|
25
|
-
|
|
26
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Focus Indicators (WCAG 2.4.7)
|
|
48
|
+
* Visible focus for keyboard navigation with 3:1 minimum contrast
|
|
49
|
+
*/
|
|
50
|
+
&:focus-visible {
|
|
51
|
+
outline: 2px solid currentColor;
|
|
52
|
+
outline-offset: 2px;
|
|
27
53
|
}
|
|
28
54
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
55
|
+
/* Remove outline for mouse users while preserving for keyboard users */
|
|
56
|
+
&:focus:not(:focus-visible) {
|
|
57
|
+
outline: none;
|
|
32
58
|
}
|
|
33
59
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Variant Modifiers
|
|
62
|
+
* Applied via data-tag attribute (e.g., data-tag="beta")
|
|
63
|
+
* Each variant includes both color AND visual symbol for accessibility (WCAG 1.4.1)
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/* Alpha variant - early development stage */
|
|
67
|
+
&[data-tag~='alpha'] {
|
|
68
|
+
--tag-color: #000000; /* Black: maximum contrast with amber background */
|
|
69
|
+
--tag-bg: var(--beta);
|
|
70
|
+
|
|
71
|
+
/* Visual indicator beyond color - warning symbol */
|
|
72
|
+
&::before {
|
|
73
|
+
content: '⚠';
|
|
74
|
+
margin-inline-end: 0.25rem;
|
|
75
|
+
font-weight: 700;
|
|
76
|
+
aria-hidden: true;
|
|
77
|
+
}
|
|
37
78
|
}
|
|
38
79
|
|
|
80
|
+
/* Beta variant - pre-release version */
|
|
39
81
|
&[data-tag~='beta'] {
|
|
40
|
-
--tag-color:
|
|
82
|
+
--tag-color: #000000; /* Black: maximum contrast with amber background */
|
|
41
83
|
--tag-bg: var(--beta);
|
|
84
|
+
|
|
85
|
+
/* Visual indicator beyond color - warning symbol */
|
|
86
|
+
&::before {
|
|
87
|
+
content: '⚠';
|
|
88
|
+
margin-inline-end: 0.25rem;
|
|
89
|
+
font-weight: 700;
|
|
90
|
+
aria-hidden: true;
|
|
91
|
+
}
|
|
42
92
|
}
|
|
43
93
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
--tag-
|
|
94
|
+
/* Stable variant - production-ready release */
|
|
95
|
+
&[data-tag~='stable'] {
|
|
96
|
+
--tag-color: #ffffff; /* White: 4.56:1 contrast with dark green */
|
|
97
|
+
--tag-bg: var(--stable);
|
|
98
|
+
|
|
99
|
+
/* Visual indicator beyond color - checkmark symbol */
|
|
100
|
+
&::before {
|
|
101
|
+
content: '✓';
|
|
102
|
+
margin-inline-end: 0.25rem;
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
aria-hidden: true;
|
|
105
|
+
}
|
|
47
106
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
107
|
+
|
|
108
|
+
/* Production variant - live environment indicator */
|
|
109
|
+
&[data-tag~='production'] {
|
|
110
|
+
--tag-color: #ffffff; /* White: 8.59:1 contrast with dark blue */
|
|
111
|
+
--tag-bg: var(--production);
|
|
112
|
+
|
|
113
|
+
/* Visual indicator beyond color - live indicator symbol */
|
|
114
|
+
&::before {
|
|
115
|
+
content: '●';
|
|
116
|
+
margin-inline-end: 0.25rem;
|
|
117
|
+
font-weight: 700;
|
|
118
|
+
aria-hidden: true;
|
|
119
|
+
}
|
|
51
120
|
}
|
|
52
121
|
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Block-level tag modifier
|
|
125
|
+
* Applied when Tag renders as <p> element
|
|
126
|
+
*/
|
|
53
127
|
p[role='note'] {
|
|
54
128
|
--tag-display: block;
|
|
55
|
-
--
|
|
129
|
+
--tag-radius: 0.5rem; /* Less rounded for block tags (8px at 16px base) */
|
|
56
130
|
}
|