@uncinq/css-components 1.7.10 → 1.8.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 +2 -1
- package/css/components/drawer.css +11 -4
- package/css/components/modal.css +151 -0
- package/css/index.css +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Each component file contains only CSS rules, using the tokens defined in the two
|
|
|
24
24
|
All component styles are declared inside `@layer components`:
|
|
25
25
|
|
|
26
26
|
```css
|
|
27
|
-
@layer reset, tokens, base, layouts,
|
|
27
|
+
@layer reset, tokens, vendors, base, layouts, components, pages, utilities;
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
This means:
|
|
@@ -110,6 +110,7 @@ css/
|
|
|
110
110
|
list.css ← styled list
|
|
111
111
|
map.css ← embedded map
|
|
112
112
|
media.css ← media object (image + text)
|
|
113
|
+
modal.css ← centered dialog / modal
|
|
113
114
|
nav.css ← navigation bar
|
|
114
115
|
nav-accessibility.css ← accessibility skip links / focus helpers
|
|
115
116
|
nav-title.css ← navigation bar title
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
/* ── Panel ───────────────────────────────────────────────────────── */
|
|
29
29
|
|
|
30
30
|
.drawer {
|
|
31
|
+
--color-link: var(--drawer-color-text);
|
|
32
|
+
--nav-color-text: var(--color-link);
|
|
33
|
+
|
|
31
34
|
background-color: var(--drawer-color-background);
|
|
32
35
|
bottom: var(--drawer-bottom, 0);
|
|
33
36
|
box-shadow: var(--drawer-shadow);
|
|
@@ -67,11 +70,12 @@
|
|
|
67
70
|
|
|
68
71
|
& > .header {
|
|
69
72
|
align-items: center;
|
|
70
|
-
border-block-end:
|
|
73
|
+
border-block-end: var(--drawer-border-width) var(--drawer-border-style) var(--drawer-border-color);
|
|
71
74
|
display: flex;
|
|
72
75
|
flex-shrink: 0;
|
|
73
76
|
justify-content: space-between;
|
|
74
|
-
padding: var(--drawer-padding);
|
|
77
|
+
padding-block: var(--drawer-header-padding-block, var(--drawer-padding-block));
|
|
78
|
+
padding-inline: var(--drawer-header-padding-inline, var(--drawer-padding-inline));
|
|
75
79
|
|
|
76
80
|
& .title {
|
|
77
81
|
font-size: var(--font-size-md);
|
|
@@ -85,14 +89,17 @@
|
|
|
85
89
|
& > .content {
|
|
86
90
|
flex-grow: 1;
|
|
87
91
|
overflow-y: auto;
|
|
88
|
-
padding: var(--drawer-padding);
|
|
92
|
+
padding-block: var(--drawer-header-padding-block, var(--drawer-padding-block));
|
|
93
|
+
padding-inline: var(--drawer-header-padding-inline, var(--drawer-padding-inline));
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
/* ── Footer ──────────────────────────────────────────────────────── */
|
|
92
97
|
|
|
93
98
|
& > .footer {
|
|
99
|
+
border-block-start: var(--drawer-border-width) var(--drawer-border-style) var(--drawer-border-color);
|
|
94
100
|
flex-shrink: 0;
|
|
95
|
-
padding: var(--drawer-padding);
|
|
101
|
+
padding-block: var(--drawer-header-padding-block, var(--drawer-padding-block));
|
|
102
|
+
padding-inline: var(--drawer-header-padding-inline, var(--drawer-padding-inline));
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/* components/modal.css */
|
|
2
|
+
/*
|
|
3
|
+
* .modal — centered dialog, native <dialog>.
|
|
4
|
+
*
|
|
5
|
+
* JS (components/modal.js) only calls showModal() / close(): [open] and
|
|
6
|
+
* ::backdrop drive the styling, and the browser handles Escape, the focus trap
|
|
7
|
+
* and making the rest of the page inert. No state class, no backdrop element.
|
|
8
|
+
*
|
|
9
|
+
* The dialog sits in the top layer, so it needs no z-index.
|
|
10
|
+
*
|
|
11
|
+
* Triggers: .js-dialog-toggle[data-target="#id"]
|
|
12
|
+
* Close: .js-dialog-close (inside the panel), click outside the panel
|
|
13
|
+
*
|
|
14
|
+
* Per-instance sizing: override --modal-max-width on the element.
|
|
15
|
+
*
|
|
16
|
+
* Expected HTML:
|
|
17
|
+
* <dialog id="navigation" class="modal" aria-labelledby="navigationLabel" aria-modal="true">
|
|
18
|
+
* <div class="header">
|
|
19
|
+
* <p class="title" id="navigationLabel">...</p>
|
|
20
|
+
* <button class="btn-close js-dialog-close">...</button>
|
|
21
|
+
* </div>
|
|
22
|
+
* <div class="content">...</div>
|
|
23
|
+
* <div class="footer">...</div>
|
|
24
|
+
* </dialog>
|
|
25
|
+
*/
|
|
26
|
+
@layer components {
|
|
27
|
+
|
|
28
|
+
/* ── Panel ───────────────────────────────────────────────────────── */
|
|
29
|
+
|
|
30
|
+
.modal {
|
|
31
|
+
background-color: var(--modal-color-background);
|
|
32
|
+
border: 0;
|
|
33
|
+
border-radius: var(--modal-radius);
|
|
34
|
+
box-shadow: var(--modal-shadow);
|
|
35
|
+
color: var(--modal-color-text);
|
|
36
|
+
display: flex;
|
|
37
|
+
flex-direction: column;
|
|
38
|
+
inline-size: 100%;
|
|
39
|
+
/* min() replaces the mobile breakpoint: the panel always keeps
|
|
40
|
+
--modal-margin clear of the viewport edges, whatever the max is set to */
|
|
41
|
+
max-block-size: min(var(--modal-max-height), 100% - var(--modal-margin) * 2);
|
|
42
|
+
max-inline-size: min(var(--modal-max-width), 100% - var(--modal-margin) * 2);
|
|
43
|
+
opacity: 0;
|
|
44
|
+
/* padding lives on the sections, so a click on the dialog itself is
|
|
45
|
+
always a click on the backdrop */
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
padding: 0;
|
|
48
|
+
transform: var(--modal-translate);
|
|
49
|
+
|
|
50
|
+
/* display: flex would override the UA rule that hides a closed dialog */
|
|
51
|
+
&:not([open]) {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Fully open — settle the panel */
|
|
56
|
+
&[open] {
|
|
57
|
+
opacity: 1;
|
|
58
|
+
transform: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* allow-discrete keeps the dialog in the top layer while it fades out */
|
|
62
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
63
|
+
transition-behavior: allow-discrete;
|
|
64
|
+
transition-duration: var(--modal-transition-duration);
|
|
65
|
+
transition-property: opacity, transform, display, overlay;
|
|
66
|
+
transition-timing-function: var(--modal-transition-easing);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* ── Header ────────────────────────────────────────────────────── */
|
|
70
|
+
|
|
71
|
+
& > .header {
|
|
72
|
+
align-items: center;
|
|
73
|
+
border-block-end: var(--modal-border-width) var(--modal-border-style) var(--modal-border-color);
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-shrink: 0;
|
|
76
|
+
justify-content: space-between;
|
|
77
|
+
padding-block: var(--modal-header-padding-block, var(--modal-padding-block));
|
|
78
|
+
padding-inline: var(--modal-header-padding-inline, var(--modal-padding-inline));
|
|
79
|
+
|
|
80
|
+
& .title {
|
|
81
|
+
font-size: var(--font-size-md);
|
|
82
|
+
font-weight: var(--font-weight-heading);
|
|
83
|
+
margin: 0;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* ── Body ──────────────────────────────────────────────────────── */
|
|
88
|
+
|
|
89
|
+
& > .content {
|
|
90
|
+
flex-grow: 1;
|
|
91
|
+
overflow-y: auto;
|
|
92
|
+
overscroll-behavior: contain;
|
|
93
|
+
padding-block: var(--modal-content-padding-block, var(--modal-padding-block));
|
|
94
|
+
padding-inline: var(--modal-content-padding-inline, var(--modal-padding-inline));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* ── Footer ────────────────────────────────────────────────────── */
|
|
98
|
+
|
|
99
|
+
& > .footer {
|
|
100
|
+
border-block-start:var(--modal-border-width) var(--modal-border-style) var(--modal-border-color);
|
|
101
|
+
display: flex;
|
|
102
|
+
flex-direction: column;
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
gap: var(--spacing-sm);
|
|
105
|
+
padding-block: var(--modal-footer-padding-block, var(--modal-padding-block));
|
|
106
|
+
padding-inline: var(--modal-footer-padding-inline, var(--modal-padding-inline));
|
|
107
|
+
|
|
108
|
+
@media (--tablet) {
|
|
109
|
+
flex-direction: row;
|
|
110
|
+
justify-content: flex-end;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* ── Backdrop ────────────────────────────────────────────────────── */
|
|
116
|
+
|
|
117
|
+
.modal::backdrop {
|
|
118
|
+
backdrop-filter: blur(var(--modal-backdrop-blur));
|
|
119
|
+
background-color: var(--modal-backdrop-color);
|
|
120
|
+
opacity: 0;
|
|
121
|
+
|
|
122
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
123
|
+
transition-behavior: allow-discrete;
|
|
124
|
+
transition-duration: var(--modal-transition-duration);
|
|
125
|
+
transition-property: opacity, display, overlay;
|
|
126
|
+
transition-timing-function: var(--modal-transition-easing);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.modal[open]::backdrop {
|
|
131
|
+
opacity: 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Opening is a discrete display change — both need an explicit start state */
|
|
135
|
+
@starting-style {
|
|
136
|
+
.modal[open] {
|
|
137
|
+
opacity: 0;
|
|
138
|
+
transform: var(--modal-translate);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.modal[open]::backdrop {
|
|
142
|
+
opacity: 0;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* ── Page scroll lock ────────────────────────────────────────────── */
|
|
147
|
+
|
|
148
|
+
body:has(.modal[open]) {
|
|
149
|
+
overflow: hidden;
|
|
150
|
+
}
|
|
151
|
+
}
|
package/css/index.css
CHANGED