@kerfjs/ui 5.0.0-beta.100 → 5.0.0-beta.101
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 +3 -1
- package/ai/component-catalog.json +214 -18
- package/ai/component-composition.json +216 -8
- package/ai/components/README.md +2 -0
- package/ai/components/backdrop-image.md +84 -0
- package/ai/components/nav-stack.md +6 -1
- package/ai/components/pane.md +11 -1
- package/ai/components/recipe-media-detail.md +57 -0
- package/ai/components/surface-scaffold.md +13 -6
- package/ai/components/tab-navigator.md +6 -1
- package/ai/components/toolbar-control-group.md +1 -0
- package/ai/public-api-signatures-v1.md +356 -32
- package/ai/skill.md +53 -5
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/backdrop-image.d.ts +132 -0
- package/dist/backdrop-image.js +5 -0
- package/dist/backdrop-image.js.map +1 -0
- package/dist/browser/backdrop-image.js +3 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +2 -2
- package/dist/catalog.js +10 -9
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-QIG4IGUP.js → chunk-2PXZBFEC.js} +3 -1
- package/dist/chunk-2PXZBFEC.js.map +1 -0
- package/dist/{chunk-T4WJ5VGP.js → chunk-3SKAEPPZ.js} +2 -2
- package/dist/{chunk-T4WJ5VGP.js.map → chunk-3SKAEPPZ.js.map} +1 -1
- package/dist/chunk-5NQF35VO.js +67 -0
- package/dist/chunk-5NQF35VO.js.map +1 -0
- package/dist/{chunk-CMETHPKR.js → chunk-6E2H2E5A.js} +29 -8
- package/dist/chunk-6E2H2E5A.js.map +1 -0
- package/dist/{chunk-PIVY32AE.js → chunk-BYFTHA4I.js} +16 -3
- package/dist/chunk-BYFTHA4I.js.map +1 -0
- package/dist/{chunk-HGV7J4T6.js → chunk-EKHDLBRP.js} +1 -1
- package/dist/chunk-EKHDLBRP.js.map +1 -0
- package/dist/{chunk-QROYYGWU.js → chunk-FNZQOUZ5.js} +2 -2
- package/dist/{chunk-QROYYGWU.js.map → chunk-FNZQOUZ5.js.map} +1 -1
- package/dist/{chunk-EOO6PYGF.js → chunk-IXLUZHGT.js} +4 -4
- package/dist/{chunk-EOO6PYGF.js.map → chunk-IXLUZHGT.js.map} +1 -1
- package/dist/{chunk-UMKV7YVQ.js → chunk-LPHU44S3.js} +5 -1
- package/dist/chunk-LPHU44S3.js.map +1 -0
- package/dist/{chunk-INI4WDWC.js → chunk-M5KZ26VV.js} +27 -4
- package/dist/chunk-M5KZ26VV.js.map +1 -0
- package/dist/{chunk-TLMMFQWM.js → chunk-NS762OVM.js} +3 -3
- package/dist/{chunk-TLMMFQWM.js.map → chunk-NS762OVM.js.map} +1 -1
- package/dist/{chunk-CXZXHZTR.js → chunk-OZ6X76G5.js} +34 -1
- package/dist/chunk-OZ6X76G5.js.map +1 -0
- package/dist/{chunk-YOA5W5ZH.js → chunk-PKL6QJKK.js} +31 -3
- package/dist/chunk-PKL6QJKK.js.map +1 -0
- package/dist/chunk-QTSMHH5J.js +85 -0
- package/dist/chunk-QTSMHH5J.js.map +1 -0
- package/dist/chunk-SCDWURBO.js +136 -0
- package/dist/chunk-SCDWURBO.js.map +1 -0
- package/dist/{chunk-RHD7RKGI.js → chunk-SIW64V65.js} +3 -3
- package/dist/{chunk-RHD7RKGI.js.map → chunk-SIW64V65.js.map} +1 -1
- package/dist/chunk-SQ5DH66U.js +37 -0
- package/dist/chunk-SQ5DH66U.js.map +1 -0
- package/dist/{chunk-PYBBYSZ3.js → chunk-YBWQR2OK.js} +5 -5
- package/dist/{chunk-PYBBYSZ3.js.map → chunk-YBWQR2OK.js.map} +1 -1
- package/dist/{chunk-3GLYIIFR.js → chunk-ZYU5WRC3.js} +2 -2
- package/dist/{chunk-3GLYIIFR.js.map → chunk-ZYU5WRC3.js.map} +1 -1
- package/dist/collapsible-panel.js +3 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +24 -20
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +1 -1
- package/dist/{nav-stack-VXTumzKa.d.ts → nav-stack-CU_0dKtI.d.ts} +41 -5
- package/dist/nav-stack.d.ts +4 -4
- package/dist/nav-stack.js +2 -1
- package/dist/pane.d.ts +76 -4
- package/dist/pane.js +2 -1
- package/dist/select.js +1 -1
- package/dist/split-view.d.ts +4 -4
- package/dist/split-view.js +3 -2
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/backdrop-image.css +241 -0
- package/dist/styles/components/actions/toolbar/toolbar.css +9 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +128 -0
- package/dist/styles/components/layout/pane/pane.css +121 -1
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +207 -6
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +121 -3
- package/dist/styles/components/surfaces/backdrop-image/backdrop-image.css +241 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +166 -2
- package/dist/styles/foundation.css +165 -8
- package/dist/styles/nav-stack.css +207 -6
- package/dist/styles/overlay-sheet.css +211 -0
- package/dist/styles/pane.css +121 -1
- package/dist/styles/styles.css +1 -0
- package/dist/styles/surface-scaffold.css +166 -2
- package/dist/styles/tab-navigator.css +121 -3
- package/dist/styles/toolbar-control-group.css +128 -0
- package/dist/styles/toolbar.css +9 -0
- package/dist/styles/webawesome.css +10 -0
- package/dist/surface-scaffold-register.d.ts +3 -2
- package/dist/surface-scaffold-register.js +113 -10
- package/dist/surface-scaffold-register.js.map +1 -1
- package/dist/surface-scaffold.d.ts +38 -5
- package/dist/surface-scaffold.js +1 -1
- package/dist/tab-navigator.d.ts +43 -3
- package/dist/tab-navigator.js +35 -6
- package/dist/tab-navigator.js.map +1 -1
- package/dist/toolbar-control-group.d.ts +13 -2
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +6 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +1 -0
- package/dist/wire-catalog.d.ts +2 -2
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-nav-stack.js +29 -3
- package/dist/wire-nav-stack.js.map +1 -1
- package/dist/wire-overlay-sheets.d.ts +20 -0
- package/dist/wire-overlay-sheets.js +4 -0
- package/dist/wire-overlay-sheets.js.map +1 -0
- package/dist/wire-scroll-dividers.js +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/workbench.d.ts +2 -2
- package/dist/workbench.js +2 -1
- package/docs/accessibility.md +35 -0
- package/docs/app-layouts.md +13 -0
- package/docs/backdrop-image.md +128 -0
- package/docs/component-contract.md +2 -0
- package/docs/component-selection.md +11 -2
- package/docs/design/templates/toolbar-control-group/glass-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/glass.svg +1 -0
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group.svg +1 -1
- package/docs/design/templates.md +8 -0
- package/docs/layout.md +135 -5
- package/docs/manual-test-plan.md +29 -0
- package/docs/nav-stack.md +37 -1
- package/docs/recipes.md +24 -0
- package/docs/surface-scaffold.md +149 -3
- package/docs/tab-navigator.md +36 -0
- package/docs/ux-demo.md +11 -1
- package/llms.txt +42 -4
- package/package.json +13 -1
- package/ux-demo/recipes/loaders.ts +2 -0
- package/ux-demo/recipes/media-detail.tsx +272 -0
- package/dist/chunk-CMETHPKR.js.map +0 -1
- package/dist/chunk-CXZXHZTR.js.map +0 -1
- package/dist/chunk-HGV7J4T6.js.map +0 -1
- package/dist/chunk-INI4WDWC.js.map +0 -1
- package/dist/chunk-PIVY32AE.js.map +0 -1
- package/dist/chunk-QIG4IGUP.js.map +0 -1
- package/dist/chunk-UMKV7YVQ.js.map +0 -1
- package/dist/chunk-YOA5W5ZH.js.map +0 -1
|
@@ -98,12 +98,30 @@
|
|
|
98
98
|
--_kui-popup-row-icon-gap: 0.5rem;
|
|
99
99
|
--_kui-popup-row-label-padding-block: 0.35rem;
|
|
100
100
|
--_kui-popup-row-label-line-height: 1.25;
|
|
101
|
+
--_kui-popup-group-title-padding: 0.2rem 0.75rem 0.3rem;
|
|
102
|
+
--_kui-popup-group-title-font-weight: 750;
|
|
103
|
+
--_kui-popup-caret-open-rotation: -180deg;
|
|
104
|
+
/* The theme's brand text color as the root resolves it. A scoped tint
|
|
105
|
+
clamps its lightness for links and brand text (below); it lives outside
|
|
106
|
+
the palette block, so a tint inherits the root's brand rather than
|
|
107
|
+
re-deriving from itself. */
|
|
108
|
+
--_kui-tint-brand-source: var(--kui-color-brand-on-quiet);
|
|
109
|
+
--_kui-popup-caret-transition: rotate var(--wa-transition-slow, 0.3s)
|
|
110
|
+
var(--wa-transition-easing, ease);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* The palette. A scoped tint ([data-kui-tint], below) re-declares this whole
|
|
114
|
+
block on its element: an unregistered custom property substitutes its var()
|
|
115
|
+
references where it is declared, so a derived token (the chrome material, a
|
|
116
|
+
quiet fill mixed into the surface, a popup's current row) resolved at the
|
|
117
|
+
root would keep the root's colors inside the tint. Only color tokens live
|
|
118
|
+
here, so a tint never resets an app's spacing or geometry override. */
|
|
119
|
+
:root,
|
|
120
|
+
[data-kui-tint] {
|
|
101
121
|
--_kui-popup-row-current-background: var(--kui-color-brand-fill-normal);
|
|
102
122
|
/* Current row text sits on the brand fill; the darker on-fill accent clears
|
|
103
123
|
WCAG AA there (brand-on-quiet is 4.26:1 over that fill). */
|
|
104
124
|
--_kui-popup-row-current-color: var(--kui-color-brand-on-fill);
|
|
105
|
-
--_kui-popup-group-title-padding: 0.2rem 0.75rem 0.3rem;
|
|
106
|
-
--_kui-popup-group-title-font-weight: 750;
|
|
107
125
|
/* A capped, scrolling popup shows that it scrolls: a soft shadow along an
|
|
108
126
|
edge while more choices lie beyond it. Covers painted in the surface
|
|
109
127
|
color scroll with the content (`local`) and hide each shadow (`scroll`,
|
|
@@ -130,9 +148,6 @@
|
|
|
130
148
|
)
|
|
131
149
|
center bottom / 100% 0.75rem no-repeat scroll,
|
|
132
150
|
var(--kui-color-surface-raised);
|
|
133
|
-
--_kui-popup-caret-open-rotation: -180deg;
|
|
134
|
-
--_kui-popup-caret-transition: rotate var(--wa-transition-slow, 0.3s)
|
|
135
|
-
var(--wa-transition-easing, ease);
|
|
136
151
|
/* macOS Tahoe light semantics used by Hot Sheet 2, with a compatible dark extension. */
|
|
137
152
|
/* Every --kui-color-* token (and the focus-ring color) that reads a --wa-*
|
|
138
153
|
token falls back to the value src/webawesome.css assigns to that token,
|
|
@@ -527,10 +542,127 @@
|
|
|
527
542
|
--kui-safe-area-inline-end: env(safe-area-inset-left, 0px);
|
|
528
543
|
}
|
|
529
544
|
|
|
545
|
+
/* Scoped tint. A Pane, NavStack, or TabNavigator `tint` ({ color, scheme })
|
|
546
|
+
marks its root `data-kui-tint="<scheme>"` with the color in
|
|
547
|
+
`--_kui-tint-color`. The app declares the scheme (there is no automatic
|
|
548
|
+
color detection), and the scope re-derives the base surface and text
|
|
549
|
+
tokens from the color; the palette block above then re-derives everything
|
|
550
|
+
built on them (raised and lowered surfaces, quiet fills, the chrome
|
|
551
|
+
material). Relative color syntax clamps each token's lightness to a band
|
|
552
|
+
that holds WCAG AA whatever the color: a light tint's surface stays at or
|
|
553
|
+
above 90% OKLCH lightness under 24% text, 44% quiet text, and brand text
|
|
554
|
+
at most 45%, and a dark tint's surface at or below 30% under 97% text, 80%
|
|
555
|
+
quiet text, and brand text at least 80%. Chroma is capped so
|
|
556
|
+
text stays near-neutral and a surface stays a tint, not a fill.
|
|
557
|
+
Without relative color syntax, and under `prefers-contrast: more`, the
|
|
558
|
+
scope keeps the plain palette in its declared scheme. */
|
|
559
|
+
[data-kui-tint="light"] {
|
|
560
|
+
color-scheme: light;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
[data-kui-tint="dark"] {
|
|
564
|
+
color-scheme: dark;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/* Inside a tint the chrome material keeps its blur but drops the saturation
|
|
568
|
+
boost: over the scope's own colored surface, saturating it would paint a
|
|
569
|
+
visibly brighter band (and a lighter edge) under an overlay header at
|
|
570
|
+
rest, where the header should read as the same surface. */
|
|
571
|
+
[data-kui-tint] {
|
|
572
|
+
color: var(--kui-color-text);
|
|
573
|
+
--kui-chrome-material-filter: blur(20px);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
@supports (color: oklch(from red l c h)) {
|
|
577
|
+
@media not (prefers-contrast: more) {
|
|
578
|
+
[data-kui-tint="light"] {
|
|
579
|
+
--wa-color-surface-default: oklch(
|
|
580
|
+
from var(--_kui-tint-color) clamp(0.9, l, 0.985) min(c, 0.08) h
|
|
581
|
+
);
|
|
582
|
+
--wa-color-surface-raised: oklch(
|
|
583
|
+
from var(--_kui-tint-color) min(1, calc(clamp(0.9, l, 0.985) + 0.03))
|
|
584
|
+
min(c, 0.05) h
|
|
585
|
+
);
|
|
586
|
+
--wa-color-text-normal: oklch(
|
|
587
|
+
from var(--_kui-tint-color) 0.24 min(c, 0.03) h
|
|
588
|
+
);
|
|
589
|
+
--wa-color-text-quiet: oklch(
|
|
590
|
+
from var(--_kui-tint-color) 0.44 min(c, 0.04) h
|
|
591
|
+
);
|
|
592
|
+
--wa-color-neutral-on-quiet: oklch(
|
|
593
|
+
from var(--_kui-tint-color) 0.42 min(c, 0.04) h
|
|
594
|
+
);
|
|
595
|
+
--wa-color-brand-on-quiet: oklch(
|
|
596
|
+
from var(--_kui-tint-brand-source) min(l, 0.45) c h
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
[data-kui-tint="dark"] {
|
|
601
|
+
--wa-color-surface-default: oklch(
|
|
602
|
+
from var(--_kui-tint-color) clamp(0.16, l, 0.3) min(c, 0.1) h
|
|
603
|
+
);
|
|
604
|
+
--wa-color-surface-raised: oklch(
|
|
605
|
+
from var(--_kui-tint-color) calc(clamp(0.16, l, 0.3) + 0.06)
|
|
606
|
+
min(c, 0.08) h
|
|
607
|
+
);
|
|
608
|
+
--wa-color-text-normal: oklch(
|
|
609
|
+
from var(--_kui-tint-color) 0.97 min(c, 0.02) h
|
|
610
|
+
);
|
|
611
|
+
--wa-color-text-quiet: oklch(
|
|
612
|
+
from var(--_kui-tint-color) 0.8 min(c, 0.04) h
|
|
613
|
+
);
|
|
614
|
+
--wa-color-neutral-on-quiet: oklch(
|
|
615
|
+
from var(--_kui-tint-color) 0.82 min(c, 0.04) h
|
|
616
|
+
);
|
|
617
|
+
--wa-color-brand-on-quiet: oklch(
|
|
618
|
+
from var(--_kui-tint-brand-source) max(l, 0.8) c h
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/* An optional accent (`tint.accent`) re-derives the brand ramp in the
|
|
623
|
+
scope: the loud fill (buttons, the current row, checked controls), its
|
|
624
|
+
on-loud text, brand text and links, text on brand fills, and the focus
|
|
625
|
+
ring. Lightness is clamped so each pair keeps WCAG AA for any accent:
|
|
626
|
+
a light scope's fill stays at or below 50% under white text, a dark
|
|
627
|
+
scope's between 72% and 85% under near-black text, and brand text at
|
|
628
|
+
most 45% (light) or at least 80% (dark). */
|
|
629
|
+
[data-kui-tint="light"][data-kui-tint-accent] {
|
|
630
|
+
--wa-color-brand-fill-loud: oklch(
|
|
631
|
+
from var(--_kui-tint-accent) min(l, 0.5) c h
|
|
632
|
+
);
|
|
633
|
+
--wa-color-brand-on-loud: #fff;
|
|
634
|
+
--wa-color-brand-on-quiet: oklch(
|
|
635
|
+
from var(--_kui-tint-accent) min(l, 0.45) c h
|
|
636
|
+
);
|
|
637
|
+
--kui-color-brand-on-fill: oklch(
|
|
638
|
+
from var(--_kui-tint-accent) min(l, 0.38) c h
|
|
639
|
+
);
|
|
640
|
+
--wa-color-focus: oklch(from var(--_kui-tint-accent) min(l, 0.5) c h);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
[data-kui-tint="dark"][data-kui-tint-accent] {
|
|
644
|
+
--wa-color-brand-fill-loud: oklch(
|
|
645
|
+
from var(--_kui-tint-accent) clamp(0.72, l, 0.85) c h
|
|
646
|
+
);
|
|
647
|
+
--wa-color-brand-on-loud: #111113;
|
|
648
|
+
--wa-color-brand-on-quiet: oklch(
|
|
649
|
+
from var(--_kui-tint-accent) max(l, 0.8) c h
|
|
650
|
+
);
|
|
651
|
+
--kui-color-brand-on-fill: oklch(
|
|
652
|
+
from var(--_kui-tint-accent) max(l, 0.82) c h
|
|
653
|
+
);
|
|
654
|
+
--wa-color-focus: oklch(
|
|
655
|
+
from var(--_kui-tint-accent) clamp(0.72, l, 0.85) c h
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
530
661
|
@supports not (
|
|
531
662
|
(backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))
|
|
532
663
|
) {
|
|
533
|
-
:root
|
|
664
|
+
:root,
|
|
665
|
+
[data-kui-tint] {
|
|
534
666
|
--kui-chrome-material: var(--kui-color-surface);
|
|
535
667
|
--kui-chrome-material-raised: var(--kui-color-surface-raised);
|
|
536
668
|
--kui-chrome-material-filter: none;
|
|
@@ -538,7 +670,31 @@
|
|
|
538
670
|
}
|
|
539
671
|
|
|
540
672
|
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
|
|
541
|
-
:root
|
|
673
|
+
:root,
|
|
674
|
+
[data-kui-tint] {
|
|
675
|
+
--kui-chrome-material: var(--kui-color-surface);
|
|
676
|
+
--kui-chrome-material-raised: var(--kui-color-surface-raised);
|
|
677
|
+
--kui-chrome-material-filter: none;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/* The static-effects switch. There is no reliable CSS signal for a low-power
|
|
682
|
+
or slow device, so an app that detects one itself sets
|
|
683
|
+
`data-kui-effects="static"` on the root element; a display that cannot
|
|
684
|
+
animate smoothly (`update: slow`, e-ink and similar) gets the same result
|
|
685
|
+
on its own. Either way every backdrop effect turns opaque here, and every
|
|
686
|
+
scroll-driven animation a component owns stops in that component's CSS
|
|
687
|
+
(tests/unit/static-effects.test.ts holds each one to it). */
|
|
688
|
+
:root[data-kui-effects="static"],
|
|
689
|
+
:root[data-kui-effects="static"] [data-kui-tint] {
|
|
690
|
+
--kui-chrome-material: var(--kui-color-surface);
|
|
691
|
+
--kui-chrome-material-raised: var(--kui-color-surface-raised);
|
|
692
|
+
--kui-chrome-material-filter: none;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
@media (update: slow) {
|
|
696
|
+
:root,
|
|
697
|
+
[data-kui-tint] {
|
|
542
698
|
--kui-chrome-material: var(--kui-color-surface);
|
|
543
699
|
--kui-chrome-material-raised: var(--kui-color-surface-raised);
|
|
544
700
|
--kui-chrome-material-filter: none;
|
|
@@ -546,7 +702,8 @@
|
|
|
546
702
|
}
|
|
547
703
|
|
|
548
704
|
@media (prefers-contrast: more) {
|
|
549
|
-
:root
|
|
705
|
+
:root,
|
|
706
|
+
[data-kui-tint] {
|
|
550
707
|
--kui-color-pop-fill-quiet: Canvas;
|
|
551
708
|
--kui-color-pop-fill-normal: Canvas;
|
|
552
709
|
--kui-color-pop-fill-loud: Highlight;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
height: 100%;
|
|
7
7
|
overflow: hidden;
|
|
8
8
|
flex-direction: column;
|
|
9
|
-
background: var(--kui-color-surface);
|
|
9
|
+
background: var(--_kui-nav-stack-background, var(--kui-color-surface));
|
|
10
10
|
/* Safe areas: the stack's surfaces paint through unsafe areas; its chrome,
|
|
11
11
|
bottom toolbar, and each view compensate for the edges the stack still
|
|
12
12
|
touches (see pane.css for the `--kui-edge-inset-*` edge context). */
|
|
@@ -60,6 +60,25 @@
|
|
|
60
60
|
opacity: 0;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/* `background`: the stack's color paints the stack, its docked chrome and
|
|
64
|
+
bottom toolbar, and every view (a view's own `pane.background` paints over
|
|
65
|
+
it). Overlay chrome keeps the chrome material. A nested stack never
|
|
66
|
+
inherits the color. Forced colors paint the system surface. */
|
|
67
|
+
.kui-nav-stack:not([data-background]) {
|
|
68
|
+
--_kui-nav-stack-background: initial;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (forced-colors: active) {
|
|
72
|
+
.kui-nav-stack[data-background],
|
|
73
|
+
.kui-nav-stack[data-background]
|
|
74
|
+
> :is(.kui-nav-stack__chrome, .kui-nav-stack__bottom),
|
|
75
|
+
.kui-nav-stack[data-background]
|
|
76
|
+
> .kui-nav-stack__viewport
|
|
77
|
+
> .kui-nav-stack__view {
|
|
78
|
+
background: Canvas;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
63
82
|
/* The chrome hosts the stack's real top Toolbar. It hands that toolbar the
|
|
64
83
|
edges the stack still touches through the edge context (never the bottom,
|
|
65
84
|
which the viewport owns); the toolbar pads for the sides it claims with
|
|
@@ -68,7 +87,7 @@
|
|
|
68
87
|
--kui-edge-inset-block-start: var(--_kui-nav-stack-safe-block-start);
|
|
69
88
|
--kui-edge-inset-inline-start: var(--_kui-nav-stack-safe-inline-start);
|
|
70
89
|
--kui-edge-inset-inline-end: var(--_kui-nav-stack-safe-inline-end);
|
|
71
|
-
background: var(--kui-color-surface);
|
|
90
|
+
background: var(--_kui-nav-stack-background, var(--kui-color-surface));
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
.kui-nav-stack__viewport {
|
|
@@ -97,7 +116,7 @@
|
|
|
97
116
|
.kui-nav-stack__view {
|
|
98
117
|
position: absolute;
|
|
99
118
|
overflow: auto;
|
|
100
|
-
background: var(--kui-color-surface);
|
|
119
|
+
background: var(--_kui-nav-stack-background, var(--kui-color-surface));
|
|
101
120
|
transition: transform var(--kui-nav-stack-transition-duration, 200ms) ease;
|
|
102
121
|
inset: 0;
|
|
103
122
|
}
|
|
@@ -179,7 +198,7 @@
|
|
|
179
198
|
--kui-edge-inset-inline-end: var(--_kui-nav-stack-safe-inline-end);
|
|
180
199
|
border-block-start: 1px solid
|
|
181
200
|
var(--_kui-nav-stack-bottom-divider, transparent);
|
|
182
|
-
background: var(--kui-color-surface);
|
|
201
|
+
background: var(--_kui-nav-stack-background, var(--kui-color-surface));
|
|
183
202
|
}
|
|
184
203
|
|
|
185
204
|
/* The live chrome is the containing block of its scroll divider; a
|
|
@@ -272,6 +291,182 @@
|
|
|
272
291
|
}
|
|
273
292
|
}
|
|
274
293
|
|
|
294
|
+
/* `clear` chrome and bottom toolbar: overlay bars (the same measuring,
|
|
295
|
+
placement, and edge insets as above) that are fully transparent, for
|
|
296
|
+
chrome over imagery. With `scrollEdge="material"` a pseudo-element
|
|
297
|
+
carrying the chrome material fades in (opacity only) while the active
|
|
298
|
+
view's content lies beneath the bar, as `wireScrollDividers` reports, and
|
|
299
|
+
out at rest. Clear bars draw no scroll divider. */
|
|
300
|
+
.kui-nav-stack[data-chrome-material="clear"] > .kui-nav-stack__chrome {
|
|
301
|
+
-webkit-backdrop-filter: none;
|
|
302
|
+
backdrop-filter: none;
|
|
303
|
+
background: transparent;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
:where(.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge])
|
|
307
|
+
> .kui-nav-stack__chrome:not(.kui-nav-stack__chrome-copy) {
|
|
308
|
+
position: relative;
|
|
309
|
+
isolation: isolate;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* The scroll edge fades in as content scrolls beneath the bar: the wiring
|
|
313
|
+
publishes `--kui-scroll-edge-progress` (0 at rest, 1 once content lies
|
|
314
|
+
`scrollEdgeDistance` beyond the bar) and only the layer's opacity follows
|
|
315
|
+
it; the filter never animates. Unwired, it stays clear. */
|
|
316
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge]
|
|
317
|
+
> .kui-nav-stack__chrome::before {
|
|
318
|
+
position: absolute;
|
|
319
|
+
z-index: -1;
|
|
320
|
+
content: "";
|
|
321
|
+
inset: 0;
|
|
322
|
+
opacity: var(--kui-scroll-edge-progress, 0);
|
|
323
|
+
pointer-events: none;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge="material"]
|
|
327
|
+
> .kui-nav-stack__chrome::before {
|
|
328
|
+
-webkit-backdrop-filter: var(--kui-chrome-material-filter);
|
|
329
|
+
backdrop-filter: var(--kui-chrome-material-filter);
|
|
330
|
+
background: var(--kui-chrome-material);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge="surface"]
|
|
334
|
+
> .kui-nav-stack__chrome::before {
|
|
335
|
+
background: var(--kui-color-surface);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/* Static effects and slow displays snap the edge on while content lies
|
|
339
|
+
beneath the bar instead of tracking the scroll. */
|
|
340
|
+
:root[data-kui-effects="static"]
|
|
341
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge]
|
|
342
|
+
> .kui-nav-stack__chrome::before {
|
|
343
|
+
opacity: 0;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
:root[data-kui-effects="static"]
|
|
347
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge]
|
|
348
|
+
> .kui-nav-stack__chrome[data-scroll-divider*="b"]::before {
|
|
349
|
+
opacity: 1;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
@media (update: slow) {
|
|
353
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge]
|
|
354
|
+
> .kui-nav-stack__chrome::before {
|
|
355
|
+
opacity: 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge]
|
|
359
|
+
> .kui-nav-stack__chrome[data-scroll-divider*="b"]::before {
|
|
360
|
+
opacity: 1;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* Clear chrome turns opaque where transparency would hurt, like the
|
|
365
|
+
material itself. */
|
|
366
|
+
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
|
|
367
|
+
.kui-nav-stack[data-chrome-material="clear"] > .kui-nav-stack__chrome {
|
|
368
|
+
background: var(--kui-chrome-material);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
@media (forced-colors: active) {
|
|
373
|
+
.kui-nav-stack[data-chrome-material="clear"] > .kui-nav-stack__chrome {
|
|
374
|
+
background: Canvas;
|
|
375
|
+
border-block-end: 1px solid CanvasText;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.kui-nav-stack[data-chrome-material="clear"][data-scroll-edge]
|
|
379
|
+
> .kui-nav-stack__chrome::before {
|
|
380
|
+
content: none;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"] > .kui-nav-stack__bottom {
|
|
385
|
+
-webkit-backdrop-filter: none;
|
|
386
|
+
backdrop-filter: none;
|
|
387
|
+
background: transparent;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
:where(.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge])
|
|
391
|
+
> .kui-nav-stack__bottom:not(.kui-nav-stack__chrome-copy) {
|
|
392
|
+
position: relative;
|
|
393
|
+
isolation: isolate;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* The scroll edge fades in as content scrolls beneath the bar: the wiring
|
|
397
|
+
publishes `--kui-scroll-edge-progress` (0 at rest, 1 once content lies
|
|
398
|
+
`scrollEdgeDistance` beyond the bar) and only the layer's opacity follows
|
|
399
|
+
it; the filter never animates. Unwired, it stays clear. */
|
|
400
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge]
|
|
401
|
+
> .kui-nav-stack__bottom::before {
|
|
402
|
+
position: absolute;
|
|
403
|
+
z-index: -1;
|
|
404
|
+
content: "";
|
|
405
|
+
inset: 0;
|
|
406
|
+
opacity: var(--kui-scroll-edge-progress, 0);
|
|
407
|
+
pointer-events: none;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge="material"]
|
|
411
|
+
> .kui-nav-stack__bottom::before {
|
|
412
|
+
-webkit-backdrop-filter: var(--kui-chrome-material-filter);
|
|
413
|
+
backdrop-filter: var(--kui-chrome-material-filter);
|
|
414
|
+
background: var(--kui-chrome-material);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge="surface"]
|
|
418
|
+
> .kui-nav-stack__bottom::before {
|
|
419
|
+
background: var(--kui-color-surface);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/* Static effects and slow displays snap the edge on while content lies
|
|
423
|
+
beneath the bar instead of tracking the scroll. */
|
|
424
|
+
:root[data-kui-effects="static"]
|
|
425
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge]
|
|
426
|
+
> .kui-nav-stack__bottom::before {
|
|
427
|
+
opacity: 0;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
:root[data-kui-effects="static"]
|
|
431
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge]
|
|
432
|
+
> .kui-nav-stack__bottom[data-scroll-divider*="t"]::before {
|
|
433
|
+
opacity: 1;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
@media (update: slow) {
|
|
437
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge]
|
|
438
|
+
> .kui-nav-stack__bottom::before {
|
|
439
|
+
opacity: 0;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge]
|
|
443
|
+
> .kui-nav-stack__bottom[data-scroll-divider*="t"]::before {
|
|
444
|
+
opacity: 1;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/* Clear chrome turns opaque where transparency would hurt, like the
|
|
449
|
+
material itself. */
|
|
450
|
+
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
|
|
451
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"]
|
|
452
|
+
> .kui-nav-stack__bottom {
|
|
453
|
+
background: var(--kui-chrome-material);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
@media (forced-colors: active) {
|
|
458
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"]
|
|
459
|
+
> .kui-nav-stack__bottom {
|
|
460
|
+
background: Canvas;
|
|
461
|
+
border-block-start-color: CanvasText;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.kui-nav-stack[data-bottom-toolbar-material="clear"][data-scroll-edge]
|
|
465
|
+
> .kui-nav-stack__bottom::before {
|
|
466
|
+
content: none;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
275
470
|
/* Chrome dividers: with `chromeDividers="scroll"` (the default, no
|
|
276
471
|
attribute) the top chrome draws a line along its bottom edge while the
|
|
277
472
|
active view's content is scrolled beneath it, and the bottom toolbar
|
|
@@ -290,7 +485,10 @@
|
|
|
290
485
|
> [data-component="pane"][data-appearance="sunken"]
|
|
291
486
|
)
|
|
292
487
|
> .kui-nav-stack__chrome::after,
|
|
293
|
-
.kui-nav-stack[data-separator="auto"]:not(
|
|
488
|
+
.kui-nav-stack[data-separator="auto"]:not(
|
|
489
|
+
[data-chrome-dividers],
|
|
490
|
+
[data-chrome-material="clear"]
|
|
491
|
+
)
|
|
294
492
|
> .kui-nav-stack__chrome[data-scroll-divider*="b"]::after,
|
|
295
493
|
.kui-nav-stack[data-separator="auto"][data-chrome-dividers="always"]
|
|
296
494
|
> .kui-nav-stack__chrome::after {
|
|
@@ -309,7 +507,10 @@
|
|
|
309
507
|
> [data-component="pane"][data-appearance="sunken"]
|
|
310
508
|
)
|
|
311
509
|
> .kui-nav-stack__bottom,
|
|
312
|
-
.kui-nav-stack[data-separator="auto"]:not(
|
|
510
|
+
.kui-nav-stack[data-separator="auto"]:not(
|
|
511
|
+
[data-chrome-dividers],
|
|
512
|
+
[data-bottom-toolbar-material="clear"]
|
|
513
|
+
)
|
|
313
514
|
> .kui-nav-stack__bottom[data-scroll-divider*="t"],
|
|
314
515
|
.kui-nav-stack[data-separator="auto"][data-chrome-dividers="always"]
|
|
315
516
|
> .kui-nav-stack__bottom {
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/* Bottom-sheet presentation for the core `kerfjs/overlay` surfaces: `overlay()`
|
|
2
|
+
and the `confirm` / `prompt` / `form` / `choice` promise dialogs opened with
|
|
3
|
+
`presentation: 'bottom-sheet'`. The core ships no CSS; it marks the overlay
|
|
4
|
+
`data-presentation="bottom-sheet"` and publishes the virtual keyboard's
|
|
5
|
+
overlap as `--kerf-keyboard-inset`. This opt-in stylesheet gives those
|
|
6
|
+
sheets the geometry of a `DialogSurface` bottom sheet: resting on the
|
|
7
|
+
bottom edge with square bottom corners and the dialog radius on top,
|
|
8
|
+
capped below the top safe area, padded at its block end by the larger of
|
|
9
|
+
the safe area and the keyboard so its content stays above both, and
|
|
10
|
+
sliding up as it opens. It styles the plain path (the wrapper is the
|
|
11
|
+
backdrop and its content the sheet) and the `native: true` path (the
|
|
12
|
+
`<dialog>` is the sheet). */
|
|
13
|
+
div.kerf-overlay[data-presentation="bottom-sheet"] {
|
|
14
|
+
position: fixed;
|
|
15
|
+
z-index: var(--kui-overlay-sheet-z-index, 1000);
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: flex-end;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
background: var(
|
|
20
|
+
--wa-color-overlay-modal,
|
|
21
|
+
light-dark(rgb(29 29 31 / 0.34), rgb(0 0 0 / 0.6))
|
|
22
|
+
);
|
|
23
|
+
inset: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"]::backdrop {
|
|
27
|
+
background: var(
|
|
28
|
+
--wa-color-overlay-modal,
|
|
29
|
+
light-dark(rgb(29 29 31 / 0.34), rgb(0 0 0 / 0.6))
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
div.kerf-overlay[data-presentation="bottom-sheet"] > *,
|
|
34
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"] {
|
|
35
|
+
--_kui-overlay-sheet-clearance: max(
|
|
36
|
+
var(--kui-safe-area-block-end, env(safe-area-inset-bottom, 0px)),
|
|
37
|
+
var(--kerf-keyboard-inset, 0px)
|
|
38
|
+
);
|
|
39
|
+
--_kui-overlay-sheet-cap: calc(
|
|
40
|
+
100dvh - var(--kui-safe-area-block-start, env(safe-area-inset-top, 0px)) -
|
|
41
|
+
1rem
|
|
42
|
+
);
|
|
43
|
+
--_kui-overlay-sheet-padding-end: calc(
|
|
44
|
+
var(--kui-space-xs) + var(--_kui-overlay-sheet-clearance)
|
|
45
|
+
);
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
width: min(100%, 35rem);
|
|
48
|
+
max-width: 100%;
|
|
49
|
+
max-height: var(--_kui-overlay-sheet-cap);
|
|
50
|
+
margin: 0;
|
|
51
|
+
/* The 8px surface inset of a DialogSurface body: content items and lists
|
|
52
|
+
inside own their own inset from there. */
|
|
53
|
+
padding: var(--kui-space-xs) var(--kui-space-xs)
|
|
54
|
+
var(--_kui-overlay-sheet-padding-end);
|
|
55
|
+
overflow: auto;
|
|
56
|
+
border: 0;
|
|
57
|
+
/* Concentric with a pill control group at the 8px surface inset, like a
|
|
58
|
+
DialogSurface. */
|
|
59
|
+
border-radius: calc(
|
|
60
|
+
var(--kui-layout-pill-radius, calc(1px + 1.3125rem)) +
|
|
61
|
+
var(--kui-wa-surface-inset, 0.5rem)
|
|
62
|
+
)
|
|
63
|
+
calc(
|
|
64
|
+
var(--kui-layout-pill-radius, calc(1px + 1.3125rem)) +
|
|
65
|
+
var(--kui-wa-surface-inset, 0.5rem)
|
|
66
|
+
)
|
|
67
|
+
0 0;
|
|
68
|
+
color: var(--kui-color-text);
|
|
69
|
+
background: var(--kui-color-surface-raised);
|
|
70
|
+
box-shadow: var(--kui-shadow-l);
|
|
71
|
+
overscroll-behavior: contain;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* The native <dialog> keeps its top-layer placement; only the UA centering
|
|
75
|
+
gives way to the bottom edge. */
|
|
76
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"] {
|
|
77
|
+
margin: auto auto 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* A resizable sheet (the `kui-overlay-sheet-resizable` class, wired by
|
|
81
|
+
`wireOverlaySheets` from `@kerfjs/ui/wire-overlay-sheets`) carries the
|
|
82
|
+
grabber of a resizable DialogSurface sheet at its top edge. It opens at its
|
|
83
|
+
content height; a drag or the keyboard publishes the visible height on the
|
|
84
|
+
wrapper, between the minimum and the cap. */
|
|
85
|
+
div.kerf-overlay.kui-overlay-sheet-resizable[data-presentation="bottom-sheet"]
|
|
86
|
+
> *,
|
|
87
|
+
dialog.kerf-overlay.kui-overlay-sheet-resizable[data-presentation="bottom-sheet"] {
|
|
88
|
+
height: calc(
|
|
89
|
+
var(--_kui-overlay-sheet-height) + var(--_kui-overlay-sheet-padding-end)
|
|
90
|
+
);
|
|
91
|
+
min-height: min(
|
|
92
|
+
calc(
|
|
93
|
+
var(--kui-overlay-sheet-min-height, 10rem) +
|
|
94
|
+
var(--_kui-overlay-sheet-padding-end)
|
|
95
|
+
),
|
|
96
|
+
var(--_kui-overlay-sheet-cap)
|
|
97
|
+
);
|
|
98
|
+
padding-block-start: 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Sticky, so it stays at the top edge while the sheet's content scrolls, and
|
|
102
|
+
overlapping the content's first 8px, so the content starts 12px down as in
|
|
103
|
+
a resizable DialogSurface sheet. */
|
|
104
|
+
.kui-overlay-sheet-handle {
|
|
105
|
+
position: sticky;
|
|
106
|
+
z-index: 2;
|
|
107
|
+
inset-block-start: 0;
|
|
108
|
+
display: block;
|
|
109
|
+
width: 6rem;
|
|
110
|
+
height: 1.25rem;
|
|
111
|
+
margin: 0 auto calc(0.75rem - 1.25rem);
|
|
112
|
+
border-radius: var(--kui-radius-s);
|
|
113
|
+
cursor: ns-resize;
|
|
114
|
+
touch-action: none;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.kui-overlay-sheet-handle::before {
|
|
118
|
+
position: absolute;
|
|
119
|
+
inset-block-start: 0.375rem;
|
|
120
|
+
inset-inline: 0;
|
|
121
|
+
width: 2.25rem;
|
|
122
|
+
height: 0.3125rem;
|
|
123
|
+
margin-inline: auto;
|
|
124
|
+
border-radius: 0.15625rem;
|
|
125
|
+
background: var(--kui-color-neutral-border-loud);
|
|
126
|
+
content: "";
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.kui-overlay-sheet-handle:focus-visible {
|
|
130
|
+
outline: var(--kui-focus-ring);
|
|
131
|
+
outline-offset: -3px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@keyframes kui-overlay-sheet-slide {
|
|
135
|
+
from {
|
|
136
|
+
translate: 0 100%;
|
|
137
|
+
}
|
|
138
|
+
to {
|
|
139
|
+
translate: 0 0;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
144
|
+
:root:not([data-kui-effects="static"])
|
|
145
|
+
div.kerf-overlay[data-presentation="bottom-sheet"]
|
|
146
|
+
> *,
|
|
147
|
+
:root:not([data-kui-effects="static"])
|
|
148
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"] {
|
|
149
|
+
animation: kui-overlay-sheet-slide var(--wa-transition-slow, 300ms)
|
|
150
|
+
cubic-bezier(0.32, 0.72, 0, 1);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* Exit motion: pass `exitClass: 'kui-overlay-sheet-exit'` (with an
|
|
155
|
+
`exitDuration` cap such as 400) to the overlay or promise dialog, and the
|
|
156
|
+
sheet slides back down while the backdrop fades. The core removes the node
|
|
157
|
+
once the animations finish, and skips the exit under reduced motion; the
|
|
158
|
+
static-effects switch leaves nothing running, so it is removed at once. A
|
|
159
|
+
closed native <dialog> is `display: none`, so the class keeps it painted
|
|
160
|
+
at the bottom edge for the exit. */
|
|
161
|
+
@keyframes kui-overlay-sheet-slide-out {
|
|
162
|
+
from {
|
|
163
|
+
translate: 0 0;
|
|
164
|
+
}
|
|
165
|
+
to {
|
|
166
|
+
translate: 0 100%;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@keyframes kui-overlay-sheet-backdrop-out {
|
|
171
|
+
to {
|
|
172
|
+
background-color: transparent;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"].kui-overlay-sheet-exit {
|
|
177
|
+
display: block;
|
|
178
|
+
position: fixed;
|
|
179
|
+
z-index: var(--kui-overlay-sheet-z-index, 1000);
|
|
180
|
+
inset: auto 0 0;
|
|
181
|
+
margin-inline: auto;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
185
|
+
:root:not([data-kui-effects="static"])
|
|
186
|
+
div.kerf-overlay[data-presentation="bottom-sheet"].kui-overlay-sheet-exit {
|
|
187
|
+
animation: kui-overlay-sheet-backdrop-out var(--wa-transition-slow, 300ms)
|
|
188
|
+
ease both;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
:root:not([data-kui-effects="static"])
|
|
192
|
+
div.kerf-overlay[data-presentation="bottom-sheet"].kui-overlay-sheet-exit
|
|
193
|
+
> *,
|
|
194
|
+
:root:not([data-kui-effects="static"])
|
|
195
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"].kui-overlay-sheet-exit {
|
|
196
|
+
animation: kui-overlay-sheet-slide-out var(--wa-transition-slow, 300ms)
|
|
197
|
+
cubic-bezier(0.32, 0.72, 0, 1) both;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@media (forced-colors: active) {
|
|
202
|
+
div.kerf-overlay[data-presentation="bottom-sheet"] > *,
|
|
203
|
+
dialog.kerf-overlay[data-presentation="bottom-sheet"] {
|
|
204
|
+
border-block-start: 1px solid CanvasText;
|
|
205
|
+
background: Canvas;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.kui-overlay-sheet-handle::before {
|
|
209
|
+
background: CanvasText;
|
|
210
|
+
}
|
|
211
|
+
}
|