@fpkit/acss 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/{chunk-2NRIP6RB.cjs → chunk-2C3YLBWP.cjs} +3 -3
- package/libs/{chunk-NWJDAHP6.cjs → chunk-2GJHKWEK.cjs} +3 -3
- package/libs/{chunk-FVROL3V5.js → chunk-2JCDEC32.js} +3 -3
- package/libs/{chunk-IRLFZ3OL.js → chunk-3XJC4XUG.js} +2 -2
- package/libs/{chunk-23ANBDCR.js → chunk-4I5MF54P.js} +3 -3
- package/libs/chunk-4I5MF54P.js.map +1 -0
- package/libs/chunk-5CJPTDK3.cjs +31 -0
- package/libs/chunk-5CJPTDK3.cjs.map +1 -0
- package/libs/{chunk-E4OSROCA.cjs → chunk-5QSNJQVH.cjs} +3 -3
- package/libs/{chunk-O3JIHC5M.cjs → chunk-6BUJZ4DJ.cjs} +3 -3
- package/libs/{chunk-WXBFBWYF.cjs → chunk-AFINOD2L.cjs} +3 -3
- package/libs/{chunk-HRRHPLER.js → chunk-AWZLSWDO.js} +2 -2
- package/libs/chunk-DDSXKOUB.js +7 -0
- package/libs/chunk-DDSXKOUB.js.map +1 -0
- package/libs/{chunk-CWRNJA4P.js → chunk-DIJBIOFE.js} +3 -3
- package/libs/chunk-EJ6KYBFE.cjs +13 -0
- package/libs/chunk-EJ6KYBFE.cjs.map +1 -0
- package/libs/{chunk-GUJSMQ3V.cjs → chunk-EKJYOCLY.cjs} +3 -3
- package/libs/{chunk-X5RKCLDC.cjs → chunk-F64GE6RG.cjs} +4 -4
- package/libs/chunk-FMIM3332.js +8 -0
- package/libs/chunk-FMIM3332.js.map +1 -0
- package/libs/{chunk-5RAWNUVD.js → chunk-IBUTNPTQ.js} +2 -2
- package/libs/chunk-IWP4VJEP.cjs +18 -0
- package/libs/chunk-IWP4VJEP.cjs.map +1 -0
- package/libs/{chunk-ZFJ4U45S.js → chunk-KDMX3FAW.js} +2 -2
- package/libs/{chunk-DYFAUAB7.cjs → chunk-LXODKKA3.cjs} +4 -4
- package/libs/chunk-M7JLT62Q.js +9 -0
- package/libs/chunk-M7JLT62Q.js.map +1 -0
- package/libs/{chunk-IQ76HGVP.js → chunk-MBWI67UT.js} +2 -2
- package/libs/{chunk-O5XAJ7BY.cjs → chunk-NCGVF2QS.cjs} +4 -4
- package/libs/{chunk-W2UIN7EV.cjs → chunk-NPWHQVYB.cjs} +3 -3
- package/libs/{chunk-G55UJ53G.cjs → chunk-NZVSXRTB.cjs} +3 -3
- package/libs/chunk-NZVSXRTB.cjs.map +1 -0
- package/libs/{chunk-43TK2ICH.js → chunk-PMWL5XZ4.js} +3 -3
- package/libs/{chunk-KVKQLRJG.js → chunk-TF3GQKOY.js} +2 -2
- package/libs/chunk-TNEJXNZA.cjs +22 -0
- package/libs/chunk-TNEJXNZA.cjs.map +1 -0
- package/libs/{chunk-IEB64SWY.js → chunk-U5VA34SU.js} +2 -2
- package/libs/chunk-UGMP72J2.js +8 -0
- package/libs/chunk-UGMP72J2.js.map +1 -0
- package/libs/{chunk-MGPWZRBX.cjs → chunk-URBGDUFN.cjs} +6 -6
- package/libs/{chunk-QKHPHMG2.js → chunk-ZF6Y7W57.js} +5 -5
- package/libs/component-props-50e69975.d.ts +66 -0
- package/libs/components/box/box.css +1 -0
- package/libs/components/box/box.css.map +1 -0
- package/libs/components/box/box.min.css +3 -0
- package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
- package/libs/components/breadcrumbs/breadcrumb.js +3 -3
- package/libs/components/button.cjs +4 -4
- package/libs/components/button.d.cts +10 -3
- package/libs/components/button.d.ts +10 -3
- package/libs/components/button.js +2 -2
- package/libs/components/card.cjs +7 -7
- package/libs/components/card.d.cts +13 -85
- package/libs/components/card.d.ts +13 -85
- 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/cluster/cluster.css +1 -0
- package/libs/components/cluster/cluster.css.map +1 -0
- package/libs/components/cluster/cluster.min.css +3 -0
- package/libs/components/dialog/dialog.cjs +7 -7
- package/libs/components/dialog/dialog.js +5 -5
- package/libs/components/form/fields.cjs +4 -4
- package/libs/components/form/fields.js +2 -2
- package/libs/components/form/textarea.cjs +4 -4
- package/libs/components/form/textarea.js +2 -2
- package/libs/components/grid/grid.css +1 -0
- package/libs/components/grid/grid.css.map +1 -0
- package/libs/components/grid/grid.min.css +3 -0
- package/libs/components/heading/heading.cjs +3 -3
- package/libs/components/heading/heading.js +2 -2
- package/libs/components/icons/icon.cjs +4 -4
- package/libs/components/icons/icon.d.cts +2 -2
- package/libs/components/icons/icon.d.ts +2 -2
- package/libs/components/icons/icon.js +2 -2
- package/libs/components/link/link.cjs +6 -6
- package/libs/components/link/link.js +2 -2
- package/libs/components/list/list.cjs +5 -5
- package/libs/components/list/list.js +2 -2
- package/libs/components/modal.cjs +4 -4
- package/libs/components/modal.d.cts +1 -1
- package/libs/components/modal.d.ts +1 -1
- package/libs/components/modal.js +3 -3
- package/libs/components/nav/nav.cjs +7 -7
- package/libs/components/nav/nav.js +3 -3
- package/libs/components/popover/popover.cjs +4 -4
- package/libs/components/popover/popover.d.cts +1 -1
- package/libs/components/popover/popover.d.ts +1 -1
- package/libs/components/popover/popover.js +1 -1
- package/libs/components/stack/stack.css +1 -0
- package/libs/components/stack/stack.css.map +1 -0
- package/libs/components/stack/stack.min.css +3 -0
- package/libs/components/tables/table.cjs +4 -4
- package/libs/components/tables/table.d.cts +2 -2
- package/libs/components/tables/table.d.ts +2 -2
- package/libs/components/tables/table.js +1 -1
- package/libs/components/text/text.cjs +5 -5
- package/libs/components/text/text.js +2 -2
- package/libs/hooks.cjs +4 -4
- package/libs/hooks.js +3 -3
- package/libs/{icons-287fce3a.d.ts → icons-df8e744f.d.ts} +1 -1
- package/libs/icons.cjs +3 -3
- package/libs/icons.d.cts +2 -2
- package/libs/icons.d.ts +2 -2
- package/libs/icons.js +2 -2
- package/libs/index.cjs +74 -73
- 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 +925 -6
- package/libs/index.d.ts +925 -6
- package/libs/index.js +30 -30
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.tsx +1 -3
- package/src/components/alert/STYLES.mdx +790 -0
- package/src/components/badge/STYLES.mdx +610 -0
- package/src/components/box/README.mdx +401 -0
- package/src/components/box/STYLES.mdx +360 -0
- package/src/components/box/box.scss +245 -0
- package/src/components/box/box.stories.tsx +395 -0
- package/src/components/box/box.test.tsx +425 -0
- package/src/components/box/box.tsx +170 -0
- package/src/components/box/box.types.ts +166 -0
- package/src/components/breadcrumbs/STYLES.mdx +99 -0
- package/src/components/breadcrumbs/bc-item.tsx +0 -1
- package/src/components/buttons/STYLES.mdx +766 -0
- package/src/components/cards/STYLES.mdx +835 -0
- package/src/components/cards/card.scss +29 -21
- package/src/components/cards/card.tsx +13 -3
- package/src/components/cards/card.types.ts +13 -0
- package/src/components/cluster/README.mdx +595 -0
- package/src/components/cluster/STYLES.mdx +626 -0
- package/src/components/cluster/cluster.scss +86 -0
- package/src/components/cluster/cluster.stories.tsx +385 -0
- package/src/components/cluster/cluster.test.tsx +655 -0
- package/src/components/cluster/cluster.tsx +94 -0
- package/src/components/cluster/cluster.types.ts +75 -0
- package/src/components/details/STYLES.mdx +445 -0
- package/src/components/dialog/STYLES.mdx +888 -0
- package/src/components/flexbox/STYLES.mdx +857 -0
- package/src/components/flexbox/flex.stories.tsx +842 -141
- package/src/components/flexbox/flex.types.ts +25 -6
- package/src/components/form/STYLES.mdx +821 -0
- package/src/components/grid/README.mdx +709 -0
- package/src/components/grid/STYLES.mdx +785 -0
- package/src/components/grid/grid.scss +287 -0
- package/src/components/grid/grid.stories.tsx +486 -0
- package/src/components/grid/grid.test.tsx +981 -0
- package/src/components/grid/grid.tsx +222 -0
- package/src/components/grid/grid.types.ts +344 -0
- package/src/components/icons/STYLES.mdx +56 -0
- package/src/components/icons/components/arrow-right.tsx +0 -5
- package/src/components/images/STYLES.mdx +75 -0
- package/src/components/kit.tsx +8 -4
- package/src/components/layout/STYLES.mdx +556 -0
- package/src/components/link/STYLES.mdx +75 -0
- package/src/components/list/STYLES.mdx +631 -0
- package/src/components/nav/STYLES.mdx +460 -0
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/progress/STYLES.mdx +64 -0
- package/src/components/stack/README.mdx +400 -0
- package/src/components/stack/STYLES.mdx +414 -0
- package/src/components/stack/stack.scss +109 -0
- package/src/components/stack/stack.stories.tsx +559 -0
- package/src/components/stack/stack.test.tsx +426 -0
- package/src/components/stack/stack.tsx +141 -0
- package/src/components/stack/stack.types.ts +133 -0
- package/src/components/tables/table-elements.tsx +1 -1
- package/src/components/tables/table.tsx +2 -2
- package/src/components/tag/STYLES.mdx +105 -0
- package/src/components/text-to-speech/STYLES.mdx +80 -0
- package/src/components/text-to-speech/TextToSpeech.tsx +0 -4
- package/src/components/text-to-speech/useTextToSpeech.tsx +2 -6
- package/src/components/ui.tsx +3 -3
- package/src/decorators/instructions.tsx +22 -18
- package/src/hooks/popover/popover.tsx +1 -1
- package/src/index.scss +5 -1
- package/src/index.ts +305 -12
- package/src/sass/GLOBALS-STYLES.md +631 -0
- package/src/sass/_globals.scss +45 -24
- package/src/styles/box/box.css +220 -0
- package/src/styles/box/box.css.map +1 -0
- package/src/styles/cards/card.css +22 -17
- package/src/styles/cards/card.css.map +1 -1
- package/src/styles/cluster/cluster.css +71 -0
- package/src/styles/cluster/cluster.css.map +1 -0
- package/src/styles/grid/grid.css +238 -0
- package/src/styles/grid/grid.css.map +1 -0
- package/src/styles/index.css +667 -49
- package/src/styles/index.css.map +1 -1
- package/src/styles/stack/stack.css +86 -0
- package/src/styles/stack/stack.css.map +1 -0
- package/src/types/component-props.ts +42 -13
- package/src/types/layout-primitives.ts +48 -0
- package/src/types/shared.ts +10 -26
- package/libs/chunk-23ANBDCR.js.map +0 -1
- package/libs/chunk-5QD3DWFI.js +0 -9
- package/libs/chunk-5QD3DWFI.js.map +0 -1
- package/libs/chunk-6WTC4JXH.cjs +0 -31
- package/libs/chunk-6WTC4JXH.cjs.map +0 -1
- package/libs/chunk-ENTCUJ3A.cjs +0 -13
- package/libs/chunk-ENTCUJ3A.cjs.map +0 -1
- package/libs/chunk-G55UJ53G.cjs.map +0 -1
- package/libs/chunk-HHLNOC5T.js +0 -7
- package/libs/chunk-HHLNOC5T.js.map +0 -1
- package/libs/chunk-KK47SYZI.js +0 -8
- package/libs/chunk-KK47SYZI.js.map +0 -1
- package/libs/chunk-US2I5GI7.cjs +0 -22
- package/libs/chunk-US2I5GI7.cjs.map +0 -1
- package/libs/chunk-W5TKWBFC.cjs +0 -18
- package/libs/chunk-W5TKWBFC.cjs.map +0 -1
- package/libs/chunk-Y2PFDELK.js +0 -8
- package/libs/chunk-Y2PFDELK.js.map +0 -1
- package/libs/component-props-67d978a2.d.ts +0 -38
- /package/libs/{chunk-2NRIP6RB.cjs.map → chunk-2C3YLBWP.cjs.map} +0 -0
- /package/libs/{chunk-NWJDAHP6.cjs.map → chunk-2GJHKWEK.cjs.map} +0 -0
- /package/libs/{chunk-FVROL3V5.js.map → chunk-2JCDEC32.js.map} +0 -0
- /package/libs/{chunk-IRLFZ3OL.js.map → chunk-3XJC4XUG.js.map} +0 -0
- /package/libs/{chunk-E4OSROCA.cjs.map → chunk-5QSNJQVH.cjs.map} +0 -0
- /package/libs/{chunk-O3JIHC5M.cjs.map → chunk-6BUJZ4DJ.cjs.map} +0 -0
- /package/libs/{chunk-WXBFBWYF.cjs.map → chunk-AFINOD2L.cjs.map} +0 -0
- /package/libs/{chunk-HRRHPLER.js.map → chunk-AWZLSWDO.js.map} +0 -0
- /package/libs/{chunk-CWRNJA4P.js.map → chunk-DIJBIOFE.js.map} +0 -0
- /package/libs/{chunk-GUJSMQ3V.cjs.map → chunk-EKJYOCLY.cjs.map} +0 -0
- /package/libs/{chunk-X5RKCLDC.cjs.map → chunk-F64GE6RG.cjs.map} +0 -0
- /package/libs/{chunk-5RAWNUVD.js.map → chunk-IBUTNPTQ.js.map} +0 -0
- /package/libs/{chunk-ZFJ4U45S.js.map → chunk-KDMX3FAW.js.map} +0 -0
- /package/libs/{chunk-DYFAUAB7.cjs.map → chunk-LXODKKA3.cjs.map} +0 -0
- /package/libs/{chunk-IQ76HGVP.js.map → chunk-MBWI67UT.js.map} +0 -0
- /package/libs/{chunk-O5XAJ7BY.cjs.map → chunk-NCGVF2QS.cjs.map} +0 -0
- /package/libs/{chunk-W2UIN7EV.cjs.map → chunk-NPWHQVYB.cjs.map} +0 -0
- /package/libs/{chunk-43TK2ICH.js.map → chunk-PMWL5XZ4.js.map} +0 -0
- /package/libs/{chunk-KVKQLRJG.js.map → chunk-TF3GQKOY.js.map} +0 -0
- /package/libs/{chunk-IEB64SWY.js.map → chunk-U5VA34SU.js.map} +0 -0
- /package/libs/{chunk-MGPWZRBX.cjs.map → chunk-URBGDUFN.cjs.map} +0 -0
- /package/libs/{chunk-QKHPHMG2.js.map → chunk-ZF6Y7W57.js.map} +0 -0
|
@@ -0,0 +1,888 @@
|
|
|
1
|
+
import { Meta } from "@storybook/addon-docs/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Dialog/Styles" />
|
|
4
|
+
|
|
5
|
+
# Dialog Styles
|
|
6
|
+
|
|
7
|
+
Modal dialog styling system with CSS custom properties for creating accessible,
|
|
8
|
+
keyboard-navigable dialogs with headers, content, and action footers.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
The fpkit dialog styling system provides a complete foundation for modal dialogs
|
|
13
|
+
using the native `<dialog>` HTML element. Includes support for headers, close
|
|
14
|
+
buttons, content sections, and action footers, all with comprehensive keyboard
|
|
15
|
+
accessibility and high contrast mode support.
|
|
16
|
+
|
|
17
|
+
### Key Features
|
|
18
|
+
|
|
19
|
+
- **Native `<dialog>` element** - Built on HTML5 dialog with proper semantics
|
|
20
|
+
- **Flexible layout** - Flexbox-based column layout with customizable gap
|
|
21
|
+
- **Header with close button** - Pre-styled header section with close control
|
|
22
|
+
- **Action footer** - Flexible footer for action buttons
|
|
23
|
+
- **Keyboard accessibility** - Full keyboard navigation with visible focus
|
|
24
|
+
indicators
|
|
25
|
+
- **High contrast mode** - Automatic adjustments for users who need high
|
|
26
|
+
contrast
|
|
27
|
+
- **CSS custom properties** - Extensive theming via CSS variables
|
|
28
|
+
- **Rem-based sizing** - All measurements use rem units (1rem = 16px)
|
|
29
|
+
- **WCAG compliant** - Accessible focus indicators and semantic structure
|
|
30
|
+
|
|
31
|
+
## CSS Custom Properties
|
|
32
|
+
|
|
33
|
+
### Base Dialog Properties
|
|
34
|
+
|
|
35
|
+
Root-level variables define the dialog's overall appearance:
|
|
36
|
+
|
|
37
|
+
```css
|
|
38
|
+
:root {
|
|
39
|
+
/* Dimensions */
|
|
40
|
+
--dialog-min-width: max(20rem, 80%); /* Responsive width: min 320px or 80% */
|
|
41
|
+
|
|
42
|
+
/* Layout */
|
|
43
|
+
--dialog-display: flex;
|
|
44
|
+
--dialog-flex-direction: column;
|
|
45
|
+
--dialog-gap: 0.625rem; /* 10px */
|
|
46
|
+
|
|
47
|
+
/* Spacing */
|
|
48
|
+
--dialog-padding: 1.5rem; /* 24px */
|
|
49
|
+
--dialog-padding-inline: 1rem; /* 16px (currently unused) */
|
|
50
|
+
|
|
51
|
+
/* Borders */
|
|
52
|
+
--dialog-border-color: lightgray;
|
|
53
|
+
--dialog-border-width: thin; /* ~1px */
|
|
54
|
+
--dialog-border-style: solid;
|
|
55
|
+
--dialog-border-radius: var(--border-radius);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Button Properties
|
|
60
|
+
|
|
61
|
+
Variables for dialog header close button:
|
|
62
|
+
|
|
63
|
+
```css
|
|
64
|
+
:root {
|
|
65
|
+
/* Close button */
|
|
66
|
+
--dialog-close-color: gray;
|
|
67
|
+
--dialog-button-bg: transparent;
|
|
68
|
+
--dialog-button-border: transparent thin solid;
|
|
69
|
+
--dialog-button-hover-bg: whitesmoke;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Focus & Accessibility Properties
|
|
74
|
+
|
|
75
|
+
```css
|
|
76
|
+
:root {
|
|
77
|
+
/* Focus indicators */
|
|
78
|
+
--dialog-focus-color: #0066cc; /* Blue focus color */
|
|
79
|
+
--dialog-focus-width: 0.125rem; /* 2px */
|
|
80
|
+
--dialog-focus-offset: 0.125rem; /* 2px */
|
|
81
|
+
--dialog-focus-outline: var(--dialog-focus-width) solid var(
|
|
82
|
+
--dialog-focus-color
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Footer Properties
|
|
88
|
+
|
|
89
|
+
```css
|
|
90
|
+
.dialog-footer {
|
|
91
|
+
/* Footer alignment */
|
|
92
|
+
--dialog-footer-justify: flex-end; /* Right-align action buttons */
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### High Contrast Mode Support
|
|
97
|
+
|
|
98
|
+
Automatic adjustments for users with high contrast preferences:
|
|
99
|
+
|
|
100
|
+
```css
|
|
101
|
+
@media (prefers-contrast: high) {
|
|
102
|
+
:root {
|
|
103
|
+
--dialog-border-color: currentColor;
|
|
104
|
+
--dialog-border-width: 0.125rem; /* 2px (thicker) */
|
|
105
|
+
--dialog-close-color: currentColor;
|
|
106
|
+
--dialog-button-border: currentColor 0.125rem solid;
|
|
107
|
+
--dialog-focus-width: 0.1875rem; /* 3px (thicker) */
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Customizing Dialog Styles
|
|
113
|
+
|
|
114
|
+
Override CSS variables:
|
|
115
|
+
|
|
116
|
+
```css
|
|
117
|
+
dialog {
|
|
118
|
+
--dialog-border-color: #0066cc;
|
|
119
|
+
--dialog-padding: 2rem;
|
|
120
|
+
--dialog-gap: 1rem;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Or inline:
|
|
125
|
+
|
|
126
|
+
```html
|
|
127
|
+
<dialog style="--dialog-border-color: blue; --dialog-padding: 2rem">
|
|
128
|
+
<!-- Dialog content -->
|
|
129
|
+
</dialog>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Dialog Structure
|
|
133
|
+
|
|
134
|
+
### Basic Dialog
|
|
135
|
+
|
|
136
|
+
Simple dialog with content:
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<dialog id="myDialog">
|
|
140
|
+
<p>This is a dialog.</p>
|
|
141
|
+
<button type="button" onclick="document.getElementById('myDialog').close()">
|
|
142
|
+
Close
|
|
143
|
+
</button>
|
|
144
|
+
</dialog>
|
|
145
|
+
|
|
146
|
+
<button onclick="document.getElementById('myDialog').showModal()">
|
|
147
|
+
Open Dialog
|
|
148
|
+
</button>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**CSS Applied:**
|
|
152
|
+
|
|
153
|
+
```css
|
|
154
|
+
dialog {
|
|
155
|
+
width: max(20rem, 80%);
|
|
156
|
+
min-width: max(20rem, 80%);
|
|
157
|
+
gap: 0.625rem;
|
|
158
|
+
border: lightgray thin solid;
|
|
159
|
+
border-radius: var(--border-radius);
|
|
160
|
+
padding: 1.5rem;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
dialog[open] {
|
|
164
|
+
display: flex;
|
|
165
|
+
flex-direction: column;
|
|
166
|
+
gap: 0.625rem;
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Dialog with Header
|
|
171
|
+
|
|
172
|
+
Dialog with title and close button:
|
|
173
|
+
|
|
174
|
+
```html
|
|
175
|
+
<dialog id="headerDialog">
|
|
176
|
+
<div class="dialog-header">
|
|
177
|
+
<h3>Dialog Title</h3>
|
|
178
|
+
<button
|
|
179
|
+
type="button"
|
|
180
|
+
class="dialog-close"
|
|
181
|
+
onclick="document.getElementById('headerDialog').close()"
|
|
182
|
+
aria-label="Close dialog"
|
|
183
|
+
>
|
|
184
|
+
✕
|
|
185
|
+
</button>
|
|
186
|
+
</div>
|
|
187
|
+
<p>Dialog content goes here.</p>
|
|
188
|
+
</dialog>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**CSS Applied:**
|
|
192
|
+
|
|
193
|
+
```css
|
|
194
|
+
.dialog-header {
|
|
195
|
+
display: flex;
|
|
196
|
+
justify-content: space-between;
|
|
197
|
+
align-items: center;
|
|
198
|
+
width: 100%;
|
|
199
|
+
min-width: 100%;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.dialog-header h3 {
|
|
203
|
+
margin-block-start: 0;
|
|
204
|
+
margin-block-end: 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.dialog-header button[type="button"] {
|
|
208
|
+
background-color: transparent;
|
|
209
|
+
border: transparent thin solid;
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.dialog-header button[type="button"]:hover {
|
|
214
|
+
border-color: gray;
|
|
215
|
+
background-color: whitesmoke;
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Dialog with Header, Content, and Footer
|
|
220
|
+
|
|
221
|
+
Complete dialog structure:
|
|
222
|
+
|
|
223
|
+
```html
|
|
224
|
+
<dialog id="fullDialog">
|
|
225
|
+
<div class="dialog-header">
|
|
226
|
+
<h3>Confirm Action</h3>
|
|
227
|
+
<button
|
|
228
|
+
type="button"
|
|
229
|
+
class="dialog-close"
|
|
230
|
+
onclick="document.getElementById('fullDialog').close()"
|
|
231
|
+
aria-label="Close dialog"
|
|
232
|
+
>
|
|
233
|
+
✕
|
|
234
|
+
</button>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
<section>
|
|
238
|
+
<p>Are you sure you want to proceed with this action?</p>
|
|
239
|
+
</section>
|
|
240
|
+
|
|
241
|
+
<div class="dialog-footer">
|
|
242
|
+
<button
|
|
243
|
+
type="button"
|
|
244
|
+
onclick="document.getElementById('fullDialog').close()"
|
|
245
|
+
>
|
|
246
|
+
Cancel
|
|
247
|
+
</button>
|
|
248
|
+
<button
|
|
249
|
+
type="submit"
|
|
250
|
+
onclick="document.getElementById('fullDialog').close()"
|
|
251
|
+
>
|
|
252
|
+
Confirm
|
|
253
|
+
</button>
|
|
254
|
+
</div>
|
|
255
|
+
</dialog>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**CSS Applied:**
|
|
259
|
+
|
|
260
|
+
```css
|
|
261
|
+
dialog section {
|
|
262
|
+
width: 100%;
|
|
263
|
+
display: flex;
|
|
264
|
+
justify-content: start;
|
|
265
|
+
gap: 0.625rem;
|
|
266
|
+
flex-direction: column;
|
|
267
|
+
margin-block-start: 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.dialog-footer {
|
|
271
|
+
display: flex;
|
|
272
|
+
flex-direction: row;
|
|
273
|
+
flex-wrap: wrap;
|
|
274
|
+
justify-content: flex-end; /* Right-aligned buttons */
|
|
275
|
+
gap: 0.625rem;
|
|
276
|
+
width: 100%;
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Dialog Components
|
|
281
|
+
|
|
282
|
+
### Dialog Header
|
|
283
|
+
|
|
284
|
+
Header section with title and close button:
|
|
285
|
+
|
|
286
|
+
```html
|
|
287
|
+
<div class="dialog-header">
|
|
288
|
+
<h3>Dialog Title</h3>
|
|
289
|
+
<button type="button" class="dialog-close" aria-label="Close">✕</button>
|
|
290
|
+
</div>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Features:**
|
|
294
|
+
|
|
295
|
+
- Flexbox layout with space-between
|
|
296
|
+
- Close button with hover state
|
|
297
|
+
- Automatic heading margin removal
|
|
298
|
+
- Full width
|
|
299
|
+
|
|
300
|
+
### Dialog Section
|
|
301
|
+
|
|
302
|
+
Content area for dialog body:
|
|
303
|
+
|
|
304
|
+
```html
|
|
305
|
+
<section>
|
|
306
|
+
<p>Main dialog content goes here.</p>
|
|
307
|
+
<p>Additional paragraphs or form elements.</p>
|
|
308
|
+
</section>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Features:**
|
|
312
|
+
|
|
313
|
+
- Full width
|
|
314
|
+
- Flexbox column layout
|
|
315
|
+
- Consistent gap spacing
|
|
316
|
+
- Zero top margin
|
|
317
|
+
|
|
318
|
+
### Dialog Footer
|
|
319
|
+
|
|
320
|
+
Action button area (also works with `alert-dialog-actions` class):
|
|
321
|
+
|
|
322
|
+
```html
|
|
323
|
+
<div class="dialog-footer">
|
|
324
|
+
<button type="button">Cancel</button>
|
|
325
|
+
<button type="submit">Confirm</button>
|
|
326
|
+
</div>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Features:**
|
|
330
|
+
|
|
331
|
+
- Right-aligned buttons (default)
|
|
332
|
+
- Flexbox row layout with wrapping
|
|
333
|
+
- Consistent gap between buttons
|
|
334
|
+
- Full width
|
|
335
|
+
|
|
336
|
+
**Custom Alignment:**
|
|
337
|
+
|
|
338
|
+
```html
|
|
339
|
+
<!-- Center-aligned buttons -->
|
|
340
|
+
<div class="dialog-footer" style="--dialog-footer-justify: center">
|
|
341
|
+
<button>OK</button>
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<!-- Left-aligned buttons -->
|
|
345
|
+
<div class="dialog-footer" style="--dialog-footer-justify: flex-start">
|
|
346
|
+
<button>Back</button>
|
|
347
|
+
<button>Next</button>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
<!-- Space between buttons -->
|
|
351
|
+
<div class="dialog-footer" style="--dialog-footer-justify: space-between">
|
|
352
|
+
<button>Cancel</button>
|
|
353
|
+
<button>Confirm</button>
|
|
354
|
+
</div>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Focus & Keyboard Accessibility
|
|
358
|
+
|
|
359
|
+
### Dialog Focus
|
|
360
|
+
|
|
361
|
+
The dialog element itself receives focus when opened:
|
|
362
|
+
|
|
363
|
+
```css
|
|
364
|
+
dialog:focus-visible {
|
|
365
|
+
outline: 0.125rem solid #0066cc;
|
|
366
|
+
outline-offset: 0.125rem;
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Button Focus
|
|
371
|
+
|
|
372
|
+
Close button and footer buttons have visible focus indicators:
|
|
373
|
+
|
|
374
|
+
```css
|
|
375
|
+
.dialog-header button:focus-visible,
|
|
376
|
+
.dialog-footer button:focus-visible {
|
|
377
|
+
outline: 0.125rem solid #0066cc;
|
|
378
|
+
outline-offset: 0.125rem;
|
|
379
|
+
border-color: #0066cc;
|
|
380
|
+
background-color: whitesmoke;
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Keyboard Navigation
|
|
385
|
+
|
|
386
|
+
- **Escape** - Close dialog (native behavior)
|
|
387
|
+
- **Tab** - Move to next focusable element
|
|
388
|
+
- **Shift+Tab** - Move to previous focusable element
|
|
389
|
+
- **Enter** or **Space** - Activate focused button
|
|
390
|
+
|
|
391
|
+
### Focus Trap
|
|
392
|
+
|
|
393
|
+
The native `<dialog>` element automatically traps focus within the dialog when
|
|
394
|
+
opened with `showModal()`.
|
|
395
|
+
|
|
396
|
+
## Real-World Examples
|
|
397
|
+
|
|
398
|
+
### Confirmation Dialog
|
|
399
|
+
|
|
400
|
+
```html
|
|
401
|
+
<dialog id="confirmDialog">
|
|
402
|
+
<div class="dialog-header">
|
|
403
|
+
<h3>Delete Item?</h3>
|
|
404
|
+
<button
|
|
405
|
+
type="button"
|
|
406
|
+
class="dialog-close"
|
|
407
|
+
onclick="document.getElementById('confirmDialog').close()"
|
|
408
|
+
aria-label="Close"
|
|
409
|
+
>
|
|
410
|
+
✕
|
|
411
|
+
</button>
|
|
412
|
+
</div>
|
|
413
|
+
|
|
414
|
+
<section>
|
|
415
|
+
<p>
|
|
416
|
+
Are you sure you want to delete this item? This action cannot be undone.
|
|
417
|
+
</p>
|
|
418
|
+
</section>
|
|
419
|
+
|
|
420
|
+
<div class="dialog-footer">
|
|
421
|
+
<button
|
|
422
|
+
type="button"
|
|
423
|
+
onclick="document.getElementById('confirmDialog').close()"
|
|
424
|
+
>
|
|
425
|
+
Cancel
|
|
426
|
+
</button>
|
|
427
|
+
<button
|
|
428
|
+
type="button"
|
|
429
|
+
onclick="handleDelete(); document.getElementById('confirmDialog').close()"
|
|
430
|
+
style="--btn-bg: #dc3545; --btn-color: white"
|
|
431
|
+
>
|
|
432
|
+
Delete
|
|
433
|
+
</button>
|
|
434
|
+
</div>
|
|
435
|
+
</dialog>
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### Form Dialog
|
|
439
|
+
|
|
440
|
+
```html
|
|
441
|
+
<dialog id="formDialog" style="--dialog-min-width: 30rem">
|
|
442
|
+
<div class="dialog-header">
|
|
443
|
+
<h3>Add New Item</h3>
|
|
444
|
+
<button
|
|
445
|
+
type="button"
|
|
446
|
+
class="dialog-close"
|
|
447
|
+
onclick="document.getElementById('formDialog').close()"
|
|
448
|
+
aria-label="Close"
|
|
449
|
+
>
|
|
450
|
+
✕
|
|
451
|
+
</button>
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<section>
|
|
455
|
+
<form id="itemForm">
|
|
456
|
+
<div>
|
|
457
|
+
<label for="itemName">Name</label>
|
|
458
|
+
<input type="text" id="itemName" name="name" required />
|
|
459
|
+
</div>
|
|
460
|
+
<div>
|
|
461
|
+
<label for="itemDescription">Description</label>
|
|
462
|
+
<textarea id="itemDescription" name="description" rows="4"></textarea>
|
|
463
|
+
</div>
|
|
464
|
+
</form>
|
|
465
|
+
</section>
|
|
466
|
+
|
|
467
|
+
<div class="dialog-footer">
|
|
468
|
+
<button
|
|
469
|
+
type="button"
|
|
470
|
+
onclick="document.getElementById('formDialog').close()"
|
|
471
|
+
>
|
|
472
|
+
Cancel
|
|
473
|
+
</button>
|
|
474
|
+
<button type="submit" form="itemForm">Save</button>
|
|
475
|
+
</div>
|
|
476
|
+
</dialog>
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Alert Dialog
|
|
480
|
+
|
|
481
|
+
```html
|
|
482
|
+
<dialog id="alertDialog">
|
|
483
|
+
<div class="dialog-header">
|
|
484
|
+
<h3>⚠️ Warning</h3>
|
|
485
|
+
<button
|
|
486
|
+
type="button"
|
|
487
|
+
class="dialog-close"
|
|
488
|
+
onclick="document.getElementById('alertDialog').close()"
|
|
489
|
+
aria-label="Close"
|
|
490
|
+
>
|
|
491
|
+
✕
|
|
492
|
+
</button>
|
|
493
|
+
</div>
|
|
494
|
+
|
|
495
|
+
<section>
|
|
496
|
+
<p>Your session will expire in 2 minutes. Please save your work.</p>
|
|
497
|
+
</section>
|
|
498
|
+
|
|
499
|
+
<div class="alert-dialog-actions">
|
|
500
|
+
<button type="button" onclick="extendSession()">Extend Session</button>
|
|
501
|
+
</div>
|
|
502
|
+
</dialog>
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Success Dialog
|
|
506
|
+
|
|
507
|
+
```html
|
|
508
|
+
<dialog id="successDialog">
|
|
509
|
+
<div class="dialog-header">
|
|
510
|
+
<h3>✓ Success</h3>
|
|
511
|
+
<button
|
|
512
|
+
type="button"
|
|
513
|
+
class="dialog-close"
|
|
514
|
+
onclick="document.getElementById('successDialog').close()"
|
|
515
|
+
aria-label="Close"
|
|
516
|
+
>
|
|
517
|
+
✕
|
|
518
|
+
</button>
|
|
519
|
+
</div>
|
|
520
|
+
|
|
521
|
+
<section>
|
|
522
|
+
<p>Your changes have been saved successfully.</p>
|
|
523
|
+
</section>
|
|
524
|
+
|
|
525
|
+
<div class="dialog-footer" style="--dialog-footer-justify: center">
|
|
526
|
+
<button
|
|
527
|
+
type="button"
|
|
528
|
+
onclick="document.getElementById('successDialog').close()"
|
|
529
|
+
>
|
|
530
|
+
OK
|
|
531
|
+
</button>
|
|
532
|
+
</div>
|
|
533
|
+
</dialog>
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Wide Dialog
|
|
537
|
+
|
|
538
|
+
```html
|
|
539
|
+
<dialog id="wideDialog" style="--dialog-min-width: max(40rem, 90%)">
|
|
540
|
+
<div class="dialog-header">
|
|
541
|
+
<h3>Settings</h3>
|
|
542
|
+
<button
|
|
543
|
+
type="button"
|
|
544
|
+
class="dialog-close"
|
|
545
|
+
onclick="document.getElementById('wideDialog').close()"
|
|
546
|
+
aria-label="Close"
|
|
547
|
+
>
|
|
548
|
+
✕
|
|
549
|
+
</button>
|
|
550
|
+
</div>
|
|
551
|
+
|
|
552
|
+
<section>
|
|
553
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem">
|
|
554
|
+
<div>
|
|
555
|
+
<h4>General</h4>
|
|
556
|
+
<!-- Settings content -->
|
|
557
|
+
</div>
|
|
558
|
+
<div>
|
|
559
|
+
<h4>Advanced</h4>
|
|
560
|
+
<!-- Settings content -->
|
|
561
|
+
</div>
|
|
562
|
+
</div>
|
|
563
|
+
</section>
|
|
564
|
+
|
|
565
|
+
<div class="dialog-footer">
|
|
566
|
+
<button
|
|
567
|
+
type="button"
|
|
568
|
+
onclick="document.getElementById('wideDialog').close()"
|
|
569
|
+
>
|
|
570
|
+
Close
|
|
571
|
+
</button>
|
|
572
|
+
</div>
|
|
573
|
+
</dialog>
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Dialog with Scrollable Content
|
|
577
|
+
|
|
578
|
+
```html
|
|
579
|
+
<dialog id="scrollDialog">
|
|
580
|
+
<div class="dialog-header">
|
|
581
|
+
<h3>Terms of Service</h3>
|
|
582
|
+
<button
|
|
583
|
+
type="button"
|
|
584
|
+
class="dialog-close"
|
|
585
|
+
onclick="document.getElementById('scrollDialog').close()"
|
|
586
|
+
aria-label="Close"
|
|
587
|
+
>
|
|
588
|
+
✕
|
|
589
|
+
</button>
|
|
590
|
+
</div>
|
|
591
|
+
|
|
592
|
+
<section style="max-height: 20rem; overflow-y: auto">
|
|
593
|
+
<p>Long content that scrolls...</p>
|
|
594
|
+
<!-- More content -->
|
|
595
|
+
</section>
|
|
596
|
+
|
|
597
|
+
<div class="dialog-footer">
|
|
598
|
+
<button
|
|
599
|
+
type="button"
|
|
600
|
+
onclick="document.getElementById('scrollDialog').close()"
|
|
601
|
+
>
|
|
602
|
+
Decline
|
|
603
|
+
</button>
|
|
604
|
+
<button
|
|
605
|
+
type="button"
|
|
606
|
+
onclick="acceptTerms(); document.getElementById('scrollDialog').close()"
|
|
607
|
+
>
|
|
608
|
+
Accept
|
|
609
|
+
</button>
|
|
610
|
+
</div>
|
|
611
|
+
</dialog>
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
## Opening and Closing Dialogs
|
|
615
|
+
|
|
616
|
+
### Modal Dialog (Recommended)
|
|
617
|
+
|
|
618
|
+
Modal dialogs block interaction with the rest of the page:
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
const dialog = document.getElementById("myDialog");
|
|
622
|
+
|
|
623
|
+
// Open as modal (with backdrop)
|
|
624
|
+
dialog.showModal();
|
|
625
|
+
|
|
626
|
+
// Close dialog
|
|
627
|
+
dialog.close();
|
|
628
|
+
|
|
629
|
+
// Close with return value
|
|
630
|
+
dialog.close("confirmed");
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### Non-Modal Dialog
|
|
634
|
+
|
|
635
|
+
Non-modal dialogs allow interaction with the page:
|
|
636
|
+
|
|
637
|
+
```javascript
|
|
638
|
+
const dialog = document.getElementById("myDialog");
|
|
639
|
+
|
|
640
|
+
// Open as non-modal (no backdrop)
|
|
641
|
+
dialog.show();
|
|
642
|
+
|
|
643
|
+
// Close
|
|
644
|
+
dialog.close();
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### Listening to Dialog Events
|
|
648
|
+
|
|
649
|
+
```javascript
|
|
650
|
+
const dialog = document.getElementById("myDialog");
|
|
651
|
+
|
|
652
|
+
// Listen for close event
|
|
653
|
+
dialog.addEventListener("close", () => {
|
|
654
|
+
console.log("Dialog closed with:", dialog.returnValue);
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
// Listen for cancel event (Escape key)
|
|
658
|
+
dialog.addEventListener("cancel", (event) => {
|
|
659
|
+
console.log("Dialog cancelled");
|
|
660
|
+
// event.preventDefault(); // Prevent closing if needed
|
|
661
|
+
});
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
## Accessibility Considerations
|
|
665
|
+
|
|
666
|
+
### ARIA Roles and Labels
|
|
667
|
+
|
|
668
|
+
Use proper ARIA attributes for accessibility:
|
|
669
|
+
|
|
670
|
+
```html
|
|
671
|
+
<dialog
|
|
672
|
+
id="myDialog"
|
|
673
|
+
role="dialog"
|
|
674
|
+
aria-labelledby="dialogTitle"
|
|
675
|
+
aria-describedby="dialogDesc"
|
|
676
|
+
>
|
|
677
|
+
<div class="dialog-header">
|
|
678
|
+
<h3 id="dialogTitle">Dialog Title</h3>
|
|
679
|
+
<button type="button" class="dialog-close" aria-label="Close dialog">
|
|
680
|
+
✕
|
|
681
|
+
</button>
|
|
682
|
+
</div>
|
|
683
|
+
|
|
684
|
+
<section>
|
|
685
|
+
<p id="dialogDesc">Dialog description for screen readers.</p>
|
|
686
|
+
</section>
|
|
687
|
+
</dialog>
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Focus Management
|
|
691
|
+
|
|
692
|
+
1. **Initial Focus:**
|
|
693
|
+
|
|
694
|
+
```javascript
|
|
695
|
+
dialog.addEventListener("open", () => {
|
|
696
|
+
// Focus first input or primary action
|
|
697
|
+
dialog.querySelector("input, button[type='submit']")?.focus();
|
|
698
|
+
});
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
2. **Return Focus:**
|
|
702
|
+
|
|
703
|
+
```javascript
|
|
704
|
+
const trigger = document.getElementById("openButton");
|
|
705
|
+
trigger.addEventListener("click", () => {
|
|
706
|
+
dialog.showModal();
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
dialog.addEventListener("close", () => {
|
|
710
|
+
trigger.focus(); // Return focus to trigger button
|
|
711
|
+
});
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### Keyboard Shortcuts
|
|
715
|
+
|
|
716
|
+
Ensure keyboard users can:
|
|
717
|
+
|
|
718
|
+
- **Tab through** all focusable elements
|
|
719
|
+
- **Escape** to close the dialog
|
|
720
|
+
- **Enter/Space** to activate buttons
|
|
721
|
+
|
|
722
|
+
### Close Button Accessibility
|
|
723
|
+
|
|
724
|
+
Always provide an accessible label:
|
|
725
|
+
|
|
726
|
+
```html
|
|
727
|
+
<!-- Good: Has aria-label -->
|
|
728
|
+
<button type="button" class="dialog-close" aria-label="Close dialog">✕</button>
|
|
729
|
+
|
|
730
|
+
<!-- Bad: No accessible label -->
|
|
731
|
+
<button type="button" class="dialog-close">✕</button>
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
## CSS Variable Naming Convention
|
|
735
|
+
|
|
736
|
+
All dialog CSS variables follow specific patterns:
|
|
737
|
+
|
|
738
|
+
### Property Mapping
|
|
739
|
+
|
|
740
|
+
| Category | Variable Pattern | Example |
|
|
741
|
+
| -------------- | ---------------------------- | ------------------------------------------------ |
|
|
742
|
+
| **Dimensions** | `--dialog-{dimension}` | `--dialog-min-width` |
|
|
743
|
+
| **Layout** | `--dialog-{layout-property}` | `--dialog-display`, `--dialog-flex-direction` |
|
|
744
|
+
| **Spacing** | `--dialog-{spacing-type}` | `--dialog-padding`, `--dialog-gap` |
|
|
745
|
+
| **Borders** | `--dialog-border-{property}` | `--dialog-border-color`, `--dialog-border-width` |
|
|
746
|
+
| **Buttons** | `--dialog-button-{property}` | `--dialog-button-bg`, `--dialog-button-border` |
|
|
747
|
+
| **Focus** | `--dialog-focus-{property}` | `--dialog-focus-color`, `--dialog-focus-width` |
|
|
748
|
+
| **Footer** | `--dialog-footer-{property}` | `--dialog-footer-justify` |
|
|
749
|
+
|
|
750
|
+
### Common Variables Quick Reference
|
|
751
|
+
|
|
752
|
+
```css
|
|
753
|
+
/* Dimensions */
|
|
754
|
+
--dialog-min-width /* Minimum width (responsive) */
|
|
755
|
+
|
|
756
|
+
/* Layout */
|
|
757
|
+
--dialog-display /* Display mode (flex) */
|
|
758
|
+
--dialog-flex-direction /* Flex direction (column) */
|
|
759
|
+
--dialog-gap /* Gap between children */
|
|
760
|
+
|
|
761
|
+
/* Spacing */
|
|
762
|
+
--dialog-padding /* Padding (all sides) */
|
|
763
|
+
--dialog-padding-inline /* Horizontal padding (unused) */
|
|
764
|
+
|
|
765
|
+
/* Borders */
|
|
766
|
+
--dialog-border-color /* Border color */
|
|
767
|
+
--dialog-border-width /* Border width */
|
|
768
|
+
--dialog-border-style /* Border style (solid) */
|
|
769
|
+
--dialog-border-radius /* Border radius */
|
|
770
|
+
|
|
771
|
+
/* Buttons */
|
|
772
|
+
--dialog-close-color /* Close button color */
|
|
773
|
+
--dialog-button-bg /* Button background */
|
|
774
|
+
--dialog-button-border /* Button border */
|
|
775
|
+
--dialog-button-hover-bg /* Button hover background */
|
|
776
|
+
|
|
777
|
+
/* Focus */
|
|
778
|
+
--dialog-focus-color /* Focus outline color */
|
|
779
|
+
--dialog-focus-width /* Focus outline width */
|
|
780
|
+
--dialog-focus-offset /* Focus outline offset */
|
|
781
|
+
--dialog-focus-outline /* Complete focus outline */
|
|
782
|
+
|
|
783
|
+
/* Footer */
|
|
784
|
+
--dialog-footer-justify /* Footer button alignment */
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
## Browser Support
|
|
788
|
+
|
|
789
|
+
The dialog styles use modern CSS features:
|
|
790
|
+
|
|
791
|
+
- **`<dialog>` element:** Chrome 37+, Firefox 98+, Safari 15.4+
|
|
792
|
+
- **CSS Custom Properties:** All modern browsers (IE11 not supported)
|
|
793
|
+
- **`:focus-visible`:** Chrome 86+, Firefox 85+, Safari 15.4+
|
|
794
|
+
- **Flexbox:** All modern browsers
|
|
795
|
+
- **`@media (prefers-contrast: high)`:** Chrome 96+, Firefox 89+, Safari 14.1+
|
|
796
|
+
- **Logical properties** (`padding-block-start`): Chrome 87+, Firefox 66+,
|
|
797
|
+
Safari 14.1+
|
|
798
|
+
|
|
799
|
+
### Polyfills
|
|
800
|
+
|
|
801
|
+
For browsers without native `<dialog>` support, use:
|
|
802
|
+
|
|
803
|
+
- **dialog-polyfill:** https://github.com/GoogleChrome/dialog-polyfill
|
|
804
|
+
|
|
805
|
+
```html
|
|
806
|
+
<script src="https://cdn.jsdelivr.net/npm/dialog-polyfill@0.5.6/dist/dialog-polyfill.min.js"></script>
|
|
807
|
+
<link
|
|
808
|
+
rel="stylesheet"
|
|
809
|
+
href="https://cdn.jsdelivr.net/npm/dialog-polyfill@0.5.6/dist/dialog-polyfill.min.css"
|
|
810
|
+
/>
|
|
811
|
+
|
|
812
|
+
<script>
|
|
813
|
+
const dialog = document.querySelector("dialog");
|
|
814
|
+
dialogPolyfill.registerDialog(dialog);
|
|
815
|
+
</script>
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
## Performance Tips
|
|
819
|
+
|
|
820
|
+
### Avoid Inline Styles
|
|
821
|
+
|
|
822
|
+
Create reusable dialog variants:
|
|
823
|
+
|
|
824
|
+
```css
|
|
825
|
+
.dialog-sm {
|
|
826
|
+
--dialog-min-width: max(15rem, 50%);
|
|
827
|
+
--dialog-padding: 1rem;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
.dialog-lg {
|
|
831
|
+
--dialog-min-width: max(40rem, 90%);
|
|
832
|
+
--dialog-padding: 2rem;
|
|
833
|
+
}
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
```html
|
|
837
|
+
<dialog class="dialog-sm">Small dialog</dialog>
|
|
838
|
+
<dialog class="dialog-lg">Large dialog</dialog>
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Use Native Dialog Methods
|
|
842
|
+
|
|
843
|
+
Prefer `.showModal()` over custom implementations:
|
|
844
|
+
|
|
845
|
+
```javascript
|
|
846
|
+
// Good: Native method
|
|
847
|
+
dialog.showModal();
|
|
848
|
+
|
|
849
|
+
// Avoid: Custom modal logic
|
|
850
|
+
dialog.style.display = "block";
|
|
851
|
+
overlay.style.display = "block";
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
## Migration from Other Systems
|
|
855
|
+
|
|
856
|
+
### From Tailwind CSS
|
|
857
|
+
|
|
858
|
+
| Tailwind | fpkit Dialog |
|
|
859
|
+
| ---------------------- | ----------------------------------- |
|
|
860
|
+
| `class="modal"` | `<dialog>` |
|
|
861
|
+
| `class="modal-box"` | `<dialog>` (styled automatically) |
|
|
862
|
+
| `class="modal-header"` | `.dialog-header` |
|
|
863
|
+
| `class="modal-body"` | `<section>` |
|
|
864
|
+
| `class="modal-footer"` | `.dialog-footer` |
|
|
865
|
+
| Custom modal backdrop | Native backdrop (via `showModal()`) |
|
|
866
|
+
|
|
867
|
+
### From Bootstrap
|
|
868
|
+
|
|
869
|
+
| Bootstrap | fpkit Dialog |
|
|
870
|
+
| ------------------------- | --------------------------------- |
|
|
871
|
+
| `class="modal"` | `<dialog>` |
|
|
872
|
+
| `class="modal-dialog"` | `<dialog>` (styled automatically) |
|
|
873
|
+
| `class="modal-header"` | `.dialog-header` |
|
|
874
|
+
| `class="modal-body"` | `<section>` |
|
|
875
|
+
| `class="modal-footer"` | `.dialog-footer` |
|
|
876
|
+
| `data-bs-toggle="modal"` | `onclick="dialog.showModal()"` |
|
|
877
|
+
| `data-bs-dismiss="modal"` | `onclick="dialog.close()"` |
|
|
878
|
+
|
|
879
|
+
## Related Resources
|
|
880
|
+
|
|
881
|
+
- **React Component** - See [README.mdx](./README.mdx) for the React Dialog
|
|
882
|
+
component API
|
|
883
|
+
- **MDN: `<dialog>` element** -
|
|
884
|
+
[https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog)
|
|
885
|
+
- **W3C ARIA: Dialog Pattern** -
|
|
886
|
+
[https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
|
|
887
|
+
- **CSS Custom Properties** -
|
|
888
|
+
[https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
|