@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
|
@@ -1,25 +1,122 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import UI from '#components/ui'
|
|
3
|
+
import type { TagProps, TagVariant } from './tag.types'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Tag - A small inline label component for displaying status, versions, or environment indicators
|
|
7
|
+
*
|
|
8
|
+
* The Tag component is used to highlight supplementary information such as release stages
|
|
9
|
+
* (alpha, beta, stable), environment indicators (production), or version labels. It renders
|
|
10
|
+
* as either a `<span>` (inline) or `<p>` (block) element with semantic ARIA roles.
|
|
11
|
+
*
|
|
12
|
+
* ## Design Philosophy
|
|
13
|
+
*
|
|
14
|
+
* Tags serve as visual and semantic indicators that:
|
|
15
|
+
* - Communicate the state or stage of features, releases, or environments
|
|
16
|
+
* - Provide quick visual scanning through color-coded variants
|
|
17
|
+
* - Maintain accessibility through proper ARIA roles and labels
|
|
18
|
+
*
|
|
19
|
+
* ## Styling Architecture
|
|
20
|
+
*
|
|
21
|
+
* The Tag component uses CSS custom properties (CSS variables) for theming and styling,
|
|
22
|
+
* allowing for easy customization through the `data-tag` attribute. Each variant
|
|
23
|
+
* (alpha, beta, stable, production) applies predefined color schemes defined in SCSS.
|
|
24
|
+
*
|
|
25
|
+
* ## Accessibility Considerations (WCAG 2.1 AA Compliance)
|
|
26
|
+
*
|
|
27
|
+
* - **Semantic Roles**: Uses `role="note"` for static tags or `role="status"` for dynamic content
|
|
28
|
+
* - `role="note"`: Read once by screen readers, suitable for static labels (default)
|
|
29
|
+
* - `role="status"`: Announces updates to screen readers, use for changing status indicators
|
|
30
|
+
* - **Color Independence**: Don't rely solely on color to convey meaning - include text labels
|
|
31
|
+
* - **Text Alternatives**: For icon-only tags, provide `aria-label` for screen reader context
|
|
32
|
+
* - **Contrast Ratios**: All variants meet WCAG AA contrast requirements (4.5:1 for normal text)
|
|
33
|
+
* - **Live Regions**: When using `role="status"`, tag becomes a live region for accessibility
|
|
34
|
+
*
|
|
35
|
+
* ## When to Use Each Role
|
|
36
|
+
*
|
|
37
|
+
* **Use `role="note"` (default) when:**
|
|
38
|
+
* - Displaying static version numbers (e.g., "v2.1.0")
|
|
39
|
+
* - Showing fixed environment indicators (e.g., "Beta Feature")
|
|
40
|
+
* - Labeling unchanging content categories
|
|
41
|
+
*
|
|
42
|
+
* **Use `role="status"` when:**
|
|
43
|
+
* - Indicating real-time status that may change (e.g., "Processing" → "Complete")
|
|
44
|
+
* - Displaying live build/deployment states
|
|
45
|
+
* - Showing dynamic feature flags that toggle
|
|
46
|
+
*
|
|
47
|
+
* @param {TagProps} props - Component props
|
|
48
|
+
* @returns {React.ReactElement} A Tag component
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Basic tag with beta variant (default inline span)
|
|
52
|
+
* <Tag variant="beta">Beta</Tag>
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // Production environment indicator as block element
|
|
56
|
+
* <Tag elm="p" variant="production">Production Environment</Tag>
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Dynamic status tag with live updates
|
|
60
|
+
* <Tag role="status" variant="stable">
|
|
61
|
+
* {isDeployed ? 'Deployed' : 'Deploying...'}
|
|
62
|
+
* </Tag>
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* // Tag with custom styling and accessibility label
|
|
66
|
+
* <Tag
|
|
67
|
+
* variant="alpha"
|
|
68
|
+
* aria-label="Alpha version - may contain bugs"
|
|
69
|
+
* styles={{ fontSize: '0.75rem' }}
|
|
70
|
+
* >
|
|
71
|
+
* Alpha
|
|
72
|
+
* </Tag>
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* // ✅ GOOD: Clear text content with variant for visual enhancement
|
|
76
|
+
* <Tag variant="stable">v2.0 Stable</Tag>
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* // ✅ GOOD: Dynamic status with proper role
|
|
80
|
+
* <Tag role="status" variant="production">{deploymentStatus}</Tag>
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* // ✅ GOOD: Accessible tag with descriptive label
|
|
84
|
+
* <Tag variant="beta" aria-label="Beta feature - feedback welcome">
|
|
85
|
+
* Beta
|
|
86
|
+
* </Tag>
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* // ❌ BAD: Relying only on color without text
|
|
90
|
+
* <Tag variant="production" aria-label="Production" />
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* // ❌ BAD: Using status role for static content
|
|
94
|
+
* <Tag role="status" variant="stable">v1.0</Tag>
|
|
95
|
+
*/
|
|
11
96
|
export const Tag = ({
|
|
12
97
|
elm = 'span',
|
|
13
98
|
role = 'note',
|
|
99
|
+
variant,
|
|
14
100
|
children,
|
|
15
101
|
styles,
|
|
16
102
|
...props
|
|
17
103
|
}: TagProps) => {
|
|
104
|
+
// Map variant to data-tag attribute for SCSS styling
|
|
105
|
+
const dataTag = variant ? variant : undefined
|
|
106
|
+
|
|
18
107
|
return (
|
|
19
|
-
<UI
|
|
108
|
+
<UI
|
|
109
|
+
as={elm}
|
|
110
|
+
role={role}
|
|
111
|
+
data-tag={dataTag}
|
|
112
|
+
styles={styles}
|
|
113
|
+
{...props}
|
|
114
|
+
>
|
|
20
115
|
{children}
|
|
21
116
|
</UI>
|
|
22
117
|
)
|
|
23
118
|
}
|
|
24
|
-
|
|
119
|
+
|
|
25
120
|
Tag.displayName = 'Tag'
|
|
121
|
+
export default Tag
|
|
122
|
+
export type { TagProps, TagVariant }
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import UI from '#components/ui'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Available visual variants for the Tag component
|
|
6
|
+
*
|
|
7
|
+
* Each variant applies predefined color schemes and styling through CSS custom properties:
|
|
8
|
+
* - `alpha`: Early development stage indicator (warning colors)
|
|
9
|
+
* - `beta`: Pre-release version indicator (warning colors)
|
|
10
|
+
* - `stable`: Production-ready release indicator (success colors)
|
|
11
|
+
* - `production`: Live production environment indicator (primary colors)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Tag variant="beta">Beta Feature</Tag>
|
|
16
|
+
* <Tag variant="stable">v2.0</Tag>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export type TagVariant = 'alpha' | 'beta' | 'stable' | 'production'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Props for the Tag component
|
|
23
|
+
*
|
|
24
|
+
* @property {React.ReactNode} children - REQUIRED - Content to display inside the tag (typically short text or version numbers)
|
|
25
|
+
* @property {'span' | 'p'} [elm='span'] - HTML element to render the tag as. Use 'p' for block-level tags, 'span' for inline
|
|
26
|
+
* @property {'note' | 'status'} [role='note'] - ARIA role for semantic meaning and screen reader announcements
|
|
27
|
+
* @property {TagVariant} [variant] - Visual variant that applies predefined color schemes (alpha, beta, stable, production)
|
|
28
|
+
* @property {string} [id] - Optional HTML id attribute for the tag element
|
|
29
|
+
* @property {React.CSSProperties} [styles] - Inline styles to apply to the tag
|
|
30
|
+
* @property {string} [classes] - CSS class names to apply to the tag
|
|
31
|
+
* @property {string} [aria-label] - Accessible label for screen readers. Recommended when tag content needs additional context
|
|
32
|
+
* @property {string} [aria-labelledby] - Reference to element(s) that label the tag for additional context
|
|
33
|
+
* @property {string} [aria-describedby] - Reference to element(s) that describe the tag for additional context
|
|
34
|
+
* @property {'off' | 'polite' | 'assertive'} [aria-live] - ARIA live region politeness setting for dynamic content (use with role="status")
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // Basic tag with variant
|
|
39
|
+
* <Tag variant="beta">Beta</Tag>
|
|
40
|
+
*
|
|
41
|
+
* // Tag with custom element and role
|
|
42
|
+
* <Tag elm="p" role="status" variant="stable">v1.0 Released</Tag>
|
|
43
|
+
*
|
|
44
|
+
* // Tag with accessibility label
|
|
45
|
+
* <Tag variant="production" aria-label="Currently in production environment">
|
|
46
|
+
* Production
|
|
47
|
+
* </Tag>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export type TagProps = {
|
|
51
|
+
/**
|
|
52
|
+
* HTML element to display the tag as
|
|
53
|
+
* - 'span': Inline tag (default) - use for inline placement within text flow
|
|
54
|
+
* - 'p': Block-level tag - use when tag should appear as a distinct block element
|
|
55
|
+
*/
|
|
56
|
+
elm?: 'span' | 'p'
|
|
57
|
+
/**
|
|
58
|
+
* ARIA role for semantic meaning and screen reader behavior
|
|
59
|
+
* - 'note': For static, informational tags (default) - screen readers read once
|
|
60
|
+
* - 'status': For dynamic tags that update - screen readers announce changes to users
|
|
61
|
+
*
|
|
62
|
+
* Choose 'status' when tag content changes dynamically (e.g., real-time status updates).
|
|
63
|
+
* Choose 'note' for static tags that provide contextual information.
|
|
64
|
+
*/
|
|
65
|
+
role?: 'note' | 'status'
|
|
66
|
+
/**
|
|
67
|
+
* Visual variant that applies predefined color schemes
|
|
68
|
+
* - 'alpha': Early development stage (amber background with warning symbol ⚠)
|
|
69
|
+
* - 'beta': Pre-release version (amber background with warning symbol ⚠)
|
|
70
|
+
* - 'stable': Production-ready release (green background with checkmark ✓)
|
|
71
|
+
* - 'production': Live production environment (blue background with live indicator ●)
|
|
72
|
+
*
|
|
73
|
+
* Each variant includes both color AND visual symbols for accessibility (WCAG 1.4.1).
|
|
74
|
+
*/
|
|
75
|
+
variant?: TagVariant
|
|
76
|
+
/**
|
|
77
|
+
* Content to display inside the tag
|
|
78
|
+
* REQUIRED - Ensures tag has meaningful content for all users including screen reader users
|
|
79
|
+
* Typically short text, version numbers, or status labels
|
|
80
|
+
*/
|
|
81
|
+
children: React.ReactNode
|
|
82
|
+
/**
|
|
83
|
+
* Accessible label for screen readers
|
|
84
|
+
* Provides additional context beyond visible text
|
|
85
|
+
*/
|
|
86
|
+
'aria-label'?: string
|
|
87
|
+
/**
|
|
88
|
+
* Reference to element(s) that label the tag
|
|
89
|
+
* Alternative to aria-label for programmatic labeling
|
|
90
|
+
*/
|
|
91
|
+
'aria-labelledby'?: string
|
|
92
|
+
/**
|
|
93
|
+
* Reference to element(s) that describe the tag
|
|
94
|
+
* Provides additional descriptive context
|
|
95
|
+
*/
|
|
96
|
+
'aria-describedby'?: string
|
|
97
|
+
/**
|
|
98
|
+
* ARIA live region politeness setting
|
|
99
|
+
* - 'off': Updates not announced (default)
|
|
100
|
+
* - 'polite': Announces when user is idle (recommended for role="status")
|
|
101
|
+
* - 'assertive': Announces immediately (use sparingly for critical updates)
|
|
102
|
+
*/
|
|
103
|
+
'aria-live'?: 'off' | 'polite' | 'assertive'
|
|
104
|
+
} & Omit<
|
|
105
|
+
React.ComponentProps<typeof UI>,
|
|
106
|
+
'as' | 'aria-label' | 'aria-labelledby' | 'aria-describedby' | 'aria-live'
|
|
107
|
+
>
|
package/src/components/ui.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import React from "react";
|
|
|
7
7
|
*
|
|
8
8
|
* This utility type ensures that refs are properly typed based on the element
|
|
9
9
|
* being rendered. For example, a button element receives HTMLButtonElement ref.
|
|
10
|
+
* Excludes legacy string refs (deprecated since React 16.3).
|
|
10
11
|
*
|
|
11
12
|
* @typeParam C - The HTML element type (e.g., 'button', 'div', 'a')
|
|
12
13
|
* @example
|
|
@@ -15,8 +16,9 @@ import React from "react";
|
|
|
15
16
|
* type DivRef = PolymorphicRef<'div'>; // React.Ref<HTMLDivElement>
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
|
-
type PolymorphicRef<C extends React.ElementType> =
|
|
19
|
-
React.
|
|
19
|
+
type PolymorphicRef<C extends React.ElementType> = React.Ref<
|
|
20
|
+
React.ElementRef<C>
|
|
21
|
+
>;
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* Defines the 'as' prop that determines which HTML element to render.
|
|
@@ -74,6 +76,9 @@ type PolymorphicComponentProp<
|
|
|
74
76
|
* to match the element being rendered, enabling focus management and direct
|
|
75
77
|
* DOM access for accessibility features like programmatic focus control.
|
|
76
78
|
*
|
|
79
|
+
* Supports both PolymorphicRef and ForwardedRef for compatibility with
|
|
80
|
+
* React.forwardRef components.
|
|
81
|
+
*
|
|
77
82
|
* @typeParam C - The HTML element type
|
|
78
83
|
* @typeParam Props - The custom props to add
|
|
79
84
|
*
|
|
@@ -93,7 +98,7 @@ type PolymorphicComponentPropWithRef<
|
|
|
93
98
|
C extends React.ElementType,
|
|
94
99
|
Props = {},
|
|
95
100
|
> = PolymorphicComponentProp<C, Props> & {
|
|
96
|
-
ref?: PolymorphicRef<C
|
|
101
|
+
ref?: PolymorphicRef<C> | React.ForwardedRef<React.ElementRef<C>>;
|
|
97
102
|
};
|
|
98
103
|
|
|
99
104
|
/**
|