@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
package/dist/list-header.js
CHANGED
package/dist/list-item.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as kerfjs from 'kerfjs';
|
|
2
2
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3
|
+
import { PaneConfig, ScrollEdge, SurfaceTint } from './pane.js';
|
|
3
4
|
import { ListConfig } from './list.js';
|
|
4
|
-
import { PaneConfig } from './pane.js';
|
|
5
5
|
import { c as PanelBottomToolbar } from './panel-toolbar-vg6Ir5Dy.js';
|
|
6
|
+
import { CssColor } from './css-values.js';
|
|
6
7
|
import { ToolbarConfig } from './toolbar.js';
|
|
7
8
|
import { ToolbarTextSize, HeadingLevel } from './toolbar-text.js';
|
|
8
9
|
|
|
@@ -56,15 +57,24 @@ interface NavStackToolbarConfig extends ToolbarConfig {
|
|
|
56
57
|
* How a {@link NavStack}'s top chrome relates to the active view: `docked`
|
|
57
58
|
* above it, or `overlay` laid over its top edge on the translucent chrome
|
|
58
59
|
* material, so the view's content scrolls visibly beneath it.
|
|
60
|
+
* `clear` lays it over
|
|
61
|
+
* the same edge fully transparent, for chrome over imagery: legibility comes
|
|
62
|
+
* from glass control groups or a scrim, and with `scrollEdge="material"` the
|
|
63
|
+
* chrome material fades in once content scrolls beneath it.
|
|
59
64
|
*/
|
|
60
|
-
type NavStackChromePresentation = 'docked' | 'overlay';
|
|
65
|
+
type NavStackChromePresentation = 'docked' | 'overlay' | 'clear';
|
|
61
66
|
/**
|
|
62
67
|
* How a {@link NavStack}'s bottom toolbar relates to the active view:
|
|
63
68
|
* `docked` below it, or `overlay` laid over its bottom edge on the
|
|
64
69
|
* translucent chrome material, so the view's content scrolls visibly beneath
|
|
65
70
|
* it.
|
|
71
|
+
* `clear` lays it over
|
|
72
|
+
* the same edge fully transparent, for chrome over imagery: legibility comes
|
|
73
|
+
* from glass control groups or a scrim, and with `scrollEdge="material"` the
|
|
74
|
+
* chrome material fades in once content scrolls beneath
|
|
75
|
+
* it, until the view scrolls to its end.
|
|
66
76
|
*/
|
|
67
|
-
type NavStackBottomToolbarPresentation = 'docked' | 'overlay';
|
|
77
|
+
type NavStackBottomToolbarPresentation = 'docked' | 'overlay' | 'clear';
|
|
68
78
|
interface NavStackProps {
|
|
69
79
|
id: string;
|
|
70
80
|
/** Accessible name for the stack region. */
|
|
@@ -123,7 +133,9 @@ interface NavStackProps {
|
|
|
123
133
|
* focused or scrolled into view, rests clear of the bar. Until then, and
|
|
124
134
|
* with `hideToolbar`, the chrome stays docked. An untoned `ToolbarText` in
|
|
125
135
|
* the chrome lifts its title and description to AA over the content passing
|
|
126
|
-
* beneath it; keep any other quiet copy in the view.
|
|
136
|
+
* beneath it; keep any other quiet copy in the view. With `clear`, the
|
|
137
|
+
* stack's own back control sits in a glass control group
|
|
138
|
+
* (`material="glass"`), so it stays legible over imagery.
|
|
127
139
|
*/
|
|
128
140
|
chromePresentation?: NavStackChromePresentation;
|
|
129
141
|
/**
|
|
@@ -141,6 +153,30 @@ interface NavStackProps {
|
|
|
141
153
|
* `ToolbarText` in the toolbar lifts to AA over the content beneath it.
|
|
142
154
|
*/
|
|
143
155
|
bottomToolbarPresentation?: NavStackBottomToolbarPresentation;
|
|
156
|
+
/**
|
|
157
|
+
* For `clear` chrome or bottom toolbar, `material` fades the chrome
|
|
158
|
+
* material in while the active view's content lies beneath it (default
|
|
159
|
+
* `none`).
|
|
160
|
+
*/
|
|
161
|
+
scrollEdge?: ScrollEdge;
|
|
162
|
+
/**
|
|
163
|
+
* The scroll distance, in CSS pixels, over which the scroll edge fades in
|
|
164
|
+
* (default 60).
|
|
165
|
+
*/
|
|
166
|
+
scrollEdgeDistance?: number;
|
|
167
|
+
/**
|
|
168
|
+
* Paint the stack, its docked chrome and bottom toolbar, and every view in
|
|
169
|
+
* an app-chosen color (a `@kerfjs/ui/css-values` color builder) instead of
|
|
170
|
+
* the surface. Overlay chrome keeps the chrome material; one view's own
|
|
171
|
+
* color goes in its `pane: { background }`. Forced colors paint `Canvas`.
|
|
172
|
+
*/
|
|
173
|
+
background?: CssColor;
|
|
174
|
+
/**
|
|
175
|
+
* A scoped tint (`{ color, scheme }`) for the stack, its chrome, bottom toolbar, and views: its surfaces and every
|
|
176
|
+
* descendant re-derive their surface and text tokens from the app's color
|
|
177
|
+
* in the declared scheme, with lightness clamped to keep text at WCAG AA.
|
|
178
|
+
*/
|
|
179
|
+
tint?: SurfaceTint;
|
|
144
180
|
className?: string;
|
|
145
181
|
/** Native named-slot assignment when composed inside a web component. */
|
|
146
182
|
slot?: string;
|
|
@@ -153,6 +189,6 @@ interface NavStackProps {
|
|
|
153
189
|
* and `toolbarConfig` supplies defaults. A single-pane
|
|
154
190
|
* layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.
|
|
155
191
|
*/
|
|
156
|
-
declare function NavStack({ id, label, views, backLabel, backIcon, backText, toolbarConfig, panelToggle, hideToolbar, bottomToolbar, separator, chromeDividers, chromePresentation, bottomToolbarPresentation, className, slot, }: NavStackProps): kerfjs.SafeHtml;
|
|
192
|
+
declare function NavStack({ id, label, views, backLabel, backIcon, backText, toolbarConfig, panelToggle, hideToolbar, bottomToolbar, separator, chromeDividers, chromePresentation, bottomToolbarPresentation, scrollEdge, scrollEdgeDistance, background, tint, className, slot, }: NavStackProps): kerfjs.SafeHtml;
|
|
157
193
|
|
|
158
194
|
export { type NavStackProps as N, type NavStackView as a, type NavPane as b, NavStack as c, type NavStackBottomToolbarPresentation as d, type NavStackChromePresentation as e, type NavStackToolbarConfig as f, type NavStackViewBottomToolbar as g, type NavStackViewToolbar as h };
|
package/dist/nav-stack.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export { c as NavStack, d as NavStackBottomToolbarPresentation, e as NavStackChromePresentation, N as NavStackProps, f as NavStackToolbarConfig, a as NavStackView, g as NavStackViewBottomToolbar, h as NavStackViewToolbar } from './nav-stack-
|
|
1
|
+
export { c as NavStack, d as NavStackBottomToolbarPresentation, e as NavStackChromePresentation, N as NavStackProps, f as NavStackToolbarConfig, a as NavStackView, g as NavStackViewBottomToolbar, h as NavStackViewToolbar } from './nav-stack-CU_0dKtI.js';
|
|
2
2
|
import 'kerfjs';
|
|
3
3
|
import './semantic-content-BbzjvSu9.js';
|
|
4
|
+
import './pane.js';
|
|
5
|
+
import './scroll-clearance-BikHljTc.js';
|
|
6
|
+
import './css-values.js';
|
|
4
7
|
import './list.js';
|
|
5
8
|
import './extension-attributes-mu8MFUl0.js';
|
|
6
9
|
import './flex-alignment-4ms8ZbV8.js';
|
|
7
|
-
import './scroll-clearance-BikHljTc.js';
|
|
8
10
|
import './sides-BPSWde0A.js';
|
|
9
|
-
import './css-values.js';
|
|
10
|
-
import './pane.js';
|
|
11
11
|
import './panel-toolbar-vg6Ir5Dy.js';
|
|
12
12
|
import './toolbar.js';
|
|
13
13
|
import './lucide-icon.js';
|
package/dist/nav-stack.js
CHANGED
package/dist/pane.d.ts
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
import * as kerfjs from 'kerfjs';
|
|
2
2
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3
3
|
import { S as ScrollClearance } from './scroll-clearance-BikHljTc.js';
|
|
4
|
+
import { CssColor } from './css-values.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* What clear (fully transparent) chrome fades in as content scrolls beneath
|
|
8
|
+
* it: `none` stays clear; `material` fades in the translucent chrome
|
|
9
|
+
* material; `surface` fades in the opaque surface. The fade tracks the scroll
|
|
10
|
+
* over `scrollEdgeDistance` (opacity only), from the scroll state
|
|
11
|
+
* `wireScrollDividers` reports; unwired, the chrome stays clear.
|
|
12
|
+
*/
|
|
13
|
+
type ScrollEdge = 'none' | 'material' | 'surface';
|
|
14
|
+
|
|
15
|
+
/** The color scheme an app declares for a {@link SurfaceTint}'s color. */
|
|
16
|
+
type SurfaceTintScheme = 'light' | 'dark';
|
|
17
|
+
/**
|
|
18
|
+
* A scoped tint for a layout surface: the app's color (usually sampled from
|
|
19
|
+
* artwork it already knows) and the scheme that color belongs to. Kerf does no
|
|
20
|
+
* color detection; `scheme` says whether the color reads as a light or a dark
|
|
21
|
+
* surface. Inside the scope the surface, raised surface, text, quiet text, and
|
|
22
|
+
* everything built on them (quiet fills, separators' backdrop, the chrome
|
|
23
|
+
* material) re-derive from the color, with lightness clamped so text keeps
|
|
24
|
+
* WCAG AA over any color.
|
|
25
|
+
*/
|
|
26
|
+
interface SurfaceTint {
|
|
27
|
+
color: CssColor;
|
|
28
|
+
scheme: SurfaceTintScheme;
|
|
29
|
+
/**
|
|
30
|
+
* An optional accent (usually the artwork's most vivid color). The scope's
|
|
31
|
+
* brand ramp re-derives from it: loud fills and their text, brand text and
|
|
32
|
+
* links, text on brand fills, and the focus ring, each clamped to keep AA.
|
|
33
|
+
*/
|
|
34
|
+
accent?: CssColor;
|
|
35
|
+
}
|
|
4
36
|
|
|
5
37
|
/**
|
|
6
38
|
* Logical pane sides: where a {@link Pane} can show a separator and where it can
|
|
@@ -24,10 +56,16 @@ type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
|
|
|
24
56
|
'data-chrome-placement'?: never;
|
|
25
57
|
'data-chrome-dividers'?: never;
|
|
26
58
|
'data-appearance'?: never;
|
|
59
|
+
'data-background'?: never;
|
|
60
|
+
'data-kui-tint'?: never;
|
|
61
|
+
'data-kui-tint-accent'?: never;
|
|
27
62
|
'data-deep-inset'?: never;
|
|
28
63
|
'data-outlined'?: never;
|
|
29
64
|
'data-scroll-clearance'?: never;
|
|
30
65
|
'data-header-presentation'?: never;
|
|
66
|
+
'data-header-material'?: never;
|
|
67
|
+
'data-scroll-edge'?: never;
|
|
68
|
+
'data-scroll-edge-distance'?: never;
|
|
31
69
|
'data-header-overlay'?: never;
|
|
32
70
|
}>;
|
|
33
71
|
/** How a Pane's header and footer relate to its scrolling content. */
|
|
@@ -42,8 +80,12 @@ type PaneChromeDividers = 'scroll' | 'always' | 'none';
|
|
|
42
80
|
* How a Pane's header relates to its scrolling content: `docked` in its own
|
|
43
81
|
* row above the content, or `overlay` laid over the content's top edge on the
|
|
44
82
|
* translucent chrome material, so content scrolls visibly beneath it.
|
|
83
|
+
* `clear` lays it over
|
|
84
|
+
* the same edge fully transparent, for chrome over imagery: legibility comes
|
|
85
|
+
* from glass control groups or a scrim, and with `scrollEdge="material"` the
|
|
86
|
+
* chrome material fades in once content scrolls beneath it.
|
|
45
87
|
*/
|
|
46
|
-
type PaneHeaderPresentation = 'docked' | 'overlay';
|
|
88
|
+
type PaneHeaderPresentation = 'docked' | 'overlay' | 'clear';
|
|
47
89
|
/** Background treatment of the Pane's scrolling work surface. */
|
|
48
90
|
type PaneAppearance = 'default' | 'sunken';
|
|
49
91
|
interface PaneProps {
|
|
@@ -89,8 +131,38 @@ interface PaneProps {
|
|
|
89
131
|
* content passing beneath it.
|
|
90
132
|
*/
|
|
91
133
|
headerPresentation?: PaneHeaderPresentation;
|
|
134
|
+
/**
|
|
135
|
+
* With `headerPresentation="clear"`, `material` fades the chrome material
|
|
136
|
+
* in behind the header once content scrolls beneath it (default `none`).
|
|
137
|
+
*/
|
|
138
|
+
scrollEdge?: ScrollEdge;
|
|
139
|
+
/**
|
|
140
|
+
* The scroll distance, in CSS pixels, over which the scroll edge fades in
|
|
141
|
+
* (default 60).
|
|
142
|
+
*/
|
|
143
|
+
scrollEdgeDistance?: number;
|
|
92
144
|
/** Paint the scrolling work surface with the shared lowered-surface color. */
|
|
93
145
|
appearance?: PaneAppearance;
|
|
146
|
+
/**
|
|
147
|
+
* Paint the whole pane, header and footer included, in an app-chosen color
|
|
148
|
+
* (`uiColor('surface-raised')`, `fillColor('#1f2a44')`, or `colorVar(…)`
|
|
149
|
+
* from `@kerfjs/ui/css-values`). It replaces the appearance's fill: a sunken
|
|
150
|
+
* pane drops its lowered color and grain. Omitted, the pane keeps its
|
|
151
|
+
* default (transparent, or the sunken surface). Forced colors paint
|
|
152
|
+
* `Canvas`. Keep text at AA over the color; a dark color needs a matching
|
|
153
|
+
* tint or dark tones for its content.
|
|
154
|
+
*/
|
|
155
|
+
background?: CssColor;
|
|
156
|
+
/**
|
|
157
|
+
* A scoped tint: `{ color, scheme }`, the app's color and the scheme it
|
|
158
|
+
* belongs to. The pane paints the tinted surface (unless `background` is
|
|
159
|
+
* set) and its whole subtree, chrome material and quiet fills included,
|
|
160
|
+
* re-derives its surface and text tokens from the color with lightness
|
|
161
|
+
* clamped to keep text at WCAG AA. Without relative color syntax, or under
|
|
162
|
+
* `prefers-contrast: more`, the scope keeps the plain palette in the
|
|
163
|
+
* declared scheme.
|
|
164
|
+
*/
|
|
165
|
+
tint?: SurfaceTint;
|
|
94
166
|
/**
|
|
95
167
|
* Clear chrome that lies over the scrolling content's block-start and/or
|
|
96
168
|
* block-end edge, such as a `DialogSurface` floating footer over a filling
|
|
@@ -141,13 +213,13 @@ interface PaneProps {
|
|
|
141
213
|
* or a CollapsiblePanel) forwards, so the app configures that pane instead of
|
|
142
214
|
* styling it. An omitted or `undefined` field keeps the composite's default.
|
|
143
215
|
*/
|
|
144
|
-
type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'headerPresentation' | 'appearance' | 'deepInset' | 'scrollClearance' | 'tabIndex' | 'outlined'>;
|
|
216
|
+
type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'headerPresentation' | 'scrollEdge' | 'scrollEdgeDistance' | 'appearance' | 'background' | 'tint' | 'deepInset' | 'scrollClearance' | 'tabIndex' | 'outlined'>;
|
|
145
217
|
/**
|
|
146
218
|
* An unpadded application column with optional fixed header/footer slots and one
|
|
147
219
|
* scrolling vertical content owner. Separator lines are independently opt-in on
|
|
148
220
|
* each logical edge, so the same component works as a sidebar, main area,
|
|
149
221
|
* inspector, or dialog column.
|
|
150
222
|
*/
|
|
151
|
-
declare function Pane({ header, children, footer, chromePlacement, chromeDividers, headerPresentation, appearance, deepInset, scrollClearance, tabIndex, outlined, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
|
|
223
|
+
declare function Pane({ header, children, footer, chromePlacement, chromeDividers, headerPresentation, scrollEdge, scrollEdgeDistance, appearance, background, tint, deepInset, scrollClearance, tabIndex, outlined, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
|
|
152
224
|
|
|
153
|
-
export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneHeaderPresentation, type PaneProps, type PaneSeparatorSide, ScrollClearance };
|
|
225
|
+
export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneHeaderPresentation, type PaneProps, type PaneSeparatorSide, ScrollClearance, type ScrollEdge, type SurfaceTint, type SurfaceTintScheme };
|
package/dist/pane.js
CHANGED
package/dist/select.js
CHANGED
package/dist/split-view.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as kerfjs from 'kerfjs';
|
|
2
2
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3
|
-
import { N as NavStackProps, a as NavStackView } from './nav-stack-
|
|
3
|
+
import { N as NavStackProps, a as NavStackView } from './nav-stack-CU_0dKtI.js';
|
|
4
4
|
import { ResizableRegionProps } from './resizable-region.js';
|
|
5
|
+
import './pane.js';
|
|
6
|
+
import './scroll-clearance-BikHljTc.js';
|
|
7
|
+
import './css-values.js';
|
|
5
8
|
import './list.js';
|
|
6
9
|
import './extension-attributes-mu8MFUl0.js';
|
|
7
10
|
import './flex-alignment-4ms8ZbV8.js';
|
|
8
|
-
import './scroll-clearance-BikHljTc.js';
|
|
9
11
|
import './sides-BPSWde0A.js';
|
|
10
|
-
import './css-values.js';
|
|
11
|
-
import './pane.js';
|
|
12
12
|
import './panel-toolbar-vg6Ir5Dy.js';
|
|
13
13
|
import './toolbar.js';
|
|
14
14
|
import './lucide-icon.js';
|
package/dist/split-view.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { NavStack } from './chunk-
|
|
2
|
-
|
|
1
|
+
import { NavStack } from './chunk-6E2H2E5A.js';
|
|
3
2
|
import { ResizableRegion } from './chunk-Y6KT7ZTR.js';
|
|
4
3
|
|
|
5
4
|
|
|
@@ -12,6 +11,8 @@ import { ResizableRegion } from './chunk-Y6KT7ZTR.js';
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
|
|
14
|
+
|
|
15
|
+
|
|
15
16
|
import { remify, pct } from './chunk-IQSRHXZR.js';
|
|
16
17
|
|
|
17
18
|
import { jsx, jsxs } from 'kerfjs/jsx-runtime';
|
package/dist/split-view.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/layout/split-view/split-view.tsx"],"names":[],"mappings":"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","file":"split-view.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { pct, remify } from '../../../shared/styles/css-values.js';\nimport {\n NavStack,\n type NavStackProps,\n type NavStackView,\n} from '../../navigation/nav-stack/nav-stack.js';\nimport {\n ResizableRegion,\n type ResizableRegionProps,\n} from '../resizable-region/resizable-region.js';\n\n/**\n * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /\n * `max` limits, plus the region configuration that forwards unchanged\n * (`separator`, `handleIcon`, `contentOverflow`, and collapse:\n * `collapsed`, `transitioning`, `collapseMotion`, `restoreControl`,\n * `restorePosition`). Omitted options keep the region's defaults.\n */\nexport interface SplitViewResizable extends Pick<\n ResizableRegionProps,\n | 'separator'\n | 'handleIcon'\n | 'contentOverflow'\n | 'collapsed'\n | 'transitioning'\n | 'collapseMotion'\n | 'restoreControl'\n | 'restorePosition'\n> {\n size: number;\n min: number;\n max: number;\n}\n\n/** One compact view's top- and bottom-toolbar content (see `NavStackView`). */\nexport type SplitViewCompactViewToolbars = Pick<\n NavStackView,\n 'toolbar' | 'bottomToolbar'\n>;\n\n/**\n * The compact `NavStack`'s configuration: its toolbar configuration, back\n * control, persistent bottom toolbar, chrome dividers, and chrome and\n * bottom-toolbar presentations forward to the stack, and `list` / `detail`\n * give each view its own toolbar groups.\n */\nexport interface SplitViewCompactStack extends Pick<\n NavStackProps,\n | 'toolbarConfig'\n | 'backIcon'\n | 'backText'\n | 'hideToolbar'\n | 'bottomToolbar'\n | 'chromeDividers'\n | 'chromePresentation'\n | 'bottomToolbarPresentation'\n> {\n /** Toolbar content for the list (root) view. */\n list?: SplitViewCompactViewToolbars;\n /** Toolbar content for the pushed detail view. */\n detail?: SplitViewCompactViewToolbars;\n}\n\n/**\n * The fixed list column's width: a size in CSS pixels, or that size capped\n * at a fraction of the SplitView's own width so a narrow container (a\n * dialog, a small window) always leaves the detail in view.\n */\nexport type SplitViewListWidth =\n | number\n | {\n /** Preferred width in CSS pixels. */\n size: number;\n /** Largest share of the SplitView's width, greater than 0 and at most 1. */\n maxFraction?: number;\n };\n\n/** The list-width custom property value for a fixed split. */\nfunction listWidthValue(listWidth: SplitViewListWidth): string {\n const { size, maxFraction } =\n typeof listWidth === 'number'\n ? { size: listWidth, maxFraction: undefined }\n : listWidth;\n if (!Number.isFinite(size) || size <= 0)\n throw new RangeError(\n 'SplitView listWidth size must be a positive number of pixels',\n );\n if (\n maxFraction !== undefined &&\n (!Number.isFinite(maxFraction) || maxFraction <= 0 || maxFraction > 1)\n )\n throw new RangeError(\n 'SplitView listWidth maxFraction must be greater than 0 and at most 1',\n );\n const preferred = remify(size);\n return maxFraction === undefined\n ? preferred\n : `min(${preferred}, ${pct(maxFraction * 100)})`;\n}\n\nexport interface SplitViewProps {\n id: string;\n label: string;\n /** The list (primary) pane. */\n list: KerfUiContent;\n /** The detail (secondary) pane. */\n detail: KerfUiContent;\n /**\n * Compact (\"one pane at a time\") classes — a handset or portrait tablet.\n * Derive from `deviceClass().value.compact`. When true the split collapses to\n * a `NavStack`: the list is the root and the detail is pushed over it.\n */\n compact?: boolean;\n /** In compact mode, whether the detail is currently pushed over the list. */\n detailActive?: boolean;\n /** Title/label for the list (compact NavStack root + region label). */\n listTitle?: string;\n /** Title/label for the detail (compact NavStack pushed view + region label). */\n detailTitle?: string;\n /** Back label for the compact NavStack (default \"Back\"). */\n backLabel?: string;\n /** Compact NavStack configuration and per-view toolbars. */\n compactStack?: SplitViewCompactStack;\n /** A resizable separator on roomy classes (min/max px). Omit for a fixed split. */\n resizable?: SplitViewResizable;\n /**\n * The fixed split's list column width (default 320px). A number is CSS\n * pixels; `{ size, maxFraction }` caps it at that share of the SplitView's\n * width. A resizable split sizes its list with `resizable` instead.\n */\n listWidth?: SplitViewListWidth;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A list-detail split. On roomy classes it shows both panes side\n * by side with an optional resizable separator; on compact classes it collapses\n * to a `NavStack` (list → detail). See `docs/23-app-layouts.md` §3.2. Compose the\n * resizable wiring with `wireResizableRegions` and the compact back with\n * `wireNavStack`.\n */\nexport function SplitView({\n id,\n label,\n list,\n detail,\n compact = false,\n detailActive = false,\n listTitle = '',\n detailTitle = '',\n backLabel = 'Back',\n compactStack = {},\n resizable,\n listWidth,\n className = '',\n slot,\n}: SplitViewProps) {\n if (listWidth !== undefined && resizable)\n throw new RangeError(\n 'SplitView listWidth applies to a fixed split; size a resizable list with resizable.size, min, and max',\n );\n const listWidthStyle =\n listWidth === undefined\n ? undefined\n : `--kui-split-view-list-width:${listWidthValue(listWidth)}`;\n if (compact) {\n const listView: NavStackView = {\n ...compactStack.list,\n key: 'list',\n toolbar: { ...compactStack.list?.toolbar, title: listTitle },\n content: list,\n };\n const views: NavStackView[] = detailActive\n ? [\n listView,\n {\n ...compactStack.detail,\n key: 'detail',\n toolbar: { ...compactStack.detail?.toolbar, title: detailTitle },\n content: detail,\n },\n ]\n : [listView];\n return (\n <div\n class={`kui-split-view kui-split-view--compact ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"compact\"\n slot={slot}\n >\n <NavStack\n id={`${id}-stack`}\n label={label}\n views={views}\n backLabel={backLabel}\n backIcon={compactStack.backIcon}\n backText={compactStack.backText}\n toolbarConfig={compactStack.toolbarConfig}\n hideToolbar={compactStack.hideToolbar}\n bottomToolbar={compactStack.bottomToolbar}\n chromeDividers={compactStack.chromeDividers}\n chromePresentation={compactStack.chromePresentation}\n bottomToolbarPresentation={compactStack.bottomToolbarPresentation}\n />\n </div>\n );\n }\n const listPane = resizable ? (\n <ResizableRegion\n id={`${id}-list`}\n label={listTitle || 'List'}\n size={resizable.size}\n min={resizable.min}\n max={resizable.max}\n separator={resizable.separator}\n handleIcon={resizable.handleIcon}\n contentOverflow={resizable.contentOverflow}\n collapsed={resizable.collapsed}\n transitioning={resizable.transitioning}\n collapseMotion={resizable.collapseMotion}\n restoreControl={resizable.restoreControl}\n restorePosition={resizable.restorePosition}\n >\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"true\"\n >\n {list}\n </div>\n </ResizableRegion>\n ) : (\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"false\"\n >\n {list}\n </div>\n );\n return (\n <div\n class={`kui-split-view ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"split\"\n aria-label={label}\n style={listWidthStyle}\n slot={slot}\n >\n {listPane}\n <div\n class=\"kui-split-view__detail kui-pane\"\n data-split-detail\n aria-label={detailTitle || undefined}\n >\n {detail}\n </div>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/split-view/split-view.tsx"],"names":[],"mappings":"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","file":"split-view.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { pct, remify } from '../../../shared/styles/css-values.js';\nimport {\n NavStack,\n type NavStackProps,\n type NavStackView,\n} from '../../navigation/nav-stack/nav-stack.js';\nimport {\n ResizableRegion,\n type ResizableRegionProps,\n} from '../resizable-region/resizable-region.js';\n\n/**\n * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /\n * `max` limits, plus the region configuration that forwards unchanged\n * (`separator`, `handleIcon`, `contentOverflow`, and collapse:\n * `collapsed`, `transitioning`, `collapseMotion`, `restoreControl`,\n * `restorePosition`). Omitted options keep the region's defaults.\n */\nexport interface SplitViewResizable extends Pick<\n ResizableRegionProps,\n | 'separator'\n | 'handleIcon'\n | 'contentOverflow'\n | 'collapsed'\n | 'transitioning'\n | 'collapseMotion'\n | 'restoreControl'\n | 'restorePosition'\n> {\n size: number;\n min: number;\n max: number;\n}\n\n/** One compact view's top- and bottom-toolbar content (see `NavStackView`). */\nexport type SplitViewCompactViewToolbars = Pick<\n NavStackView,\n 'toolbar' | 'bottomToolbar'\n>;\n\n/**\n * The compact `NavStack`'s configuration: its toolbar configuration, back\n * control, persistent bottom toolbar, chrome dividers, and chrome and\n * bottom-toolbar presentations forward to the stack, and `list` / `detail`\n * give each view its own toolbar groups.\n */\nexport interface SplitViewCompactStack extends Pick<\n NavStackProps,\n | 'toolbarConfig'\n | 'backIcon'\n | 'backText'\n | 'hideToolbar'\n | 'bottomToolbar'\n | 'chromeDividers'\n | 'chromePresentation'\n | 'bottomToolbarPresentation'\n> {\n /** Toolbar content for the list (root) view. */\n list?: SplitViewCompactViewToolbars;\n /** Toolbar content for the pushed detail view. */\n detail?: SplitViewCompactViewToolbars;\n}\n\n/**\n * The fixed list column's width: a size in CSS pixels, or that size capped\n * at a fraction of the SplitView's own width so a narrow container (a\n * dialog, a small window) always leaves the detail in view.\n */\nexport type SplitViewListWidth =\n | number\n | {\n /** Preferred width in CSS pixels. */\n size: number;\n /** Largest share of the SplitView's width, greater than 0 and at most 1. */\n maxFraction?: number;\n };\n\n/** The list-width custom property value for a fixed split. */\nfunction listWidthValue(listWidth: SplitViewListWidth): string {\n const { size, maxFraction } =\n typeof listWidth === 'number'\n ? { size: listWidth, maxFraction: undefined }\n : listWidth;\n if (!Number.isFinite(size) || size <= 0)\n throw new RangeError(\n 'SplitView listWidth size must be a positive number of pixels',\n );\n if (\n maxFraction !== undefined &&\n (!Number.isFinite(maxFraction) || maxFraction <= 0 || maxFraction > 1)\n )\n throw new RangeError(\n 'SplitView listWidth maxFraction must be greater than 0 and at most 1',\n );\n const preferred = remify(size);\n return maxFraction === undefined\n ? preferred\n : `min(${preferred}, ${pct(maxFraction * 100)})`;\n}\n\nexport interface SplitViewProps {\n id: string;\n label: string;\n /** The list (primary) pane. */\n list: KerfUiContent;\n /** The detail (secondary) pane. */\n detail: KerfUiContent;\n /**\n * Compact (\"one pane at a time\") classes — a handset or portrait tablet.\n * Derive from `deviceClass().value.compact`. When true the split collapses to\n * a `NavStack`: the list is the root and the detail is pushed over it.\n */\n compact?: boolean;\n /** In compact mode, whether the detail is currently pushed over the list. */\n detailActive?: boolean;\n /** Title/label for the list (compact NavStack root + region label). */\n listTitle?: string;\n /** Title/label for the detail (compact NavStack pushed view + region label). */\n detailTitle?: string;\n /** Back label for the compact NavStack (default \"Back\"). */\n backLabel?: string;\n /** Compact NavStack configuration and per-view toolbars. */\n compactStack?: SplitViewCompactStack;\n /** A resizable separator on roomy classes (min/max px). Omit for a fixed split. */\n resizable?: SplitViewResizable;\n /**\n * The fixed split's list column width (default 320px). A number is CSS\n * pixels; `{ size, maxFraction }` caps it at that share of the SplitView's\n * width. A resizable split sizes its list with `resizable` instead.\n */\n listWidth?: SplitViewListWidth;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A list-detail split. On roomy classes it shows both panes side\n * by side with an optional resizable separator; on compact classes it collapses\n * to a `NavStack` (list → detail). See `docs/23-app-layouts.md` §3.2. Compose the\n * resizable wiring with `wireResizableRegions` and the compact back with\n * `wireNavStack`.\n */\nexport function SplitView({\n id,\n label,\n list,\n detail,\n compact = false,\n detailActive = false,\n listTitle = '',\n detailTitle = '',\n backLabel = 'Back',\n compactStack = {},\n resizable,\n listWidth,\n className = '',\n slot,\n}: SplitViewProps) {\n if (listWidth !== undefined && resizable)\n throw new RangeError(\n 'SplitView listWidth applies to a fixed split; size a resizable list with resizable.size, min, and max',\n );\n const listWidthStyle =\n listWidth === undefined\n ? undefined\n : `--kui-split-view-list-width:${listWidthValue(listWidth)}`;\n if (compact) {\n const listView: NavStackView = {\n ...compactStack.list,\n key: 'list',\n toolbar: { ...compactStack.list?.toolbar, title: listTitle },\n content: list,\n };\n const views: NavStackView[] = detailActive\n ? [\n listView,\n {\n ...compactStack.detail,\n key: 'detail',\n toolbar: { ...compactStack.detail?.toolbar, title: detailTitle },\n content: detail,\n },\n ]\n : [listView];\n return (\n <div\n class={`kui-split-view kui-split-view--compact ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"compact\"\n slot={slot}\n >\n <NavStack\n id={`${id}-stack`}\n label={label}\n views={views}\n backLabel={backLabel}\n backIcon={compactStack.backIcon}\n backText={compactStack.backText}\n toolbarConfig={compactStack.toolbarConfig}\n hideToolbar={compactStack.hideToolbar}\n bottomToolbar={compactStack.bottomToolbar}\n chromeDividers={compactStack.chromeDividers}\n chromePresentation={compactStack.chromePresentation}\n bottomToolbarPresentation={compactStack.bottomToolbarPresentation}\n />\n </div>\n );\n }\n const listPane = resizable ? (\n <ResizableRegion\n id={`${id}-list`}\n label={listTitle || 'List'}\n size={resizable.size}\n min={resizable.min}\n max={resizable.max}\n separator={resizable.separator}\n handleIcon={resizable.handleIcon}\n contentOverflow={resizable.contentOverflow}\n collapsed={resizable.collapsed}\n transitioning={resizable.transitioning}\n collapseMotion={resizable.collapseMotion}\n restoreControl={resizable.restoreControl}\n restorePosition={resizable.restorePosition}\n >\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"true\"\n >\n {list}\n </div>\n </ResizableRegion>\n ) : (\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"false\"\n >\n {list}\n </div>\n );\n return (\n <div\n class={`kui-split-view ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"split\"\n aria-label={label}\n style={listWidthStyle}\n slot={slot}\n >\n {listPane}\n <div\n class=\"kui-split-view__detail kui-pane\"\n data-split-detail\n aria-label={detailTitle || undefined}\n >\n {detail}\n </div>\n </div>\n );\n}\n"]}
|
package/dist/state-banner.js
CHANGED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/* An image block at the top of a scrolling Pane or NavStack view. The root
|
|
2
|
+
paints fadeTo, so the image fades into it and the content below sits on the
|
|
3
|
+
same color. It bleeds to the Pane's resolved inline insets (the safe area)
|
|
4
|
+
and hands them back to its overlay and content, so their own items keep
|
|
5
|
+
the ordinary text axis. */
|
|
6
|
+
.kui-backdrop-image {
|
|
7
|
+
--_kui-backdrop-image-height: 20rem;
|
|
8
|
+
--_kui-backdrop-image-fade-to: transparent;
|
|
9
|
+
--_kui-backdrop-image-parallax: 0;
|
|
10
|
+
--_kui-backdrop-image-position: center;
|
|
11
|
+
--_kui-backdrop-image-fit: cover;
|
|
12
|
+
--_kui-backdrop-image-inset-start: var(
|
|
13
|
+
--kui-pane-content-inset-inline-start,
|
|
14
|
+
0px
|
|
15
|
+
);
|
|
16
|
+
--_kui-backdrop-image-inset-end: var(
|
|
17
|
+
--kui-pane-content-inset-inline-end,
|
|
18
|
+
0px
|
|
19
|
+
);
|
|
20
|
+
--_kui-backdrop-image-bleed-block-start: 0px;
|
|
21
|
+
display: flow-root;
|
|
22
|
+
position: relative;
|
|
23
|
+
min-width: 0;
|
|
24
|
+
margin-inline: calc(-1 * var(--_kui-backdrop-image-inset-start))
|
|
25
|
+
calc(-1 * var(--_kui-backdrop-image-inset-end));
|
|
26
|
+
background-color: var(--_kui-backdrop-image-fade-to);
|
|
27
|
+
isolation: isolate;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* `underChrome`: the block runs up beneath the scroller's block-start inset
|
|
31
|
+
(overlay or clear chrome clearance plus the top safe area, as the Pane
|
|
32
|
+
publishes it) and the hero grows by the same amount, so the visible image
|
|
33
|
+
keeps its height below the chrome and the overlay stays where it was. */
|
|
34
|
+
.kui-backdrop-image[data-under-chrome="true"] {
|
|
35
|
+
--_kui-backdrop-image-bleed-block-start: var(
|
|
36
|
+
--kui-pane-content-inset-block-start,
|
|
37
|
+
0px
|
|
38
|
+
);
|
|
39
|
+
margin-block-start: calc(-1 * var(--_kui-backdrop-image-bleed-block-start));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* The view timeline's inset defaults to the scroller's scroll padding, which
|
|
43
|
+
is the chrome clearance this image now runs beneath; measured from there,
|
|
44
|
+
the parallax would start part-way through at rest and shift the image
|
|
45
|
+
down. Measure from the scroller's real edge instead. */
|
|
46
|
+
.kui-backdrop-image[data-under-chrome="true"] .kui-backdrop-image__hero {
|
|
47
|
+
view-timeline-inset: 0px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* The hero is the scroll-timeline subject: its own block of scroll drives
|
|
51
|
+
the parallax, whatever sits above it and however tall it is. */
|
|
52
|
+
.kui-backdrop-image__hero {
|
|
53
|
+
display: grid;
|
|
54
|
+
position: relative;
|
|
55
|
+
min-height: calc(
|
|
56
|
+
var(--_kui-backdrop-image-height) +
|
|
57
|
+
var(--_kui-backdrop-image-bleed-block-start)
|
|
58
|
+
);
|
|
59
|
+
grid-template: minmax(0, 1fr) / minmax(0, 1fr);
|
|
60
|
+
view-timeline: --kui-backdrop-image block;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.kui-backdrop-image__backdrop {
|
|
64
|
+
position: absolute;
|
|
65
|
+
inset: 0;
|
|
66
|
+
overflow: clip;
|
|
67
|
+
pointer-events: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* The fade is a mask on the backdrop, not a painted gradient, so the image
|
|
71
|
+
dissolves into whatever fadeTo is without a visible band. */
|
|
72
|
+
.kui-backdrop-image[data-fade="true"] .kui-backdrop-image__backdrop {
|
|
73
|
+
mask-image: linear-gradient(to bottom, #000 50%, transparent);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* The moving layer: everything that lags the scroll. */
|
|
77
|
+
.kui-backdrop-image__layers {
|
|
78
|
+
position: absolute;
|
|
79
|
+
inset: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.kui-backdrop-image__media,
|
|
83
|
+
.kui-backdrop-image__blurred {
|
|
84
|
+
display: block;
|
|
85
|
+
width: 100%;
|
|
86
|
+
height: 100%;
|
|
87
|
+
object-fit: var(--_kui-backdrop-image-fit);
|
|
88
|
+
object-position: var(--_kui-backdrop-image-position);
|
|
89
|
+
background-position: var(--_kui-backdrop-image-position);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Progressive blur: a copy over the sharp image, blurred once and hidden
|
|
93
|
+
until the scroll timeline fades it in. A filtered copy overhangs the block
|
|
94
|
+
by its radius on every side, so the blur's transparent fringe falls outside
|
|
95
|
+
the clip instead of letting the sharp edge show through. The dim layer
|
|
96
|
+
darkens toward its peak opacity with it. */
|
|
97
|
+
.kui-backdrop-image__blurred {
|
|
98
|
+
position: absolute;
|
|
99
|
+
inset: 0;
|
|
100
|
+
opacity: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.kui-backdrop-image[data-blur="filter"] .kui-backdrop-image__blurred {
|
|
104
|
+
inset: calc(-1 * var(--_kui-backdrop-image-blur)) auto auto
|
|
105
|
+
calc(-1 * var(--_kui-backdrop-image-blur));
|
|
106
|
+
width: calc(100% + 2 * var(--_kui-backdrop-image-blur));
|
|
107
|
+
height: calc(100% + 2 * var(--_kui-backdrop-image-blur));
|
|
108
|
+
filter: blur(var(--_kui-backdrop-image-blur));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.kui-backdrop-image__dim {
|
|
112
|
+
position: absolute;
|
|
113
|
+
inset: 0;
|
|
114
|
+
background: rgb(0 0 0 / var(--_kui-backdrop-image-dim));
|
|
115
|
+
opacity: 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.kui-backdrop-image__scrim {
|
|
119
|
+
position: absolute;
|
|
120
|
+
inset: 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.kui-backdrop-image[data-scrim="bottom"] .kui-backdrop-image__scrim {
|
|
124
|
+
background: linear-gradient(to bottom, rgb(0 0 0 / 0) 35%, rgb(0 0 0 / 0.5));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.kui-backdrop-image[data-scrim="full"] .kui-backdrop-image__scrim {
|
|
128
|
+
background: rgb(0 0 0 / 0.35);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.kui-backdrop-image__overlay {
|
|
132
|
+
position: relative;
|
|
133
|
+
min-width: 0;
|
|
134
|
+
align-self: end;
|
|
135
|
+
padding-inline: var(--_kui-backdrop-image-inset-start)
|
|
136
|
+
var(--_kui-backdrop-image-inset-end);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* A scrim is dark in both color schemes, so the content laid over it takes
|
|
140
|
+
the dark scheme: default-tone titles and controls resolve their light
|
|
141
|
+
foregrounds whatever the page's scheme. */
|
|
142
|
+
.kui-backdrop-image:is([data-scrim="bottom"], [data-scrim="full"])
|
|
143
|
+
.kui-backdrop-image__overlay {
|
|
144
|
+
color-scheme: dark;
|
|
145
|
+
color: var(--kui-color-text);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.kui-backdrop-image__content {
|
|
149
|
+
min-width: 0;
|
|
150
|
+
padding-inline: var(--_kui-backdrop-image-inset-start)
|
|
151
|
+
var(--_kui-backdrop-image-inset-end);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* Parallax: as the hero scrolls out past the scroller's start edge, the
|
|
155
|
+
layer slides down by the lag factor of that distance, so the image moves
|
|
156
|
+
slower than the content. The blurred copy and dim layer fade in over the
|
|
157
|
+
same range. Only transform and opacity animate, on a scroll-driven
|
|
158
|
+
timeline the compositor runs; the blur filter is never animated, and there
|
|
159
|
+
is no scroll listener and no background-attachment: fixed. Without
|
|
160
|
+
scroll-driven animations (Firefox today) or with reduced motion the image
|
|
161
|
+
stays static and sharp. */
|
|
162
|
+
@supports (animation-timeline: view()) {
|
|
163
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
164
|
+
.kui-backdrop-image[data-parallax="scroll"] .kui-backdrop-image__layers {
|
|
165
|
+
animation: kui-backdrop-image-parallax linear both;
|
|
166
|
+
animation-timeline: --kui-backdrop-image;
|
|
167
|
+
animation-range: exit-crossing 0% exit-crossing 100%;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* The blur reaches full strength halfway through the exit, while most
|
|
171
|
+
of the image is still in view; ramping over the whole exit left it
|
|
172
|
+
barely visible before the image had scrolled away. */
|
|
173
|
+
.kui-backdrop-image[data-blur]
|
|
174
|
+
:is(.kui-backdrop-image__blurred, .kui-backdrop-image__dim) {
|
|
175
|
+
animation: kui-backdrop-image-reveal linear both;
|
|
176
|
+
animation-timeline: --kui-backdrop-image;
|
|
177
|
+
animation-range: exit-crossing 0% exit-crossing 50%;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@keyframes kui-backdrop-image-parallax {
|
|
183
|
+
from {
|
|
184
|
+
transform: none;
|
|
185
|
+
}
|
|
186
|
+
to {
|
|
187
|
+
transform: translateY(calc(var(--_kui-backdrop-image-parallax) * 100%));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@keyframes kui-backdrop-image-reveal {
|
|
192
|
+
from {
|
|
193
|
+
opacity: 0;
|
|
194
|
+
}
|
|
195
|
+
to {
|
|
196
|
+
opacity: 1;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* The document-wide static-effects switch and slow-update displays (e-ink,
|
|
201
|
+
print) get the same static, sharp image as reduced motion. */
|
|
202
|
+
:root[data-kui-effects="static"]
|
|
203
|
+
.kui-backdrop-image[data-parallax="scroll"]
|
|
204
|
+
.kui-backdrop-image__layers,
|
|
205
|
+
:root[data-kui-effects="static"]
|
|
206
|
+
.kui-backdrop-image[data-blur]
|
|
207
|
+
:is(.kui-backdrop-image__blurred, .kui-backdrop-image__dim) {
|
|
208
|
+
animation: none;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@media (update: slow) {
|
|
212
|
+
.kui-backdrop-image[data-parallax="scroll"] .kui-backdrop-image__layers,
|
|
213
|
+
.kui-backdrop-image[data-blur]
|
|
214
|
+
:is(.kui-backdrop-image__blurred, .kui-backdrop-image__dim) {
|
|
215
|
+
animation: none;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Reduced transparency or increased contrast: no dissolve. The image ends on
|
|
220
|
+
a hard edge over solid fadeTo, and overlay content sits on a solid fadeTo
|
|
221
|
+
band instead of the image, so text chosen for the fade color stays
|
|
222
|
+
legible. */
|
|
223
|
+
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
|
|
224
|
+
.kui-backdrop-image[data-fade="true"] .kui-backdrop-image__backdrop {
|
|
225
|
+
mask-image: none;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.kui-backdrop-image[data-fade="true"] .kui-backdrop-image__overlay {
|
|
229
|
+
background-color: var(--_kui-backdrop-image-fade-to);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Over that solid band the overlay keeps the page's scheme. */
|
|
233
|
+
.kui-backdrop-image[data-fade="true"]:is(
|
|
234
|
+
[data-scrim="bottom"],
|
|
235
|
+
[data-scrim="full"]
|
|
236
|
+
)
|
|
237
|
+
.kui-backdrop-image__overlay {
|
|
238
|
+
color-scheme: inherit;
|
|
239
|
+
color: inherit;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
@@ -217,6 +217,15 @@
|
|
|
217
217
|
overflow-clip-margin: 4px;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
/* A glass control group floats on a soft shadow that reaches well past the
|
|
221
|
+
ring margin (about 24px below and 18px to the side). While the zone holds
|
|
222
|
+
one it stops clipping, so the shadow is never cut off flat: a margin would
|
|
223
|
+
not do, since WebKit has no `overflow-clip-margin`. A title beside it still
|
|
224
|
+
truncates itself with its own ellipsis. */
|
|
225
|
+
.kui-toolbar__leading:has(> .kui-toolbar-control-group[data-material="glass"]) {
|
|
226
|
+
overflow: visible;
|
|
227
|
+
}
|
|
228
|
+
|
|
220
229
|
.kui-toolbar__center {
|
|
221
230
|
/* The center content never compresses below its own width (a group cannot
|
|
222
231
|
shrink or clip its controls). The track above takes this as its minimum, so
|