modal_stack 0.2.0 → 0.4.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -0
- data/README.md +136 -52
- data/app/assets/javascripts/modal_stack.js +612 -63
- data/app/assets/stylesheets/modal_stack/bootstrap.css +120 -11
- data/app/assets/stylesheets/modal_stack/{tailwind.css → tailwind_v3.css} +82 -14
- data/app/assets/stylesheets/modal_stack/tailwind_v4.css +372 -0
- data/app/assets/stylesheets/modal_stack/vanilla.css +128 -11
- data/app/javascript/modal_stack/controllers/modal_stack_back_link_controller.js +32 -0
- data/app/javascript/modal_stack/controllers/modal_stack_controller.js +54 -0
- data/app/javascript/modal_stack/controllers/modal_stack_link_controller.js +29 -7
- data/app/javascript/modal_stack/install.js +7 -1
- data/app/javascript/modal_stack/orchestrator.js +132 -3
- data/app/javascript/modal_stack/orchestrator.test.js +264 -2
- data/app/javascript/modal_stack/runtime.js +222 -13
- data/app/javascript/modal_stack/runtime.test.js +151 -0
- data/app/javascript/modal_stack/state.js +338 -39
- data/app/javascript/modal_stack/state.test.js +400 -13
- data/app/views/modal_stack/_dialog.html.erb +1 -0
- data/app/views/modal_stack/_panel.html.erb +4 -0
- data/lib/generators/modal_stack/install/install_generator.rb +18 -4
- data/lib/generators/modal_stack/install/templates/initializer.rb +21 -5
- data/lib/generators/modal_stack/views/templates/_dialog.html.erb +9 -0
- data/lib/generators/modal_stack/views/templates/_panel.html.erb +18 -0
- data/lib/generators/modal_stack/views/views_generator.rb +50 -0
- data/lib/modal_stack/capybara.rb +21 -0
- data/lib/modal_stack/configuration.rb +43 -17
- data/lib/modal_stack/controller_extensions.rb +8 -1
- data/lib/modal_stack/engine.rb +2 -0
- data/lib/modal_stack/helpers/modal_back_link_helper.rb +48 -0
- data/lib/modal_stack/helpers/modal_stack_assets_helper.rb +15 -3
- data/lib/modal_stack/helpers/modal_stack_container_helper.rb +42 -15
- data/lib/modal_stack/turbo_streams_extension.rb +56 -0
- data/lib/modal_stack/version.rb +1 -1
- data/lib/modal_stack.rb +5 -1
- metadata +11 -3
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* :root { --modal-stack-radius: 4px; }
|
|
11
11
|
*
|
|
12
12
|
* Variants: [data-variant="modal" | "drawer" | "bottom_sheet" | "confirmation"]
|
|
13
|
-
* Drawer side: [data-side="left" | "right"]
|
|
13
|
+
* Drawer side: [data-side="left" | "right" | "top" | "bottom"]
|
|
14
14
|
* Sizes: [data-modal-stack-size="sm" | "md" | "lg" | "xl"]
|
|
15
15
|
*/
|
|
16
16
|
|
|
@@ -23,13 +23,16 @@
|
|
|
23
23
|
--modal-stack-fg: var(--bs-body-color, #212529);
|
|
24
24
|
--modal-stack-shadow: var(--bs-box-shadow-lg, 0 1rem 3rem rgba(0, 0, 0, 0.175));
|
|
25
25
|
--modal-stack-backdrop: rgba(var(--bs-backdrop-color, 0, 0, 0), var(--bs-backdrop-opacity, 0.5));
|
|
26
|
-
|
|
26
|
+
/* Default `none` so Chrome skips the filter pass. Opt in with
|
|
27
|
+
* `:root { --modal-stack-backdrop-filter: blur(8px); }`. */
|
|
28
|
+
--modal-stack-backdrop-filter: none;
|
|
27
29
|
--modal-stack-panel-padding: var(--bs-modal-padding, 1rem);
|
|
28
30
|
--modal-stack-size-sm: 300px;
|
|
29
31
|
--modal-stack-size-md: 500px;
|
|
30
32
|
--modal-stack-size-lg: 800px;
|
|
31
33
|
--modal-stack-size-xl: 1140px;
|
|
32
34
|
--modal-stack-drawer-width: 400px;
|
|
35
|
+
--modal-stack-drawer-height: 22rem; /* 352px */
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
body[data-modal-stack-locked] {
|
|
@@ -65,23 +68,22 @@ body[data-modal-stack-locked] {
|
|
|
65
68
|
|
|
66
69
|
#modal-stack-root::backdrop {
|
|
67
70
|
background: rgba(0, 0, 0, 0);
|
|
68
|
-
backdrop-filter: blur(0);
|
|
69
71
|
transition:
|
|
70
72
|
background var(--modal-stack-duration) var(--modal-stack-ease),
|
|
71
|
-
backdrop-filter var(--modal-stack-duration) var(--modal-stack-ease),
|
|
72
73
|
overlay var(--modal-stack-duration) var(--modal-stack-ease) allow-discrete,
|
|
73
74
|
display var(--modal-stack-duration) var(--modal-stack-ease) allow-discrete;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
#modal-stack-root[open]::backdrop {
|
|
77
78
|
background: var(--modal-stack-backdrop);
|
|
78
|
-
|
|
79
|
+
/* Static. Default is `none` (no filter pass). Opt in with
|
|
80
|
+
* --modal-stack-backdrop-filter on :root. */
|
|
81
|
+
backdrop-filter: var(--modal-stack-backdrop-filter);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
@starting-style {
|
|
82
85
|
#modal-stack-root[open]::backdrop {
|
|
83
86
|
background: rgba(0, 0, 0, 0);
|
|
84
|
-
backdrop-filter: blur(0);
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
|
|
@@ -93,6 +95,7 @@ body[data-modal-stack-locked] {
|
|
|
93
95
|
max-width: 92vw;
|
|
94
96
|
max-height: min(85vh, 720px);
|
|
95
97
|
overflow-y: auto;
|
|
98
|
+
overscroll-behavior: contain;
|
|
96
99
|
background: var(--modal-stack-bg);
|
|
97
100
|
color: var(--modal-stack-fg);
|
|
98
101
|
border-radius: var(--modal-stack-radius);
|
|
@@ -101,8 +104,7 @@ body[data-modal-stack-locked] {
|
|
|
101
104
|
transform: translate(-50%, -50%);
|
|
102
105
|
transition:
|
|
103
106
|
transform var(--modal-stack-duration) var(--modal-stack-ease),
|
|
104
|
-
opacity var(--modal-stack-duration) var(--modal-stack-ease)
|
|
105
|
-
filter var(--modal-stack-duration) var(--modal-stack-ease);
|
|
107
|
+
opacity var(--modal-stack-duration) var(--modal-stack-ease);
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
@starting-style {
|
|
@@ -114,13 +116,12 @@ body[data-modal-stack-locked] {
|
|
|
114
116
|
|
|
115
117
|
[data-modal-stack-target="layer"][data-leaving] {
|
|
116
118
|
opacity: 0;
|
|
117
|
-
transform: translate(-50%, -
|
|
119
|
+
transform: translate(-50%, -44%) scale(0.97);
|
|
118
120
|
pointer-events: none;
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
[data-modal-stack-target="layer"][inert] {
|
|
122
124
|
opacity: 0.5;
|
|
123
|
-
filter: blur(0.5px);
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
[data-modal-stack-target="layer"][data-modal-stack-size="sm"] { width: var(--modal-stack-size-sm); }
|
|
@@ -143,7 +144,14 @@ body[data-modal-stack-locked] {
|
|
|
143
144
|
/* --- Drawer (Bootstrap offcanvas-flavored) ----------------------- */
|
|
144
145
|
|
|
145
146
|
[data-modal-stack-target="layer"][data-variant="drawer"] {
|
|
147
|
+
left: 0;
|
|
146
148
|
top: 0;
|
|
149
|
+
max-width: 100vw;
|
|
150
|
+
max-height: 100vh;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="right"],
|
|
154
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="left"] {
|
|
147
155
|
height: 100vh;
|
|
148
156
|
max-height: none;
|
|
149
157
|
width: var(--modal-stack-drawer-width);
|
|
@@ -163,6 +171,30 @@ body[data-modal-stack-locked] {
|
|
|
163
171
|
border-radius: 0 var(--modal-stack-radius) var(--modal-stack-radius) 0;
|
|
164
172
|
}
|
|
165
173
|
|
|
174
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="top"] {
|
|
175
|
+
left: 0;
|
|
176
|
+
top: 0;
|
|
177
|
+
width: 100vw;
|
|
178
|
+
max-width: none;
|
|
179
|
+
height: var(--modal-stack-drawer-height);
|
|
180
|
+
max-height: 85vh;
|
|
181
|
+
transform: translateY(0);
|
|
182
|
+
border-radius: 0 0 var(--modal-stack-radius) var(--modal-stack-radius);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="bottom"] {
|
|
186
|
+
left: 0;
|
|
187
|
+
top: auto;
|
|
188
|
+
bottom: 0;
|
|
189
|
+
width: 100vw;
|
|
190
|
+
max-width: none;
|
|
191
|
+
height: var(--modal-stack-drawer-height);
|
|
192
|
+
max-height: 85vh;
|
|
193
|
+
transform: translateY(0);
|
|
194
|
+
border-radius: var(--modal-stack-radius) var(--modal-stack-radius) 0 0;
|
|
195
|
+
padding-bottom: env(safe-area-inset-bottom, 0);
|
|
196
|
+
}
|
|
197
|
+
|
|
166
198
|
@starting-style {
|
|
167
199
|
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="right"] {
|
|
168
200
|
opacity: 0;
|
|
@@ -172,6 +204,14 @@ body[data-modal-stack-locked] {
|
|
|
172
204
|
opacity: 0;
|
|
173
205
|
transform: translateX(-100%);
|
|
174
206
|
}
|
|
207
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="top"] {
|
|
208
|
+
opacity: 0;
|
|
209
|
+
transform: translateY(-100%);
|
|
210
|
+
}
|
|
211
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="bottom"] {
|
|
212
|
+
opacity: 0;
|
|
213
|
+
transform: translateY(100%);
|
|
214
|
+
}
|
|
175
215
|
}
|
|
176
216
|
|
|
177
217
|
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="right"][data-leaving] {
|
|
@@ -184,6 +224,16 @@ body[data-modal-stack-locked] {
|
|
|
184
224
|
transform: translateX(-100%);
|
|
185
225
|
}
|
|
186
226
|
|
|
227
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="top"][data-leaving] {
|
|
228
|
+
opacity: 0;
|
|
229
|
+
transform: translateY(-100%);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
[data-modal-stack-target="layer"][data-variant="drawer"][data-side="bottom"][data-leaving] {
|
|
233
|
+
opacity: 0;
|
|
234
|
+
transform: translateY(100%);
|
|
235
|
+
}
|
|
236
|
+
|
|
187
237
|
/* --- Bottom sheet ------------------------------------------------ */
|
|
188
238
|
|
|
189
239
|
[data-modal-stack-target="layer"][data-variant="bottom_sheet"] {
|
|
@@ -195,6 +245,7 @@ body[data-modal-stack-locked] {
|
|
|
195
245
|
transform: translate(0, 0);
|
|
196
246
|
border-radius: var(--modal-stack-radius) var(--modal-stack-radius) 0 0;
|
|
197
247
|
max-height: 90vh;
|
|
248
|
+
padding-bottom: env(safe-area-inset-bottom, 0);
|
|
198
249
|
}
|
|
199
250
|
|
|
200
251
|
@starting-style {
|
|
@@ -223,10 +274,68 @@ body[data-modal-stack-locked] {
|
|
|
223
274
|
gap: 0.5rem;
|
|
224
275
|
}
|
|
225
276
|
|
|
277
|
+
/* Path frames are transparent layout wrappers — CSS transitions can hook
|
|
278
|
+
on [data-modal-stack-frame][data-transition][data-direction] to
|
|
279
|
+
animate slide/fade. */
|
|
280
|
+
[data-modal-stack-frame] {
|
|
281
|
+
display: contents;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
[data-modal-stack-target="layer"]:has([data-modal-stack-frame][data-transition="slide"]),
|
|
285
|
+
[data-modal-stack-target="layer"]:has([data-modal-stack-frame][data-transition="fade"]) {
|
|
286
|
+
overflow: hidden;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
[data-modal-stack-frame][data-transition="slide"] {
|
|
290
|
+
display: block;
|
|
291
|
+
translate: 0 0;
|
|
292
|
+
transition: translate var(--modal-stack-duration) var(--modal-stack-ease);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
[data-modal-stack-frame][data-transition="fade"] {
|
|
296
|
+
display: block;
|
|
297
|
+
opacity: 1;
|
|
298
|
+
transition: opacity var(--modal-stack-duration) var(--modal-stack-ease);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@starting-style {
|
|
302
|
+
[data-modal-stack-frame][data-transition="slide"][data-direction="forward"] {
|
|
303
|
+
translate: 100% 0;
|
|
304
|
+
}
|
|
305
|
+
[data-modal-stack-frame][data-transition="slide"][data-direction="back"] {
|
|
306
|
+
translate: -100% 0;
|
|
307
|
+
}
|
|
308
|
+
[data-modal-stack-frame][data-transition="fade"] {
|
|
309
|
+
opacity: 0;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.modal-stack__panel-back {
|
|
314
|
+
font: inherit;
|
|
315
|
+
color: inherit;
|
|
316
|
+
background: transparent;
|
|
317
|
+
border: 0;
|
|
318
|
+
padding: 0;
|
|
319
|
+
cursor: pointer;
|
|
320
|
+
align-self: start;
|
|
321
|
+
justify-self: start;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.modal-stack__panel-back:focus-visible {
|
|
325
|
+
outline: 2px solid currentColor;
|
|
326
|
+
outline-offset: 4px;
|
|
327
|
+
border-radius: 2px;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
[data-modal-stack-target="layer"][data-frame-depth="1"] .modal-stack__panel-back {
|
|
331
|
+
display: none;
|
|
332
|
+
}
|
|
333
|
+
|
|
226
334
|
@media (prefers-reduced-motion: reduce) {
|
|
227
335
|
#modal-stack-root,
|
|
228
336
|
#modal-stack-root::backdrop,
|
|
229
|
-
[data-modal-stack-target="layer"]
|
|
337
|
+
[data-modal-stack-target="layer"],
|
|
338
|
+
[data-modal-stack-frame][data-transition] {
|
|
230
339
|
transition-duration: 1ms !important;
|
|
231
340
|
}
|
|
232
341
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* modal_stack — Tailwind preset
|
|
2
|
+
* modal_stack — Tailwind v3 preset
|
|
3
|
+
*
|
|
4
|
+
* Tailwind v3 doesn't expose its design tokens as native CSS variables,
|
|
5
|
+
* so this preset ships static values aligned with the Tailwind defaults
|
|
6
|
+
* (slate text, white surface, rounded-2xl-ish radius, container sizes).
|
|
7
|
+
* Override the `--modal-stack-*` tokens on `:root` to retheme without
|
|
8
|
+
* touching the gem.
|
|
3
9
|
*
|
|
4
10
|
* Structural CSS for the <dialog id="modal-stack-root"> + layered
|
|
5
11
|
* `[data-modal-stack-target="layer"]` setup driven by the JS runtime.
|
|
6
|
-
* Visual tokens are exposed as CSS custom properties on `:root` so they
|
|
7
|
-
* can be overridden globally, per scope, or via Tailwind's
|
|
8
|
-
* `:root { --modal-stack-* }` declaration.
|
|
9
12
|
*
|
|
10
13
|
* Variants: [data-variant="modal" | "drawer" | "bottom_sheet" | "confirmation"]
|
|
11
14
|
* Drawer side: [data-side="left" | "right" | "top" | "bottom"]
|
|
@@ -27,7 +30,13 @@
|
|
|
27
30
|
--modal-stack-fg: #0f172a;
|
|
28
31
|
--modal-stack-shadow: 0 30px 60px -20px rgba(15, 23, 42, 0.35);
|
|
29
32
|
--modal-stack-backdrop: rgba(15, 23, 42, 0.55);
|
|
30
|
-
|
|
33
|
+
/* `none` by default — `backdrop-filter: blur()` even at radius 0
|
|
34
|
+
* still allocates a filter layer on the compositor, and animating
|
|
35
|
+
* a non-zero radius costs ~190ms/frame on Hi-DPI displays. Opt in
|
|
36
|
+
* with `:root { --modal-stack-backdrop-filter: blur(8px); }` —
|
|
37
|
+
* the filter is applied statically when the dialog opens (no
|
|
38
|
+
* per-frame compositor cost). */
|
|
39
|
+
--modal-stack-backdrop-filter: none;
|
|
31
40
|
--modal-stack-panel-padding: 24px;
|
|
32
41
|
--modal-stack-size-sm: 24rem; /* 384px */
|
|
33
42
|
--modal-stack-size-md: 34rem; /* 544px */
|
|
@@ -79,23 +88,23 @@ body[data-modal-stack-locked] {
|
|
|
79
88
|
|
|
80
89
|
#modal-stack-root::backdrop {
|
|
81
90
|
background: rgba(15, 23, 42, 0);
|
|
82
|
-
backdrop-filter: blur(0);
|
|
83
91
|
transition:
|
|
84
92
|
background var(--modal-stack-duration) var(--modal-stack-ease),
|
|
85
|
-
backdrop-filter var(--modal-stack-duration) var(--modal-stack-ease),
|
|
86
93
|
overlay var(--modal-stack-duration) var(--modal-stack-ease) allow-discrete,
|
|
87
94
|
display var(--modal-stack-duration) var(--modal-stack-ease) allow-discrete;
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
#modal-stack-root[open]::backdrop {
|
|
91
98
|
background: var(--modal-stack-backdrop);
|
|
92
|
-
|
|
99
|
+
/* Static (not in the transition list above). Default is `none` so
|
|
100
|
+
* Chrome skips the filter pass entirely. Override --modal-stack-
|
|
101
|
+
* backdrop-filter to opt in. */
|
|
102
|
+
backdrop-filter: var(--modal-stack-backdrop-filter);
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
@starting-style {
|
|
96
106
|
#modal-stack-root[open]::backdrop {
|
|
97
107
|
background: rgba(15, 23, 42, 0);
|
|
98
|
-
backdrop-filter: blur(0);
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
|
|
@@ -109,6 +118,7 @@ body[data-modal-stack-locked] {
|
|
|
109
118
|
max-width: 92vw;
|
|
110
119
|
max-height: min(85vh, 720px);
|
|
111
120
|
overflow-y: auto;
|
|
121
|
+
overscroll-behavior: contain;
|
|
112
122
|
background: var(--modal-stack-bg);
|
|
113
123
|
color: var(--modal-stack-fg);
|
|
114
124
|
border-radius: var(--modal-stack-radius);
|
|
@@ -117,8 +127,7 @@ body[data-modal-stack-locked] {
|
|
|
117
127
|
transform: translate(-50%, -50%);
|
|
118
128
|
transition:
|
|
119
129
|
transform var(--modal-stack-duration) var(--modal-stack-ease),
|
|
120
|
-
opacity var(--modal-stack-duration) var(--modal-stack-ease)
|
|
121
|
-
filter var(--modal-stack-duration) var(--modal-stack-ease);
|
|
130
|
+
opacity var(--modal-stack-duration) var(--modal-stack-ease);
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
@starting-style {
|
|
@@ -130,13 +139,12 @@ body[data-modal-stack-locked] {
|
|
|
130
139
|
|
|
131
140
|
[data-modal-stack-target="layer"][data-leaving] {
|
|
132
141
|
opacity: 0;
|
|
133
|
-
transform: translate(-50%, -
|
|
142
|
+
transform: translate(-50%, -44%) scale(0.97);
|
|
134
143
|
pointer-events: none;
|
|
135
144
|
}
|
|
136
145
|
|
|
137
146
|
[data-modal-stack-target="layer"][inert] {
|
|
138
147
|
opacity: 0.5;
|
|
139
|
-
filter: blur(0.5px);
|
|
140
148
|
}
|
|
141
149
|
|
|
142
150
|
/* --- Sizes via [data-modal-stack-size] ----------------------------- */
|
|
@@ -212,6 +220,7 @@ body[data-modal-stack-locked] {
|
|
|
212
220
|
max-height: 85vh;
|
|
213
221
|
transform: translateY(0);
|
|
214
222
|
border-radius: var(--modal-stack-radius) var(--modal-stack-radius) 0 0;
|
|
223
|
+
padding-bottom: env(safe-area-inset-bottom, 0);
|
|
215
224
|
}
|
|
216
225
|
|
|
217
226
|
@starting-style {
|
|
@@ -264,6 +273,7 @@ body[data-modal-stack-locked] {
|
|
|
264
273
|
transform: translate(0, 0);
|
|
265
274
|
border-radius: var(--modal-stack-radius) var(--modal-stack-radius) 0 0;
|
|
266
275
|
max-height: 90vh;
|
|
276
|
+
padding-bottom: env(safe-area-inset-bottom, 0);
|
|
267
277
|
}
|
|
268
278
|
|
|
269
279
|
@starting-style {
|
|
@@ -292,12 +302,70 @@ body[data-modal-stack-locked] {
|
|
|
292
302
|
gap: 14px;
|
|
293
303
|
}
|
|
294
304
|
|
|
305
|
+
/* Path frames are transparent layout wrappers — CSS transitions can hook
|
|
306
|
+
on [data-modal-stack-frame][data-transition][data-direction] to
|
|
307
|
+
animate slide/fade. */
|
|
308
|
+
[data-modal-stack-frame] {
|
|
309
|
+
display: contents;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
[data-modal-stack-target="layer"]:has([data-modal-stack-frame][data-transition="slide"]),
|
|
313
|
+
[data-modal-stack-target="layer"]:has([data-modal-stack-frame][data-transition="fade"]) {
|
|
314
|
+
overflow: hidden;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
[data-modal-stack-frame][data-transition="slide"] {
|
|
318
|
+
display: block;
|
|
319
|
+
translate: 0 0;
|
|
320
|
+
transition: translate var(--modal-stack-duration) var(--modal-stack-ease);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
[data-modal-stack-frame][data-transition="fade"] {
|
|
324
|
+
display: block;
|
|
325
|
+
opacity: 1;
|
|
326
|
+
transition: opacity var(--modal-stack-duration) var(--modal-stack-ease);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
@starting-style {
|
|
330
|
+
[data-modal-stack-frame][data-transition="slide"][data-direction="forward"] {
|
|
331
|
+
translate: 100% 0;
|
|
332
|
+
}
|
|
333
|
+
[data-modal-stack-frame][data-transition="slide"][data-direction="back"] {
|
|
334
|
+
translate: -100% 0;
|
|
335
|
+
}
|
|
336
|
+
[data-modal-stack-frame][data-transition="fade"] {
|
|
337
|
+
opacity: 0;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.modal-stack__panel-back {
|
|
342
|
+
font: inherit;
|
|
343
|
+
color: inherit;
|
|
344
|
+
background: transparent;
|
|
345
|
+
border: 0;
|
|
346
|
+
padding: 0;
|
|
347
|
+
cursor: pointer;
|
|
348
|
+
align-self: start;
|
|
349
|
+
justify-self: start;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.modal-stack__panel-back:focus-visible {
|
|
353
|
+
outline: 2px solid currentColor;
|
|
354
|
+
outline-offset: 4px;
|
|
355
|
+
border-radius: 2px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
[data-modal-stack-target="layer"][data-frame-depth="1"] .modal-stack__panel-back {
|
|
359
|
+
display: none;
|
|
360
|
+
}
|
|
361
|
+
|
|
295
362
|
/* --- Reduced motion ---------------------------------------------- */
|
|
296
363
|
|
|
297
364
|
@media (prefers-reduced-motion: reduce) {
|
|
298
365
|
#modal-stack-root,
|
|
299
366
|
#modal-stack-root::backdrop,
|
|
300
|
-
[data-modal-stack-target="layer"]
|
|
367
|
+
[data-modal-stack-target="layer"],
|
|
368
|
+
[data-modal-stack-frame][data-transition] {
|
|
301
369
|
transition-duration: 1ms !important;
|
|
302
370
|
}
|
|
303
371
|
}
|