@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,326 @@
|
|
|
1
|
+
# Title Component
|
|
2
|
+
|
|
3
|
+
A semantic heading component for document structure and hierarchy.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `Title` component renders semantic HTML headings (h1-h6) with proper accessibility support, ensuring WCAG 2.1 AA compliance by maintaining semantic document structure for screen readers and assistive technologies.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ✅ **Semantic HTML** - Renders actual heading elements (h1-h6) for proper document outline
|
|
12
|
+
- ✅ **Accessibility** - Full ARIA support and proper heading hierarchy
|
|
13
|
+
- ✅ **Flexible Styling** - Supports fpkit's UI system, custom classes, and inline styles
|
|
14
|
+
- ✅ **Type Safety** - Fully typed with TypeScript for excellent developer experience
|
|
15
|
+
- ✅ **Performance** - Memoized to prevent unnecessary re-renders
|
|
16
|
+
- ✅ **Ref Forwarding** - Access the underlying DOM element for focus management
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @fpkit/acss
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Basic Usage
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { Title } from '@fpkit/acss';
|
|
28
|
+
|
|
29
|
+
function MyComponent() {
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
<Title level="h1">Page Title</Title>
|
|
33
|
+
<Title level="h2">Section Heading</Title>
|
|
34
|
+
<Title level="h3">Subsection Heading</Title>
|
|
35
|
+
</>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
|------|------|---------|-------------|
|
|
44
|
+
| `level` | `"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6"` | `"h2"` | The semantic heading level to render |
|
|
45
|
+
| `children` | `React.ReactNode` | *required* | The content to display in the heading |
|
|
46
|
+
| `id` | `string` | - | Unique identifier (useful for anchor links) |
|
|
47
|
+
| `ui` | `string` | - | Data attribute for fpkit styling hooks |
|
|
48
|
+
| `className` | `string` | - | CSS class names to apply |
|
|
49
|
+
| `styles` | `React.CSSProperties` | - | Inline styles to apply |
|
|
50
|
+
| `ref` | `React.Ref<HTMLHeadingElement>` | - | Forwarded ref to the heading element |
|
|
51
|
+
|
|
52
|
+
The component also accepts all standard HTML heading attributes and ARIA properties.
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Default Usage
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<Title>This renders as h2 (default)</Title>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Page Title
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<Title level="h1">Welcome to Our Application</Title>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### With ID for Anchor Links
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<Title level="h2" id="getting-started">
|
|
72
|
+
Getting Started
|
|
73
|
+
</Title>
|
|
74
|
+
|
|
75
|
+
{/* Link to this section */}
|
|
76
|
+
<a href="#getting-started">Jump to Getting Started</a>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### With Custom Styling
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
{/* Using fpkit's UI system */}
|
|
83
|
+
<Title level="h2" ui="section-title">
|
|
84
|
+
Features Overview
|
|
85
|
+
</Title>
|
|
86
|
+
|
|
87
|
+
{/* Using CSS classes */}
|
|
88
|
+
<Title level="h2" className="text-primary font-bold">
|
|
89
|
+
Custom Styled Title
|
|
90
|
+
</Title>
|
|
91
|
+
|
|
92
|
+
{/* Using inline styles */}
|
|
93
|
+
<Title
|
|
94
|
+
level="h2"
|
|
95
|
+
styles={{ color: '#0066cc', marginBottom: '1rem' }}
|
|
96
|
+
>
|
|
97
|
+
Inline Styled Title
|
|
98
|
+
</Title>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### With ARIA Attributes
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
{/* Enhanced accessibility with aria-label */}
|
|
105
|
+
<Title level="h2" aria-label="User dashboard overview">
|
|
106
|
+
Dashboard
|
|
107
|
+
</Title>
|
|
108
|
+
|
|
109
|
+
{/* Using aria-labelledby */}
|
|
110
|
+
<>
|
|
111
|
+
<div id="section-label">Important Section</div>
|
|
112
|
+
<Title level="h2" aria-labelledby="section-label">
|
|
113
|
+
Section Content
|
|
114
|
+
</Title>
|
|
115
|
+
</>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### With Ref for Focus Management
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { useRef, useEffect } from 'react';
|
|
122
|
+
|
|
123
|
+
function AutoFocusTitle() {
|
|
124
|
+
const titleRef = useRef<HTMLHeadingElement>(null);
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
// Focus the title on mount (useful for accessibility)
|
|
128
|
+
titleRef.current?.focus();
|
|
129
|
+
}, []);
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<Title ref={titleRef} tabIndex={-1}>
|
|
133
|
+
This title receives focus
|
|
134
|
+
</Title>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Complex Content
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
<Title level="h2">
|
|
143
|
+
<Icon name="chart" aria-hidden="true" />
|
|
144
|
+
<span>Statistics Dashboard</span>
|
|
145
|
+
</Title>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Accessibility Guidelines
|
|
149
|
+
|
|
150
|
+
### WCAG 2.1 AA Compliance
|
|
151
|
+
|
|
152
|
+
The Title component helps you comply with:
|
|
153
|
+
|
|
154
|
+
- **1.3.1 Info and Relationships (Level A)** - Semantic heading elements preserve document structure
|
|
155
|
+
- **2.4.6 Headings and Labels (Level AA)** - Headings should be descriptive and properly ordered
|
|
156
|
+
- **2.4.10 Section Headings (Level AAA)** - Use headings to organize content
|
|
157
|
+
|
|
158
|
+
### Best Practices
|
|
159
|
+
|
|
160
|
+
#### ✅ DO: Maintain Proper Heading Hierarchy
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<Title level="h1">Page Title</Title>
|
|
164
|
+
<Title level="h2">Main Section</Title>
|
|
165
|
+
<Title level="h3">Subsection</Title>
|
|
166
|
+
<Title level="h4">Sub-subsection</Title>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Why?** Screen readers use heading hierarchy to build a document outline for navigation.
|
|
170
|
+
|
|
171
|
+
#### ❌ DON'T: Skip Heading Levels
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
{/* ❌ BAD: Skipping from h1 to h4 */}
|
|
175
|
+
<Title level="h1">Page Title</Title>
|
|
176
|
+
<Title level="h4">Skipped h2 and h3</Title>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Why?** This confuses screen reader users and violates WCAG guidelines.
|
|
180
|
+
|
|
181
|
+
#### ✅ DO: Use One h1 Per Page
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
<Title level="h1">Main Page Title</Title>
|
|
185
|
+
{/* Only one h1 per page */}
|
|
186
|
+
<Title level="h2">Section 1</Title>
|
|
187
|
+
<Title level="h2">Section 2</Title>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Why?** Multiple h1 elements can confuse users about the page's main purpose.
|
|
191
|
+
|
|
192
|
+
#### ✅ DO: Make Headings Descriptive
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
{/* ✅ GOOD: Descriptive */}
|
|
196
|
+
<Title level="h2">User Account Settings</Title>
|
|
197
|
+
|
|
198
|
+
{/* ❌ BAD: Vague */}
|
|
199
|
+
<Title level="h2">Settings</Title>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Why?** Users navigating by headings need context to understand each section.
|
|
203
|
+
|
|
204
|
+
#### ✅ DO: Avoid Empty or Meaningless Headings
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
{/* ❌ BAD: No meaningful content */}
|
|
208
|
+
<Title level="h2"> </Title>
|
|
209
|
+
|
|
210
|
+
{/* ✅ GOOD: Clear content */}
|
|
211
|
+
<Title level="h2">Contact Information</Title>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Performance Considerations
|
|
215
|
+
|
|
216
|
+
The Title component is wrapped with `React.memo`, which prevents re-renders when parent components update if the props haven't changed.
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
// This will only re-render when `title` prop changes
|
|
220
|
+
function ParentComponent({ title, someOtherState }) {
|
|
221
|
+
return (
|
|
222
|
+
<>
|
|
223
|
+
<Title level="h2">{title}</Title>
|
|
224
|
+
<p>{someOtherState}</p>
|
|
225
|
+
</>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## TypeScript
|
|
231
|
+
|
|
232
|
+
The component is fully typed with comprehensive TypeScript support:
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
import { Title, type TitleProps, type HeadingLevel } from '@fpkit/acss';
|
|
236
|
+
|
|
237
|
+
// Custom wrapper with additional props
|
|
238
|
+
interface SectionTitleProps extends TitleProps {
|
|
239
|
+
highlighted?: boolean;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function SectionTitle({ highlighted, ...props }: SectionTitleProps) {
|
|
243
|
+
return (
|
|
244
|
+
<Title
|
|
245
|
+
{...props}
|
|
246
|
+
className={highlighted ? 'highlighted' : ''}
|
|
247
|
+
/>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Type-safe heading level
|
|
252
|
+
const level: HeadingLevel = 'h2';
|
|
253
|
+
<Title level={level}>Typed Title</Title>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Migration from Heading Component
|
|
257
|
+
|
|
258
|
+
If you're migrating from the deprecated `Heading` component, follow these steps:
|
|
259
|
+
|
|
260
|
+
### Step 1: Update Imports
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
// Before:
|
|
264
|
+
import { Heading } from '@fpkit/acss';
|
|
265
|
+
|
|
266
|
+
// After:
|
|
267
|
+
import { Title } from '@fpkit/acss';
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Step 2: Update Component Name and Props
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
// Before:
|
|
274
|
+
<Heading type="h2">Section Title</Heading>
|
|
275
|
+
|
|
276
|
+
// After:
|
|
277
|
+
<Title level="h2">Section Title</Title>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Step 3: Update Default Behavior
|
|
281
|
+
|
|
282
|
+
The default heading level changed from `h3` to `h2`:
|
|
283
|
+
|
|
284
|
+
```tsx
|
|
285
|
+
// Before (rendered as h3):
|
|
286
|
+
<Heading>Default Heading</Heading>
|
|
287
|
+
|
|
288
|
+
// After (renders as h2):
|
|
289
|
+
<Title>Default Title</Title>
|
|
290
|
+
|
|
291
|
+
// To maintain h3 behavior explicitly:
|
|
292
|
+
<Title level="h3">Default Title</Title>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Automated Migration
|
|
296
|
+
|
|
297
|
+
You can use a codemod or find-and-replace:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# Find all instances
|
|
301
|
+
grep -r "Heading" src/
|
|
302
|
+
|
|
303
|
+
# Replace in files (review changes before committing!)
|
|
304
|
+
find src/ -type f -name "*.tsx" -exec sed -i '' 's/<Heading/<Title/g' {} +
|
|
305
|
+
find src/ -type f -name "*.tsx" -exec sed -i '' 's/type="/level="/g' {} +
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Deprecation Timeline
|
|
309
|
+
|
|
310
|
+
- **Current**: `Heading` component works but logs warnings in development
|
|
311
|
+
- **v3.0.0**: `Heading` component will be removed
|
|
312
|
+
|
|
313
|
+
## Related Components
|
|
314
|
+
|
|
315
|
+
- **Text** - For body text and paragraphs
|
|
316
|
+
- **UI** - The underlying polymorphic component
|
|
317
|
+
|
|
318
|
+
## Support
|
|
319
|
+
|
|
320
|
+
For issues, questions, or contributions, visit:
|
|
321
|
+
- GitHub: [fpkit/acss](https://github.com/fpkit/acss)
|
|
322
|
+
- Documentation: [fpkit.dev](https://fpkit.dev)
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
MIT © FirstPaint
|