@fpkit/acss 0.5.12 → 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 +89 -0
- package/libs/{chunk-DV56L5YX.cjs → chunk-2LTJ7HHX.cjs} +4 -4
- package/libs/{chunk-EQ67LF46.js → chunk-2Y7W75TT.js} +3 -3
- package/libs/{chunk-KKLTUJFB.cjs → chunk-3MKLDCKQ.cjs} +5 -5
- package/libs/chunk-3MKLDCKQ.cjs.map +1 -0
- package/libs/{chunk-X3EVB7VS.cjs → chunk-5S4ORA4C.cjs} +3 -3
- package/libs/{chunk-O6QZBB6G.js → chunk-772NRB75.js} +5 -5
- package/libs/chunk-772NRB75.js.map +1 -0
- package/libs/{chunk-6BVXFW7U.cjs → chunk-AHDJGCG5.cjs} +3 -3
- package/libs/{chunk-E3XP6BEX.cjs → chunk-B7F5FS6D.cjs} +3 -3
- 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-GZ4QFPRY.js +9 -0
- package/libs/chunk-GZ4QFPRY.js.map +1 -0
- package/libs/{chunk-LHVJKDMA.cjs → chunk-J32EZPYD.cjs} +3 -3
- 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-LL7HTLMS.cjs → chunk-M5RRNTVX.cjs} +3 -3
- package/libs/{chunk-LIQJ7ZZR.js → chunk-NGTJDDFO.js} +2 -2
- 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-PQ2K3BM6.cjs +17 -0
- package/libs/chunk-PQ2K3BM6.cjs.map +1 -0
- package/libs/{chunk-QCMV4VQZ.js → chunk-QLZWHAMK.js} +2 -2
- package/libs/{chunk-BIP2NY53.js → chunk-RIVUMPOG.js} +2 -2
- package/libs/{chunk-ICCKQ2GC.cjs → chunk-ROZI23GS.cjs} +4 -4
- package/libs/{chunk-NHYXGV3L.js → chunk-SMYRLO3E.js} +2 -2
- package/libs/{chunk-5ZM4XL44.js → chunk-TYRCEX2L.js} +2 -2
- package/libs/chunk-VUH3FXGJ.js +11 -0
- package/libs/chunk-VUH3FXGJ.js.map +1 -0
- package/libs/{chunk-PPOOBUOS.js → chunk-XBA562WW.js} +2 -2
- package/libs/{chunk-QVV34QEH.cjs → chunk-XTQKWY7W.cjs} +3 -3
- package/libs/{chunk-YWOYVRFT.js → chunk-ZANSFMTD.js} +3 -3
- 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 +9 -5
- package/libs/components/breadcrumbs/breadcrumb.d.cts +271 -32
- package/libs/components/breadcrumbs/breadcrumb.d.ts +271 -32
- package/libs/components/breadcrumbs/breadcrumb.js +3 -3
- package/libs/components/button.cjs +4 -4
- package/libs/components/button.d.cts +2 -2
- package/libs/components/button.d.ts +2 -2
- package/libs/components/button.js +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/card.cjs +7 -7
- package/libs/components/card.d.cts +277 -33
- package/libs/components/card.d.ts +277 -33
- package/libs/components/card.js +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.cjs +7 -7
- package/libs/components/dialog/dialog.css +1 -1
- package/libs/components/dialog/dialog.css.map +1 -1
- package/libs/components/dialog/dialog.d.cts +88 -34
- package/libs/components/dialog/dialog.d.ts +88 -34
- package/libs/components/dialog/dialog.js +5 -5
- package/libs/components/dialog/dialog.min.css +2 -2
- package/libs/components/form/fields.cjs +4 -4
- package/libs/components/form/fields.d.cts +2 -2
- package/libs/components/form/fields.d.ts +2 -2
- package/libs/components/form/fields.js +2 -2
- package/libs/components/form/textarea.cjs +4 -4
- package/libs/components/form/textarea.d.cts +2 -2
- package/libs/components/form/textarea.d.ts +2 -2
- package/libs/components/form/textarea.js +2 -2
- package/libs/components/heading/heading.cjs +3 -3
- package/libs/components/heading/heading.d.cts +3 -14
- package/libs/components/heading/heading.d.ts +3 -14
- package/libs/components/heading/heading.js +2 -2
- package/libs/components/icons/icon.cjs +4 -4
- package/libs/components/icons/icon.d.cts +148 -4
- package/libs/components/icons/icon.d.ts +148 -4
- package/libs/components/icons/icon.js +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/link/link.cjs +4 -4
- package/libs/components/link/link.d.cts +2 -2
- package/libs/components/link/link.d.ts +2 -2
- package/libs/components/link/link.js +2 -2
- package/libs/components/list/list.cjs +5 -5
- package/libs/components/list/list.d.cts +3 -3
- package/libs/components/list/list.d.ts +3 -3
- package/libs/components/list/list.js +2 -2
- package/libs/components/modal.cjs +4 -4
- package/libs/components/modal.js +3 -3
- package/libs/components/nav/nav.cjs +7 -7
- package/libs/components/nav/nav.d.cts +2 -2
- package/libs/components/nav/nav.d.ts +2 -2
- package/libs/components/nav/nav.js +3 -3
- package/libs/components/text/text.cjs +5 -5
- package/libs/components/text/text.d.cts +2 -2
- package/libs/components/text/text.d.ts +2 -2
- package/libs/components/text/text.js +2 -2
- 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 -3
- package/libs/icons.d.cts +1 -1
- package/libs/icons.d.ts +1 -1
- package/libs/icons.js +2 -2
- package/libs/index.cjs +112 -91
- 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 +515 -31
- package/libs/index.d.ts +515 -31
- package/libs/index.js +31 -19
- package/libs/index.js.map +1 -1
- package/libs/ui-645f95b5.d.ts +285 -0
- package/package.json +2 -83
- 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/buttons/button.scss +34 -31
- package/src/components/buttons/button.stories.tsx +35 -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 -7
- 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/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 +10 -2
- 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 -8
- 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 -51
- 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-6TE5QEVE.cjs +0 -13
- package/libs/chunk-6TE5QEVE.cjs.map +0 -1
- package/libs/chunk-7K76RW2A.cjs +0 -18
- package/libs/chunk-7K76RW2A.cjs.map +0 -1
- package/libs/chunk-BSPKFLO4.js +0 -8
- package/libs/chunk-BSPKFLO4.js.map +0 -1
- package/libs/chunk-BV5CLH44.cjs +0 -18
- package/libs/chunk-BV5CLH44.cjs.map +0 -1
- package/libs/chunk-DKGJHKGW.js +0 -9
- package/libs/chunk-DKGJHKGW.js.map +0 -1
- package/libs/chunk-ECLD37WN.cjs +0 -16
- package/libs/chunk-ECLD37WN.cjs.map +0 -1
- package/libs/chunk-HYBZBN4G.js +0 -8
- package/libs/chunk-HYBZBN4G.js.map +0 -1
- package/libs/chunk-KKLTUJFB.cjs.map +0 -1
- package/libs/chunk-M5QL5TAE.cjs +0 -14
- package/libs/chunk-M5QL5TAE.cjs.map +0 -1
- package/libs/chunk-NE6YXTMC.js +0 -7
- package/libs/chunk-NE6YXTMC.js.map +0 -1
- package/libs/chunk-O6QZBB6G.js.map +0 -1
- package/libs/chunk-SXVZSWX6.js +0 -11
- package/libs/chunk-SXVZSWX6.js.map +0 -1
- package/libs/ui-9a6f9f8d.d.ts +0 -24
- package/src/components/cards/README.md +0 -80
- package/src/components/dialog/hooks/useClickOutside.ts +0 -33
- /package/libs/{chunk-DV56L5YX.cjs.map → chunk-2LTJ7HHX.cjs.map} +0 -0
- /package/libs/{chunk-EQ67LF46.js.map → chunk-2Y7W75TT.js.map} +0 -0
- /package/libs/{chunk-X3EVB7VS.cjs.map → chunk-5S4ORA4C.cjs.map} +0 -0
- /package/libs/{chunk-6BVXFW7U.cjs.map → chunk-AHDJGCG5.cjs.map} +0 -0
- /package/libs/{chunk-E3XP6BEX.cjs.map → chunk-B7F5FS6D.cjs.map} +0 -0
- /package/libs/{chunk-LHVJKDMA.cjs.map → chunk-J32EZPYD.cjs.map} +0 -0
- /package/libs/{chunk-LL7HTLMS.cjs.map → chunk-M5RRNTVX.cjs.map} +0 -0
- /package/libs/{chunk-LIQJ7ZZR.js.map → chunk-NGTJDDFO.js.map} +0 -0
- /package/libs/{chunk-QCMV4VQZ.js.map → chunk-QLZWHAMK.js.map} +0 -0
- /package/libs/{chunk-BIP2NY53.js.map → chunk-RIVUMPOG.js.map} +0 -0
- /package/libs/{chunk-ICCKQ2GC.cjs.map → chunk-ROZI23GS.cjs.map} +0 -0
- /package/libs/{chunk-NHYXGV3L.js.map → chunk-SMYRLO3E.js.map} +0 -0
- /package/libs/{chunk-5ZM4XL44.js.map → chunk-TYRCEX2L.js.map} +0 -0
- /package/libs/{chunk-PPOOBUOS.js.map → chunk-XBA562WW.js.map} +0 -0
- /package/libs/{chunk-QVV34QEH.cjs.map → chunk-XTQKWY7W.cjs.map} +0 -0
- /package/libs/{chunk-YWOYVRFT.js.map → chunk-ZANSFMTD.js.map} +0 -0
|
@@ -6,39 +6,165 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
|
|
6
6
|
|
|
7
7
|
## Summary
|
|
8
8
|
|
|
9
|
-
The `Alert` component is a customizable component for displaying status messages
|
|
10
|
-
with different severity levels. It supports multiple severity types (default,
|
|
11
|
-
info, success, warning, error) and can include optional titles and dismissal
|
|
12
|
-
functionality.
|
|
9
|
+
The `Alert` component is a highly customizable and accessible component for displaying status messages with different severity levels. It supports multiple severity types (default, info, success, warning, error), visual variants, auto-dismiss functionality, exit animations, and optional action buttons. **Fully WCAG 2.1 Level AA compliant** with comprehensive accessibility features.
|
|
13
10
|
|
|
14
11
|
## Features
|
|
15
12
|
|
|
16
|
-
- Multiple
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
13
|
+
- **Multiple Severity Levels** - Info, success, warning, error, and default states with matching visual indicators
|
|
14
|
+
- **Visual Variants** - Choose from outlined (default), filled, or soft styles
|
|
15
|
+
- **Flexible Content** - Simple text mode or complex layouts with the `contentType` prop
|
|
16
|
+
- **Exit Animations** - Smooth fade-out and slide-up transitions using CSS
|
|
17
|
+
- **Auto-Dismiss with Pause** - Automatic dismissal that pauses on hover/focus (WCAG 2.2.1)
|
|
18
|
+
- **Keyboard Support** - ESC key dismisses dismissible alerts
|
|
19
|
+
- **Custom Actions** - Add custom action buttons alongside the message
|
|
20
|
+
- **Icon Customization** - Adjust icon size or hide icons completely
|
|
21
|
+
- **Configurable Headings** - Maintain proper document hierarchy with `titleLevel` prop
|
|
22
|
+
- **Auto-Focus** - Automatically focus critical alerts for accessibility
|
|
23
|
+
- **Screen Reader Support** - Severity announcements and proper ARIA attributes
|
|
24
|
+
- **WCAG 2.1 Level AA Compliant** - Meets all accessibility standards including color contrast, touch targets, and focus indicators
|
|
20
25
|
|
|
21
26
|
## Props
|
|
22
27
|
|
|
23
28
|
```tsx
|
|
24
29
|
export type AlertProps = {
|
|
30
|
+
/**
|
|
31
|
+
* Whether the alert is open.
|
|
32
|
+
*/
|
|
25
33
|
open: boolean;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The severity level of the alert.
|
|
37
|
+
* @default "default"
|
|
38
|
+
*/
|
|
26
39
|
severity?: "default" | "info" | "success" | "warning" | "error";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The main message content.
|
|
43
|
+
*/
|
|
27
44
|
children: React.ReactNode;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Optional title for the alert.
|
|
48
|
+
*/
|
|
28
49
|
title?: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Whether the alert can be dismissed.
|
|
53
|
+
* @default false
|
|
54
|
+
*/
|
|
29
55
|
dismissible?: boolean;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Callback when alert is dismissed.
|
|
59
|
+
*/
|
|
30
60
|
onDismiss?: () => void;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Size of the icon in pixels.
|
|
64
|
+
* @default 24
|
|
65
|
+
*/
|
|
66
|
+
iconSize?: number;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Whether to hide the icon.
|
|
70
|
+
*/
|
|
71
|
+
hideIcon?: boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Additional props to pass to the Icon component.
|
|
75
|
+
*/
|
|
31
76
|
iconProps?: IconProps;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Duration in milliseconds before the alert automatically dismisses.
|
|
80
|
+
* Set to 0 or undefined to disable auto-dismiss.
|
|
81
|
+
* @default undefined
|
|
82
|
+
*/
|
|
83
|
+
autoHideDuration?: number;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Whether to pause auto-dismiss when hovered or focused.
|
|
87
|
+
* Complies with WCAG 2.2.1 (Timing Adjustable).
|
|
88
|
+
* @default true
|
|
89
|
+
*/
|
|
90
|
+
pauseOnHover?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Semantic heading level for the title (2-6).
|
|
94
|
+
* When undefined, uses default heading level.
|
|
95
|
+
* Use this to maintain proper document hierarchy.
|
|
96
|
+
* @default 3
|
|
97
|
+
*/
|
|
98
|
+
titleLevel?: 2 | 3 | 4 | 5 | 6;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Custom action buttons to display in the alert.
|
|
102
|
+
*/
|
|
103
|
+
actions?: React.ReactNode;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Whether to automatically focus the alert when it becomes visible.
|
|
107
|
+
* Useful for critical alerts that require immediate attention.
|
|
108
|
+
* @default false
|
|
109
|
+
*/
|
|
110
|
+
autoFocus?: boolean;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Visual variant of the alert.
|
|
114
|
+
* - outlined: Border with lighter background (default)
|
|
115
|
+
* - filled: Solid colored background
|
|
116
|
+
* - soft: No border, subtle background
|
|
117
|
+
* @default "outlined"
|
|
118
|
+
*/
|
|
119
|
+
variant?: "outlined" | "filled" | "soft";
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Content rendering mode for alert children.
|
|
123
|
+
* - "text": Wraps children in paragraph tag (default, for simple text)
|
|
124
|
+
* - "node": Renders children directly (for complex layouts, lists, or custom components)
|
|
125
|
+
* @default "text"
|
|
126
|
+
*/
|
|
127
|
+
contentType?: "text" | "node";
|
|
32
128
|
} & React.ComponentProps<typeof UI>;
|
|
33
129
|
```
|
|
34
130
|
|
|
35
131
|
## Technical Details
|
|
36
132
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
133
|
+
### Component Architecture
|
|
134
|
+
|
|
135
|
+
The `Alert` component uses the `UI` component for rendering and includes:
|
|
136
|
+
|
|
137
|
+
- **Animation State Management** - Separate `isVisible` and `shouldRender` states for smooth exit animations
|
|
138
|
+
- **Auto-Dismiss Timer** - Automatic cleanup of setTimeout when component unmounts or alert is dismissed
|
|
139
|
+
- **Keyboard Event Handler** - ESC key support with proper cleanup
|
|
140
|
+
- **Memoized Icons** - Performance-optimized icon rendering using `useMemo`
|
|
141
|
+
- **ARIA Attributes** - Proper `role="alert"`, `aria-live`, and `aria-atomic` for screen readers
|
|
142
|
+
|
|
143
|
+
### Accessibility Features (WCAG 2.1 Level AA Compliant)
|
|
144
|
+
|
|
145
|
+
- **ARIA Roles** - Uses `role="alert"` for proper screen reader announcements
|
|
146
|
+
- **Live Regions** - `aria-live="polite"` for info/success/warning, `aria-live="assertive"` for errors
|
|
147
|
+
- **Screen Reader Announcements** - Visually hidden severity text ("Error:", "Warning:", etc.) for context
|
|
148
|
+
- **Keyboard Navigation** - ESC key dismisses alerts when `dismissible` is true
|
|
149
|
+
- **Focus Management** - Optional auto-focus for critical alerts via `autoFocus` prop with visible focus indicators
|
|
150
|
+
- **Semantic HTML** - Configurable heading levels (h2-h6) via `titleLevel` prop for proper document hierarchy
|
|
151
|
+
- **Flexible Content Structure** - `contentType` prop enables semantic HTML for complex content (lists, multiple paragraphs)
|
|
152
|
+
- **Touch Target Compliance** - Dismiss button meets 44×44px minimum size (WCAG 2.5.5)
|
|
153
|
+
- **Pause on Interaction** - Auto-dismiss pauses when alert is hovered or focused (WCAG 2.2.1)
|
|
154
|
+
- **Color Contrast** - All text meets 4.5:1 minimum contrast ratio (WCAG 1.4.3)
|
|
155
|
+
- **Focus Indicators** - 2px visible outline for keyboard navigation (WCAG 2.4.7)
|
|
156
|
+
- **Reduced Motion Support** - Respects `prefers-reduced-motion` user preference
|
|
157
|
+
|
|
158
|
+
### Animation Behavior
|
|
159
|
+
|
|
160
|
+
Exit animations use CSS transitions (300ms duration) for smooth fade-out and slide-up effects. The component:
|
|
40
161
|
|
|
41
|
-
|
|
162
|
+
1. Sets `isVisible` to `false` when dismissed
|
|
163
|
+
2. Waits for CSS transition to complete (300ms)
|
|
164
|
+
3. Removes component from DOM by setting `shouldRender` to `false`
|
|
165
|
+
4. Calls `onDismiss` callback after animation completes
|
|
166
|
+
|
|
167
|
+
## Usage Examples
|
|
42
168
|
|
|
43
169
|
### Basic Usage
|
|
44
170
|
|
|
@@ -50,7 +176,7 @@ import Alert from "#components/alert";
|
|
|
50
176
|
</Alert>;
|
|
51
177
|
```
|
|
52
178
|
|
|
53
|
-
###
|
|
179
|
+
### With Title and Dismissal
|
|
54
180
|
|
|
55
181
|
```tsx
|
|
56
182
|
import Alert from "#components/alert";
|
|
@@ -61,14 +187,344 @@ import Alert from "#components/alert";
|
|
|
61
187
|
title="Error"
|
|
62
188
|
dismissible={true}
|
|
63
189
|
onDismiss={() => console.log("Alert dismissed")}
|
|
64
|
-
iconProps={{ fill: "#000", size: 24 }}
|
|
65
190
|
>
|
|
66
|
-
This is an error alert with a
|
|
191
|
+
This is an error alert with a title and dismiss button.
|
|
192
|
+
</Alert>;
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Auto-Dismiss Alert
|
|
196
|
+
|
|
197
|
+
Automatically dismiss the alert after 5 seconds:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
import Alert from "#components/alert";
|
|
201
|
+
|
|
202
|
+
<Alert
|
|
203
|
+
open={true}
|
|
204
|
+
severity="success"
|
|
205
|
+
title="Success"
|
|
206
|
+
autoHideDuration={5000}
|
|
207
|
+
onDismiss={() => console.log("Auto-dismissed after 5 seconds")}
|
|
208
|
+
>
|
|
209
|
+
Your changes have been saved successfully!
|
|
210
|
+
</Alert>;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Alert with Custom Actions
|
|
214
|
+
|
|
215
|
+
Add custom action buttons for user interactions:
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import Alert from "#components/alert";
|
|
219
|
+
import Button from "#components/buttons/button";
|
|
220
|
+
|
|
221
|
+
<Alert
|
|
222
|
+
open={true}
|
|
223
|
+
severity="warning"
|
|
224
|
+
title="Unsaved Changes"
|
|
225
|
+
actions={
|
|
226
|
+
<>
|
|
227
|
+
<Button size="sm" onClick={handleSave}>
|
|
228
|
+
Save
|
|
229
|
+
</Button>
|
|
230
|
+
<Button size="sm" onClick={handleDiscard}>
|
|
231
|
+
Discard
|
|
232
|
+
</Button>
|
|
233
|
+
</>
|
|
234
|
+
}
|
|
235
|
+
>
|
|
236
|
+
You have unsaved changes that will be lost.
|
|
237
|
+
</Alert>;
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Visual Variants
|
|
241
|
+
|
|
242
|
+
Use different visual styles for the alert:
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import Alert from "#components/alert";
|
|
246
|
+
|
|
247
|
+
// Outlined (default) - border with lighter background
|
|
248
|
+
<Alert open={true} variant="outlined" severity="info">
|
|
249
|
+
Outlined variant with border
|
|
250
|
+
</Alert>;
|
|
251
|
+
|
|
252
|
+
// Filled - solid colored background
|
|
253
|
+
<Alert open={true} variant="filled" severity="success">
|
|
254
|
+
Filled variant with solid background
|
|
255
|
+
</Alert>;
|
|
256
|
+
|
|
257
|
+
// Soft - no border, subtle background
|
|
258
|
+
<Alert open={true} variant="soft" severity="warning">
|
|
259
|
+
Soft variant with subtle styling
|
|
260
|
+
</Alert>;
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Hidden Icon
|
|
264
|
+
|
|
265
|
+
Hide the severity icon when needed:
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
import Alert from "#components/alert";
|
|
269
|
+
|
|
270
|
+
<Alert open={true} hideIcon severity="info">
|
|
271
|
+
This alert has no icon.
|
|
272
|
+
</Alert>;
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Custom Icon Size
|
|
276
|
+
|
|
277
|
+
Adjust the icon size:
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import Alert from "#components/alert";
|
|
281
|
+
|
|
282
|
+
<Alert open={true} iconSize={48} severity="error">
|
|
283
|
+
This alert has a larger icon (48px).
|
|
284
|
+
</Alert>;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Critical Alert with Auto-Focus
|
|
288
|
+
|
|
289
|
+
Automatically focus critical alerts for accessibility:
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
import Alert from "#components/alert";
|
|
293
|
+
|
|
294
|
+
<Alert
|
|
295
|
+
open={true}
|
|
296
|
+
severity="error"
|
|
297
|
+
title="Critical Error"
|
|
298
|
+
autoFocus={true}
|
|
299
|
+
dismissible={true}
|
|
300
|
+
>
|
|
301
|
+
A critical error occurred. Please contact support.
|
|
302
|
+
</Alert>;
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Complex Content with Lists
|
|
306
|
+
|
|
307
|
+
Use `contentType="node"` for complex layouts with lists:
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
import Alert from "#components/alert";
|
|
311
|
+
|
|
312
|
+
<Alert
|
|
313
|
+
open={true}
|
|
314
|
+
severity="warning"
|
|
315
|
+
title="Action Required"
|
|
316
|
+
contentType="node"
|
|
317
|
+
dismissible={true}
|
|
318
|
+
>
|
|
319
|
+
<p>Please complete the following security steps:</p>
|
|
320
|
+
<ul>
|
|
321
|
+
<li>Review your recent login activity</li>
|
|
322
|
+
<li>Update your password</li>
|
|
323
|
+
<li>Enable two-factor authentication</li>
|
|
324
|
+
</ul>
|
|
325
|
+
</Alert>;
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Multiple Paragraphs
|
|
329
|
+
|
|
330
|
+
Render multiple paragraphs for detailed messages:
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import Alert from "#components/alert";
|
|
334
|
+
|
|
335
|
+
<Alert
|
|
336
|
+
open={true}
|
|
337
|
+
severity="info"
|
|
338
|
+
title="Privacy Policy Update"
|
|
339
|
+
contentType="node"
|
|
340
|
+
dismissible={true}
|
|
341
|
+
>
|
|
342
|
+
<p>
|
|
343
|
+
We've made significant improvements to our privacy policy to better
|
|
344
|
+
protect your data and give you more control.
|
|
345
|
+
</p>
|
|
346
|
+
<p>
|
|
347
|
+
Please review the changes. The new policy takes effect January 1, 2026.
|
|
348
|
+
</p>
|
|
349
|
+
</Alert>;
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Custom Layout with contentType
|
|
353
|
+
|
|
354
|
+
Create custom layouts for rich alert content:
|
|
355
|
+
|
|
356
|
+
```tsx
|
|
357
|
+
import Alert from "#components/alert";
|
|
358
|
+
|
|
359
|
+
<Alert
|
|
360
|
+
open={true}
|
|
361
|
+
severity="success"
|
|
362
|
+
title="Deployment Complete"
|
|
363
|
+
contentType="node"
|
|
364
|
+
dismissible={true}
|
|
365
|
+
>
|
|
366
|
+
<p>Your application has been deployed successfully!</p>
|
|
367
|
+
<div style={{ display: 'flex', gap: '1rem', marginTop: '0.5rem' }}>
|
|
368
|
+
<div><strong>Build #:</strong> 1234</div>
|
|
369
|
+
<div><strong>Duration:</strong> 2m 34s</div>
|
|
370
|
+
<div><strong>Status:</strong> Live</div>
|
|
371
|
+
</div>
|
|
372
|
+
</Alert>;
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Configurable Heading Hierarchy
|
|
376
|
+
|
|
377
|
+
Maintain proper document structure with `titleLevel`:
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
import Alert from "#components/alert";
|
|
381
|
+
|
|
382
|
+
// In a section with h2 heading
|
|
383
|
+
<section>
|
|
384
|
+
<h2>Account Settings</h2>
|
|
385
|
+
<Alert
|
|
386
|
+
open={true}
|
|
387
|
+
severity="info"
|
|
388
|
+
title="Email Verification Required"
|
|
389
|
+
titleLevel={3}
|
|
390
|
+
dismissible={true}
|
|
391
|
+
>
|
|
392
|
+
Please verify your email address to continue.
|
|
393
|
+
</Alert>
|
|
394
|
+
</section>;
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Advanced Example
|
|
398
|
+
|
|
399
|
+
Combine multiple features:
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
import Alert from "#components/alert";
|
|
403
|
+
import Button from "#components/buttons/button";
|
|
404
|
+
|
|
405
|
+
<Alert
|
|
406
|
+
open={true}
|
|
407
|
+
severity="warning"
|
|
408
|
+
title="Session Expiring Soon"
|
|
409
|
+
variant="filled"
|
|
410
|
+
autoFocus={true}
|
|
411
|
+
dismissible={true}
|
|
412
|
+
autoHideDuration={30000}
|
|
413
|
+
onDismiss={() => console.log("Alert dismissed")}
|
|
414
|
+
iconSize={40}
|
|
415
|
+
actions={
|
|
416
|
+
<Button size="sm" onClick={handleExtendSession}>
|
|
417
|
+
Extend Session
|
|
418
|
+
</Button>
|
|
419
|
+
}
|
|
420
|
+
>
|
|
421
|
+
Your session will expire in 5 minutes. Save your work or extend your session.
|
|
67
422
|
</Alert>;
|
|
68
423
|
```
|
|
69
424
|
|
|
70
|
-
|
|
425
|
+
## Keyboard Interactions
|
|
426
|
+
|
|
427
|
+
| Key | Action |
|
|
428
|
+
| ----- | ---------------------------------------------- |
|
|
429
|
+
| `ESC` | Dismisses the alert (when `dismissible=true`) |
|
|
430
|
+
| `Tab` | Moves focus to dismiss button or action buttons|
|
|
431
|
+
|
|
432
|
+
## Visual Variants
|
|
433
|
+
|
|
434
|
+
### Outlined (Default)
|
|
435
|
+
- Border with background color
|
|
436
|
+
- Icon in severity color
|
|
437
|
+
- Default variant for most use cases
|
|
438
|
+
|
|
439
|
+
### Filled
|
|
440
|
+
- Solid background in severity color
|
|
441
|
+
- White text and icon
|
|
442
|
+
- High visual emphasis
|
|
443
|
+
- Best for critical alerts
|
|
444
|
+
|
|
445
|
+
### Soft
|
|
446
|
+
- No border
|
|
447
|
+
- Subtle background color
|
|
448
|
+
- Low visual weight
|
|
449
|
+
- Best for informational messages
|
|
450
|
+
|
|
451
|
+
## Best Practices
|
|
452
|
+
|
|
453
|
+
### When to Use Each Severity
|
|
454
|
+
|
|
455
|
+
- **Default** - Generic notifications without specific status
|
|
456
|
+
- **Info** - Informational messages that don't require action
|
|
457
|
+
- **Success** - Confirmation of successful actions
|
|
458
|
+
- **Warning** - Alerts requiring attention but not critical
|
|
459
|
+
- **Error** - Critical errors requiring immediate attention
|
|
460
|
+
|
|
461
|
+
### Auto-Dismiss Guidelines
|
|
462
|
+
|
|
463
|
+
- Use for **success** and **info** alerts (non-critical)
|
|
464
|
+
- Avoid for **error** and **warning** alerts (user should explicitly dismiss)
|
|
465
|
+
- Recommended duration: 5000-7000ms for readable messages
|
|
466
|
+
- Always provide `onDismiss` callback for cleanup
|
|
467
|
+
|
|
468
|
+
### Accessibility Guidelines
|
|
469
|
+
|
|
470
|
+
- Use `autoFocus` only for critical errors that require immediate attention
|
|
471
|
+
- Always provide meaningful titles for better screen reader experience
|
|
472
|
+
- Ensure action buttons have descriptive labels
|
|
473
|
+
- Test with keyboard-only navigation
|
|
474
|
+
|
|
475
|
+
### Action Buttons
|
|
476
|
+
|
|
477
|
+
- Limit to 2-3 action buttons for clarity
|
|
478
|
+
- Use small button sizes (`size="sm"`)
|
|
479
|
+
- Primary action first, secondary actions after
|
|
480
|
+
- Always include dismiss option for dismissible alerts
|
|
481
|
+
|
|
482
|
+
### Content Type Selection
|
|
483
|
+
|
|
484
|
+
Choose the appropriate `contentType` based on your content:
|
|
485
|
+
|
|
486
|
+
**Use `contentType="text"` (default) when:**
|
|
487
|
+
- Displaying simple, single-line or single-paragraph text
|
|
488
|
+
- Content is purely text without HTML structure
|
|
489
|
+
- You want automatic semantic paragraph wrapping
|
|
490
|
+
|
|
491
|
+
**Use `contentType="node"` when:**
|
|
492
|
+
- Including lists (ul, ol) in your alert
|
|
493
|
+
- Rendering multiple paragraphs with different styling
|
|
494
|
+
- Using custom components or complex layouts
|
|
495
|
+
- Need fine-grained control over HTML structure
|
|
496
|
+
- Content includes interactive elements
|
|
497
|
+
|
|
498
|
+
### Heading Hierarchy
|
|
499
|
+
|
|
500
|
+
Maintain proper document structure with `titleLevel`:
|
|
501
|
+
|
|
502
|
+
- Always consider the parent heading level
|
|
503
|
+
- Use `titleLevel={2}` for alerts in main content areas
|
|
504
|
+
- Use `titleLevel={3}` for alerts within sections
|
|
505
|
+
- Use `titleLevel={4}` or higher for nested subsections
|
|
506
|
+
- Screen readers use heading levels for navigation
|
|
507
|
+
|
|
508
|
+
**Example:**
|
|
509
|
+
```tsx
|
|
510
|
+
<h1>Dashboard</h1>
|
|
511
|
+
<h2>Notifications</h2>
|
|
512
|
+
<Alert titleLevel={3} title="New Message">...</Alert>
|
|
513
|
+
<h2>Settings</h2>
|
|
514
|
+
<Alert titleLevel={3} title="Update Available">...</Alert>
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## Additional Notes
|
|
71
518
|
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
519
|
+
- **WCAG 2.1 Level AA Compliant** - Meets all accessibility standards including color contrast, touch targets, focus indicators, and screen reader support
|
|
520
|
+
- **Flexible Content Rendering** - `contentType` prop supports both simple text and complex HTML structures while maintaining semantic correctness
|
|
521
|
+
- **Screen Reader Optimized** - Visually hidden severity text provides context ("Error:", "Warning:", etc.) for screen reader users
|
|
522
|
+
- **Pause on Interaction** - Auto-dismiss automatically pauses when users hover or focus the alert (WCAG 2.2.1)
|
|
523
|
+
- **Semantic Heading Levels** - `titleLevel` prop enables proper document hierarchy for accessibility and SEO
|
|
524
|
+
- **Exit Animations** - GPU-accelerated CSS transitions with automatic cleanup and reduced-motion support
|
|
525
|
+
- **Performance Optimized** - Severity icons are memoized, timers auto-cleanup on unmount
|
|
526
|
+
- **Keyboard Accessible** - ESC key dismissal with proper event listener cleanup
|
|
527
|
+
- **Touch-Friendly** - Dismiss button meets 44×44px minimum touch target size
|
|
528
|
+
- **Focus Management** - Visible 2px focus indicators for keyboard navigation
|
|
529
|
+
- **Custom Icons** - Fine-grained icon control through `iconProps` for advanced use cases
|
|
530
|
+
- **Backward Compatible** - All new features have sensible defaults and zero breaking changes
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/* Screen reader only utility class */
|
|
2
|
+
.sr-only {
|
|
3
|
+
position: absolute;
|
|
4
|
+
width: 1px;
|
|
5
|
+
height: 1px;
|
|
6
|
+
padding: 0;
|
|
7
|
+
margin: -1px;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
clip: rect(0, 0, 0, 0);
|
|
10
|
+
white-space: nowrap;
|
|
11
|
+
border-width: 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
1
14
|
[role="alert"] {
|
|
2
15
|
/* Success colors */
|
|
3
16
|
--alert-success-bg: #e6f4ea;
|
|
@@ -19,6 +32,9 @@
|
|
|
19
32
|
--alert-info-border: #0288d1;
|
|
20
33
|
--alert-info-text: #084154;
|
|
21
34
|
|
|
35
|
+
/* Animation */
|
|
36
|
+
--alert-transition-duration: 0.3s;
|
|
37
|
+
|
|
22
38
|
--alert-border: thin solid currentColor;
|
|
23
39
|
|
|
24
40
|
background-color: var(--alert-bg, whitesmoke);
|
|
@@ -30,11 +46,37 @@
|
|
|
30
46
|
line-height: 1.6;
|
|
31
47
|
display: flex;
|
|
32
48
|
flex-direction: row;
|
|
33
|
-
// align-items: center;
|
|
34
49
|
border-radius: var(--alert-border-radius, var(--border-radius));
|
|
35
|
-
border: var(--alert-border);
|
|
36
50
|
gap: var(--alert-gap, var(--spc-4));
|
|
37
|
-
|
|
51
|
+
|
|
52
|
+
/* Exit animations */
|
|
53
|
+
transition:
|
|
54
|
+
opacity var(--alert-transition-duration) ease,
|
|
55
|
+
transform var(--alert-transition-duration) ease;
|
|
56
|
+
opacity: 1;
|
|
57
|
+
transform: translateY(0);
|
|
58
|
+
|
|
59
|
+
&:not([data-visible="true"]) {
|
|
60
|
+
opacity: 0;
|
|
61
|
+
transform: translateY(-0.5rem);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@media (prefers-reduced-motion: reduce) {
|
|
65
|
+
transition-duration: 0.01ms;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Focus indicators for keyboard navigation (WCAG 2.4.7) */
|
|
69
|
+
&:focus {
|
|
70
|
+
outline: 2px solid currentColor;
|
|
71
|
+
outline-offset: 2px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Hide focus outline for mouse clicks, keep for keyboard */
|
|
75
|
+
&:focus:not(:focus-visible) {
|
|
76
|
+
outline: none;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.alert-icon {
|
|
38
80
|
margin-block-start: 0;
|
|
39
81
|
align-items: center;
|
|
40
82
|
}
|
|
@@ -42,8 +84,26 @@
|
|
|
42
84
|
.alert-message {
|
|
43
85
|
flex: 2;
|
|
44
86
|
margin-block-start: 0;
|
|
45
|
-
|
|
46
|
-
|
|
87
|
+
|
|
88
|
+
/* Title styles for both heading and strong elements */
|
|
89
|
+
.alert-title {
|
|
90
|
+
margin-block-end: var(--spc-1, 0.25rem);
|
|
91
|
+
margin-block-start: 0;
|
|
92
|
+
font-weight: var(--alert-title-weight, 600);
|
|
93
|
+
font-size: var(--alert-title-size, inherit);
|
|
94
|
+
line-height: 1.4;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Reset heading-specific styles */
|
|
98
|
+
h2.alert-title,
|
|
99
|
+
h3.alert-title,
|
|
100
|
+
h4.alert-title,
|
|
101
|
+
h5.alert-title,
|
|
102
|
+
h6.alert-title {
|
|
103
|
+
margin: 0;
|
|
104
|
+
margin-block-end: var(--spc-1, 0.25rem);
|
|
105
|
+
font-size: inherit;
|
|
106
|
+
font-weight: var(--alert-title-weight, 600);
|
|
47
107
|
}
|
|
48
108
|
}
|
|
49
109
|
|
|
@@ -74,7 +134,54 @@
|
|
|
74
134
|
button {
|
|
75
135
|
&[data-btn~="icon"] {
|
|
76
136
|
--btn-bg: transparent;
|
|
77
|
-
// max-height: 1.5rem;
|
|
78
137
|
}
|
|
79
138
|
}
|
|
139
|
+
|
|
140
|
+
* + div {
|
|
141
|
+
margin-block-start: var(--spc-1);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Variant: Filled - Solid colored background */
|
|
145
|
+
&[data-variant="filled"] {
|
|
146
|
+
border: none;
|
|
147
|
+
|
|
148
|
+
&[data-alert~="info"] {
|
|
149
|
+
--alert-bg: var(--alert-info-border);
|
|
150
|
+
--alert-color: white;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
&[data-alert~="warning"] {
|
|
154
|
+
--alert-bg: var(--alert-warning-border);
|
|
155
|
+
--alert-color: white;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
&[data-alert~="error"] {
|
|
159
|
+
--alert-bg: var(--alert-error-border);
|
|
160
|
+
--alert-color: white;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
&[data-alert~="success"] {
|
|
164
|
+
--alert-bg: var(--alert-success-border);
|
|
165
|
+
--alert-color: white;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&[data-alert~="default"] {
|
|
169
|
+
--alert-bg: #757575;
|
|
170
|
+
--alert-color: white;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Variant: Soft - No border, subtle background */
|
|
175
|
+
&[data-variant="soft"] {
|
|
176
|
+
border: none;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Variant: Outlined - Default with border (no additional styles needed) */
|
|
180
|
+
&[data-variant="outlined"] {
|
|
181
|
+
/* This is the default variant, styles already applied above */
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
p {
|
|
185
|
+
font-size: 0.875rem;
|
|
186
|
+
}
|
|
80
187
|
}
|