@fpkit/acss 0.6.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/docs/README.md +325 -0
- package/docs/guides/accessibility.md +764 -0
- package/docs/guides/architecture.md +705 -0
- package/docs/guides/composition.md +688 -0
- package/docs/guides/css-variables.md +522 -0
- package/docs/guides/storybook.md +828 -0
- package/docs/guides/testing.md +817 -0
- package/docs/testing/focus-indicator-testing.md +437 -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.css +1 -1
- package/libs/components/breadcrumbs/breadcrumb.css.map +1 -1
- package/libs/components/breadcrumbs/breadcrumb.min.css +2 -2
- 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/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.css +1 -1
- package/libs/components/dialog/dialog.css.map +1 -1
- package/libs/components/dialog/dialog.min.css +2 -2
- package/libs/components/form/form.css +1 -1
- package/libs/components/form/form.css.map +1 -1
- package/libs/components/form/form.min.css +2 -2
- 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/layout/landmarks.css +1 -1
- package/libs/components/layout/landmarks.css.map +1 -1
- package/libs/components/layout/landmarks.min.css +2 -2
- package/libs/components/link/link.css +1 -1
- package/libs/components/link/link.css.map +1 -1
- package/libs/components/link/link.min.css +2 -2
- package/libs/components/list/list.css +1 -1
- package/libs/components/list/list.min.css +1 -1
- package/libs/components/nav/nav.css +1 -1
- package/libs/components/nav/nav.css.map +1 -1
- package/libs/components/nav/nav.min.css +2 -2
- package/libs/components/progress/progress.css +1 -1
- package/libs/components/progress/progress.css.map +1 -1
- package/libs/components/progress/progress.min.css +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/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/package.json +4 -3
- package/src/components/README.mdx +1 -1
- package/src/components/alert/alert.scss +4 -4
- package/src/components/alert/alert.scss.backup +184 -0
- package/src/components/alert/alert.stories.tsx +53 -2
- package/src/components/badge/badge.scss +2 -2
- package/src/components/badge/badge.scss.backup +39 -0
- package/src/components/badge/badge.stories.tsx +40 -0
- package/src/components/breadcrumbs/breadcrumb.scss +5 -5
- package/src/components/breadcrumbs/breadcrumb.scss.backup +35 -0
- package/src/components/breadcrumbs/breadcrumb.stories.tsx +17 -1
- package/src/components/buttons/button.scss +32 -27
- package/src/components/buttons/button.scss.backup +145 -0
- package/src/components/buttons/button.stories.tsx +196 -7
- package/src/components/cards/card.scss +39 -5
- package/src/components/cards/card.scss.backup +67 -0
- package/src/components/cards/card.stories.tsx +184 -1
- package/src/components/details/details.scss +14 -14
- package/src/components/details/details.scss.backup +126 -0
- package/src/components/details/details.stories.tsx +41 -1
- package/src/components/dialog/dialog.scss +3 -3
- package/src/components/dialog/dialog.scss.backup +126 -0
- package/src/components/form/form.scss +25 -9
- package/src/components/form/form.scss.backup +87 -0
- package/src/components/form/form.stories.tsx +272 -1
- package/src/components/form/input.stories.tsx +159 -1
- package/src/components/form/select.stories.tsx +1 -1
- package/src/components/heading/README.mdx +292 -0
- package/src/components/icons/icon.stories.tsx +1 -1
- package/src/components/images/figure.stories.tsx +41 -1
- package/src/components/images/img.scss +8 -8
- package/src/components/images/img.scss.backup +59 -0
- package/src/components/layout/_header.scss +14 -14
- package/src/components/layout/_header.scss.backup +72 -0
- package/src/components/layout/landmarks.scss +7 -7
- package/src/components/layout/landmarks.scss.backup +51 -0
- package/src/components/layout/landmarks.stories.tsx +42 -0
- package/src/components/link/link.scss +5 -5
- package/src/components/link/link.scss.backup +145 -0
- package/src/components/link/link.stories.tsx +38 -2
- package/src/components/list/list.scss +1 -1
- package/src/components/nav/nav.scss +17 -17
- package/src/components/nav/nav.scss.backup +123 -0
- package/src/components/nav/nav.stories.tsx +36 -2
- package/src/components/progress/progress.scss +7 -7
- package/src/components/progress/progress.scss.backup +70 -0
- package/src/components/tag/tag.scss +10 -10
- package/src/components/tag/tag.scss.backup +130 -0
- package/src/components/tag/tag.stories.tsx +23 -2
- package/src/components/ui.stories.tsx +53 -19
- package/src/docs/accessibility.mdx +484 -0
- package/src/docs/composition.mdx +549 -0
- package/src/docs/css-variables.mdx +380 -0
- package/src/docs/fpkit-developer.mdx +545 -0
- package/src/introduction.mdx +356 -0
- package/src/styles/alert/alert.css +4 -4
- package/src/styles/badge/badge.css +2 -2
- package/src/styles/breadcrumbs/breadcrumb.css +5 -5
- package/src/styles/buttons/button.css +30 -27
- package/src/styles/buttons/button.css.map +1 -1
- package/src/styles/cards/card.css +35 -5
- package/src/styles/cards/card.css.map +1 -1
- package/src/styles/details/details.css +14 -14
- package/src/styles/dialog/dialog.css +3 -3
- package/src/styles/form/form.css +20 -10
- package/src/styles/form/form.css.map +1 -1
- package/src/styles/images/img.css +8 -8
- package/src/styles/index.css +179 -134
- package/src/styles/index.css.map +1 -1
- package/src/styles/layout/landmarks.css +21 -21
- package/src/styles/link/link.css +5 -5
- package/src/styles/list/list.css +1 -1
- package/src/styles/nav/nav.css +17 -17
- package/src/styles/progress/progress.css +6 -6
- package/src/styles/tag/tag.css +4 -4
- package/src/styles/utilities/_disabled.scss +5 -4
|
@@ -15,6 +15,48 @@ import Img from "#components/images/img";
|
|
|
15
15
|
const meta: Meta<typeof Header> = {
|
|
16
16
|
title: "FP.React Components/Layout/Landmarks",
|
|
17
17
|
component: Header,
|
|
18
|
+
parameters: {
|
|
19
|
+
docs: {
|
|
20
|
+
description: {
|
|
21
|
+
component: `Semantic landmark components including Header (banner), Main, and Footer with responsive content layout.
|
|
22
|
+
|
|
23
|
+
## CSS Variables (Header/Overlay)
|
|
24
|
+
|
|
25
|
+
### Layout & Display
|
|
26
|
+
- \`--overlay-display\`: Display mode (default: grid)
|
|
27
|
+
- \`--overlay-grid-area\`: Grid area name (default: overlay)
|
|
28
|
+
- \`--overlay-placement\`: Item placement (default: center)
|
|
29
|
+
|
|
30
|
+
### Sizing
|
|
31
|
+
- \`--overlay-width\`: Overlay width (default: 100%)
|
|
32
|
+
- \`--overlay-height\`: Minimum overlay height (default: 40vh)
|
|
33
|
+
- \`--overlay-max-height\`: Maximum overlay height (default: 500px)
|
|
34
|
+
- \`--overlay-content-width\`: Content max width (default: 80%)
|
|
35
|
+
|
|
36
|
+
### Spacing
|
|
37
|
+
- \`--overlay-padding\`: General padding (default: 2rem)
|
|
38
|
+
- \`--overlay-padding-inline\`: Horizontal padding (default: auto)
|
|
39
|
+
- \`--overlay-padding-block\`: Vertical padding (default: auto)
|
|
40
|
+
- \`--overlay-margin-inline\`: Horizontal margin (default: auto)
|
|
41
|
+
- \`--overlay-margin-block\`: Vertical margin (default: auto)
|
|
42
|
+
- \`--overlay-gap\`: Gap between elements (default: 2rem)
|
|
43
|
+
|
|
44
|
+
### Colors & Typography
|
|
45
|
+
- \`--overlay-color\`: Text color (default: currentColor)
|
|
46
|
+
- \`--overlay-bg\`: Background color (default: whitesmoke)
|
|
47
|
+
- \`--header-line-height\`: Heading line height (default: 1.1)
|
|
48
|
+
|
|
49
|
+
## CSS Variables (Main/Footer)
|
|
50
|
+
|
|
51
|
+
### Content Layout
|
|
52
|
+
- \`--content-width\`: Max content width (default: min(100%, 1480px))
|
|
53
|
+
- \`--content-margin-inline\`: Horizontal margin for centering (default: auto)
|
|
54
|
+
- \`--content-padding-inline\`: Horizontal padding (default: 1rem)
|
|
55
|
+
- \`--content-gap\`: Gap between article and aside (default: 2rem)
|
|
56
|
+
`,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
18
60
|
args: {
|
|
19
61
|
children: "Default Header",
|
|
20
62
|
"data-testid": "banner",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
a[href] {
|
|
16
16
|
// Color & Typography
|
|
17
17
|
--link-color: #085ab7;
|
|
18
|
-
--link-
|
|
18
|
+
--link-fw: 400;
|
|
19
19
|
--link-fs: 1rem;
|
|
20
20
|
|
|
21
21
|
// Text Decoration
|
|
@@ -29,8 +29,8 @@ a[href] {
|
|
|
29
29
|
--link-radius: 0.25rem;
|
|
30
30
|
|
|
31
31
|
// Spacing (for button variants)
|
|
32
|
-
--link-
|
|
33
|
-
--link-
|
|
32
|
+
--link-padding-inline: 0;
|
|
33
|
+
--link-padding-block: 0;
|
|
34
34
|
|
|
35
35
|
// Transitions
|
|
36
36
|
--link-transition: all 0.75s ease-in-out;
|
|
@@ -44,7 +44,7 @@ a[href] {
|
|
|
44
44
|
// Apply base styles
|
|
45
45
|
color: var(--link-color);
|
|
46
46
|
font-size: var(--link-fs);
|
|
47
|
-
font-weight: var(--link-
|
|
47
|
+
font-weight: var(--link-fw);
|
|
48
48
|
text-decoration: var(--link-decoration);
|
|
49
49
|
text-underline-offset: var(--link-decoration-offset);
|
|
50
50
|
text-decoration-thickness: var(--link-decoration-thickness);
|
|
@@ -56,7 +56,7 @@ a[href] {
|
|
|
56
56
|
// Ensure child elements inherit weight/style
|
|
57
57
|
> i,
|
|
58
58
|
> b {
|
|
59
|
-
font-weight: var(--link-
|
|
59
|
+
font-weight: var(--link-fw);
|
|
60
60
|
font-style: normal;
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
@use '../../sass/mixins';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Link Component Styles
|
|
5
|
+
*
|
|
6
|
+
* Provides accessible, customizable link styles using CSS custom properties.
|
|
7
|
+
* Supports standard text links, button-styled links, and pill variants.
|
|
8
|
+
*
|
|
9
|
+
* WCAG 2.1 AA Compliance:
|
|
10
|
+
* - Focus indicators meet 2.4.7 (3:1 contrast minimum)
|
|
11
|
+
* - Color contrast meets 1.4.3 (4.5:1 for normal text)
|
|
12
|
+
* - Uses :focus-visible for better UX (keyboard vs mouse)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
a[href] {
|
|
16
|
+
// Color & Typography
|
|
17
|
+
--link-color: #085ab7;
|
|
18
|
+
--link-weight: 400;
|
|
19
|
+
--link-fs: 1rem;
|
|
20
|
+
|
|
21
|
+
// Text Decoration
|
|
22
|
+
--link-decoration: none;
|
|
23
|
+
--link-decoration-offset: 0.09375rem; // 1.5px converted to rem
|
|
24
|
+
--link-decoration-thickness: 0.0625rem; // 1px converted to rem
|
|
25
|
+
--link-skip-ink: auto;
|
|
26
|
+
|
|
27
|
+
// Background & Border
|
|
28
|
+
--link-bg: transparent;
|
|
29
|
+
--link-radius: 0.25rem;
|
|
30
|
+
|
|
31
|
+
// Spacing (for button variants)
|
|
32
|
+
--link-px: 0;
|
|
33
|
+
--link-py: 0;
|
|
34
|
+
|
|
35
|
+
// Transitions
|
|
36
|
+
--link-transition: all 0.75s ease-in-out;
|
|
37
|
+
|
|
38
|
+
// Focus Indicator (WCAG 2.4.7 - 3:1 contrast minimum)
|
|
39
|
+
--link-focus-color: currentColor;
|
|
40
|
+
--link-focus-width: 0.125rem; // 2px
|
|
41
|
+
--link-focus-offset: 0.125rem; // 2px
|
|
42
|
+
--link-focus-style: solid;
|
|
43
|
+
|
|
44
|
+
// Apply base styles
|
|
45
|
+
color: var(--link-color);
|
|
46
|
+
font-size: var(--link-fs);
|
|
47
|
+
font-weight: var(--link-weight);
|
|
48
|
+
text-decoration: var(--link-decoration);
|
|
49
|
+
text-underline-offset: var(--link-decoration-offset);
|
|
50
|
+
text-decoration-thickness: var(--link-decoration-thickness);
|
|
51
|
+
text-decoration-skip-ink: var(--link-skip-ink);
|
|
52
|
+
background-color: var(--link-bg);
|
|
53
|
+
border-radius: var(--link-radius);
|
|
54
|
+
transition: var(--link-transition);
|
|
55
|
+
|
|
56
|
+
// Ensure child elements inherit weight/style
|
|
57
|
+
> i,
|
|
58
|
+
> b {
|
|
59
|
+
font-weight: var(--link-weight);
|
|
60
|
+
font-style: normal;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Hover state - add underline for clarity
|
|
64
|
+
&:hover {
|
|
65
|
+
--link-decoration: underline;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Focus state - WCAG 2.4.7 compliant focus indicator
|
|
69
|
+
&:focus {
|
|
70
|
+
outline: var(--link-focus-width) var(--link-focus-style)
|
|
71
|
+
var(--link-focus-color);
|
|
72
|
+
outline-offset: var(--link-focus-offset);
|
|
73
|
+
--link-decoration: underline;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Focus-visible for better UX (only show outline on keyboard focus)
|
|
77
|
+
&:focus-visible {
|
|
78
|
+
outline: var(--link-focus-width) var(--link-focus-style)
|
|
79
|
+
var(--link-focus-color);
|
|
80
|
+
outline-offset: var(--link-focus-offset);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Visited and active states
|
|
84
|
+
&:visited,
|
|
85
|
+
&:active {
|
|
86
|
+
--link-color: currentColor;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Button-styled links (via <b> wrapper, data-btn attribute, or <i> for pill)
|
|
90
|
+
&:has(> b),
|
|
91
|
+
&[data-btn],
|
|
92
|
+
&:has(> i) {
|
|
93
|
+
--link-button-color: var(--link-color);
|
|
94
|
+
--link-bg: transparent;
|
|
95
|
+
--link-decoration: none;
|
|
96
|
+
--link-border-width: 0.125rem; // 2px
|
|
97
|
+
--link-border-color: currentColor;
|
|
98
|
+
--link-border-style: solid;
|
|
99
|
+
--link-fs: 0.9rem;
|
|
100
|
+
|
|
101
|
+
color: var(--link-button-color);
|
|
102
|
+
background-color: var(--link-bg);
|
|
103
|
+
font-style: normal;
|
|
104
|
+
font-size: var(--link-fs);
|
|
105
|
+
padding-inline: var(--link-fs);
|
|
106
|
+
padding-block: calc(var(--link-fs) - 0.4rem);
|
|
107
|
+
border-radius: var(--link-radius, 99rem);
|
|
108
|
+
display: inline-flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
justify-content: center;
|
|
111
|
+
outline: var(--link-border-width) var(--link-border-color)
|
|
112
|
+
var(--link-border-style);
|
|
113
|
+
|
|
114
|
+
// Focus state for button links
|
|
115
|
+
&:focus,
|
|
116
|
+
&:focus-visible {
|
|
117
|
+
outline: var(--link-border-width) var(--link-border-color)
|
|
118
|
+
var(--link-border-style);
|
|
119
|
+
outline-offset: var(--link-focus-offset);
|
|
120
|
+
--link-decoration: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Hover state for button links
|
|
124
|
+
&:hover {
|
|
125
|
+
--link-decoration: none;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Apply scale transition from mixins
|
|
129
|
+
@include mixins.scale-transitions;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Pill variant (rounded corners)
|
|
133
|
+
&[data-link~='pill'],
|
|
134
|
+
&:has(> i) {
|
|
135
|
+
--link-radius: 99rem;
|
|
136
|
+
--link-decoration: none;
|
|
137
|
+
font-style: normal;
|
|
138
|
+
|
|
139
|
+
&:hover,
|
|
140
|
+
&:focus,
|
|
141
|
+
&:focus-visible {
|
|
142
|
+
--link-decoration: none;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -39,8 +39,44 @@ const meta = {
|
|
|
39
39
|
parameters: {
|
|
40
40
|
docs: {
|
|
41
41
|
description: {
|
|
42
|
-
component:
|
|
43
|
-
|
|
42
|
+
component: `A semantic, accessible anchor component with enhanced security for external links and flexible styling variants.
|
|
43
|
+
|
|
44
|
+
## CSS Variables
|
|
45
|
+
|
|
46
|
+
### Typography & Color
|
|
47
|
+
- \`--link-color\`: Link text color (default: #085ab7)
|
|
48
|
+
- \`--link-fw\`: Font weight (default: 400)
|
|
49
|
+
- \`--link-fs\`: Font size (default: 1rem)
|
|
50
|
+
|
|
51
|
+
### Text Decoration
|
|
52
|
+
- \`--link-decoration\`: Text decoration style (default: none, underline on hover/focus)
|
|
53
|
+
- \`--link-decoration-offset\`: Underline offset (default: 0.09375rem / 1.5px)
|
|
54
|
+
- \`--link-decoration-thickness\`: Underline thickness (default: 0.0625rem / 1px)
|
|
55
|
+
- \`--link-skip-ink\`: Text decoration skip ink (default: auto)
|
|
56
|
+
|
|
57
|
+
### Background & Border
|
|
58
|
+
- \`--link-bg\`: Background color (default: transparent)
|
|
59
|
+
- \`--link-radius\`: Border radius (default: 0.25rem, 99rem for pills)
|
|
60
|
+
|
|
61
|
+
### Spacing (Button Variants)
|
|
62
|
+
- \`--link-padding-inline\`: Horizontal padding (default: 0, calculated for button variants)
|
|
63
|
+
- \`--link-padding-block\`: Vertical padding (default: 0, calculated for button variants)
|
|
64
|
+
|
|
65
|
+
### Focus Indicators (WCAG 2.4.7)
|
|
66
|
+
- \`--link-focus-color\`: Focus outline color (default: currentColor)
|
|
67
|
+
- \`--link-focus-width\`: Focus outline width (default: 0.125rem / 2px)
|
|
68
|
+
- \`--link-focus-offset\`: Focus outline offset (default: 0.125rem / 2px)
|
|
69
|
+
- \`--link-focus-style\`: Focus outline style (default: solid)
|
|
70
|
+
|
|
71
|
+
### Transitions
|
|
72
|
+
- \`--link-transition\`: Transition timing (default: all 0.75s ease-in-out)
|
|
73
|
+
|
|
74
|
+
### Button Variants
|
|
75
|
+
- \`--link-button-color\`: Button link text color (default: var(--link-color))
|
|
76
|
+
- \`--link-border-width\`: Button border width (default: 0.125rem / 2px)
|
|
77
|
+
- \`--link-border-color\`: Button border color (default: currentColor)
|
|
78
|
+
- \`--link-border-style\`: Button border style (default: solid)
|
|
79
|
+
`,
|
|
44
80
|
},
|
|
45
81
|
},
|
|
46
82
|
},
|
|
@@ -18,7 +18,7 @@ dl {
|
|
|
18
18
|
--list-margin-top: 0;
|
|
19
19
|
--list-margin-bottom: 1rem; // 16px
|
|
20
20
|
--list-margin-inline: 0;
|
|
21
|
-
--list-padding-inline:
|
|
21
|
+
--list-padding-inline: 0.5rem; // 40px - default browser indent
|
|
22
22
|
--list-gap: 0.5rem; // 8px - gap between items
|
|
23
23
|
|
|
24
24
|
// List marker/bullet styling
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
body > nav,
|
|
2
2
|
[aria-label~="navbar"],
|
|
3
3
|
.navbar {
|
|
4
|
-
padding-inline: var(--nav-
|
|
5
|
-
min-height: var(--nav-
|
|
4
|
+
padding-inline: var(--nav-padding-inline, 1rem);
|
|
5
|
+
min-height: var(--nav-height, fit-content);
|
|
6
6
|
|
|
7
7
|
@media (max-width: 580px) {
|
|
8
8
|
flex-direction: column;
|
|
@@ -19,10 +19,10 @@ body > nav,
|
|
|
19
19
|
margin: 0;
|
|
20
20
|
padding: 0;
|
|
21
21
|
min-height: 100%;
|
|
22
|
-
padding-inline: var(--nav-
|
|
22
|
+
padding-inline: var(--nav-padding-inline, 0.75rem);
|
|
23
23
|
|
|
24
24
|
&:hover {
|
|
25
|
-
background-color: var(--nav-
|
|
25
|
+
background-color: var(--nav-hover-bg, #e8e8e8);
|
|
26
26
|
}
|
|
27
27
|
&:hover:where(img) {
|
|
28
28
|
background-color: transparent;
|
|
@@ -38,25 +38,25 @@ nav {
|
|
|
38
38
|
--nav-focus-offset: 0.125rem; // 2px
|
|
39
39
|
--nav-focus-style: solid;
|
|
40
40
|
|
|
41
|
-
display: var(--nav-
|
|
41
|
+
display: var(--nav-display, flex);
|
|
42
42
|
flex-direction: var(--nav-direction, row);
|
|
43
|
-
width: var(--nav-
|
|
43
|
+
width: var(--nav-width, auto);
|
|
44
44
|
place-items: var(--nav-align, center);
|
|
45
45
|
justify-content: var(--nav-justify, space-between);
|
|
46
|
-
margin-inline: var(--nav-
|
|
46
|
+
margin-inline: var(--nav-margin-inline, 0);
|
|
47
47
|
background-color: var(--nav-bg, initial);
|
|
48
48
|
|
|
49
49
|
> section,
|
|
50
50
|
> ul {
|
|
51
|
-
--nav-
|
|
51
|
+
--nav-display: flex;
|
|
52
52
|
flex-direction: var(--nav-direction, row);
|
|
53
|
-
display: var(--nav-
|
|
53
|
+
display: var(--nav-display, flex);
|
|
54
54
|
gap: var(--nav-gap, 0);
|
|
55
55
|
font-size: var(--nav-fs, 0.9rem);
|
|
56
56
|
align-items: var(--nav-align, center);
|
|
57
|
-
padding-inline: var(--nav-
|
|
58
|
-
padding-block: var(--nav-
|
|
59
|
-
margin-block-end: var(--nav-
|
|
57
|
+
padding-inline: var(--nav-padding-inline, 1rem);
|
|
58
|
+
padding-block: var(--nav-padding-block, 0);
|
|
59
|
+
margin-block-end: var(--nav-margin-block-end, 0);
|
|
60
60
|
height: 100%;
|
|
61
61
|
&[data-list~="block"] {
|
|
62
62
|
--nav-direction: column;
|
|
@@ -65,7 +65,7 @@ nav {
|
|
|
65
65
|
|
|
66
66
|
> section {
|
|
67
67
|
> div {
|
|
68
|
-
--
|
|
68
|
+
--nav-padding-block: 0;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -77,18 +77,18 @@ nav {
|
|
|
77
77
|
margin: 0;
|
|
78
78
|
padding: 0;
|
|
79
79
|
min-height: 100%;
|
|
80
|
-
padding-inline: var(--nav-
|
|
80
|
+
padding-inline: var(--nav-padding-inline, 1rem);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
img[alt] {
|
|
85
|
-
--
|
|
86
|
-
--
|
|
85
|
+
--nav-img-padding-inline: 0 var(--s1);
|
|
86
|
+
--nav-img-width: var(--brand-w, 3.6rem);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
&[data-variant] {
|
|
90
90
|
background-color: var(--nav-bg);
|
|
91
|
-
color: var(--nav-
|
|
91
|
+
color: var(--nav-color);
|
|
92
92
|
font-size: var(--nav-fs, 0.9rem);
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
body > nav,
|
|
2
|
+
[aria-label~="navbar"],
|
|
3
|
+
.navbar {
|
|
4
|
+
padding-inline: var(--nav-px, 1rem);
|
|
5
|
+
min-height: var(--nav-h, fit-content);
|
|
6
|
+
|
|
7
|
+
@media (max-width: 580px) {
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
height: fit-content;
|
|
10
|
+
min-height: fit-content;
|
|
11
|
+
padding-block: unset;
|
|
12
|
+
gap: 0.5rem;
|
|
13
|
+
}
|
|
14
|
+
ul {
|
|
15
|
+
> li {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
list-style: none;
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
min-height: 100%;
|
|
22
|
+
padding-inline: var(--nav-px, 0.75rem);
|
|
23
|
+
|
|
24
|
+
&:hover {
|
|
25
|
+
background-color: var(--nav-hov-bg, #e8e8e8);
|
|
26
|
+
}
|
|
27
|
+
&:hover:where(img) {
|
|
28
|
+
background-color: transparent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
nav {
|
|
35
|
+
// Focus Indicator Variables (WCAG 2.4.7 - 3:1 contrast minimum)
|
|
36
|
+
--nav-focus-color: currentColor;
|
|
37
|
+
--nav-focus-width: 0.125rem; // 2px
|
|
38
|
+
--nav-focus-offset: 0.125rem; // 2px
|
|
39
|
+
--nav-focus-style: solid;
|
|
40
|
+
|
|
41
|
+
display: var(--nav-dsp, flex);
|
|
42
|
+
flex-direction: var(--nav-direction, row);
|
|
43
|
+
width: var(--nav-w, auto);
|
|
44
|
+
place-items: var(--nav-align, center);
|
|
45
|
+
justify-content: var(--nav-justify, space-between);
|
|
46
|
+
margin-inline: var(--nav-mx, 0);
|
|
47
|
+
background-color: var(--nav-bg, initial);
|
|
48
|
+
|
|
49
|
+
> section,
|
|
50
|
+
> ul {
|
|
51
|
+
--nav-dsp: flex;
|
|
52
|
+
flex-direction: var(--nav-direction, row);
|
|
53
|
+
display: var(--nav-dsp, flex);
|
|
54
|
+
gap: var(--nav-gap, 0);
|
|
55
|
+
font-size: var(--nav-fs, 0.9rem);
|
|
56
|
+
align-items: var(--nav-align, center);
|
|
57
|
+
padding-inline: var(--nav-px, 1rem);
|
|
58
|
+
padding-block: var(--nav-py, 0);
|
|
59
|
+
margin-block-end: var(--nav-mb, 0);
|
|
60
|
+
height: 100%;
|
|
61
|
+
&[data-list~="block"] {
|
|
62
|
+
--nav-direction: column;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
> section {
|
|
67
|
+
> div {
|
|
68
|
+
--py: 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
ul {
|
|
73
|
+
> li {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
list-style: none;
|
|
77
|
+
margin: 0;
|
|
78
|
+
padding: 0;
|
|
79
|
+
min-height: 100%;
|
|
80
|
+
padding-inline: var(--nav-px, 1rem);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
img[alt] {
|
|
85
|
+
--px: 0 var(--s1);
|
|
86
|
+
--w: var(--brand-w, 3.6rem);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&[data-variant] {
|
|
90
|
+
background-color: var(--nav-bg);
|
|
91
|
+
color: var(--nav-cl);
|
|
92
|
+
font-size: var(--nav-fs, 0.9rem);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
> div {
|
|
96
|
+
margin-block-start: 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Focus indicators for links and buttons (WCAG 2.4.7)
|
|
100
|
+
a:focus {
|
|
101
|
+
outline: var(--nav-focus-width) var(--nav-focus-style)
|
|
102
|
+
var(--nav-focus-color);
|
|
103
|
+
outline-offset: var(--nav-focus-offset);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
a:focus-visible {
|
|
107
|
+
outline: var(--nav-focus-width) var(--nav-focus-style)
|
|
108
|
+
var(--nav-focus-color);
|
|
109
|
+
outline-offset: var(--nav-focus-offset);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
button:focus {
|
|
113
|
+
outline: var(--nav-focus-width) var(--nav-focus-style)
|
|
114
|
+
var(--nav-focus-color);
|
|
115
|
+
outline-offset: var(--nav-focus-offset);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
button:focus-visible {
|
|
119
|
+
outline: var(--nav-focus-width) var(--nav-focus-style)
|
|
120
|
+
var(--nav-focus-color);
|
|
121
|
+
outline-offset: var(--nav-focus-offset);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -9,12 +9,46 @@ import Link from "../link/link";
|
|
|
9
9
|
const meta: Meta<typeof Nav> = {
|
|
10
10
|
title: "FP.REACT Components/Nav",
|
|
11
11
|
component: Nav,
|
|
12
|
-
tags: ["
|
|
12
|
+
tags: ["stable"],
|
|
13
13
|
parameters: {
|
|
14
14
|
actions: { argTypesRegex: "^on.*" },
|
|
15
15
|
docs: {
|
|
16
16
|
description: {
|
|
17
|
-
component:
|
|
17
|
+
component: `Navigation component with accessible markup and customizable styling via CSS variables.
|
|
18
|
+
|
|
19
|
+
## CSS Variables
|
|
20
|
+
|
|
21
|
+
### Layout & Sizing
|
|
22
|
+
- \`--nav-display\`: Display mode (default: flex)
|
|
23
|
+
- \`--nav-width\`: Nav width (default: auto)
|
|
24
|
+
- \`--nav-height\`: Minimum height (default: fit-content)
|
|
25
|
+
- \`--nav-direction\`: Flex direction (default: row)
|
|
26
|
+
- \`--nav-align\`: Vertical alignment (default: center)
|
|
27
|
+
- \`--nav-justify\`: Horizontal justification (default: space-between)
|
|
28
|
+
|
|
29
|
+
### Spacing
|
|
30
|
+
- \`--nav-padding-inline\`: Horizontal padding (default: 1rem)
|
|
31
|
+
- \`--nav-padding-block\`: Vertical padding (default: 0)
|
|
32
|
+
- \`--nav-margin-inline\`: Horizontal margin (default: 0)
|
|
33
|
+
- \`--nav-margin-block-end\`: Bottom margin (default: 0)
|
|
34
|
+
- \`--nav-gap\`: Gap between nav items (default: 0)
|
|
35
|
+
|
|
36
|
+
### Typography & Color
|
|
37
|
+
- \`--nav-fs\`: Font size (default: 0.9rem)
|
|
38
|
+
- \`--nav-color\`: Text color
|
|
39
|
+
- \`--nav-bg\`: Background color (default: initial)
|
|
40
|
+
- \`--nav-hover-bg\`: Background color on hover (default: #e8e8e8)
|
|
41
|
+
|
|
42
|
+
### Focus Indicators (WCAG 2.4.7)
|
|
43
|
+
- \`--nav-focus-color\`: Focus outline color (default: currentColor)
|
|
44
|
+
- \`--nav-focus-width\`: Focus outline width (default: 0.125rem / 2px)
|
|
45
|
+
- \`--nav-focus-offset\`: Focus outline offset (default: 0.125rem / 2px)
|
|
46
|
+
- \`--nav-focus-style\`: Focus outline style (default: solid)
|
|
47
|
+
|
|
48
|
+
### Image Elements
|
|
49
|
+
- \`--nav-img-padding-inline\`: Image padding (default: 0 var(--s1))
|
|
50
|
+
- \`--nav-img-width\`: Image width (default: var(--brand-w, 3.6rem))
|
|
51
|
+
`,
|
|
18
52
|
},
|
|
19
53
|
},
|
|
20
54
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
progress {
|
|
2
2
|
/* Revert all styles */
|
|
3
3
|
all: revert;
|
|
4
|
-
--progress-
|
|
5
|
-
--progress-
|
|
4
|
+
--progress-width: 100%;
|
|
5
|
+
--progress-height: 1rem;
|
|
6
6
|
--progress-bg: #cccccc;
|
|
7
7
|
--progress-color: rgb(71, 71, 245);
|
|
8
8
|
--progress-accent-color: var(--progress-color);
|
|
@@ -12,8 +12,8 @@ progress {
|
|
|
12
12
|
/* The colors are used in the progress bar. */
|
|
13
13
|
&[value] {
|
|
14
14
|
|
|
15
|
-
width: var(--progress-
|
|
16
|
-
height: var(--progress-
|
|
15
|
+
width: var(--progress-width);
|
|
16
|
+
height: var(--progress-height);
|
|
17
17
|
background-color: var(--progress-bg);
|
|
18
18
|
accent-color: var(--progress-accent-color);
|
|
19
19
|
|
|
@@ -42,9 +42,9 @@ progress {
|
|
|
42
42
|
/* If the progress element is busy, remove the revert styles */
|
|
43
43
|
&[aria-busy] {
|
|
44
44
|
// all: revert;
|
|
45
|
-
width: var(--progress-
|
|
46
|
-
height: var(--progress-
|
|
47
|
-
// height: calc(var(--progress-
|
|
45
|
+
width: var(--progress-width);
|
|
46
|
+
height: var(--progress-height);
|
|
47
|
+
// height: calc(var(--progress-height) + var(--progress-height));
|
|
48
48
|
accent-color: var(--progress-accent-color);
|
|
49
49
|
|
|
50
50
|
&::-webkit-progress-value {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
progress {
|
|
2
|
+
/* Revert all styles */
|
|
3
|
+
all: revert;
|
|
4
|
+
--progress-w: 100%;
|
|
5
|
+
--progress-h: 1rem;
|
|
6
|
+
--progress-bg: #cccccc;
|
|
7
|
+
--progress-color: rgb(71, 71, 245);
|
|
8
|
+
--progress-accent-color: var(--progress-color);
|
|
9
|
+
|
|
10
|
+
/* This code changes the color of the progress bar. */
|
|
11
|
+
/* The variable names indicate the colors that are used. */
|
|
12
|
+
/* The colors are used in the progress bar. */
|
|
13
|
+
&[value] {
|
|
14
|
+
|
|
15
|
+
width: var(--progress-w);
|
|
16
|
+
height: var(--progress-h);
|
|
17
|
+
background-color: var(--progress-bg);
|
|
18
|
+
accent-color: var(--progress-accent-color);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
&::-webkit-progress-value {
|
|
22
|
+
/* Color for Chrome, Safari, and newer Opera */
|
|
23
|
+
background-color: var(--progress-accent-color);
|
|
24
|
+
accent-color: var(--progress-accent-color);
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&::-moz-progress-bar {
|
|
29
|
+
/* Color for Firefox */
|
|
30
|
+
background-color: var(--progress-accent-color);
|
|
31
|
+
accent-color: var(--progress-accent-color)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Styling for the remaining part of the& bar */
|
|
35
|
+
&::-webkit-progress-bar {
|
|
36
|
+
/* Background for Chrome, Safari, and newer Opera */
|
|
37
|
+
background-color: var(--progress-background-color);
|
|
38
|
+
accent-color: var(--progress-accent-color)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* If the progress element is busy, remove the revert styles */
|
|
43
|
+
&[aria-busy] {
|
|
44
|
+
// all: revert;
|
|
45
|
+
width: var(--progress-w);
|
|
46
|
+
height: var(--progress-h);
|
|
47
|
+
// height: calc(var(--progress-h) + var(--progress-h));
|
|
48
|
+
accent-color: var(--progress-accent-color);
|
|
49
|
+
|
|
50
|
+
&::-webkit-progress-value {
|
|
51
|
+
/* Color for Chrome, Safari, and newer Opera */
|
|
52
|
+
// background-color: var(--progress-accent-color);
|
|
53
|
+
accent-color: var(--progress-accent-color)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&::-moz-progress-bar {
|
|
57
|
+
// /* Color for Firefox */
|
|
58
|
+
// background-color: var(--progress-bg);
|
|
59
|
+
accent-color: var(--progress-accent-color)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Styling for the remaining part of the& bar */
|
|
63
|
+
&::-webkit-progress-bar {
|
|
64
|
+
/* Background for Chrome, Safari, and newer Opera */
|
|
65
|
+
// background-color: var(--progress-bg);
|
|
66
|
+
accent-color: var(--progress-accent-color)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
@@ -25,19 +25,19 @@ small > span,
|
|
|
25
25
|
--production: #1e3a8a; /* Dark blue: 8.59:1 contrast with white */
|
|
26
26
|
|
|
27
27
|
/* Tag component tokens */
|
|
28
|
-
--tag-
|
|
29
|
-
--tag-
|
|
30
|
-
--tag-fs: 0.8rem;
|
|
31
|
-
--tag-radius: 99rem;
|
|
32
|
-
--tag-bg: lightgray;
|
|
33
|
-
--tag-fw: 500;
|
|
34
|
-
--tag-color: currentColor;
|
|
35
|
-
--tag-display: inline-block
|
|
28
|
+
--tag-padding-inline: 0.7rem; /* Horizontal padding (11.2px at 16px base) */
|
|
29
|
+
--tag-padding-block: 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 */
|
|
36
36
|
|
|
37
37
|
/* Apply CSS custom properties */
|
|
38
38
|
display: var(--tag-display);
|
|
39
|
-
padding-inline: var(--tag-
|
|
40
|
-
padding-block: var(--tag-
|
|
39
|
+
padding-inline: var(--tag-padding-inline);
|
|
40
|
+
padding-block: var(--tag-padding-block);
|
|
41
41
|
font-size: var(--tag-fs);
|
|
42
42
|
color: var(--tag-color);
|
|
43
43
|
background-color: var(--tag-bg);
|