@aceshooting/lyra-ui 12.0.0 → 12.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/custom-elements.json +1 -1
- package/dist/autoloader.js +1 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +0 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
- package/dist/components/charts/chart/histogram-bin.d.ts +0 -1
- package/dist/components/charts/chart/histogram-bin.js +1 -1
- package/dist/components/charts/chart/lite-chart.class.d.ts +22 -9
- package/dist/components/charts/chart/lite-chart.class.js +6 -6
- package/dist/components/conversation/code-block/code-block-shared.d.ts +4 -54
- package/dist/components/conversation/code-block/code-block-shared.js +1 -1
- package/dist/components/conversation/code-block/shiki-types.d.ts +2 -1
- package/dist/components/conversation/generation-metrics/generation-metrics.class.js +1 -1
- package/dist/components/conversation/model-select/model-select.class.d.ts +0 -3
- package/dist/components/conversation/model-select/model-select.class.js +1 -1
- package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
- package/dist/components/conversation/voice-picker/voice-picker.class.d.ts +0 -1
- package/dist/components/conversation/voice-picker/voice-picker.class.js +1 -1
- package/dist/components/data/data-grid/data-grid.class.js +1 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +0 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
- package/dist/components/data/heatmap/heatmap.class.d.ts +4 -1
- package/dist/components/data/heatmap/heatmap.class.js +2 -2
- package/dist/components/data/table/table.class.d.ts +18 -4
- package/dist/components/data/table/table.class.js +2 -2
- package/dist/components/data/table/table.styles.js +2 -1
- package/dist/components/data/timeline/timeline-cluster.d.ts +1 -0
- package/dist/components/data/timeline/timeline-cluster.js +1 -0
- package/dist/components/data/timeline/timeline-item.class.d.ts +17 -2
- package/dist/components/data/timeline/timeline-item.class.js +13 -2
- package/dist/components/data/timeline/timeline-item.styles.js +65 -0
- package/dist/components/data/timeline/timeline.class.d.ts +83 -27
- package/dist/components/data/timeline/timeline.class.js +3 -3
- package/dist/components/data/timeline/timeline.d.ts +1 -0
- package/dist/components/data/timeline/timeline.js +1 -1
- package/dist/components/data/timeline/timeline.styles.js +14 -0
- package/dist/components/forms/button/button.class.js +1 -1
- package/dist/components/forms/checkbox/checkbox.class.d.ts +0 -1
- package/dist/components/forms/checkbox/checkbox.class.js +1 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +0 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
- package/dist/components/forms/code-editor/code-editor.class.js +1 -1
- package/dist/components/forms/color-picker/color-picker.class.js +1 -1
- package/dist/components/forms/combobox/combobox.class.d.ts +7 -1
- package/dist/components/forms/combobox/combobox.class.js +3 -2
- package/dist/components/forms/combobox/combobox.styles.js +1 -1
- package/dist/components/forms/date-picker/date-input.class.js +1 -1
- package/dist/components/forms/emoji-picker/emoji-data-loader.d.ts +0 -1
- package/dist/components/forms/input/native-time-input.class.js +1 -1
- package/dist/components/forms/input/time-input-shared.d.ts +2 -1
- package/dist/components/forms/input/time-input.class.js +1 -1
- package/dist/components/forms/locale-picker/locale-picker.class.d.ts +0 -1
- package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
- package/dist/components/forms/radio/radio-button.styles.d.ts +0 -1
- package/dist/components/forms/radio/radio-button.styles.js +1 -1
- package/dist/components/forms/radio/radio-group.class.d.ts +0 -1
- package/dist/components/forms/radio/radio-group.class.js +1 -1
- package/dist/components/forms/radio/radio.class.d.ts +0 -1
- package/dist/components/forms/radio/radio.class.js +1 -1
- package/dist/components/forms/rubric-form/rubric-form.class.d.ts +0 -1
- package/dist/components/forms/rubric-form/rubric-form.class.js +1 -1
- package/dist/components/forms/select/select.class.d.ts +0 -1
- package/dist/components/forms/select/select.class.js +1 -1
- package/dist/components/forms/slider/slider.class.d.ts +0 -1
- package/dist/components/forms/slider/slider.class.js +1 -1
- package/dist/components/forms/switch/switch.class.d.ts +0 -1
- package/dist/components/forms/switch/switch.class.js +1 -1
- package/dist/components/forms/time-range/time-range.class.d.ts +0 -1
- package/dist/components/forms/time-range/time-range.class.js +1 -1
- package/dist/components/forms/token-input/token-input.class.d.ts +0 -1
- package/dist/components/forms/token-input/token-input.class.js +1 -1
- package/dist/components/layout/dashboard-grid/layout-internal.d.ts +0 -1
- package/dist/components/layout/dashboard-grid/layout-internal.js +1 -1
- package/dist/components/layout/details/accordion-owner.d.ts +1 -1
- package/dist/components/layout/filter-bar/filter-bar.class.js +1 -1
- package/dist/components/layout/menu/menu-item.class.js +1 -1
- package/dist/components/layout/virtual-list/virtual-list.class.js +1 -1
- package/dist/components/media/av-player/av-metadata.d.ts +0 -2
- package/dist/components/media/av-player/av-metadata.js +1 -1
- package/dist/components/media/file-input/file-input.class.d.ts +0 -1
- package/dist/components/media/file-input/file-input.class.js +1 -1
- package/dist/components/media/map/map-loader.d.ts +4 -1
- package/dist/components/media/map/map.class.d.ts +50 -12
- package/dist/components/media/map/map.class.js +2 -2
- package/dist/components/overlays/overlay/popover.class.d.ts +7 -1
- package/dist/components/overlays/overlay/popover.class.js +1 -1
- package/dist/components/overlays/overlay/tooltip.class.d.ts +1 -0
- package/dist/components/overlays/overlay/tooltip.class.js +1 -1
- package/dist/components/overlays/progress/progress-shared.d.ts +0 -2
- package/dist/components/overlays/progress/progress-shared.js +1 -1
- package/dist/components/overlays/rating/rating.class.js +1 -1
- package/dist/components/retrieval/graph/graph-canvas.d.ts +10 -9
- package/dist/components/retrieval/mind-map/mind-map-layout.d.ts +0 -4
- package/dist/components/retrieval/mind-map/mind-map-layout.js +1 -1
- package/dist/components/utility/format/format-options.d.ts +0 -2
- package/dist/components/utility/format/format-options.js +1 -1
- package/dist/components/utility/icon/icon-resource.d.ts +0 -2
- package/dist/components/utility/icon/icon-resource.js +1 -1
- package/dist/components/viewers/archive-viewer/zip-resource-guard.d.ts +2 -1
- package/dist/components/viewers/docx-viewer/docx-resource-guard.d.ts +0 -3
- package/dist/components/viewers/docx-viewer/docx-resource-guard.js +1 -1
- package/dist/components/viewers/ebook-viewer/ebook-loader.d.ts +2 -1
- package/dist/components/viewers/ebook-viewer/epub-resource-guard.d.ts +0 -3
- package/dist/components/viewers/ebook-viewer/epub-resource-guard.js +1 -1
- package/dist/components/viewers/pdf-viewer/pdf-loader.d.ts +2 -2
- package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
- package/dist/components/viewers/pptx-viewer/pptx-resource-guard.d.ts +0 -2
- package/dist/components/viewers/pptx-viewer/pptx-resource-guard.js +1 -1
- package/dist/components/viewers/spreadsheet-viewer/xlsx-resource-guard.d.ts +0 -5
- package/dist/components/viewers/spreadsheet-viewer/xlsx-resource-guard.js +1 -1
- package/dist/custom-elements-jsx.d.ts +4 -4
- package/dist/events.d.ts +15 -0
- package/dist/internal/accessibility-visibility.d.ts +1 -1
- package/dist/internal/anchor-target.d.ts +1 -3
- package/dist/internal/anchor-target.js +2 -2
- package/dist/internal/anchored-overlay-runtime.d.ts +7 -0
- package/dist/internal/anchored-overlay-runtime.js +1 -0
- package/dist/internal/announcement-text.d.ts +1 -1
- package/dist/internal/ansi.d.ts +0 -4
- package/dist/internal/ansi.js +1 -1
- package/dist/internal/aria-ownership.d.ts +2 -1
- package/dist/internal/default-strings.generated.d.ts +1 -0
- package/dist/internal/default-strings.generated.js +1 -1
- package/dist/internal/focus-navigation.d.ts +3 -2
- package/dist/internal/form-associated.d.ts +0 -1
- package/dist/internal/form-associated.js +1 -1
- package/dist/internal/form-control-labels.d.ts +0 -3
- package/dist/internal/form-control-labels.js +1 -1
- package/dist/internal/localization-runtime.js +1 -1
- package/dist/internal/localization-types.d.ts +1 -1
- package/dist/internal/localization.js +1 -1
- package/dist/internal/lyra-element.d.ts +0 -13
- package/dist/internal/lyra-element.js +1 -1
- package/dist/internal/nonmodal-overlay-manager.d.ts +9 -0
- package/dist/internal/nonmodal-overlay-manager.js +1 -0
- package/dist/internal/overlay-manager.d.ts +4 -20
- package/dist/internal/overlay-manager.js +1 -1
- package/dist/internal/overlay-stack.d.ts +66 -0
- package/dist/internal/overlay-stack.js +1 -0
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/internal/positioner.js +1 -1
- package/dist/internal/text-quote.d.ts +1 -1
- package/dist/lyra.d.ts +2 -3
- package/dist/svelte.d.ts +4 -4
- package/dist/translations/ar.js +1 -1
- package/dist/translations/de.js +1 -1
- package/dist/translations/es.js +1 -1
- package/dist/translations/fa.js +1 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/he.js +1 -1
- package/dist/translations/ja.js +1 -1
- package/dist/translations/pt-BR.js +1 -1
- package/dist/translations/ru.js +1 -1
- package/dist/translations/zh-CN.js +1 -1
- package/dist/utilities/localization.js +1 -1
- package/dist/vue.d.ts +4 -4
- package/llms/components/lr-combobox.md +42 -0
- package/llms/components/lr-date-input.md +1 -1
- package/llms/components/lr-date-picker.md +1 -1
- package/llms/components/lr-filter-bar.md +2 -2
- package/llms/components/lr-heatmap.md +4 -1
- package/llms/components/lr-lite-chart.md +20 -8
- package/llms/components/lr-map.md +52 -22
- package/llms/components/lr-option.md +42 -0
- package/llms/components/lr-popover.md +39 -0
- package/llms/components/lr-table.md +7 -3
- package/llms/components/lr-timeline-item.md +49 -24
- package/llms/components/lr-timeline.md +49 -24
- package/llms-full.txt +224 -60
- package/package.json +3 -4
- package/vscode-css-data.json +21 -0
- package/vscode-html-data.json +12 -6
- package/web-types.json +47 -16
|
@@ -18,12 +18,17 @@
|
|
|
18
18
|
A `maplibre-gl` wrapper with a declarative legend, a single choropleth GeoJSON fill layer, markers,
|
|
19
19
|
and additive `dataLayers` — plain GeoJSON, natively clustered points, or a heatmap density surface —
|
|
20
20
|
plus a peer-neutral `map` getter for common imperative operations. Its runtime value is the
|
|
21
|
-
underlying MapLibre map.
|
|
21
|
+
underlying MapLibre map. The component observes its own map-container allocation and calls the
|
|
22
|
+
peer's `resize()` when that allocation changes.
|
|
22
23
|
|
|
23
24
|
**Properties:**
|
|
24
25
|
|
|
25
26
|
- `center: [number, number] = [0, 0]`
|
|
26
27
|
- `zoom: number = 2`
|
|
28
|
+
- `renderWorldCopies?: boolean` (attribute: false) — forwarded to MapLibre when its map is
|
|
29
|
+
constructed. Leave it unset to preserve MapLibre's own current default; set `false` before
|
|
30
|
+
construction to stop repeating the world horizontally. This is a construction-time option, so a
|
|
31
|
+
later change takes effect after the component is disconnected and reconnected.
|
|
27
32
|
- `mapStyle?: LyraMapStyleSpecification | string` (attribute: false) — required before a map is
|
|
28
33
|
constructed. Object assignments are detached and recursively frozen; create and reassign a new
|
|
29
34
|
style to update it. `LyraMapStyleSpecification` is the peer-neutral structural subset accepted from
|
|
@@ -98,6 +103,10 @@ string; geojson: GeoJSON.FeatureCollection; field: string; stops: [number, strin
|
|
|
98
103
|
gotchas. Entries with non-finite coordinates or latitude outside `[-90, 90]` are skipped without
|
|
99
104
|
aborting valid siblings. `color` is used only when the browser accepts it as CSS `color`;
|
|
100
105
|
declaration breaks and `url()` paint servers fall back to MapLibre's default marker color.
|
|
106
|
+
Every retained marker is a named `role="button"` tab stop, including one without a popup. Click,
|
|
107
|
+
Enter, and Space emit `lr-map-marker-activate`; Space suppresses its page-scroll default while
|
|
108
|
+
preserving MapLibre's popup toggle. A popup-bearing marker additionally exposes
|
|
109
|
+
`aria-haspopup="dialog"`, `aria-controls`, and explicit `aria-expanded`.
|
|
101
110
|
- `dataLayers: LyraMapGeoJsonDataLayer[] = []` (attribute: false) —
|
|
102
111
|
`LyraMapGeoJsonDataLayer { sourceId: string; geojson: GeoJSON.Feature |
|
|
103
112
|
GeoJSON.FeatureCollection; tone?: 'accent' | 'success' | 'warning' |
|
|
@@ -122,11 +131,12 @@ heatmap?: LyraMapHeatmapOptions; cluster?: LyraMapClusterOptions }`. `sourceId`
|
|
|
122
131
|
from overwriting or removing a same-named source supplied by `mapStyle`. Independent of
|
|
123
132
|
`choropleth` — no `field`/`stops` color-interpolation, just the geometry rendered in a flat tone;
|
|
124
133
|
use `choropleth` instead when you need a data-driven color ramp. An entry whose `sourceId`
|
|
125
|
-
persists across a `dataLayers` reassignment gets its GeoJSON updated in place (`
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
persists across a `dataLayers` reassignment gets its GeoJSON updated in place (`updateData()`
|
|
135
|
+
when stable feature IDs make a safe diff possible, otherwise `setData()`), one that's dropped has
|
|
136
|
+
its private source/layers removed, and a genuinely new `sourceId` gets new resources — nothing
|
|
137
|
+
leaks on removal, style change, or disconnect.
|
|
128
138
|
|
|
129
|
-
`cluster` and `kind` (both new in
|
|
139
|
+
`cluster` and `kind` (both new in 12.1.0) opt one entry out of that three-layer geometry split.
|
|
130
140
|
**Both are strictly additive: an entry that sets neither renders exactly what it rendered before,
|
|
131
141
|
down to the layer ids and the point layer's filter.**
|
|
132
142
|
|
|
@@ -156,7 +166,9 @@ number][]; colorSteps?: [number, string][]; countFont?: string[] }` turns the en
|
|
|
156
166
|
renders the source as MapLibre's own first-class `heatmap` layer instead, which the geometry split
|
|
157
167
|
cannot express at all: thousands of overlapping circles read as one opaque blob rather than as
|
|
158
168
|
where the data is concentrated. `heatmap?: LyraMapHeatmapOptions { weightField?: string;
|
|
159
|
-
weightRange?: [number, number]; stops?: [number, string][]; radius?:
|
|
169
|
+
weightRange?: [number, number]; stops?: [number, string][]; radius?: LyraMapHeatmapZoomValue;
|
|
170
|
+
intensity?: LyraMapHeatmapZoomValue; opacity?: number }`, where `LyraMapHeatmapZoomValue` is a
|
|
171
|
+
scalar number or bounded `[zoom, value][]` stops,
|
|
160
172
|
configures it. `weightField` weights each point by a feature property, and `weightRange` maps that
|
|
161
173
|
property's own units onto the 0–1 weight MapLibre expects — without it the raw value is passed
|
|
162
174
|
through, which saturates the surface for any quantity above ~1; with neither, every point weighs 1.
|
|
@@ -170,10 +182,14 @@ weightRange?: [number, number]; stops?: [number, string][]; radius?: number; int
|
|
|
170
182
|
describes a flat colour rather than a gradient; that one — like an unset or wholly unusable
|
|
171
183
|
`stops` — falls back to the built-in ramp, which runs transparent → `--lr-color-brand` →
|
|
172
184
|
`--lr-color-success` → `--lr-color-warning` → `--lr-color-danger`, so a retheme moves the density
|
|
173
|
-
surface with everything else. `radius`
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
185
|
+
surface with everything else. Scalar `radius` (default 30) and `intensity` (default 1) preserve
|
|
186
|
+
their established behavior. Two or more usable `[zoom, value]` stops emit linear zoom
|
|
187
|
+
interpolation; stops are sorted, duplicate zooms removed, zoom clamped into `[0, 24]`, radius
|
|
188
|
+
into `[1, 200]`, and intensity into `[0, 100]`. One usable stop becomes a scalar and an unusable
|
|
189
|
+
array falls back to the existing default. `opacity` is clamped into `[0, 1]`; omission leaves the
|
|
190
|
+
peer's default untouched on construction, and dropping a previously-authored value restores 1.
|
|
191
|
+
`cluster` is ignored on a heatmap entry: a heatmap already aggregates density, and clustering its
|
|
192
|
+
input would feed it one point per cluster instead of the real distribution.
|
|
177
193
|
- `maxBounds: LyraMapBounds | null = null` (attribute: false) — box the map may not pan outside,
|
|
178
194
|
`[[west, south], [east, north]]`. Prefer it over calling `map.setMaxBounds()` through the `.map`
|
|
179
195
|
escape hatch: constraining the camera can wedge maplibre-gl at a sub-1 fractional zoom in a wide
|
|
@@ -185,14 +201,15 @@ weightRange?: [number, number]; stops?: [number, string][]; radius?: number; int
|
|
|
185
201
|
|
|
186
202
|
**Choropleth and `dataLayers` updates are diffed before they reach the peer.** `setData()`
|
|
187
203
|
unconditionally re-tiles and repaints an entire source, which is invisible on a static map and
|
|
188
|
-
expensive on an animated one. When
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
`setData()` with no change in behaviour. Peers
|
|
204
|
+
expensive on an animated one. When every feature has a unique `string`/`number` `id` and retained
|
|
205
|
+
features keep semantically unchanged geometry/bbox values, the component emits MapLibre's
|
|
206
|
+
incremental `updateData()` for property changes, additions, removals, and order changes. The exact
|
|
207
|
+
next order is preserved: an unchanged prefix stays in place and only the invalidated suffix is
|
|
208
|
+
removed and re-added. Lyra's immutable ownership boundary detaches GeoJSON assignments, so geometry
|
|
209
|
+
reference identity cannot survive between frames; a bounded, accessor-free comparison verifies the
|
|
210
|
+
JSON geometry graph instead. A missing/duplicate ID, changed geometry, exceeded bound, or uncertain
|
|
211
|
+
comparison falls back to `setData()` with no change in rendered behaviour. Peers without
|
|
212
|
+
`updateData()` always take the old path.
|
|
196
213
|
|
|
197
214
|
**Feature properties are tiled, and therefore bounded in numeric magnitude.** MapLibre GL tiles
|
|
198
215
|
every GeoJSON source through a worker into a protobuf vector tile, so a property carrying a huge
|
|
@@ -212,7 +229,8 @@ payload beside the map.
|
|
|
212
229
|
|
|
213
230
|
**Authoring types:** `LyraMapLegendEntry`, `LyraMapLegendPattern`, `LyraMapLegendProjection`, `LyraMapChoroplethLayer`,
|
|
214
231
|
`LyraMapGeoJsonDataLayer`, `LyraMapDataLayerKind`, `LyraMapClusterOptions`, `LyraMapHeatmapOptions`,
|
|
215
|
-
`
|
|
232
|
+
`LyraMapHeatmapZoomValue`, `LyraMapMarker`, `LyraMapMarkerActivationDetail`,
|
|
233
|
+
`LyraMapMarkerActivationSource`, `LyraMapStyleSpecification`, and `LyraMapInstance`.
|
|
216
234
|
The former `LegendEntry`, `ChoroplethLayer`, `GeoJsonDataLayer`, and `MapMarker` names are removed
|
|
217
235
|
in v9 rather than retained as aliases.
|
|
218
236
|
|
|
@@ -227,7 +245,10 @@ shared `maplibre-gl` import without constructing a map or allocating a WebGL con
|
|
|
227
245
|
`false` when the peer is unavailable, allowing an application to choose a fallback before connecting
|
|
228
246
|
an element.
|
|
229
247
|
|
|
230
|
-
**Events:** `lr-map-load` (fired once, after the underlying map's own `'load'`),
|
|
248
|
+
**Events:** `lr-map-load` (fired once, after the underlying map's own `'load'`),
|
|
249
|
+
`lr-map-marker-activate` (non-cancelable; frozen `LyraMapMarkerActivationDetail { id, lngLat,
|
|
250
|
+
marker, source }`; `id` is the trimmed explicit identity or `undefined`, `marker` is the accepted
|
|
251
|
+
declarative snapshot, and `source` is `'pointer' | 'keyboard'`), and `lr-map-click`
|
|
231
252
|
(frozen `detail: { readonly lngLat: readonly [lng, lat], readonly feature?, readonly origin?,
|
|
232
253
|
readonly sourceId? }`; the tuple and any hit GeoJSON feature are detached and recursively frozen).
|
|
233
254
|
`feature` resolves against the choropleth fill layer **and** every applied `dataLayers`
|
|
@@ -305,6 +326,10 @@ Vite with v6:
|
|
|
305
326
|
{ color: "#0969da", label: "High", pattern: "diagonal" },
|
|
306
327
|
];
|
|
307
328
|
m.markers = [{ lngLat: [2.29, 48.86], label: "Eiffel Tower" }];
|
|
329
|
+
m.renderWorldCopies = false;
|
|
330
|
+
m.addEventListener("lr-map-marker-activate", (e) =>
|
|
331
|
+
console.log(e.detail.id, e.detail.lngLat)
|
|
332
|
+
);
|
|
308
333
|
m.addEventListener("lr-map-click", (e) =>
|
|
309
334
|
console.log(e.detail.feature?.properties)
|
|
310
335
|
);
|
|
@@ -321,8 +346,9 @@ https://maplibre.org/maplibre-gl-js/docs/#esm.
|
|
|
321
346
|
created peer instance, renders only the localized initialization failure, and can retry after a
|
|
322
347
|
new style or reconnect without an unhandled promise rejection. Capability probes and error
|
|
323
348
|
constructors come from the current owner document, including after same-origin adoption.
|
|
324
|
-
-
|
|
325
|
-
|
|
349
|
+
- Every marker handles Enter and Space as button activation. Space suppresses the page-scroll
|
|
350
|
+
default whether or not a popup exists; when one does, MapLibre still receives its own popup
|
|
351
|
+
toggle and the component emits exactly one `lr-map-marker-activate` notification.
|
|
326
352
|
- clearing or swapping the choropleth no longer leaks the old layer: setting `choropleth =
|
|
327
353
|
undefined`, or changing `choropleth.sourceId` to a different value, now calls `removeLayer`/
|
|
328
354
|
`removeSource` on whatever was previously applied before adding the new one (or nothing, if
|
|
@@ -367,5 +393,9 @@ undefined`, or changing `choropleth.sourceId` to a different value, now calls `r
|
|
|
367
393
|
`lr-map-load` never fires until the element is actually scrolled into view. Deliberate: caps
|
|
368
394
|
concurrent WebGL contexts when many `<lr-map>`s sit in one dashboard/grid. Skipped entirely
|
|
369
395
|
(constructs immediately once the peer loads) when `IntersectionObserver` itself is unavailable.
|
|
396
|
+
- Once constructed, the owner realm's `ResizeObserver` watches the rendered map container and calls
|
|
397
|
+
the current peer's `resize()` on allocation changes. It is replaced on reconnect/adoption and
|
|
398
|
+
disconnected before peer teardown, so a stale delivery cannot resize a removed map. Browsers
|
|
399
|
+
without `ResizeObserver` retain MapLibre's own window-resize behavior.
|
|
370
400
|
|
|
371
401
|
---
|
|
@@ -20,6 +20,48 @@ Filterable single/multi-select combining a text input with a listbox. Mirrors th
|
|
|
20
20
|
`<wa-combobox>` API under the `lr-` prefix. **Form-associated** (hand-rolled internals, not the
|
|
21
21
|
shared `FormAssociated` mixin — see gotchas).
|
|
22
22
|
|
|
23
|
+
**First-interaction registration.** Where initial-route weight is stricter than a static combobox
|
|
24
|
+
registration allows, keep a labelled native `<input list>` as the working pre-JavaScript control
|
|
25
|
+
and import only the granular combobox registration on its first focus. Copy the native value after
|
|
26
|
+
the import resolves so typing that happens while the chunk is in flight is not lost, then transfer
|
|
27
|
+
focus explicitly — the browser does not replay the focus event after custom-element upgrade:
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<div id="country-fallback">
|
|
31
|
+
<label for="country-native">Country</label>
|
|
32
|
+
<input id="country-native" name="country" list="country-options">
|
|
33
|
+
<datalist id="country-options"><option value="France"></option></datalist>
|
|
34
|
+
</div>
|
|
35
|
+
<lr-combobox id="country-enhanced" name="country" label="Country" hidden>
|
|
36
|
+
<lr-option value="France">France</lr-option>
|
|
37
|
+
</lr-combobox>
|
|
38
|
+
<script type="module">
|
|
39
|
+
const fallback = document.querySelector("#country-fallback");
|
|
40
|
+
const input = document.querySelector("#country-native");
|
|
41
|
+
const combobox = document.querySelector("#country-enhanced");
|
|
42
|
+
let registration;
|
|
43
|
+
input.addEventListener("focus", async () => {
|
|
44
|
+
if (!combobox.hidden) return;
|
|
45
|
+
registration ??= import(
|
|
46
|
+
"@aceshooting/lyra-ui/components/forms/combobox/combobox.js"
|
|
47
|
+
).catch((error) => {
|
|
48
|
+
registration = undefined; // let a later interaction retry
|
|
49
|
+
throw error;
|
|
50
|
+
});
|
|
51
|
+
await registration;
|
|
52
|
+
await customElements.whenDefined("lr-combobox");
|
|
53
|
+
combobox.value = input.value;
|
|
54
|
+
fallback.hidden = true;
|
|
55
|
+
combobox.hidden = false;
|
|
56
|
+
combobox.focus();
|
|
57
|
+
});
|
|
58
|
+
</script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Leave the native control in place if registration fails. This pattern preserves the initial shell;
|
|
62
|
+
the full form-label, option, overlay, and first-open positioning contracts arrive in deferred
|
|
63
|
+
chunks instead of being weakened in a separate partial combobox implementation.
|
|
64
|
+
|
|
23
65
|
An `lr-option` row remains bounded by its owning listbox: the default label ellipsizes and each
|
|
24
66
|
`start`/`end` (or `prefix`/`suffix`) adornment is capped at 40% of the row. Unbroken metadata
|
|
25
67
|
therefore cannot widen a 320px LTR or RTL picker.
|
|
@@ -17,6 +17,45 @@
|
|
|
17
17
|
|
|
18
18
|
A click-triggered, light-dismiss floating surface positioned with the shared Floating UI positioner.
|
|
19
19
|
|
|
20
|
+
**First-interaction registration.** A performance-sensitive navigation shell can keep a native
|
|
21
|
+
`<details>` disclosure working before JavaScript, then load only the granular popover registration
|
|
22
|
+
when that fallback first opens. The interaction that starts an async import is not replayed after
|
|
23
|
+
the custom element upgrades, so finish the handoff explicitly with `show()`:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<details id="account-fallback">
|
|
27
|
+
<summary>Account</summary>
|
|
28
|
+
<nav aria-label="Account"><a href="/profile">Profile</a></nav>
|
|
29
|
+
</details>
|
|
30
|
+
<lr-popover id="account-popover" popup-role="none" hidden>
|
|
31
|
+
<button slot="trigger">Account</button>
|
|
32
|
+
<nav aria-label="Account"><a href="/profile">Profile</a></nav>
|
|
33
|
+
</lr-popover>
|
|
34
|
+
<script type="module">
|
|
35
|
+
const fallback = document.querySelector("#account-fallback");
|
|
36
|
+
const popover = document.querySelector("#account-popover");
|
|
37
|
+
let registration;
|
|
38
|
+
fallback.addEventListener("toggle", async () => {
|
|
39
|
+
if (!fallback.open || !popover.hidden) return;
|
|
40
|
+
registration ??= import(
|
|
41
|
+
"@aceshooting/lyra-ui/components/overlays/overlay/popover.js"
|
|
42
|
+
).catch((error) => {
|
|
43
|
+
registration = undefined; // let a later interaction retry
|
|
44
|
+
throw error;
|
|
45
|
+
});
|
|
46
|
+
await registration;
|
|
47
|
+
await customElements.whenDefined("lr-popover");
|
|
48
|
+
fallback.hidden = true;
|
|
49
|
+
popover.hidden = false;
|
|
50
|
+
await popover.show();
|
|
51
|
+
});
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This keeps the fallback's markup and semantics in the initial document. The registration, Lyra
|
|
56
|
+
base, nonmodal stack, and first-open positioning runtime remain outside that initial module graph.
|
|
57
|
+
If the import fails, leave the native disclosure visible and usable.
|
|
58
|
+
|
|
20
59
|
**Properties:**
|
|
21
60
|
|
|
22
61
|
- `open: boolean = false` (reflected) — assigning it runs the same `lr-show`/`lr-hide` lifecycle as
|
|
@@ -331,7 +331,7 @@ no-rows states return the empty element as the shadow root's own root, with no `
|
|
|
331
331
|
wrapper around it — `::part(base)` does not apply in those two states, only in the filtered-to-zero
|
|
332
332
|
one — and that `empty` disappears entirely once the `empty` slot is filled.
|
|
333
333
|
|
|
334
|
-
- `scrollMode: 'self' | 'page' = 'self'` (attribute `scroll-mode`, reflected) — which element
|
|
334
|
+
- `scrollMode: 'self' | 'page' | 'auto' = 'self'` (attribute `scroll-mode`, reflected) — which element
|
|
335
335
|
scrolls when the table overflows. `'self'` makes `[part="base"]` the scroll container, which is
|
|
336
336
|
what pairs with `--lr-table-max-height` and makes the sticky header pin inside the table's own
|
|
337
337
|
viewport. `'page'` hands scrolling back to the document. Needed because a scroll container clips
|
|
@@ -339,8 +339,12 @@ one — and that `empty` disappears entirely once the `empty` slot is filled.
|
|
|
339
339
|
still `overflow: auto` becomes a sticky containing block that never scrolls, and its header
|
|
340
340
|
scrolls away with the page. With `'page'` the header's nearest scrollport is the page, so it pins
|
|
341
341
|
there; the cost is that a table wider than its host overflows the page instead of scrolling
|
|
342
|
-
inside itself.
|
|
343
|
-
|
|
342
|
+
inside itself. The opt-in `'auto'` mode resolves between those two behaviors from the rendered
|
|
343
|
+
allocation: while content fits it uses page flow, and only while content actually overflows
|
|
344
|
+
horizontally does `[part="base"]` become the contained scrollport. It re-evaluates when either
|
|
345
|
+
the allocated width or the rendered table's intrinsic width changes, so the same table can flow
|
|
346
|
+
with a desktop page and contain itself in a 320px panel. The default remains `'self'`. Named
|
|
347
|
+
`scrollMode` rather than `scroll` because a `scroll` property would shadow `Element.prototype.scroll()`
|
|
344
348
|
|
|
345
349
|
**Themeable custom properties:** `--lr-table-cell-color` (default `inherit`),
|
|
346
350
|
`--lr-table-cell-link-color` (default `var(--lr-color-brand)`) and
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
|
|
9
9
|
- **Deprecations** none
|
|
10
10
|
- **Optional peers** none
|
|
11
|
-
- **Themeable via**
|
|
11
|
+
- **Themeable via** 11 parts, 8 custom properties — see this component's own `@csspart`/`@cssprop` list below
|
|
12
12
|
- **Documented with** `lr-timeline` (same section below)
|
|
13
13
|
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
|
|
14
14
|
|
|
@@ -16,20 +16,21 @@
|
|
|
16
16
|
|
|
17
17
|
## `lr-timeline` and `lr-timeline-item`
|
|
18
18
|
|
|
19
|
-
Read-only chronological sequence. `lr-timeline` is a `role="list"` flex container; each
|
|
19
|
+
Read-only chronological sequence by default. `lr-timeline` is a `role="list"` flex container; each
|
|
20
20
|
`lr-timeline-item` is a light-DOM child that sets `role="listitem"` on itself and renders its own
|
|
21
21
|
marker plus the trailing rail segment reaching toward the next item's marker. The last item's rail is
|
|
22
22
|
suppressed purely in CSS (`::slotted([role='listitem']:last-child)`) — no JS coordination anywhere.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
Items have no keyboard navigation or selection model: a passive record display, by design (an
|
|
24
|
+
item's `title`/`description` routinely hold focusable content, so wrapping the row in `role="button"`
|
|
25
|
+
would trip `nested-interactive`). The opt-in clustered time scale adds only native count-marker
|
|
26
|
+
buttons; it does not make the individual rows interactive.
|
|
26
27
|
|
|
27
28
|
**`lr-timeline` properties:** `orientation: 'vertical' | 'horizontal' = 'vertical'` — note the
|
|
28
29
|
opposite default from `lr-stepper`; `horizontal` makes `[part='base']` a horizontally scrollable row.
|
|
29
30
|
`accessibleLabel: string = ''` (attribute `aria-label`) overrides the localized `"Timeline"` name
|
|
30
31
|
(the `role="list"` element is in the shadow root and never inherits a host attribute). Read-only
|
|
31
|
-
`itemCount: number` is the live count of
|
|
32
|
-
unrelated slotted elements and text nodes are ignored.
|
|
32
|
+
`itemCount: number` is the live count of default-slot `<lr-timeline-item>` assignments (including
|
|
33
|
+
flattened forwarding slots); unrelated slotted elements and text nodes are ignored.
|
|
33
34
|
`scale: 'flow' | 'time' = 'flow'` (attribute `scale`, type `LyraTimelineScale`) chooses how items
|
|
34
35
|
are distributed along the main axis. `'flow'` is the default even sequence, where `timestamp` is
|
|
35
36
|
rendered as text but carries no positional meaning. `'time'` positions each item at its true
|
|
@@ -37,23 +38,34 @@ proportion of the range, so a gap of weeks and a gap of decades stop looking ide
|
|
|
37
38
|
needs a definite extent to distribute along — `--lr-timeline-time-extent` (default
|
|
38
39
|
`var(--lr-size-20rem)`), applied as `block-size` when vertical and `inline-size` when horizontal —
|
|
39
40
|
because items are absolutely positioned and a percentage against an auto-sized track resolves to
|
|
40
|
-
zero. `collision: 'overlap' | 'stack' = 'overlap'` (attribute `collision`, type
|
|
41
|
-
chooses what `scale="time"` does with items landing on nearly the same
|
|
42
|
-
them stacked on one another, `'stack'` steps each colliding item one
|
|
43
|
-
(indent per lane: `--lr-timeline-collision-offset`, default
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
zero. `collision: 'overlap' | 'stack' | 'cluster' = 'overlap'` (attribute `collision`, type
|
|
42
|
+
`LyraTimelineCollision`) chooses what `scale="time"` does with items landing on nearly the same
|
|
43
|
+
position: `'overlap'` leaves them stacked on one another, `'stack'` steps each colliding item one
|
|
44
|
+
lane along the **cross** axis (indent per lane: `--lr-timeline-collision-offset`, default
|
|
45
|
+
`var(--lr-space-l)`), and `'cluster'` replaces every group of at least two colliding items with one
|
|
46
|
+
count marker. The group's first member in author order becomes its representative and renders the
|
|
47
|
+
button in that item's existing list/Tab position; the remaining members are hidden, so visual,
|
|
48
|
+
semantic, and keyboard order do not diverge merely because clustering is enabled. Stack mode and
|
|
49
|
+
the cluster floor treat items within 1.5% of the axis as colliding.
|
|
50
|
+
Cluster mode widens that floor to the rendered count action's footprint on the currently allocated
|
|
51
|
+
axis, then reclusters when the allocation or rendered action size changes, so interactive marker
|
|
52
|
+
hit areas do not overlap.
|
|
53
|
+
Cluster windows are bounded from their first sorted position rather than transitively chaining every
|
|
54
|
+
dense neighbour, so a large history becomes a useful sequence of markers rather than one axis-wide
|
|
55
|
+
cluster. An isolated item remains an ordinary timeline item. Activating a count marker is a
|
|
56
|
+
notification only; it never expands or selects items internally.
|
|
48
57
|
`rangeStart` / `rangeEnd` (`Date | string | number`, attribute: false) pin the axis instead of
|
|
49
58
|
deriving it from the earliest/latest item; a reversed or non-finite pair falls back to the derived
|
|
50
59
|
range. An item with no parseable `timestamp` (including one supplied only through the `timestamp`
|
|
51
60
|
slot, which carries no machine-readable instant) keeps document order and is spread evenly, so a
|
|
52
|
-
partially-timestamped list degrades rather than stacking at the origin.
|
|
53
|
-
|
|
54
|
-
selection belong to a denser component than this deliberately passive one. Positions are written to
|
|
61
|
+
partially-timestamped list degrades rather than stacking at the origin. Reassigning an item's
|
|
62
|
+
`timestamp` reclusters without requiring a slot mutation. Positions are written to
|
|
55
63
|
each child as a private `--_lr-timeline-item-offset` custom property and removed again on a switch
|
|
56
|
-
back to `'flow'
|
|
64
|
+
back to `'flow'`. Cluster mode adds and removes a private visibility marker on non-representative
|
|
65
|
+
members and temporarily changes only the representative item's shadow presentation; switching
|
|
66
|
+
mode, shrinking the data, or disconnecting restores every ordinary row. If regrouping would remove
|
|
67
|
+
the focused row content or count action, focus moves to the replacement cluster action, the first
|
|
68
|
+
surviving item action, or the timeline list as a programmatic fallback.
|
|
57
69
|
|
|
58
70
|
**`lr-timeline-item` properties:** `timestamp?: Date | string | number` (attribute: false — `Date`
|
|
59
71
|
isn't attribute-serializable; invalid input normalizes to unset and renders no timestamp UI),
|
|
@@ -63,8 +75,16 @@ isn't attribute-serializable; invalid input normalizes to unset and renders no t
|
|
|
63
75
|
optional pulse disabled under `prefers-reduced-motion: reduce`, with explicit `aria-current="true"`
|
|
64
76
|
or `"false"` on the host).
|
|
65
77
|
|
|
66
|
-
**Events:**
|
|
67
|
-
|
|
78
|
+
**Events:** `lr-timeline` emits `lr-cluster-activate` when a `collision="cluster"` marker is
|
|
79
|
+
activated by pointer, Enter, or Space. Its non-cancelable, bubbling, composed
|
|
80
|
+
`detail: LyraTimelineClusterActivateDetail` is `{ items: readonly LyraTimelineItem[] }`: a fresh
|
|
81
|
+
frozen snapshot of the cluster members in document order, preserving each element's identity.
|
|
82
|
+
`LyraTimelineClusterActivateDetail {
|
|
83
|
+
items: unknown;
|
|
84
|
+
}`
|
|
85
|
+
Use it to open a consumer-owned popover, dialog, or detail view. `lr-timeline-item` emits no events.
|
|
86
|
+
Read the reactive `itemCount` property after changing assigned items; the internal slot's
|
|
87
|
+
non-composed `slotchange` event is not a host-level public signal.
|
|
68
88
|
|
|
69
89
|
**Slots:** `lr-timeline`'s default slot holds the items, in display order. On an item the **default
|
|
70
90
|
slot is the title** (there is no `title` slot), plus `marker-icon` (marker glyph override; an empty
|
|
@@ -73,7 +93,9 @@ slot falls back to a color-coded dot), `timestamp` (wins outright over the
|
|
|
73
93
|
entirely when empty).
|
|
74
94
|
|
|
75
95
|
**CSS parts:** timeline `base` — the `role="list"` flex container (no separate `list` part). Item:
|
|
76
|
-
`
|
|
96
|
+
`cluster` — the native count button rendered while that item represents a cluster, with a 40px
|
|
97
|
+
minimum action surface; `cluster-count` — its painted count pill; `base`, `track`
|
|
98
|
+
(marker + rail spine, always the opposite axis from `base`), `marker`
|
|
77
99
|
(`aria-hidden="true"`, decorative), `rail` (the connecting segment; `visibility: hidden` rather than
|
|
78
100
|
removed on the last item, so marker alignment stays consistent), `content`, `header` (flex row
|
|
79
101
|
wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating), `title`,
|
|
@@ -81,8 +103,11 @@ wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating)
|
|
|
81
103
|
|
|
82
104
|
**Themeable custom properties:** `--lr-timeline-gap` (default `var(--lr-space-l)`) — declared on
|
|
83
105
|
`lr-timeline` but consumed inside each item via inheritance across the slot boundary; it is both the
|
|
84
|
-
inter-item spacing and the length each rail bridges. `--lr-
|
|
85
|
-
|
|
106
|
+
inter-item spacing and the length each rail bridges. `--lr-timeline-cluster-size` (default
|
|
107
|
+
`var(--lr-size-2rem)`) sizes the painted count pill, `--lr-timeline-cluster-bg` (default
|
|
108
|
+
`var(--lr-color-brand)`) sets its background, and `--lr-timeline-cluster-color` (default
|
|
109
|
+
`var(--lr-color-on-brand)`) sets its foreground. `--lr-scroll-fade-size` (default `2rem`) controls
|
|
110
|
+
each horizontal-overflow edge fade; forced-colors mode removes the masks while retaining native
|
|
86
111
|
scrolling. On the item: `--lr-timeline-marker-size`
|
|
87
112
|
(default `var(--lr-size-1-25rem)`, both dimensions so the dot stays circular),
|
|
88
113
|
`--lr-timeline-rail-width` (default `var(--lr-border-width-medium)`), `--lr-timeline-rail-color`
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
|
|
9
9
|
- **Deprecations** none
|
|
10
10
|
- **Optional peers** none
|
|
11
|
-
- **Themeable via** 1 part,
|
|
11
|
+
- **Themeable via** 1 part, 7 custom properties — see this component's own `@csspart`/`@cssprop` list below
|
|
12
12
|
- **Documented with** `lr-timeline-item` (same section below)
|
|
13
13
|
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
|
|
14
14
|
|
|
@@ -16,20 +16,21 @@
|
|
|
16
16
|
|
|
17
17
|
## `lr-timeline` and `lr-timeline-item`
|
|
18
18
|
|
|
19
|
-
Read-only chronological sequence. `lr-timeline` is a `role="list"` flex container; each
|
|
19
|
+
Read-only chronological sequence by default. `lr-timeline` is a `role="list"` flex container; each
|
|
20
20
|
`lr-timeline-item` is a light-DOM child that sets `role="listitem"` on itself and renders its own
|
|
21
21
|
marker plus the trailing rail segment reaching toward the next item's marker. The last item's rail is
|
|
22
22
|
suppressed purely in CSS (`::slotted([role='listitem']:last-child)`) — no JS coordination anywhere.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
Items have no keyboard navigation or selection model: a passive record display, by design (an
|
|
24
|
+
item's `title`/`description` routinely hold focusable content, so wrapping the row in `role="button"`
|
|
25
|
+
would trip `nested-interactive`). The opt-in clustered time scale adds only native count-marker
|
|
26
|
+
buttons; it does not make the individual rows interactive.
|
|
26
27
|
|
|
27
28
|
**`lr-timeline` properties:** `orientation: 'vertical' | 'horizontal' = 'vertical'` — note the
|
|
28
29
|
opposite default from `lr-stepper`; `horizontal` makes `[part='base']` a horizontally scrollable row.
|
|
29
30
|
`accessibleLabel: string = ''` (attribute `aria-label`) overrides the localized `"Timeline"` name
|
|
30
31
|
(the `role="list"` element is in the shadow root and never inherits a host attribute). Read-only
|
|
31
|
-
`itemCount: number` is the live count of
|
|
32
|
-
unrelated slotted elements and text nodes are ignored.
|
|
32
|
+
`itemCount: number` is the live count of default-slot `<lr-timeline-item>` assignments (including
|
|
33
|
+
flattened forwarding slots); unrelated slotted elements and text nodes are ignored.
|
|
33
34
|
`scale: 'flow' | 'time' = 'flow'` (attribute `scale`, type `LyraTimelineScale`) chooses how items
|
|
34
35
|
are distributed along the main axis. `'flow'` is the default even sequence, where `timestamp` is
|
|
35
36
|
rendered as text but carries no positional meaning. `'time'` positions each item at its true
|
|
@@ -37,23 +38,34 @@ proportion of the range, so a gap of weeks and a gap of decades stop looking ide
|
|
|
37
38
|
needs a definite extent to distribute along — `--lr-timeline-time-extent` (default
|
|
38
39
|
`var(--lr-size-20rem)`), applied as `block-size` when vertical and `inline-size` when horizontal —
|
|
39
40
|
because items are absolutely positioned and a percentage against an auto-sized track resolves to
|
|
40
|
-
zero. `collision: 'overlap' | 'stack' = 'overlap'` (attribute `collision`, type
|
|
41
|
-
chooses what `scale="time"` does with items landing on nearly the same
|
|
42
|
-
them stacked on one another, `'stack'` steps each colliding item one
|
|
43
|
-
(indent per lane: `--lr-timeline-collision-offset`, default
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
zero. `collision: 'overlap' | 'stack' | 'cluster' = 'overlap'` (attribute `collision`, type
|
|
42
|
+
`LyraTimelineCollision`) chooses what `scale="time"` does with items landing on nearly the same
|
|
43
|
+
position: `'overlap'` leaves them stacked on one another, `'stack'` steps each colliding item one
|
|
44
|
+
lane along the **cross** axis (indent per lane: `--lr-timeline-collision-offset`, default
|
|
45
|
+
`var(--lr-space-l)`), and `'cluster'` replaces every group of at least two colliding items with one
|
|
46
|
+
count marker. The group's first member in author order becomes its representative and renders the
|
|
47
|
+
button in that item's existing list/Tab position; the remaining members are hidden, so visual,
|
|
48
|
+
semantic, and keyboard order do not diverge merely because clustering is enabled. Stack mode and
|
|
49
|
+
the cluster floor treat items within 1.5% of the axis as colliding.
|
|
50
|
+
Cluster mode widens that floor to the rendered count action's footprint on the currently allocated
|
|
51
|
+
axis, then reclusters when the allocation or rendered action size changes, so interactive marker
|
|
52
|
+
hit areas do not overlap.
|
|
53
|
+
Cluster windows are bounded from their first sorted position rather than transitively chaining every
|
|
54
|
+
dense neighbour, so a large history becomes a useful sequence of markers rather than one axis-wide
|
|
55
|
+
cluster. An isolated item remains an ordinary timeline item. Activating a count marker is a
|
|
56
|
+
notification only; it never expands or selects items internally.
|
|
48
57
|
`rangeStart` / `rangeEnd` (`Date | string | number`, attribute: false) pin the axis instead of
|
|
49
58
|
deriving it from the earliest/latest item; a reversed or non-finite pair falls back to the derived
|
|
50
59
|
range. An item with no parseable `timestamp` (including one supplied only through the `timestamp`
|
|
51
60
|
slot, which carries no machine-readable instant) keeps document order and is spread evenly, so a
|
|
52
|
-
partially-timestamped list degrades rather than stacking at the origin.
|
|
53
|
-
|
|
54
|
-
selection belong to a denser component than this deliberately passive one. Positions are written to
|
|
61
|
+
partially-timestamped list degrades rather than stacking at the origin. Reassigning an item's
|
|
62
|
+
`timestamp` reclusters without requiring a slot mutation. Positions are written to
|
|
55
63
|
each child as a private `--_lr-timeline-item-offset` custom property and removed again on a switch
|
|
56
|
-
back to `'flow'
|
|
64
|
+
back to `'flow'`. Cluster mode adds and removes a private visibility marker on non-representative
|
|
65
|
+
members and temporarily changes only the representative item's shadow presentation; switching
|
|
66
|
+
mode, shrinking the data, or disconnecting restores every ordinary row. If regrouping would remove
|
|
67
|
+
the focused row content or count action, focus moves to the replacement cluster action, the first
|
|
68
|
+
surviving item action, or the timeline list as a programmatic fallback.
|
|
57
69
|
|
|
58
70
|
**`lr-timeline-item` properties:** `timestamp?: Date | string | number` (attribute: false — `Date`
|
|
59
71
|
isn't attribute-serializable; invalid input normalizes to unset and renders no timestamp UI),
|
|
@@ -63,8 +75,16 @@ isn't attribute-serializable; invalid input normalizes to unset and renders no t
|
|
|
63
75
|
optional pulse disabled under `prefers-reduced-motion: reduce`, with explicit `aria-current="true"`
|
|
64
76
|
or `"false"` on the host).
|
|
65
77
|
|
|
66
|
-
**Events:**
|
|
67
|
-
|
|
78
|
+
**Events:** `lr-timeline` emits `lr-cluster-activate` when a `collision="cluster"` marker is
|
|
79
|
+
activated by pointer, Enter, or Space. Its non-cancelable, bubbling, composed
|
|
80
|
+
`detail: LyraTimelineClusterActivateDetail` is `{ items: readonly LyraTimelineItem[] }`: a fresh
|
|
81
|
+
frozen snapshot of the cluster members in document order, preserving each element's identity.
|
|
82
|
+
`LyraTimelineClusterActivateDetail {
|
|
83
|
+
items: unknown;
|
|
84
|
+
}`
|
|
85
|
+
Use it to open a consumer-owned popover, dialog, or detail view. `lr-timeline-item` emits no events.
|
|
86
|
+
Read the reactive `itemCount` property after changing assigned items; the internal slot's
|
|
87
|
+
non-composed `slotchange` event is not a host-level public signal.
|
|
68
88
|
|
|
69
89
|
**Slots:** `lr-timeline`'s default slot holds the items, in display order. On an item the **default
|
|
70
90
|
slot is the title** (there is no `title` slot), plus `marker-icon` (marker glyph override; an empty
|
|
@@ -73,7 +93,9 @@ slot falls back to a color-coded dot), `timestamp` (wins outright over the
|
|
|
73
93
|
entirely when empty).
|
|
74
94
|
|
|
75
95
|
**CSS parts:** timeline `base` — the `role="list"` flex container (no separate `list` part). Item:
|
|
76
|
-
`
|
|
96
|
+
`cluster` — the native count button rendered while that item represents a cluster, with a 40px
|
|
97
|
+
minimum action surface; `cluster-count` — its painted count pill; `base`, `track`
|
|
98
|
+
(marker + rail spine, always the opposite axis from `base`), `marker`
|
|
77
99
|
(`aria-hidden="true"`, decorative), `rail` (the connecting segment; `visibility: hidden` rather than
|
|
78
100
|
removed on the last item, so marker alignment stays consistent), `content`, `header` (flex row
|
|
79
101
|
wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating), `title`,
|
|
@@ -81,8 +103,11 @@ wrapping `title` and `timestamp`; wraps at narrow widths rather than truncating)
|
|
|
81
103
|
|
|
82
104
|
**Themeable custom properties:** `--lr-timeline-gap` (default `var(--lr-space-l)`) — declared on
|
|
83
105
|
`lr-timeline` but consumed inside each item via inheritance across the slot boundary; it is both the
|
|
84
|
-
inter-item spacing and the length each rail bridges. `--lr-
|
|
85
|
-
|
|
106
|
+
inter-item spacing and the length each rail bridges. `--lr-timeline-cluster-size` (default
|
|
107
|
+
`var(--lr-size-2rem)`) sizes the painted count pill, `--lr-timeline-cluster-bg` (default
|
|
108
|
+
`var(--lr-color-brand)`) sets its background, and `--lr-timeline-cluster-color` (default
|
|
109
|
+
`var(--lr-color-on-brand)`) sets its foreground. `--lr-scroll-fade-size` (default `2rem`) controls
|
|
110
|
+
each horizontal-overflow edge fade; forced-colors mode removes the masks while retaining native
|
|
86
111
|
scrolling. On the item: `--lr-timeline-marker-size`
|
|
87
112
|
(default `var(--lr-size-1-25rem)`, both dimensions so the dot stays circular),
|
|
88
113
|
`--lr-timeline-rail-width` (default `var(--lr-border-width-medium)`), `--lr-timeline-rail-color`
|