@kerfjs/ui 5.0.0-beta.111 → 5.0.0-beta.113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/ai/component-catalog.json +152 -6
- package/ai/component-composition.json +111 -1
- package/ai/components/README.md +2 -0
- package/ai/components/backdrop-image.md +1 -0
- package/ai/components/content-item.md +1 -0
- package/ai/components/editor-frame.md +80 -0
- package/ai/components/summary-row.md +5 -2
- package/ai/components/value-preview.md +75 -0
- package/ai/public-api-signatures-v1.md +124 -14
- package/ai/skill.md +13 -0
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/backdrop-image.d.ts +3 -0
- package/dist/backdrop-image.js +1 -1
- package/dist/browser/editor-frame.js +3 -0
- package/dist/browser/value-preview.js +3 -0
- package/dist/catalog.js +4 -3
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-JCCN3U6X.js → chunk-2J7XKAZX.js} +3 -2
- package/dist/chunk-2J7XKAZX.js.map +1 -0
- package/dist/{chunk-WD6KABEU.js → chunk-3KFMLOTH.js} +3 -2
- package/dist/chunk-3KFMLOTH.js.map +1 -0
- package/dist/{chunk-ATGAJVZ6.js → chunk-3OP66VXU.js} +64 -4
- package/dist/chunk-3OP66VXU.js.map +1 -0
- package/dist/{chunk-ZNROKDSZ.js → chunk-3V4OCDTL.js} +2 -8
- package/dist/chunk-3V4OCDTL.js.map +1 -0
- package/dist/{chunk-3GLYIIFR.js → chunk-3WWX2O4G.js} +3 -2
- package/dist/chunk-3WWX2O4G.js.map +1 -0
- package/dist/{chunk-SOBRGH7T.js → chunk-5CLMV5YU.js} +5 -2
- package/dist/chunk-5CLMV5YU.js.map +1 -0
- package/dist/chunk-F653O57X.js +41 -0
- package/dist/chunk-F653O57X.js.map +1 -0
- package/dist/{chunk-4UB5Z3ZZ.js → chunk-K67XBCHG.js} +8 -4
- package/dist/chunk-K67XBCHG.js.map +1 -0
- package/dist/chunk-OK7FUK7U.js +9 -0
- package/dist/chunk-OK7FUK7U.js.map +1 -0
- package/dist/{chunk-VGECEXM6.js → chunk-S3DCRI2M.js} +21 -4
- package/dist/chunk-S3DCRI2M.js.map +1 -0
- package/dist/chunk-V6N3YLTM.js +56 -0
- package/dist/chunk-V6N3YLTM.js.map +1 -0
- package/dist/content-item.d.ts +2 -0
- package/dist/content-item.js +1 -1
- package/dist/editor-frame.d.ts +41 -0
- package/dist/editor-frame.js +3 -0
- package/dist/editor-frame.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +24 -21
- package/dist/list-action-row.js +2 -1
- package/dist/list-detail-dialog.js +2 -2
- package/dist/list-item.js +2 -1
- package/dist/styles/backdrop-image.css +6 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +1 -1
- package/dist/styles/components/collections/summary-row/summary-row.css +7 -3
- package/dist/styles/components/data-display/value-preview/value-preview.css +18 -0
- package/dist/styles/components/surfaces/backdrop-image/backdrop-image.css +6 -0
- package/dist/styles/components/surfaces/editor-frame/editor-frame.css +121 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +16 -0
- package/dist/styles/editor-frame.css +121 -0
- package/dist/styles/foundation.css +5 -0
- package/dist/styles/popup-menu.css +1 -1
- package/dist/styles/styles.css +2 -0
- package/dist/styles/summary-row.css +7 -3
- package/dist/styles/surface-scaffold.css +16 -0
- package/dist/styles/value-preview.css +18 -0
- package/dist/summary-row.d.ts +20 -11
- package/dist/summary-row.js +2 -1
- package/dist/surface-scaffold-register.js +1 -1
- package/dist/surface-scaffold.d.ts +26 -2
- package/dist/surface-scaffold.js +2 -2
- package/dist/value-preview.d.ts +21 -0
- package/dist/value-preview.js +3 -0
- package/dist/value-preview.js.map +1 -0
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-content-items.js +34 -8
- package/dist/wire-content-items.js.map +1 -1
- package/dist/workbench-dialog.js +2 -2
- package/docs/component-contract.md +28 -5
- package/docs/component-selection.md +15 -0
- package/docs/editor-frame.md +47 -0
- package/docs/investigations/content-item-media-scroll-performance.md +46 -0
- package/docs/layout.md +10 -1
- package/docs/surface-scaffold.md +46 -0
- package/docs/value-preview.md +16 -0
- package/llms.txt +7 -1
- package/package.json +13 -1
- package/dist/chunk-3GLYIIFR.js.map +0 -1
- package/dist/chunk-4UB5Z3ZZ.js.map +0 -1
- package/dist/chunk-ATGAJVZ6.js.map +0 -1
- package/dist/chunk-JCCN3U6X.js.map +0 -1
- package/dist/chunk-SOBRGH7T.js.map +0 -1
- package/dist/chunk-VGECEXM6.js.map +0 -1
- package/dist/chunk-WD6KABEU.js.map +0 -1
- package/dist/chunk-ZNROKDSZ.js.map +0 -1
|
@@ -432,10 +432,14 @@ content surface's fill: a `SunkenPanel`, a sunken `Disclosure`, a lowered
|
|
|
432
432
|
`ContentItem`, a `TabBar` strip, and translucent glass chrome at rest — a
|
|
433
433
|
`Pane` overlay header, `NavStack` overlay chrome or bottom toolbar, a
|
|
434
434
|
`TabNavigator` overlay bar, and a dialog's floating header; clear chrome
|
|
435
|
-
paints nothing and keeps the inherited context). Interactive
|
|
436
|
-
`ListActionRow
|
|
437
|
-
|
|
438
|
-
|
|
435
|
+
paints nothing and keeps the inherited context). Interactive `ListItem` and
|
|
436
|
+
`ListActionRow` actions are buttons or links themselves, so no control nests on
|
|
437
|
+
their hover or selection fill. A default `SummaryRow` is a selectable option;
|
|
438
|
+
`semanticRole="group"` makes it a static labeled group whose title may contain
|
|
439
|
+
a nested native action. These rows publish nothing. They are undeclared at
|
|
440
|
+
`:root` and a scoped `[data-kui-tint]` resets them. An option `SummaryRow`
|
|
441
|
+
also accepts `draggable` on its root in row and card presentations; the app
|
|
442
|
+
owns the drag gesture and drop policy. A control that must match what
|
|
439
443
|
lies behind it (the inset focus ring's inner line on `Button` and
|
|
440
444
|
`SplitButton`) layers tint over region over the opaque color, falling back to
|
|
441
445
|
`--kui-color-surface`. Custom properties cannot fold an inherited value into a
|
|
@@ -598,9 +602,15 @@ An image-led feed card uses `ContentItem.media` and an optional app-supplied
|
|
|
598
602
|
`SurfaceTint` in `tint`. Its media composes `BackdropImage`, reserving an aspect
|
|
599
603
|
ratio and running a per-image view timeline in the shared scrollport. Optional
|
|
600
604
|
`overlay`, `scrim`, `fadeTo`, and `blur` use the same behavior as a page hero;
|
|
605
|
+
`media.deferOffscreen` opts dense feeds into offscreen hero paint deferral
|
|
606
|
+
without changing card geometry or the shared scroll owner;
|
|
601
607
|
`edgeToEdge` extends media to the card's top and inline inner edges;
|
|
602
608
|
`wireContentItems` handles load/error and restores the normal surface when the
|
|
603
|
-
lead image fails.
|
|
609
|
+
lead image fails. The once-wired helper also restores the native image state
|
|
610
|
+
and tint after a render rewrites card attributes without replacing the image.
|
|
611
|
+
On a light card tint without an accent, the brand on-fill token is darkened for
|
|
612
|
+
AA-readable compact info Badges.
|
|
613
|
+
See [Content items](layout.md#content-items).
|
|
604
614
|
For an interactive ContentItem, `wireContentItems` activates the card on Enter
|
|
605
615
|
or Space only when the key event originated from the card itself. A nested
|
|
606
616
|
native control, including one inside a custom element's shadow root, keeps its
|
|
@@ -707,6 +717,10 @@ item padding, omit an internal separator, and let the raised selected item paint
|
|
|
707
717
|
over the outer border instead of shrinking to an inset highlight. The
|
|
708
718
|
PopupMenu trigger sizes to max-content, so icons, localized text, and the caret
|
|
709
719
|
determine the width without a fixed measurement.
|
|
720
|
+
Inside a `single` icon `ToolbarControlGroup`, an icon-only PopupMenu trigger
|
|
721
|
+
fills the group's control slot, keeping its glyph centered and the full
|
|
722
|
+
40px hit target in enabled and disabled states. Text and mixed-content triggers
|
|
723
|
+
continue to size to their content.
|
|
710
724
|
At viewport widths of 480px or less, `PopupMenu` places an open submenu above
|
|
711
725
|
or below its parent menu, choosing the side with room and constraining the
|
|
712
726
|
submenu to the viewport. It never paints over the parent list. The reverse
|
|
@@ -753,6 +767,15 @@ action on click or keyboard activation. The application owns the editing control
|
|
|
753
767
|
and the swap between display and edit states. An actionable title is a button,
|
|
754
768
|
so place any required heading landmark on another element in the view.
|
|
755
769
|
|
|
770
|
+
`ValuePreview` displays a literal read-only string in a bounded, keyboard-scrollable
|
|
771
|
+
`output` with an accessible label. It preserves line breaks and wraps long
|
|
772
|
+
tokens without painting a second surface; compose it inside `SunkenPanel` for
|
|
773
|
+
a lowered frame. See [ValuePreview](value-preview.md).
|
|
774
|
+
`EditorFrame` owns a fixed Toolbar row over a native textarea in source mode
|
|
775
|
+
or a scrolling rendered preview. Its framed, embedded, flush, autosize, and
|
|
776
|
+
expanded variants keep editing and draft policy in the application. See
|
|
777
|
+
[EditorFrame](editor-frame.md).
|
|
778
|
+
|
|
756
779
|
`ValueTable` composes typed `ValueTableRow` entries. A row owns its `dt`/`dd`
|
|
757
780
|
semantics and may receive a leading `SafeHtml` icon. Every row keeps 8px of
|
|
758
781
|
root-scaled padding above and below its content; the shared item-padding token
|
|
@@ -323,6 +323,11 @@ For a lowered background behind an entire scrolling work area, choose
|
|
|
323
323
|
`Pane appearance="sunken"` or the appearance option on the layout that owns
|
|
324
324
|
the scroll viewport. Use `SunkenPanel` for a padded content group that does
|
|
325
325
|
not introduce scrolling. See [Lowered work surfaces](./layout.md#lowered-work-surfaces).
|
|
326
|
+
For a long read-only value inside that panel, use `ValuePreview`
|
|
327
|
+
([guide](./value-preview.md))
|
|
328
|
+
to preserve line breaks and keep the value's own scroll region bounded.
|
|
329
|
+
For a toolbar above a native editing or preview surface, use `EditorFrame`
|
|
330
|
+
([guide](./editor-frame.md)); it owns the bounded frame and one scroll owner.
|
|
326
331
|
|
|
327
332
|
Set `ResizableRegion`'s `--kui-resizable-region-background` for an inline
|
|
328
333
|
surface. A `PopupMenu` opens in the browser top layer, so the region keeps
|
|
@@ -818,6 +823,16 @@ are distinct interaction contracts: a command menu still uses `PopupMenu`.
|
|
|
818
823
|
|
|
819
824
|
## Configuring recurring list rows
|
|
820
825
|
|
|
826
|
+
`SummaryRow` is a selectable `role="option"` by default. For an unreadable
|
|
827
|
+
item diagnostic with a recovery button inside the title, set
|
|
828
|
+
`semanticRole="group"` and a required `ariaLabel`. The row keeps its `row` or
|
|
829
|
+
`card` chrome, rail, list-edge rounding, and selected visual fill, but it has
|
|
830
|
+
no root Tab stop or `aria-selected`; the nested button owns keyboard focus and
|
|
831
|
+
activation. Keep option rows in the app's labeled listbox.
|
|
832
|
+
Set `draggable` on an option to make the same row or card root a native drag
|
|
833
|
+
source; it preserves role, selection, focus, and delegated `data-*` identity
|
|
834
|
+
through rerenders. Handle `dragstart` and drop policy in the application.
|
|
835
|
+
|
|
821
836
|
Configure the List family instead of selecting its descendant classes. Use
|
|
822
837
|
`density="compact"` for result-heavy panes, `description` for the secondary
|
|
823
838
|
label line, `status` for dormant state text, and `busy` for known progress that
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# EditorFrame
|
|
2
|
+
|
|
3
|
+
`EditorFrame` owns the geometry of a bounded writing surface. It keeps a Kerf
|
|
4
|
+
`Toolbar` above one scroll owner and gives standalone editors their border,
|
|
5
|
+
surface, radius, and inset. The application supplies a native `<textarea>` in
|
|
6
|
+
`mode="source"` or rendered content in `mode="preview"`; it retains the draft,
|
|
7
|
+
recovery, edit actions, and preview rendering.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { EditorFrame } from '@kerfjs/ui/editor-frame';
|
|
11
|
+
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
12
|
+
|
|
13
|
+
<EditorFrame
|
|
14
|
+
mode="source"
|
|
15
|
+
label="Markdown Editor"
|
|
16
|
+
toolbar={<Toolbar label="Markdown Editor Toolbar" trailing={actions} />}
|
|
17
|
+
>
|
|
18
|
+
<textarea name="markdown-source" aria-label="Markdown Source">
|
|
19
|
+
{draft}
|
|
20
|
+
</textarea>
|
|
21
|
+
</EditorFrame>;
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The framed default is 320px high and at most 672px wide; `height` and `maxWidth`
|
|
25
|
+
accept typed `CssLength` values. The toolbar row stays fixed. In source mode,
|
|
26
|
+
the native textarea fills the remaining space and scrolls its own text while
|
|
27
|
+
the surrounding surface clips overflow. In preview mode, the surface scrolls
|
|
28
|
+
around the application's rendered content. No second nested scrollport is
|
|
29
|
+
introduced.
|
|
30
|
+
|
|
31
|
+
Set `appearance="embedded"` when a host already owns the frame. The border,
|
|
32
|
+
radius, fill, and fixed height then drop away. The embedded source can use
|
|
33
|
+
`sourceHeight` for a restored native textarea height or `sourceAutosize` to
|
|
34
|
+
grow with its content; the application still owns persistence and value updates.
|
|
35
|
+
Set `inset="flush"` when the host already provides the text inset. These modes
|
|
36
|
+
preserve the native textarea's selection, input events, and form behavior.
|
|
37
|
+
|
|
38
|
+
Set `expanded` to place the same editor in a fixed viewport overlay with a
|
|
39
|
+
32px inset and raised shadow. This takes precedence over embedded appearance
|
|
40
|
+
while expanded. The application owns the expand control, focus management, and
|
|
41
|
+
any modal behavior it needs. `toolbar` accepts a normal Kerf Toolbar and is
|
|
42
|
+
omitted when the embedded host supplies its own controls.
|
|
43
|
+
|
|
44
|
+
Import `@kerfjs/ui/editor-frame.css` when not using the browser export
|
|
45
|
+
condition; the browser entry includes its stylesheet automatically. The
|
|
46
|
+
component is demonstrated by the EditorFrame UX catalog route, with source,
|
|
47
|
+
preview, and embedded variants.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ContentItem media scroll performance investigation
|
|
2
|
+
|
|
3
|
+
`ContentItem.media` composes `BackdropImage` for image-led cards. A recorded Newsmonger feed with 200 image-backed cards exposed a Chromium scroll regression under fourfold CPU throttling (KF-NMB087, 200-card media performance investigation). The comparison used the former feed image nodes as its baseline and the public beta.111 media composition as its effect. Both loaded the same server data and 200 unique image URLs; all images decoded before scrolling, and neither run reported page errors. The baseline bundle override was checked for raw story images and zero `BackdropImage` nodes, and the effect for the inverse.
|
|
4
|
+
|
|
5
|
+
| 200 cards, 240 forward/reverse frames | Former feed p95 | Media effect p95 | Frames over 50 ms, former → effect |
|
|
6
|
+
| ------------------------------------- | --------------: | ---------------: | ---------------------------------: |
|
|
7
|
+
| 1440px, 2400px local crossing | 19.0 ms | 50.9 ms | 0 → 13 |
|
|
8
|
+
| 390px, 2400px local crossing | 19.0 ms | 26.7 ms | 0 → 0 |
|
|
9
|
+
| 1440px, rapid full-feed sweep | 23.6 ms | 73.0 ms | 0 → 123 |
|
|
10
|
+
| 390px, rapid full-feed sweep | 18.8 ms | 42.4 ms | 0 → 1 |
|
|
11
|
+
|
|
12
|
+
The rapid desktop trace increased Layerize from 389 to 3621 ms, PrePaint from 55 to 629 ms, Paint from 2704 to 3346 ms, raster from 1065 to 1870 ms, and peak observed layers from 9 to 141. These event durations overlap and cannot be summed as CPU time. The trace recorded no geometric Layout events, and app JavaScript was comparatively small. Layer construction, prepaint, and raster are leading suspects; the trace does not isolate parallax, blur, fade, mask, tint, or image memory. The 432 MB unique-source RGBA figure is an estimate from natural image sizes, not measured GPU allocation.
|
|
13
|
+
|
|
14
|
+
A browser-side CSS ablation toggled the moving, blurred, filtered, and masked layers without changing component source. It did not establish a causal ranking: in a single page of 200 cards (396 image elements, because two media blocks were absent), the unchanged desktop effect measured 43.1 ms p95 on its first pass and 22.6 ms when repeated after the variants. That run requested decode for every present image but did not separately record the decoded count. The two completed fresh-context variants were not counterbalanced. Each toggle's computed animation, filter, and mask state was checked, and no page errors occurred. The narrow, warmed passes clustered near 19 ms p95. One-pass toggles therefore cannot justify a component change or an application CSS workaround.
|
|
15
|
+
|
|
16
|
+
KF-J5SAFS followed up with counterbalanced measurements and an opt-in shared-component change below. The original raw traces and harnesses are attached to KF-NMB087.
|
|
17
|
+
|
|
18
|
+
## Follow-up measurement and shipped option
|
|
19
|
+
|
|
20
|
+
KF-J5SAFS repeated fresh-context CSS ablations against the same seeded real feed under Chromium fourfold CPU throttling. In two counterbalanced 200-card desktop blocks, the unchanged effect measured 44–46 ms first-pass p95. Removing the parallax layer lowered it to 33–34 ms; removing filters alone did not improve it. Deferring the whole card's offscreen rendering lowered it to 19–21 ms, but initially shortened the feed's scroll height by 473–507px. That violates scroll restoration and can cause a jump as cards become visible.
|
|
21
|
+
|
|
22
|
+
Applying `content-visibility: auto` only to the `BackdropImage` hero preserved the measured scroll height exactly while lowering first-pass p95 from 44.7 to 33.3 ms at 1440px and 31.0 to 25.1 ms at 390px. Peak observed layers fell from 97 to 33 and from 44 to 16, respectively. This is an opt-in `BackdropImage.deferOffscreen` / `ContentItem.media.deferOffscreen` setting for dense feeds. It leaves the card body, actions, aspect-ratio reservation, and shared Pane scrollport in layout; browsers without `content-visibility` simply paint the hero normally. The existing scroll timeline and static accessibility fallbacks remain unchanged.
|
|
23
|
+
|
|
24
|
+
An exact 50-card counterbalanced follow-up found first-pass p95 of 18.7 ms unchanged versus 18.6 ms with hero deferral at 1440px, and 18.2 versus 18.6 ms at 390px. All four runs preserved feed scroll height; peak layers were 97 versus 33 on desktop and 44 versus 16 on narrow. The 50-card feed is near the display cadence floor, so deferral provides no measurable frame-time gain at that size. The earlier mismatched 50/52-card block is excluded from this conclusion.
|
|
25
|
+
|
|
26
|
+
The 200-card hero ablation decoded 324/396 images before traversal on desktop and 352/396 on narrow, versus all images in the unchanged effect. Browser checks therefore verify that visible images are ready after scrolling to them and that feed geometry remains stable. These numbers measure a specific seeded local feed and CPU setting, not a general frame-time guarantee.
|
|
27
|
+
|
|
28
|
+
## Residual dense-feed investigation
|
|
29
|
+
|
|
30
|
+
KF-CG0G0S used the NM-PSF3FN production bundle and seeded real server to probe the remaining 200-card cost. The published comparison had already shown that replacing the 16px CSS blur with independent 64px pre-blurred assets did not help: at 1440px and Chromium CPU4x, local p95 was 39.4–40.2ms with the filter and 42.0–49.8ms with the asset, versus 18.1–19.6ms for the archived plain-image control. Both effect modes peaked at 33 layers, versus 9 for the control. That control is historical, so this gap is not an isolated estimate of any one CSS property.
|
|
31
|
+
|
|
32
|
+
The follow-up used the same current effect bundle, 200 seeded cards, fresh browser contexts, decoded images, a 240-frame 2400px forward/reverse local path, and CPU4x. Each CSS variant was injected before warmup and run in counterbalanced order. These probes omitted CDP tracing to keep the experiment bounded; peak layer counts came from `LayerTree` and p95 from animation frames. The raw scripts and results are attached to KF-CG0G0S.
|
|
33
|
+
|
|
34
|
+
| CSS probe | 1440px local p95, two contexts | 390px local p95, two contexts | Peak layers, wide / narrow | Finding |
|
|
35
|
+
| ---------------------------------------------------------- | -----------------------------: | ----------------------------: | -------------------------: | ------------------------------------------------ |
|
|
36
|
+
| Current effect (containment block) | 34.5–46.0ms | 36.0–37.8ms | 33 / 16 | Counterbalanced reference |
|
|
37
|
+
| `contain: paint` on hero | 39.4–48.4ms | 34.0–35.7ms | 33 / 16 | No consistent gain; same layer count |
|
|
38
|
+
| `contain: paint` on backdrop | 45.8–46.7ms | 32.4–37.6ms | 33 / 16 | No consistent gain; same layer count |
|
|
39
|
+
| Current effect (root-deferral block) | 44.9–46.4ms | 31.1–38.1ms | 33 / 16 | Counterbalanced reference |
|
|
40
|
+
| `content-visibility: auto` plus aspect ratio on media root | 45.0–45.3ms | 32.1–36.9ms | 33 / 16 | Exact feed height, but no demonstrated reduction |
|
|
41
|
+
|
|
42
|
+
In the root-deferral block, initial, warmed, and post-scroll heights matched the control exactly: 56,353px wide and 157,333px narrow. This does not justify moving deferral from the hero: it adds a second offscreen containment boundary without lowering layer count or showing a repeatable p95 gain.
|
|
43
|
+
|
|
44
|
+
A separate wide-only block isolated the animated parts. Current effect p95 was 43.0–43.8ms with 33 peak layers. Hiding the dim layer yielded 38.5 and 46.1ms with 33 layers: inconclusive. Hiding the blurred copy yielded 38.9 and 40.7ms with 27 layers. Disabling parallax yielded 36.8 and 37.2ms with 27 layers. The latter two changes remove required visible behavior, so neither is a component fix. They do support the layer/timeline composition as the next investigation target rather than mutation-rescan wiring, whose cost was not implicated by this scroll experiment.
|
|
45
|
+
|
|
46
|
+
No public component change is justified by these probes. KF-QX18S3 tracks target-device validation and a lower-layer design that retains independent reverse transitions, progressive blur/dim, static fallbacks, controls, focus, and feed geometry. A physical device/browser and normal-scroll frame budget are needed before a headless Mac CPU4x result can serve as acceptance evidence.
|
package/docs/layout.md
CHANGED
|
@@ -458,7 +458,12 @@ The card composes `BackdropImage` for its scroll timeline, optional overlay and
|
|
|
458
458
|
scrim, progressive `blur`, and typed `fadeTo` that continues behind its body.
|
|
459
459
|
`blurredSrc` is a pre-blurred decorative copy; the browser animates
|
|
460
460
|
only its opacity and the image layer's transform. Each image has its own view
|
|
461
|
-
timeline in the containing Pane's shared vertical scroller.
|
|
461
|
+
timeline in the containing Pane's shared vertical scroller. Set
|
|
462
|
+
`media.deferOffscreen` for dense feeds: it skips painting an offscreen
|
|
463
|
+
image hero while preserving the card and its reserved media height. Enable it
|
|
464
|
+
only when many media cards share a scrollport; it has no effect in browsers
|
|
465
|
+
without `content-visibility`. The card body and controls remain in the layout.
|
|
466
|
+
`wireContentItems`
|
|
462
467
|
also listens for image load/error from one containing root: a broken lead image
|
|
463
468
|
hides its media block and removes its tint, leaving an ordinary ContentItem;
|
|
464
469
|
changing its source and loading successfully restores the card treatment. A
|
|
@@ -466,12 +471,16 @@ card with no `media` keeps the existing surface and geometry. Do not create a
|
|
|
466
471
|
scroller inside each card. A source link or multiple actions belong inside a
|
|
467
472
|
static ContentItem so each retains native keyboard behavior.
|
|
468
473
|
|
|
474
|
+
For long image-led feeds, see the [200-card scroll performance investigation](investigations/content-item-media-scroll-performance.md) before choosing media effects. Its controlled measurements and warmup limit are recorded there; optimization is tracked separately.
|
|
475
|
+
|
|
469
476
|
The image stays sharp and static under reduced motion, the static-effects
|
|
470
477
|
switch, a slow-update display, or missing scroll-timeline support. Reduced
|
|
471
478
|
transparency and increased contrast also stop the movement and blur; forced
|
|
472
479
|
colors hides the image and uses system surface colors. The tint uses the same
|
|
473
480
|
light/dark AA-clamped tokens as a tinted Pane, including quiet text, links,
|
|
474
481
|
controls, and focus. The application provides the sampled color and scheme.
|
|
482
|
+
On a light tint without an accent, the brand on-fill color is capped at 30%
|
|
483
|
+
OKLCH lightness so a compact info Badge remains AA-readable on its pale fill.
|
|
475
484
|
|
|
476
485
|
For a static item that needs focus, set `tabIndex={0}` for a Tab stop or
|
|
477
486
|
`tabIndex={-1}` for programmatic focus. Set `outlined` for a persistent focus
|
package/docs/surface-scaffold.md
CHANGED
|
@@ -105,6 +105,52 @@ of wrapping it in an app `div`:
|
|
|
105
105
|
`rootAttributes` takes `data-*` identity only; the surface's own configuration
|
|
106
106
|
attributes (`data-size`, `data-presentation`, …) stay protected.
|
|
107
107
|
|
|
108
|
+
### Controlled modal stacks
|
|
109
|
+
|
|
110
|
+
For a reader stack, render one `DialogSurface` per reader with a stable `id` or
|
|
111
|
+
`data-key`, and pass each layer its controlled `stack` state:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
<DialogSurface
|
|
115
|
+
id={`reader-${reader.id}`}
|
|
116
|
+
label={reader.title}
|
|
117
|
+
preferredWidth={remify(1024)}
|
|
118
|
+
height="viewport"
|
|
119
|
+
bodyInset="none"
|
|
120
|
+
bodyLayout="fill"
|
|
121
|
+
stack={{
|
|
122
|
+
open: reader.open,
|
|
123
|
+
active: reader.id === activeReaderId,
|
|
124
|
+
position: reader.position,
|
|
125
|
+
count: readers.length,
|
|
126
|
+
offset: remify(-10 * (readers.length - reader.position)),
|
|
127
|
+
}}
|
|
128
|
+
rootAttributes={{ 'data-key': reader.id }}
|
|
129
|
+
>
|
|
130
|
+
{reader.content}
|
|
131
|
+
</DialogSurface>;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Call `wireDialogStack(container)` once on a stable ancestor after rendering and
|
|
135
|
+
call its returned cleanup when that ancestor unmounts; cleanup closes its open
|
|
136
|
+
layers. It observes subsequent
|
|
137
|
+
renders and calls `syncDialogStack(container)` to open layers back to front in
|
|
138
|
+
the browser's native top layer. `position` is a unique 1-based order within the
|
|
139
|
+
stack; `count` includes closed layers that remain rendered. Exactly one open
|
|
140
|
+
layer must be `active`, and it must have the highest open position. An inactive
|
|
141
|
+
layer has `aria-hidden` and `inert`, and only the active layer has
|
|
142
|
+
`aria-modal="true"`. The optional typed `offset` translates inactive layers on
|
|
143
|
+
roomy screens; compact screens stay aligned. Stacked modals default to a 24px
|
|
144
|
+
desktop and 16px phone viewport gutter, overridable with `viewportGutter`.
|
|
145
|
+
|
|
146
|
+
Handle `kui-request-close` by updating application state to close the top
|
|
147
|
+
layer; the stack controller then reconciles it. It never closes a controlled
|
|
148
|
+
layer on its own. A reorder may briefly close and reopen moved native dialogs
|
|
149
|
+
to establish browser top-layer order, so do not treat the native `close` event
|
|
150
|
+
as a user dismissal. Each dialog retains its own in-dialog overlay host for
|
|
151
|
+
popups and menus. The catalog's **Controlled Reader Stack** demonstrates push,
|
|
152
|
+
reorder, Escape, and close at desktop and phone widths.
|
|
153
|
+
|
|
108
154
|
### Modal viewport bounds
|
|
109
155
|
|
|
110
156
|
`viewportGutter` accepts a branded `CssLength` from `@kerfjs/ui/css-values`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# ValuePreview
|
|
2
|
+
|
|
3
|
+
`ValuePreview` displays a literal, read-only multiline string inside a bounded, keyboard-scrollable region. Use it for an existing value that may contain line breaks or long unbroken tokens, such as two versions in a conflict review. It owns compact text, pre-wrapping, anywhere wrapping, and a 48–96px default height window. It does not paint a background, border, or outer inset; compose it inside `SunkenPanel` when the value needs a lowered frame.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { SunkenPanel } from '@kerfjs/ui/sunken-panel';
|
|
7
|
+
import { ValuePreview } from '@kerfjs/ui/value-preview';
|
|
8
|
+
|
|
9
|
+
<SunkenPanel>
|
|
10
|
+
<ValuePreview label="Their Latest Version" value={remoteText} />
|
|
11
|
+
</SunkenPanel>;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`label` gives the focusable output an accessible name. The string in `value` is rendered as text, not HTML; newlines remain visible and long tokens wrap instead of widening the pane. An empty string stays empty, so the application chooses any placeholder wording. `minHeight` and `maxHeight` take typed CSS lengths from `@kerfjs/ui/css-values` when a different scroll window is needed. The component itself scrolls long content; the containing `SunkenPanel` remains the sole owner of its surface.
|
|
15
|
+
|
|
16
|
+
Use `TextField multiline` when the person can edit the value. Use `ValueTable` for labelled short facts. `ValuePreview` is for one potentially long, read-only value.
|
package/llms.txt
CHANGED
|
@@ -732,7 +732,10 @@ headingLevel`, `SearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
732
732
|
per item as a list `row` or board `card`, with a state `rail`, a clamped
|
|
733
733
|
`title`, `trailingMeta`, a `metadata` line, `selected`, `dimmed`, and
|
|
734
734
|
`listEdge` rounding; the app owns the listbox and keyboard movement. Never
|
|
735
|
-
hand-roll ticket-row chrome.
|
|
735
|
+
hand-roll ticket-row chrome. For a non-option diagnostic with a nested
|
|
736
|
+
recovery button, set `semanticRole="group"` and `ariaLabel`; the root is not
|
|
737
|
+
a Tab stop and only the button activates. Set `draggable` on an option row or
|
|
738
|
+
card for a native drag source on that same selection root.
|
|
736
739
|
- **Group settings rows in `FramedList`.** For rows of arbitrary content in
|
|
737
740
|
one rounded frame with dividers between them (settings, account cards,
|
|
738
741
|
shortcut lists), compose `FramedListRow`s; `ValueTable` is the same frame for
|
|
@@ -919,6 +922,9 @@ created, input }`. Never use a hand-styled `<input list>` + `<datalist>`.
|
|
|
919
922
|
`data-kui-effects="static"`, or without scroll-driven animations, and ends on
|
|
920
923
|
a hard edge (overlay on a solid `fadeTo` band) under reduced transparency. Never hand-roll scroll listeners or
|
|
921
924
|
`background-attachment: fixed`.
|
|
925
|
+
In a dense image-led feed, opt into `ContentItem.media.deferOffscreen` (or
|
|
926
|
+
`BackdropImage.deferOffscreen` directly) to skip offscreen hero painting while
|
|
927
|
+
preserving card height and the shared scroll owner.
|
|
922
928
|
|
|
923
929
|
- **Use `MessageComposer` for a chat or prompt composer.** `@kerfjs/ui/message-composer`
|
|
924
930
|
renders a raised frame (standard border, large radius, `shadow-l`) whose
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kerfjs/ui",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.113",
|
|
4
4
|
"description": "Accessible, composable UI primitives for kerf applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -561,6 +561,16 @@
|
|
|
561
561
|
"browser": "./dist/browser/value-table.js",
|
|
562
562
|
"import": "./dist/value-table.js"
|
|
563
563
|
},
|
|
564
|
+
"./value-preview": {
|
|
565
|
+
"types": "./dist/value-preview.d.ts",
|
|
566
|
+
"browser": "./dist/browser/value-preview.js",
|
|
567
|
+
"import": "./dist/value-preview.js"
|
|
568
|
+
},
|
|
569
|
+
"./editor-frame": {
|
|
570
|
+
"types": "./dist/editor-frame.d.ts",
|
|
571
|
+
"browser": "./dist/browser/editor-frame.js",
|
|
572
|
+
"import": "./dist/editor-frame.js"
|
|
573
|
+
},
|
|
564
574
|
"./unstyled": {
|
|
565
575
|
"types": "./dist/index.d.ts",
|
|
566
576
|
"import": "./dist/index.js"
|
|
@@ -642,6 +652,8 @@
|
|
|
642
652
|
"./summary-row.css": "./dist/styles/summary-row.css",
|
|
643
653
|
"./empty-state.css": "./dist/styles/empty-state.css",
|
|
644
654
|
"./value-table.css": "./dist/styles/value-table.css",
|
|
655
|
+
"./value-preview.css": "./dist/styles/value-preview.css",
|
|
656
|
+
"./editor-frame.css": "./dist/styles/editor-frame.css",
|
|
645
657
|
"./ai/*": "./ai/*",
|
|
646
658
|
"./docs/*": "./docs/*"
|
|
647
659
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/collections/list-item/list-item.tsx"],"names":[],"mappings":"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","file":"chunk-3GLYIIFR.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport {\n type ListIconTile,\n type ListIconTilePresentation,\n listIconTilePresentation,\n} from '../../../shared/content/list-icon-tile.js';\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { nativeDraggable } from '../../../shared/dom/draggable.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport { em, remify } from '../../../shared/styles/css-values.js';\nimport { withWordBreaks } from '../../../shared/text/word-breaks.js';\nimport { LoadingSpinner } from '../../feedback/loading-spinner/loading-spinner.js';\nimport { Skeleton } from '../../feedback/skeleton/skeleton.js';\n\nexport type {\n ListIconTile,\n ListIconTileColor,\n ListIconTileTone,\n} from '../../../shared/content/list-icon-tile.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-has-description',\n 'data-multiline',\n 'data-density',\n 'data-divider',\n 'data-busy',\n 'data-state',\n 'data-kui-disabled',\n 'data-icon-align',\n 'data-icon-tile',\n 'data-icon-tile-tone',\n 'data-dragging',\n 'data-drop-position',\n]);\n\ntype ListItemRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-has-description'?: never;\n 'data-multiline'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-busy'?: never;\n 'data-state'?: never;\n 'data-kui-disabled'?: never;\n 'data-icon-align'?: never;\n 'data-icon-tile'?: never;\n 'data-icon-tile-tone'?: never;\n 'data-dragging'?: never;\n 'data-drop-position'?: never;\n }\n>;\n\nexport interface ListItemProps {\n label: string | SafeHtml;\n /** App-owned supporting text rendered in the component's stable label stack. */\n description?: string | SafeHtml;\n icon?: SafeHtml;\n /** Present `icon` in a filled 32px rounded tile with an 18px glyph: a quiet tone preset, or `{ color, foreground? }` for an application color. */\n iconTile?: ListIconTile;\n /** Dormant author content at the row's end; a placeholder renders it as a skeleton. */\n trailing?: KerfUiContent;\n /** Dormant status metadata rendered before trailing content; a placeholder renders it as a skeleton. */\n status?: string | SafeHtml;\n /** Show a progress indicator and expose the row as busy without replacing its content; a placeholder keeps the indicator. */\n busy?: boolean;\n density?: 'standard' | 'compact' | 'spacious';\n divider?: 'none' | 'before' | 'after' | 'both';\n selected?: boolean;\n action: string;\n itemId?: string;\n className?: string;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n /** Alignment of an icon beside a wrapped label. Defaults to its first line. */\n multilineIconAlign?: 'first-line' | 'center';\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render the row as an unanimated loading skeleton, disabling its action: label, description, icon, status, and trailing content become skeletons; the `busy` indicator stays live. */\n placeholder?: boolean;\n /** Native HTML drag source (`draggable=\"true\"`); a placeholder is never draggable. Pair with `wireListReorder` for pointer and keyboard reordering. */\n draggable?: boolean;\n /** Dim this row as one of the rows being dragged. */\n dragging?: boolean;\n /** Draw the insertion line at this row's leading (`before`) or trailing (`after`) block edge. */\n dropPosition?: 'before' | 'after';\n rootAttributes?: ListItemRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport interface ListItemLinkProps extends Omit<\n ListItemProps,\n 'action' | 'pressed'\n> {\n /** Native destination for this navigation row. */\n href: string;\n /** Open in a new tab with a safe rel and announce that behavior. */\n external?: boolean;\n action?: never;\n pressed?: never;\n}\n\nfunction listItemContent({\n label,\n description,\n icon,\n tile,\n trailing,\n status,\n busy = false,\n multiline = false,\n placeholder = false,\n}: Pick<\n ListItemProps,\n | 'label'\n | 'description'\n | 'icon'\n | 'trailing'\n | 'status'\n | 'busy'\n | 'multiline'\n | 'placeholder'\n> & { tile: ListIconTilePresentation | null }) {\n const tileSize = tile?.tile ? 32 : 18;\n return (\n <>\n {icon && (\n <span\n class=\"kui-list-item__icon\"\n style={placeholder ? undefined : tile?.style}\n >\n {placeholder ? (\n <Skeleton\n block\n width={remify(tileSize)}\n height={remify(tileSize)}\n />\n ) : (\n icon\n )}\n </span>\n )}\n <span class=\"kui-list-item__label\">\n <span class=\"kui-list-item__primary-label\">\n {placeholder ? (\n <Skeleton width={em(9)} />\n ) : multiline ? (\n withWordBreaks(label)\n ) : (\n label\n )}\n </span>\n {description && (\n <span class=\"kui-list-item__description\">\n {placeholder ? <Skeleton width={em(11)} /> : description}\n </span>\n )}\n </span>\n {(busy || status || trailing) && (\n <span class=\"kui-list-item__trailing\">\n {/* The busy spinner is component-owned chrome drawn from a known\n prop, so a placeholder keeps it live. Status text and\n author-supplied trailing content are values: skeletons. */}\n {busy && <LoadingSpinner />}\n {status && (\n <span class=\"kui-list-item__status\">\n {placeholder ? <Skeleton width={em(3.5)} /> : status}\n </span>\n )}\n {trailing && (placeholder ? <Skeleton width={em(1.5)} /> : trailing)}\n </span>\n )}\n </>\n );\n}\n\nexport function ListItem({\n label,\n description,\n icon,\n iconTile,\n trailing,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n selected = false,\n action,\n itemId,\n className = '',\n pressed,\n accessibleLabel,\n title,\n multiline = false,\n multilineIconAlign = 'first-line',\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n draggable,\n dragging = false,\n dropPosition,\n rootAttributes = {},\n slot,\n}: ListItemProps) {\n const extensionAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const tile = icon ? listIconTilePresentation(iconTile, 'list-item') : null;\n return (\n <button\n {...extensionAttributes}\n type=\"button\"\n class={`kui-list-item ${className}`.trim()}\n title={placeholder ? undefined : title}\n disabled={disabled || placeholder}\n tabindex={placeholder ? -1 : tabIndex}\n data-component=\"list-item\"\n data-action={placeholder ? undefined : action}\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-has-description={String(Boolean(description))}\n data-multiline={multiline ? 'true' : undefined}\n data-icon-align={multiline ? multilineIconAlign : undefined}\n data-icon-tile={tile?.tile}\n data-icon-tile-tone={tile?.tone}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-state={state}\n data-kui-disabled={disabled ? 'true' : undefined}\n data-placeholder={placeholder ? 'true' : undefined}\n draggable={nativeDraggable(draggable, placeholder)}\n data-dragging={dragging ? 'true' : undefined}\n data-drop-position={dropPosition}\n aria-label={accessibleLabel}\n aria-current={selected ? 'page' : undefined}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n aria-busy={placeholder || busy ? 'true' : undefined}\n slot={slot}\n >\n {listItemContent({\n label,\n description,\n icon,\n tile,\n trailing,\n status,\n busy,\n multiline,\n placeholder,\n })}\n </button>\n );\n}\n\n/** A navigation row with native link activation and ListItem geometry. */\nexport function ListItemLink({\n href,\n external = false,\n label,\n description,\n icon,\n iconTile,\n trailing,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n selected = false,\n itemId,\n className = '',\n accessibleLabel,\n title,\n multiline = false,\n multilineIconAlign = 'first-line',\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n draggable,\n dragging = false,\n dropPosition,\n rootAttributes = {},\n slot,\n}: ListItemLinkProps) {\n const extensionAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const tile = icon ? listIconTilePresentation(iconTile, 'list-item') : null;\n const inactive = disabled || placeholder;\n const linkLabel =\n accessibleLabel ??\n (external && typeof label === 'string'\n ? `${label} (opens in new tab)`\n : undefined);\n return (\n <a\n {...extensionAttributes}\n class={`kui-list-item ${className}`.trim()}\n href={inactive ? undefined : href}\n target={inactive || !external ? undefined : '_blank'}\n rel={inactive || !external ? undefined : 'noopener noreferrer'}\n title={placeholder ? undefined : title}\n tabindex={inactive ? -1 : tabIndex}\n data-component=\"list-item-link\"\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-has-description={String(Boolean(description))}\n data-multiline={multiline ? 'true' : undefined}\n data-icon-align={multiline ? multilineIconAlign : undefined}\n data-icon-tile={tile?.tile}\n data-icon-tile-tone={tile?.tone}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-state={state}\n data-kui-disabled={disabled ? 'true' : undefined}\n data-placeholder={placeholder ? 'true' : undefined}\n draggable={nativeDraggable(draggable, placeholder)}\n data-dragging={dragging ? 'true' : undefined}\n data-drop-position={dropPosition}\n aria-label={linkLabel}\n aria-current={selected ? 'page' : undefined}\n aria-disabled={inactive ? 'true' : undefined}\n aria-busy={placeholder || busy ? 'true' : undefined}\n slot={slot}\n >\n {listItemContent({\n label,\n description,\n icon,\n tile,\n trailing,\n status,\n busy,\n multiline,\n placeholder,\n })}\n </a>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/collections/summary-row/summary-row.tsx"],"names":[],"mappings":";;;AAWA,IAAM,mBAAA,uBAA0B,GAAA,CAAI;AAAA,EAClC,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAC,CAAA;AAmDM,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,GAAe,KAAA;AAAA,EACf,UAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS,KAAA;AAAA,EACT,QAAA;AAAA,EACA,cAAA,GAAiB,KAAA;AAAA,EACjB,SAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,iBAAiB;AACnB,CAAA,EAAoB;AAClB,EAAA,IACE,eAAe,MAAA,KACd,CAAC,OAAO,SAAA,CAAU,UAAU,KAAK,UAAA,GAAa,CAAA,CAAA;AAE/C,IAAA,MAAM,IAAI,WAAW,kDAAkD,CAAA;AACzE,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,oBAAA,CAAqB,cAAA,EAAgB,mBAAmB,CAAA;AAAA,MAC5D,EAAA;AAAA,MACA,KAAA,EAAO,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC3C,gBAAA,EAAe,aAAA;AAAA,MACf,mBAAA,EAAmB,YAAA;AAAA,MACnB,gBAAA,EAAgB,QAAA;AAAA,MAChB,WAAA,EAAW,IAAA;AAAA,MACX,eAAA,EAAe,WAAW,MAAA,GAAS,MAAA;AAAA,MACnC,aAAA,EAAa,SAAS,MAAA,GAAS,MAAA;AAAA,MAC/B,YAAA,EAAY,iBAAiB,MAAA,GAAS,MAAA;AAAA,MACtC,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAS,GAAA;AAAA,MACT,eAAA,EAAe,WAAW,MAAA,GAAS,OAAA;AAAA,MACnC,YAAA,EAAY,SAAA;AAAA,MACZ,KAAA,EACE,UAAA,KAAe,MAAA,GACX,MAAA,GACA,kCAAkC,UAAU,CAAA,CAAA;AAAA,MAGjD,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,uBAAA,EAAwB,eAAY,MAAA,EAAO,CAAA;AAAA,wBAChE,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EACR,QAAA,EAAA;AAAA,UAAA,OAAA,oBAAW,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,0BAAA,EAA4B,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,0BAC5D,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,0BAAA,EACT,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,OAAM,wBAAA,EACR,QAAA,EAAA;AAAA,cAAA,YAAA,KAAiB,MAAA,oBAChB,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,6BAA6B,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,cAEvD;AAAA,aAAA,EACH,CAAA;AAAA,YACC,QAAA,oBAAY,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,6BAA6B,QAAA,EAAA,QAAA,EAAS;AAAA,WAAA,EAChE;AAAA,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ","file":"chunk-4UB5Z3ZZ.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport type { SemanticTone } from '../../../shared/styles/semantic-tone.js';\n\n/** `row` for a list section; `card` for a board column. */\nexport type SummaryRowPresentation = 'row' | 'card';\n/** A row's place in a rounded list section, so its corners match. */\nexport type SummaryRowListEdge = 'start' | 'end' | 'only';\n\nconst summaryRowProtected = new Set([\n 'data-component',\n 'data-presentation',\n 'data-list-edge',\n 'data-rail',\n 'data-selected',\n 'data-dimmed',\n]);\n\ntype SummaryRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-presentation'?: never;\n 'data-list-edge'?: never;\n 'data-rail'?: never;\n 'data-selected'?: never;\n 'data-dimmed'?: never;\n }\n>;\n\nexport interface SummaryRowProps {\n /** The identity line: an identifier, inline status glyphs, and the title. */\n title: KerfUiContent;\n /** Optional leading glyph, such as a category icon. */\n leading?: SafeHtml;\n /** Quiet text at the end of the title line, such as a relative time. */\n trailingMeta?: string | SafeHtml;\n /** A wrapping line of badges, chips, and quiet text below the title. */\n metadata?: KerfUiContent;\n /** `row` (default) or `card`. */\n presentation?: SummaryRowPresentation;\n /** Title lines before clipping; default 2 for a row and 4 for a card. */\n titleLines?: number;\n /** A leading state rail in a semantic tone (Up Next, blocked, …). */\n rail?: SemanticTone;\n /** Selected state, exposed as `aria-selected`. */\n selected?: boolean;\n /** Dim a finished or cut item; hover and selection restore it. */\n dimmed?: boolean;\n /** Round the corners that meet a rounded list section's edge. */\n listEdge?: SummaryRowListEdge;\n /** Skip rendering while off screen in long lists (`content-visibility`). */\n deferRendering?: boolean;\n /** Accessible name when the visible content is not a good one. */\n ariaLabel?: string;\n id?: string;\n className?: string;\n /** Safe `data-*` identity (an item id or delegated action) on the option. */\n rootAttributes?: SummaryRowRootAttributes;\n}\n\n/**\n * A selectable, keyboard-focusable summary of one item, as a list row or a\n * board card: an optional leading glyph and state rail, a clamped identity line\n * with trailing quiet metadata, and a wrapping metadata line. It is a\n * `role=\"option\"`; place rows in a labeled `role=\"listbox\"` and own selection\n * and keyboard movement in the application.\n */\nexport function SummaryRow({\n title,\n leading,\n trailingMeta,\n metadata,\n presentation = 'row',\n titleLines,\n rail,\n selected = false,\n dimmed = false,\n listEdge,\n deferRendering = false,\n ariaLabel,\n id,\n className = '',\n rootAttributes = {},\n}: SummaryRowProps) {\n if (\n titleLines !== undefined &&\n (!Number.isInteger(titleLines) || titleLines < 1)\n )\n throw new RangeError('SummaryRow titleLines must be a positive integer');\n return (\n <div\n {...filterDataAttributes(rootAttributes, summaryRowProtected)}\n id={id}\n class={`kui-summary-row ${className}`.trim()}\n data-component=\"summary-row\"\n data-presentation={presentation}\n data-list-edge={listEdge}\n data-rail={rail}\n data-selected={selected ? 'true' : undefined}\n data-dimmed={dimmed ? 'true' : undefined}\n data-defer={deferRendering ? 'true' : undefined}\n role=\"option\"\n tabindex=\"0\"\n aria-selected={selected ? 'true' : 'false'}\n aria-label={ariaLabel}\n style={\n titleLines === undefined\n ? undefined\n : `--_kui-summary-row-title-lines:${titleLines}`\n }\n >\n {rail && <span class=\"kui-summary-row__rail\" aria-hidden=\"true\" />}\n <div class=\"kui-summary-row__body\">\n {leading && <span class=\"kui-summary-row__leading\">{leading}</span>}\n <div class=\"kui-summary-row__content\">\n <div class=\"kui-summary-row__title\">\n {trailingMeta !== undefined && (\n <span class=\"kui-summary-row__trailing\">{trailingMeta}</span>\n )}\n {title}\n </div>\n {metadata && <div class=\"kui-summary-row__metadata\">{metadata}</div>}\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/surfaces/surface-scaffold/internal/dialog-surface-controller.ts"],"names":[],"mappings":"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","file":"chunk-ATGAJVZ6.js","sourcesContent":["import { syncSheetHandleValues, wireSheetHandle } from './sheet-handle.js';\n\n/** What asked an open DialogSurface to close. */\nexport type DialogCloseSource = 'close-button' | 'escape' | 'backdrop';\n\n/** The detail of a DialogSurface's cancelable `kui-request-close` event. */\nexport interface DialogRequestCloseDetail {\n readonly source: DialogCloseSource;\n}\n\nconst SURFACE = 'dialog.kui-dialog-surface';\n\n/** The attribute marking a running enter, exit, or pulse animation. */\nexport const DIALOG_MOTION_ATTRIBUTE = 'data-kui-dialog-motion';\n\n/** The panel variable a floating header's body clearance reads. */\nexport const HEADER_BLOCK_SIZE_PROPERTY =\n '--_kui-dialog-surface-header-block-size';\n\n/** The panel variable a floating footer's body clearance reads. */\nexport const FOOTER_BLOCK_SIZE_PROPERTY =\n '--_kui-dialog-surface-footer-block-size';\n\n/**\n * The panel variable a floating header's divider reads: set while content\n * is scrolled away beneath the header, unset (no divider) otherwise.\n */\nexport const HEADER_DIVIDER_PROPERTY = '--_kui-dialog-surface-header-divider';\n\n/** The panel variable holding a resized sheet's visible height. */\nexport const SHEET_HEIGHT_PROPERTY = '--_kui-dialog-surface-sheet-height';\n\n/** The panel variable holding the virtual keyboard's overlap. */\nexport const KEYBOARD_INSET_PROPERTY = '--_kui-dialog-surface-keyboard-inset';\n\n/** The value published while the divider shows: the color the CSS owns. */\nconst DIVIDER_SHOWN = 'var(--_kui-dialog-surface-header-divider-color)';\n\n/**\n * Scroll distance, in px, that counts as \"away from the top\": a scroller at\n * rest can report a fractional offset.\n */\nconst SCROLL_THRESHOLD = 1;\n\ntype Motion = 'enter' | 'exit' | 'pulse';\n\ninterface OpenState {\n /** Panel variables the controller owns while open, restored after a morph. */\n readonly owned: Map<string, string>;\n readonly stop: (() => void)[];\n motionTimer: ReturnType<typeof globalThis.setTimeout> | undefined;\n closing: boolean;\n}\n\nconst states = new WeakMap<HTMLDialogElement, OpenState>();\nconst installed = new WeakSet<Document>();\n\nconst isSurface = (target: EventTarget | null): target is HTMLDialogElement =>\n target instanceof Element && target.matches(SURFACE);\n\n/**\n * The layout viewport's bottom band a virtual keyboard covers: what the\n * visual viewport no longer shows below itself. Zero while pinch-zoomed (the\n * visual viewport then shrinks for another reason) and wherever the keyboard\n * resizes the layout viewport instead (`interactive-widget=resizes-content`).\n */\nexport function keyboardInset(\n viewport: Pick<VisualViewport, 'height' | 'offsetTop' | 'scale'>,\n layoutHeight: number,\n): number {\n if (viewport.scale > 1.01) return 0;\n const inset = Math.round(layoutHeight - viewport.height - viewport.offsetTop);\n return inset > 0 ? inset : 0;\n}\n\n/** The longest running animation on the panel, in ms (0 when none runs). */\nfunction motionDuration(dialog: HTMLElement): number {\n const style = globalThis.getComputedStyle(dialog);\n if (!style.animationName || style.animationName === 'none') return 0;\n return Math.max(\n 0,\n ...style.animationDuration.split(',').map((part) => {\n const value = parseFloat(part);\n return part.trim().endsWith('ms') ? value : value * 1000;\n }),\n );\n}\n\n/**\n * Mark a motion while its keyframes run, then finish it. A timer, not\n * `animationend`, ends it, so an application re-render that drops the marker\n * mid-animation still closes the dialog.\n */\nfunction runMotion(\n dialog: HTMLDialogElement,\n motion: Motion,\n done?: () => void,\n): void {\n const state = states.get(dialog);\n if (state) globalThis.clearTimeout(state.motionTimer);\n dialog.setAttribute(DIALOG_MOTION_ATTRIBUTE, motion);\n const finish = () => {\n done?.();\n if (dialog.getAttribute(DIALOG_MOTION_ATTRIBUTE) === motion)\n dialog.removeAttribute(DIALOG_MOTION_ATTRIBUTE);\n };\n const duration = motionDuration(dialog);\n if (duration === 0 || !state) finish();\n else state.motionTimer = globalThis.setTimeout(finish, duration);\n}\n\n/** Set (or, with `null`, clear) a panel variable the controller owns. */\nfunction own(\n dialog: HTMLDialogElement,\n property: string,\n value: string | null,\n): void {\n const owned = states.get(dialog)?.owned;\n if (value === null) {\n owned?.delete(property);\n dialog.style.removeProperty(property);\n return;\n }\n owned?.set(property, value);\n if (dialog.style.getPropertyValue(property) !== value)\n dialog.style.setProperty(property, value);\n}\n\n/** Watch an open dialog: owned state, chrome sizes, divider, and sheet. */\nfunction follow(dialog: HTMLDialogElement, state: OpenState): void {\n const sheet = dialog.getAttribute('data-presentation') === 'bottom-sheet';\n // Layout sizes, not boxes: the panel opens scaled while its enter motion\n // runs. A resize observation reports the exact border box; until the first\n // one, `offsetHeight` stands in.\n const blockSizes = new WeakMap<Element, number>();\n const sizes = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const box = entry.borderBoxSize?.[0];\n if (box) blockSizes.set(entry.target, box.blockSize);\n }\n measure();\n });\n const blockSize = (element: HTMLElement) =>\n `${blockSizes.get(element) ?? element.offsetHeight}px`;\n let header: HTMLElement | null = null;\n let footer: HTMLElement | null = null;\n let handle: HTMLElement | null = null;\n let unwireHandle: (() => void) | undefined;\n const measure = () => {\n own(dialog, HEADER_BLOCK_SIZE_PROPERTY, header ? blockSize(header) : null);\n own(dialog, FOOTER_BLOCK_SIZE_PROPERTY, footer ? blockSize(footer) : null);\n };\n // The header, footer, and grabber the template renders; a re-render may\n // replace them.\n const track = () => {\n const nextHeader = dialog.querySelector<HTMLElement>(\n ':scope > .kui-dialog-surface__header',\n );\n const nextFooter = dialog.querySelector<HTMLElement>(\n ':scope > .kui-dialog-surface__footer',\n );\n if (nextHeader !== header || nextFooter !== footer) {\n sizes.disconnect();\n header = nextHeader;\n footer = nextFooter;\n for (const element of [header, footer])\n if (element) sizes.observe(element);\n measure();\n }\n const nextHandle = dialog.querySelector<HTMLElement>(\n ':scope > .kui-dialog-surface__sheet-handle',\n );\n if (nextHandle !== handle) {\n unwireHandle?.();\n unwireHandle = undefined;\n handle = nextHandle;\n if (handle) {\n unwireHandle = wireSheetHandle(handle, {\n panel: dialog,\n host: dialog,\n property: SHEET_HEIGHT_PROPERTY,\n enabled: () => true,\n publish: (value) => own(dialog, SHEET_HEIGHT_PROPERTY, value),\n });\n syncSheetHandleValues(handle, dialog);\n }\n }\n };\n track();\n // An application re-render morphs the panel back to its rendered\n // attributes and may replace its chrome: restore the owned variables and\n // follow the new elements.\n const restore = new MutationObserver(() => {\n for (const [property, value] of state.owned)\n if (dialog.style.getPropertyValue(property) !== value)\n dialog.style.setProperty(property, value);\n track();\n });\n restore.observe(dialog, {\n attributes: true,\n attributeFilter: ['style'],\n childList: true,\n });\n // A floating header's divider shows while a scroller reaching beneath it\n // is scrolled away from its top. `scroll` does not bubble: capture it.\n const scrolled = new Set<Element>();\n const onScroll = (event: Event) => {\n const scroller = event.target as Element;\n const floating =\n dialog.getAttribute('data-header-presentation') === 'floating';\n if (\n floating &&\n header &&\n scroller.scrollTop > SCROLL_THRESHOLD &&\n scroller.getBoundingClientRect().top <=\n header.getBoundingClientRect().bottom\n )\n scrolled.add(scroller);\n else scrolled.delete(scroller);\n for (const element of scrolled)\n if (!element.isConnected) scrolled.delete(element);\n own(\n dialog,\n HEADER_DIVIDER_PROPERTY,\n scrolled.size > 0 ? DIVIDER_SHOWN : null,\n );\n };\n dialog.addEventListener('scroll', onScroll, { capture: true, passive: true });\n state.stop.push(() => {\n sizes.disconnect();\n restore.disconnect();\n unwireHandle?.();\n dialog.removeEventListener('scroll', onScroll, { capture: true });\n });\n // A bottom sheet keeps its content above a virtual keyboard.\n const viewport = dialog.ownerDocument.defaultView?.visualViewport;\n if (sheet && viewport) {\n const publish = () => {\n const inset = keyboardInset(viewport, globalThis.innerHeight);\n own(dialog, KEYBOARD_INSET_PROPERTY, inset > 0 ? `${inset}px` : null);\n };\n viewport.addEventListener('resize', publish);\n viewport.addEventListener('scroll', publish);\n state.stop.push(() => {\n viewport.removeEventListener('resize', publish);\n viewport.removeEventListener('scroll', publish);\n });\n publish();\n }\n}\n\n/** Stop following a closed dialog and drop the state it owned. */\nfunction settle(dialog: HTMLDialogElement): void {\n const state = states.get(dialog);\n if (!state) return;\n states.delete(dialog);\n globalThis.clearTimeout(state.motionTimer);\n for (const stop of state.stop) stop();\n for (const property of state.owned.keys())\n dialog.style.removeProperty(property);\n dialog.removeAttribute(DIALOG_MOTION_ATTRIBUTE);\n}\n\n/**\n * Open a DialogSurface as a modal dialog: in the top layer, the rest of the\n * page inert, focus on its `autofocus` element or else the panel. It plays\n * its enter motion and, with the controller installed here, keeps its\n * measured chrome, sheet height, and keyboard clearance across application\n * re-renders. Opening an open dialog does nothing.\n */\nexport function openDialog(dialog: HTMLDialogElement): void {\n installDialogSurfaces(dialog.ownerDocument);\n const closing = states.get(dialog);\n if (closing?.closing) {\n // The latest request wins: reopening during the exit motion keeps it open.\n closing.closing = false;\n runMotion(dialog, 'enter');\n return;\n }\n if (dialog.open) return;\n dialog.showModal();\n const state: OpenState = {\n owned: new Map(),\n stop: [],\n motionTimer: undefined,\n closing: false,\n };\n states.set(dialog, state);\n if (!dialog.querySelector('[autofocus]'))\n dialog.focus({ preventScroll: true });\n follow(dialog, state);\n runMotion(dialog, 'enter');\n}\n\n/**\n * Close an open DialogSurface after its exit motion. The application's own\n * close is never refused: no `kui-request-close` is dispatched. The native\n * `close` event fires once it has closed.\n */\nexport function closeDialog(dialog: HTMLDialogElement): void {\n const state = states.get(dialog);\n if (!dialog.open) return;\n if (!state) {\n dialog.close();\n return;\n }\n if (state.closing) return;\n state.closing = true;\n runMotion(dialog, 'exit', () => dialog.close());\n}\n\n/**\n * A person asked to close the dialog: dispatch the cancelable\n * `kui-request-close`; refused, the panel pulses, otherwise it closes.\n */\nfunction requestClose(\n dialog: HTMLDialogElement,\n source: DialogCloseSource,\n): void {\n const allowed = dialog.dispatchEvent(\n new CustomEvent<DialogRequestCloseDetail>('kui-request-close', {\n bubbles: true,\n cancelable: true,\n detail: { source },\n }),\n );\n if (allowed) closeDialog(dialog);\n else runMotion(dialog, 'pulse');\n}\n\nconst outside = (dialog: HTMLElement, event: MouseEvent): boolean => {\n const box = dialog.getBoundingClientRect();\n return (\n event.clientX < box.left ||\n event.clientX > box.right ||\n event.clientY < box.top ||\n event.clientY > box.bottom\n );\n};\n\n/**\n * Wire every DialogSurface in `doc`: the close button and any element with\n * `data-dialog-close`, Escape, and a press on the backdrop (closing with\n * `lightDismiss`, pulsing without) ask to close through `kui-request-close`;\n * a closed dialog stops being followed. `openDialog` installs this itself;\n * the `surface-scaffold/register` entry installs it for the document.\n * Idempotent per document.\n */\nexport function installDialogSurfaces(doc: Document = document): void {\n if (installed.has(doc)) return;\n installed.add(doc);\n // A backdrop press starts and ends outside the panel; a drag out of the\n // panel (a text selection) is not one.\n let pressedOutside: HTMLDialogElement | null = null;\n doc.addEventListener(\n 'pointerdown',\n (event) => {\n pressedOutside =\n isSurface(event.target) && outside(event.target, event)\n ? event.target\n : null;\n },\n true,\n );\n doc.addEventListener(\n 'click',\n (event) => {\n const target = event.target as Element;\n const dialog = target.closest?.<HTMLDialogElement>(SURFACE);\n if (!dialog?.open) return;\n if (target === dialog) {\n if (pressedOutside !== dialog || !outside(dialog, event)) return;\n if (dialog.hasAttribute('data-light-dismiss'))\n requestClose(dialog, 'backdrop');\n else runMotion(dialog, 'pulse');\n return;\n }\n const closer = target.closest('[data-dialog-close]');\n if (closer && closer.closest(SURFACE) === dialog) {\n event.preventDefault();\n requestClose(dialog, 'close-button');\n }\n },\n true,\n );\n // Escape fires `cancel`; the dialog closes through the same request.\n doc.addEventListener(\n 'cancel',\n (event) => {\n if (!isSurface(event.target)) return;\n event.preventDefault();\n requestClose(event.target, 'escape');\n },\n true,\n );\n // However it closed (including an engine closing it past a refused\n // Escape), stop following it.\n doc.addEventListener(\n 'close',\n (event) => {\n if (isSurface(event.target)) settle(event.target);\n },\n true,\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/collections/list-action-row/list-action-row.tsx"],"names":[],"mappings":"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","file":"chunk-JCCN3U6X.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport {\n type ListIconTile,\n listIconTilePresentation,\n} from '../../../shared/content/list-icon-tile.js';\nimport { nativeDraggable } from '../../../shared/dom/draggable.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from '../../../shared/dom/extension-attributes.js';\nimport { em, remify } from '../../../shared/styles/css-values.js';\nimport { withWordBreaks } from '../../../shared/text/word-breaks.js';\nimport {\n PopupMenu,\n type PopupMenuEntry,\n type PopupMenuPlacement,\n} from '../../actions/popup-menu/popup-menu.js';\nimport { LoadingSpinner } from '../../feedback/loading-spinner/loading-spinner.js';\nimport { Skeleton } from '../../feedback/skeleton/skeleton.js';\n\nexport type {\n ListIconTile,\n ListIconTileColor,\n ListIconTileTone,\n} from '../../../shared/content/list-icon-tile.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-icon-tile',\n 'data-icon-tile-tone',\n 'data-multiline',\n 'data-density',\n 'data-divider',\n 'data-busy',\n 'data-trailing-visibility',\n 'data-state',\n 'data-selected',\n 'data-pressed',\n 'data-dragging',\n 'data-drop-position',\n]);\nconst PROTECTED_TRAILING_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-kui-disabled',\n]);\n\ntype ListActionRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-icon-tile'?: never;\n 'data-icon-tile-tone'?: never;\n 'data-multiline'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-busy'?: never;\n 'data-trailing-visibility'?: never;\n 'data-state'?: never;\n 'data-selected'?: never;\n 'data-pressed'?: never;\n 'data-dragging'?: never;\n 'data-drop-position'?: never;\n }\n>;\n\ntype ListActionRowTrailingAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-kui-disabled'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\n/** A trailing overflow `PopupMenu` rendered as the row's sibling trailing control. */\nexport interface ListActionRowTrailingMenu {\n /** Accessible name of the icon-only menu trigger, such as `Actions for report.json`. */\n label: string;\n /** Decorative trigger icon, typically a `MoreHorizontal` `LucideIcon`. */\n icon: SafeHtml;\n /** The menu's commands, headings, and dividers; items dispatch their own `data-action`s. */\n items: readonly PopupMenuEntry[];\n /** Where the menu opens relative to its trigger. Defaults to `bottom-end`. */\n placement?: PopupMenuPlacement;\n disabled?: boolean;\n}\n\ninterface ListActionRowTrailingButtonProps {\n trailingAction: string;\n trailingActionLabel: string;\n /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */\n trailingActionIcon: SafeHtml;\n trailingActionDisabled?: boolean;\n trailingActionTitle?: string;\n trailingActionAttributes?: ListActionRowTrailingAttributes;\n trailingMenu?: never;\n}\n\ninterface ListActionRowTrailingMenuProps {\n /** A trailing overflow menu in place of the trailing button. Import `@kerfjs/ui/popup-menu/register` once. */\n trailingMenu: ListActionRowTrailingMenu;\n trailingAction?: never;\n trailingActionLabel?: never;\n trailingActionIcon?: never;\n trailingActionDisabled?: never;\n trailingActionTitle?: never;\n trailingActionAttributes?: never;\n}\n\ninterface ListActionRowCommonProps {\n /** Visible dormant content for the primary button. Must not contain interactive descendants. */\n label: string | SafeHtml;\n description?: string | SafeHtml;\n status?: string | SafeHtml;\n busy?: boolean;\n /** Row height: `standard` is 44px; `compact` is 36px (42px with `iconTile`), the height of a compact `ListItem`. */\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Decorative dormant content for the primary button. Must not contain interactive descendants. */\n icon?: SafeHtml;\n /** Present `icon` in a filled 32px rounded tile with an 18px glyph: a quiet tone preset, or `{ color, foreground? }` for an application color. */\n iconTile?: ListIconTile;\n action: string;\n itemId?: string;\n selected?: boolean;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render as an unanimated loading skeleton, disabling both actions: label, description, icon, and status text become skeletons; the `busy` indicator stays live. */\n placeholder?: boolean;\n /** Native HTML drag source (`draggable=\"true\"` on the row root); a placeholder is never draggable. Pair with `wireListReorder` for pointer and keyboard reordering. */\n draggable?: boolean;\n /** Dim this row as one of the rows being dragged. */\n dragging?: boolean;\n /** Draw the insertion line at this row's leading (`before`) or trailing (`after`) block edge. */\n dropPosition?: 'before' | 'after';\n trailingActionVisibility?: 'always' | 'interaction';\n className?: string;\n rootAttributes?: ListActionRowRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** Exactly one trailing control: a native button (`trailingAction*`) or an overflow menu (`trailingMenu`). */\nexport type ListActionRowProps = ListActionRowCommonProps &\n (ListActionRowTrailingButtonProps | ListActionRowTrailingMenuProps);\n\nexport function ListActionRow({\n label,\n description,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n icon,\n iconTile,\n action,\n itemId,\n selected = false,\n pressed,\n accessibleLabel,\n title,\n multiline = false,\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n draggable,\n dragging = false,\n dropPosition,\n trailingAction,\n trailingActionLabel,\n trailingActionIcon,\n trailingActionDisabled = false,\n trailingActionTitle,\n trailingActionVisibility = 'always',\n trailingMenu,\n className = '',\n rootAttributes = {},\n trailingActionAttributes = {},\n slot,\n}: ListActionRowProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTrailingAttributes = filterControlAttributes(\n trailingActionAttributes,\n PROTECTED_TRAILING_DATA_ATTRIBUTES,\n );\n const tile = icon\n ? listIconTilePresentation(iconTile, 'list-action-row')\n : null;\n const iconSize = tile?.tile ? 32 : 18;\n\n return (\n <div\n {...extensionRootAttributes}\n class={`kui-list-action-row ${className}`.trim()}\n data-component=\"list-action-row\"\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-icon-tile={tile?.tile}\n data-icon-tile-tone={tile?.tone}\n data-multiline={multiline ? 'true' : undefined}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-trailing-visibility={trailingActionVisibility}\n data-state={state}\n data-selected={String(selected)}\n data-pressed={pressed === undefined ? undefined : String(pressed)}\n data-placeholder={placeholder ? 'true' : undefined}\n draggable={nativeDraggable(draggable, placeholder)}\n data-dragging={dragging ? 'true' : undefined}\n data-drop-position={dropPosition}\n aria-busy={placeholder || busy ? 'true' : undefined}\n slot={slot}\n >\n <button\n type=\"button\"\n class=\"kui-list-action-row__primary\"\n title={placeholder ? undefined : title}\n disabled={disabled || placeholder}\n tabindex={placeholder ? -1 : tabIndex}\n data-kui-disabled={disabled ? 'true' : undefined}\n data-action={placeholder ? undefined : action}\n data-item-id={itemId}\n aria-label={accessibleLabel}\n aria-current={selected ? 'page' : undefined}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {icon && (\n <span\n class=\"kui-list-action-row__icon\"\n style={placeholder ? undefined : tile?.style}\n >\n {placeholder ? (\n <Skeleton\n block\n width={remify(iconSize)}\n height={remify(iconSize)}\n />\n ) : (\n icon\n )}\n </span>\n )}\n <span class=\"kui-list-action-row__label\">\n <span class=\"kui-list-action-row__primary-label\">\n {placeholder ? (\n <Skeleton width={em(9)} />\n ) : multiline ? (\n withWordBreaks(label)\n ) : (\n label\n )}\n </span>\n {description && (\n <span class=\"kui-list-action-row__description\">\n {placeholder ? <Skeleton width={em(11)} /> : description}\n </span>\n )}\n {(busy || status) && (\n <span class=\"kui-list-action-row__status\">\n {/* The busy spinner is component-owned chrome drawn from a\n known prop, so a placeholder keeps it live; only the status\n text is a value and becomes a skeleton. */}\n {busy && <LoadingSpinner />}\n {status && (placeholder ? <Skeleton width={em(6)} /> : status)}\n </span>\n )}\n </span>\n </button>\n {trailingMenu ? (\n <PopupMenu\n label={trailingMenu.label}\n icon={trailingMenu.icon}\n items={trailingMenu.items}\n placement={trailingMenu.placement ?? 'bottom-end'}\n caret={false}\n disabled={Boolean(trailingMenu.disabled) || placeholder}\n />\n ) : (\n <button\n {...extensionTrailingAttributes}\n type=\"button\"\n class=\"kui-list-action-row__trailing-action\"\n data-action={placeholder ? undefined : trailingAction}\n data-item-id={itemId}\n aria-label={trailingActionLabel}\n title={trailingActionTitle ?? trailingActionLabel}\n disabled={trailingActionDisabled || placeholder || undefined}\n data-kui-disabled={trailingActionDisabled ? 'true' : undefined}\n >\n {trailingActionIcon}\n </button>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/surfaces/backdrop-image/backdrop-image.tsx"],"names":["className"],"mappings":"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","file":"chunk-SOBRGH7T.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport {\n filterRootAttributes,\n type StructuralRootAttributes,\n} from '../../../shared/dom/extension-attributes.js';\nimport {\n type CssColor,\n type CssLength,\n remify,\n} from '../../../shared/styles/css-values.js';\n\n/** How a single image fills the backdrop (`object-fit`). */\nexport type BackdropImageFit = 'cover' | 'contain' | 'fill';\n\n/** Which part of the image stays in view when it is cropped. */\nexport type BackdropImagePosition =\n | 'center'\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top left'\n | 'top right'\n | 'bottom left'\n | 'bottom right';\n\n/** Tile the image as a background instead of fitting one copy. */\nexport type BackdropImageRepeat = 'repeat' | 'repeat-x' | 'repeat-y';\n\n/**\n * How far the image lags the scroll: `none` scrolls with the content,\n * `subtle` lags by 35%, and a number from 0 to 1 is the lag factor (0.5\n * moves the image at half the scroll speed).\n */\nexport type BackdropImageParallax = 'none' | 'subtle' | number;\n\n/**\n * A dimming layer under `overlay` content: `bottom` darkens toward the\n * block end where a title sits, `full` dims the whole image evenly.\n */\nexport type BackdropImageScrim = 'none' | 'bottom' | 'full';\n\n/**\n * A scroll-linked progressive blur: a statically blurred copy of the image\n * fades in as the image block scrolls away. Only the copy's opacity (and the\n * optional dim layer's) animates; the blur itself is set once.\n */\nexport interface BackdropImageBlur {\n /**\n * CSS blur radius applied once to the copy. Default 24px; with\n * `blurredSrc` the default is no filter, since that asset is already soft.\n */\n radius?: CssLength;\n /**\n * An app-supplied pre-blurred or low-resolution copy of the image, used\n * instead of filtering `src`.\n */\n blurredSrc?: string;\n /**\n * Peak opacity, from 0 to 1, of a black dim layer that ramps in with the\n * blur. Default 0 (no dim layer).\n */\n dim?: number;\n}\n\nconst backdropImageProtected = new Set([\n 'data-component',\n 'data-blur',\n 'data-parallax',\n 'data-scrim',\n 'data-fade',\n 'data-repeat',\n 'data-under-chrome',\n 'data-aspect-ratio',\n 'data-inline-bleed',\n]);\n\ntype BackdropImageRootAttributes = StructuralRootAttributes &\n Readonly<{\n 'data-component'?: never;\n 'data-blur'?: never;\n 'data-parallax'?: never;\n 'data-scrim'?: never;\n 'data-fade'?: never;\n 'data-repeat'?: never;\n 'data-under-chrome'?: never;\n 'data-aspect-ratio'?: never;\n 'data-inline-bleed'?: never;\n }>;\n\ninterface BackdropImageCommonProps {\n /** Image URL. */\n src: string;\n /**\n * Accessible description of the image. Pass `''` for a decorative image\n * that only sets a mood; assistive technology then skips it.\n */\n alt: string;\n /** Which part of a cropped image stays in view. Default `center`. */\n position?: BackdropImagePosition;\n /** Height of the image block. Default 320px (`remify(320)`). */\n height?: CssLength;\n /** Reserve image height from its width, useful for an inline card. Cannot be combined with `height`. */\n aspectRatio?: number;\n /** Native image loading behavior. Omit for the browser default. */\n loading?: 'eager' | 'lazy';\n /** Bleed to a Pane's inline content edges. Set false when embedded in a card. Defaults to true. */\n bleedInline?: boolean;\n /** How far the image lags the scroll. Default `none`. */\n parallax?: BackdropImageParallax;\n /**\n * The color the image fades into at its block end. It also paints the\n * whole surface, so `children` below the image sit on the same color and\n * the page reads as one surface. Omit for a hard edge with no surface.\n */\n fadeTo?: CssColor;\n /**\n * Blur the image progressively as it scrolls away, by cross-fading a\n * statically blurred copy. Static (unblurred) wherever parallax is.\n */\n blur?: BackdropImageBlur;\n /**\n * Run the image up beneath the scroller's block-start inset: an overlay or\n * clear Pane header, NavStack chrome handed to a view's Pane, and the top\n * safe area, the way a media page's artwork fills the screen behind\n * transparent chrome. The visible image keeps `height` below that inset,\n * and `overlay` content stays clear of the chrome. Place the image first in\n * the Pane's content; it reads the Pane's\n * `--kui-pane-content-inset-block-start`. Default `false`.\n */\n underChrome?: boolean;\n /** Dim the image under `overlay` content. Default `none`. */\n scrim?: BackdropImageScrim;\n /** Content laid over the image's block end, such as a title and actions. */\n overlay?: KerfUiContent;\n /** Content that continues below the image on the `fadeTo` surface. */\n children?: KerfUiContent;\n id?: string;\n className?: string;\n /** Safe `data-*`, `aria-*`, and structural `role` metadata on the root. */\n rootAttributes?: BackdropImageRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** One fitted image, with optional responsive candidates. */\nexport interface BackdropImageSingleProps extends BackdropImageCommonProps {\n repeat?: undefined;\n /** Responsive image candidates (`srcset`). */\n srcset?: string;\n /** Rendered-size hints for `srcset` (`sizes`). */\n sizes?: string;\n /** How the image fills the block. Default `cover`. */\n fit?: BackdropImageFit;\n}\n\n/** A tiled background image at its natural size. */\nexport interface BackdropImageTiledProps extends BackdropImageCommonProps {\n repeat: BackdropImageRepeat;\n srcset?: never;\n sizes?: never;\n fit?: never;\n}\n\nexport type BackdropImageProps =\n BackdropImageSingleProps | BackdropImageTiledProps;\n\nconst SUBTLE_PARALLAX = 0.35;\n\nfunction parallaxFactor(parallax: BackdropImageParallax): number {\n if (parallax === 'none') return 0;\n if (parallax === 'subtle') return SUBTLE_PARALLAX;\n if (!Number.isFinite(parallax) || parallax < 0 || parallax > 1)\n throw new RangeError(\n 'BackdropImage parallax must be none, subtle, or a number from 0 to 1.',\n );\n return parallax;\n}\n\nfunction blurDim(dim: number | undefined): number {\n if (dim === undefined) return 0;\n if (!Number.isFinite(dim) || dim < 0 || dim > 1)\n throw new RangeError('BackdropImage blur.dim must be from 0 to 1.');\n return dim;\n}\n\nconst unsafeStyleValue = /[;{}<>\"'\\\\]|\\p{Cc}/u;\n\nfunction styleValue(value: string, prop: string): string {\n const trimmed = value.trim();\n if (!trimmed || unsafeStyleValue.test(trimmed))\n throw new TypeError(`BackdropImage ${prop} requires one CSS value.`);\n return trimmed;\n}\n\n/** A CSS `url(\"…\")` for the tiled form; quotes and backslashes are escaped. */\nfunction cssUrl(src: string): string {\n if (/\\p{Cc}/u.test(src))\n throw new TypeError(\n 'BackdropImage src must not contain control characters.',\n );\n return `url(\"${src.replace(/[\"\\\\]/g, (char) => `\\\\${char}`)}\")`;\n}\n\n/**\n * An image backdrop at the top of a scrolling Pane or NavStack view: the\n * image can lag the scroll (parallax on a scroll-driven, compositor-only\n * transform), fade through a mask into `fadeTo`, and that color keeps\n * painting under `children` so the page reads as one surface. Kerf owns the\n * static fallbacks: no parallax without scroll-driven animation support,\n * under reduced motion, under `data-kui-effects=\"static\"`, or on a\n * slow-update display, and a hard edge onto solid `fadeTo` under reduced\n * transparency.\n */\nexport function BackdropImage(props: BackdropImageProps) {\n const {\n src,\n alt,\n position = 'center',\n height,\n aspectRatio,\n loading,\n bleedInline = true,\n parallax = 'none',\n blur,\n fadeTo,\n scrim = 'none',\n underChrome = false,\n overlay,\n children,\n id,\n className = '',\n rootAttributes = {},\n slot,\n } = props;\n const factor = parallaxFactor(parallax);\n if (\n aspectRatio !== undefined &&\n (!Number.isFinite(aspectRatio) || aspectRatio <= 0)\n )\n throw new RangeError('BackdropImage aspectRatio must be positive.');\n if (aspectRatio !== undefined && height !== undefined)\n throw new TypeError(\n 'BackdropImage height and aspectRatio cannot be combined.',\n );\n const dim = blurDim(blur?.dim);\n const blurRadius =\n blur === undefined\n ? undefined\n : (blur.radius ??\n (blur.blurredSrc === undefined ? remify(24) : undefined));\n const style = [\n height === undefined\n ? ''\n : `--_kui-backdrop-image-height:${styleValue(height, 'height')}`,\n aspectRatio === undefined\n ? ''\n : `--_kui-backdrop-image-ratio:${String(aspectRatio)}`,\n fadeTo === undefined\n ? ''\n : `--_kui-backdrop-image-fade-to:${styleValue(fadeTo, 'fadeTo')}`,\n factor === 0 ? '' : `--_kui-backdrop-image-parallax:${String(factor)}`,\n position === 'center' ? '' : `--_kui-backdrop-image-position:${position}`,\n props.fit === undefined || props.fit === 'cover'\n ? ''\n : `--_kui-backdrop-image-fit:${props.fit}`,\n blurRadius === undefined\n ? ''\n : `--_kui-backdrop-image-blur:${styleValue(blurRadius, 'blur.radius')}`,\n dim === 0 ? '' : `--_kui-backdrop-image-dim:${String(dim)}`,\n ]\n .filter(Boolean)\n .join(';');\n const image = (className: string, source: string, copy: boolean) =>\n props.repeat === undefined ? (\n <img\n class={className}\n src={source}\n srcSet={source === src ? props.srcset : undefined}\n sizes={source === src ? props.sizes : undefined}\n alt={copy ? '' : alt}\n aria-hidden={copy ? 'true' : undefined}\n decoding=\"async\"\n loading={loading}\n />\n ) : (\n <div\n class={className}\n role={!copy && alt ? 'img' : undefined}\n aria-label={!copy && alt ? alt : undefined}\n aria-hidden={copy ? 'true' : undefined}\n style={`background-image:${cssUrl(source)};background-repeat:${props.repeat}`}\n />\n );\n const hasOverlay =\n overlay !== undefined && overlay !== null && overlay !== false;\n const hasChildren =\n children !== undefined && children !== null && children !== false;\n return (\n <div\n {...filterRootAttributes(rootAttributes, backdropImageProtected)}\n id={id}\n class={`kui-backdrop-image ${className}`.trim()}\n data-component=\"backdrop-image\"\n data-parallax={factor === 0 ? 'none' : 'scroll'}\n data-blur={\n blur === undefined\n ? undefined\n : blurRadius === undefined\n ? 'asset'\n : 'filter'\n }\n data-fade={fadeTo === undefined ? undefined : 'true'}\n data-scrim={scrim === 'none' ? undefined : scrim}\n data-repeat={props.repeat}\n data-under-chrome={underChrome ? 'true' : undefined}\n data-aspect-ratio={aspectRatio === undefined ? undefined : 'true'}\n data-inline-bleed={bleedInline ? undefined : 'false'}\n style={style || undefined}\n slot={slot}\n >\n <div class=\"kui-backdrop-image__hero\">\n <div class=\"kui-backdrop-image__backdrop\">\n <div class=\"kui-backdrop-image__layers\">\n {image('kui-backdrop-image__media', src, false)}\n {blur === undefined\n ? null\n : image(\n 'kui-backdrop-image__blurred',\n blur.blurredSrc ?? src,\n true,\n )}\n </div>\n {dim === 0 ? null : <div class=\"kui-backdrop-image__dim\" />}\n {scrim === 'none' ? null : <div class=\"kui-backdrop-image__scrim\" />}\n </div>\n {hasOverlay ? (\n <div class=\"kui-backdrop-image__overlay\">{overlay}</div>\n ) : null}\n </div>\n {hasChildren ? (\n <div class=\"kui-backdrop-image__content\">{children}</div>\n ) : null}\n </div>\n );\n}\n"]}
|