@aceshooting/lyra-ui 10.0.1 → 11.0.0

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/custom-elements.json +1 -1
  3. package/design-tokens.json +13 -0
  4. package/dist/cli/migrate-wa.mjs +164 -1
  5. package/dist/cli/migration-contract.json +1 -1
  6. package/dist/components/charts/chart/box-plot.class.d.ts +27 -0
  7. package/dist/components/charts/chart/box-plot.class.js +14 -4
  8. package/dist/components/charts/chart/box-plot.styles.js +28 -0
  9. package/dist/components/charts/chart/chart.class.d.ts +27 -0
  10. package/dist/components/charts/chart/chart.class.js +15 -5
  11. package/dist/components/charts/chart/chart.styles.js +28 -0
  12. package/dist/components/data/heatmap/heatmap.class.d.ts +35 -2
  13. package/dist/components/data/heatmap/heatmap.class.js +2 -2
  14. package/dist/components/forms/combobox/combobox.class.d.ts +71 -3
  15. package/dist/components/forms/combobox/combobox.class.js +4 -2
  16. package/dist/components/forms/combobox/combobox.styles.js +9 -0
  17. package/dist/components/forms/date-picker/date-picker.class.d.ts +46 -0
  18. package/dist/components/forms/date-picker/date-picker.class.js +15 -3
  19. package/dist/components/forms/date-picker/date-picker.styles.js +46 -0
  20. package/dist/components/media/flag/flag.class.d.ts +3 -1
  21. package/dist/components/media/flag/flag.class.js +1 -1
  22. package/dist/components/media/map/map.class.d.ts +39 -2
  23. package/dist/components/media/map/map.class.js +1 -1
  24. package/dist/components/overlays/dialog/dialog.class.d.ts +20 -0
  25. package/dist/components/overlays/overlay/popover.class.d.ts +19 -3
  26. package/dist/components/overlays/overlay/popover.class.js +1 -1
  27. package/dist/custom-elements-jsx.d.ts +27 -14
  28. package/dist/internal/package-metadata.d.ts +1 -1
  29. package/dist/internal/package-metadata.js +1 -1
  30. package/dist/internal/tokens.styles.js +1 -0
  31. package/dist/lyra.d.ts +1 -1
  32. package/dist/svelte.d.ts +27 -14
  33. package/dist/vue.d.ts +27 -14
  34. package/llms/components/lr-bar-chart.md +4 -3
  35. package/llms/components/lr-box-plot.md +14 -3
  36. package/llms/components/lr-bubble-chart.md +4 -3
  37. package/llms/components/lr-chart.md +13 -3
  38. package/llms/components/lr-combobox.md +42 -6
  39. package/llms/components/lr-date-input.md +22 -2
  40. package/llms/components/lr-date-picker.md +23 -3
  41. package/llms/components/lr-dialog.md +2 -1
  42. package/llms/components/lr-doughnut-chart.md +4 -3
  43. package/llms/components/lr-flag.md +10 -3
  44. package/llms/components/lr-heatmap.md +20 -2
  45. package/llms/components/lr-histogram.md +4 -3
  46. package/llms/components/lr-line-chart.md +4 -3
  47. package/llms/components/lr-map.md +21 -4
  48. package/llms/components/lr-option.md +41 -5
  49. package/llms/components/lr-pie-chart.md +4 -3
  50. package/llms/components/lr-polar-area-chart.md +4 -3
  51. package/llms/components/lr-popover.md +20 -1
  52. package/llms/components/lr-radar-chart.md +4 -3
  53. package/llms/components/lr-scatter-chart.md +4 -3
  54. package/llms/tokens.md +15 -1
  55. package/llms-full.txt +197 -26
  56. package/package.json +1 -1
  57. package/vscode-css-data.json +56 -0
  58. package/vscode-html-data.json +115 -18
  59. package/web-types.json +162 -21
@@ -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** `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 15 parts, 33 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 16 parts, 35 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Documented with** `lr-line-chart`, `lr-pie-chart`, `lr-doughnut-chart`, `lr-radar-chart`, `lr-polar-area-chart`, `lr-bubble-chart`, `lr-scatter-chart` (same section below)
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
@@ -44,7 +44,7 @@ complete `hiddenDatasets` snapshot).
44
44
  **Slots:** default JSON configuration script, `data-table`, `center`.
45
45
 
46
46
  **CSS parts:** `base`, `plot`, `canvas`, `legend`, `legend-item`, `legend-item-hidden`, `legend-swatch`,
47
- `reset-zoom-button`, `description`, `notices`, `data-table`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
47
+ `reset-zoom-button`, `description`, `notices`, `data-table`, `data-table-toggle`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
48
48
  rendered in place of `canvas` when the optional `chart.js` peer dependency fails to load; the
49
49
  failure transition is announced through the shared document-level light-DOM assertive sink — see
50
50
  `llms/components/lr-chart.md`).
@@ -53,7 +53,8 @@ failure transition is announced through the shared document-level light-DOM asse
53
53
  `--lr-chart-tick-color`, `--lr-chart-legend-color`, `--lr-chart-tooltip-bg`,
54
54
  `--lr-chart-tooltip-text`, `--lr-chart-legend-item-hover-bg`,
55
55
  `--lr-chart-legend-item-active-bg`, `--lr-chart-data-table-button-hover-bg`,
56
- `--lr-chart-data-table-button-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
56
+ `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
57
+ `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
57
58
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
58
59
  `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — all inherited from `LyraChart`, identical in meaning and default (see
59
60
  `lr-chart` above); each of the eight variants below reads the same set, so one rule retunes them
@@ -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** `@sgratzl/chartjs-chart-boxplot`, `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 11 parts, 11 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 12 parts, 13 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
13
13
 
14
14
  ---
@@ -46,6 +46,14 @@ browser). Does **not** extend `LyraChart` — a deliberately bespoke API.
46
46
  - `formatter?: LyraChartFormatter`, `valueFormatter?: LyraChartValueFormatter` — numeric axis,
47
47
  tooltip, table, summary, and export formatting; the context-object formatter takes precedence
48
48
  - `showDataTable: boolean = false` (attribute `show-data-table`) — reveals the accessible data table
49
+ - `dataTableToggle: boolean = false` (attribute `data-table-toggle`, new in 10.1.0) — renders a
50
+ localized disclosure button (`part="data-table-toggle"`) above the data table so a *sighted*
51
+ reader can reveal the numbers on demand. `showDataTable` alone is all-or-nothing, which left
52
+ consumers wrapping a duplicated table in their own `<details>`. With the toggle on,
53
+ `showDataTable` becomes the disclosure's **initial** state rather than its whole behavior; the
54
+ table stays in the DOM in both states, so assistive technology never loses it, and the button
55
+ carries `aria-expanded` plus `aria-controls` pointing at the `data-table` wrapper. Unset, nothing
56
+ renders and behavior is identical to before.
49
57
 
50
58
  **Methods:** `exportData('csv'|'png')` returns spreadsheet-safe summary rows or the current canvas
51
59
  PNG data URL. `refreshTheme()` re-reads canvas theme custom properties after an ancestor theme
@@ -84,7 +92,7 @@ detailed sample and notice, making it the escape hatch for complete data.
84
92
 
85
93
  **CSS parts:** `base`, `plot` (the fixed-height canvas region), `canvas`, `legend`,
86
94
  `legend-item`, `legend-item-hidden` (added to a legend item while its box series is hidden),
87
- `legend-swatch`, `description`, `data-table`, `error` (neutral visible message shown
95
+ `legend-swatch`, `description`, `data-table`, `data-table-toggle` (the `dataTableToggle` disclosure button), `error` (neutral visible message shown
88
96
  instead of `canvas` when the optional box-plot peer fails to load; the failure transition is
89
97
  announced through the shared document-level light-DOM assertive sink), `data-truncation` (the
90
98
  bounded-alternative sampling notice)
@@ -101,7 +109,10 @@ so `--lr-theme-color-chart-*` retheming reaches box plots too. `--lr-chart-patte
101
109
  `--lr-chart-canvas-hover-outline-width` (default `var(--lr-border-width-thin)`) sizes the `canvas`
102
110
  hover outline, `--lr-chart-legend-item-active-bg` and `--lr-chart-legend-item-hover-bg` retune the
103
111
  pressed and hovered legend rows, and `--lr-chart-legend-side-max` caps a side legend — the same tokens and defaults as
104
- `lr-chart`.
112
+ `lr-chart`. Its own `dataTableToggle` disclosure button carries box-plot-namespaced hooks rather
113
+ than inheriting the chart pair, since its stylesheet is not a re-export:
114
+ `--lr-box-plot-data-table-toggle-hover-bg` (defaults to `--lr-color-brand-quiet`) and
115
+ `--lr-box-plot-data-table-toggle-active-bg` (defaults to its standard active color mix).
105
116
 
106
117
  **Forced colors:** under `forced-colors: active` the eight-color ramp is remapped onto the small
107
118
  repeating system-color cycle the platform exposes, so series 1/4/7 (and 2/5/8, 3/6) would otherwise
@@ -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** `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 15 parts, 33 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 16 parts, 35 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Documented with** `lr-line-chart`, `lr-bar-chart`, `lr-pie-chart`, `lr-doughnut-chart`, `lr-radar-chart`, `lr-polar-area-chart`, `lr-scatter-chart` (same section below)
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
@@ -44,7 +44,7 @@ complete `hiddenDatasets` snapshot).
44
44
  **Slots:** default JSON configuration script, `data-table`, `center`.
45
45
 
46
46
  **CSS parts:** `base`, `plot`, `canvas`, `legend`, `legend-item`, `legend-item-hidden`, `legend-swatch`,
47
- `reset-zoom-button`, `description`, `notices`, `data-table`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
47
+ `reset-zoom-button`, `description`, `notices`, `data-table`, `data-table-toggle`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
48
48
  rendered in place of `canvas` when the optional `chart.js` peer dependency fails to load; the
49
49
  failure transition is announced through the shared document-level light-DOM assertive sink — see
50
50
  `llms/components/lr-chart.md`).
@@ -53,7 +53,8 @@ failure transition is announced through the shared document-level light-DOM asse
53
53
  `--lr-chart-tick-color`, `--lr-chart-legend-color`, `--lr-chart-tooltip-bg`,
54
54
  `--lr-chart-tooltip-text`, `--lr-chart-legend-item-hover-bg`,
55
55
  `--lr-chart-legend-item-active-bg`, `--lr-chart-data-table-button-hover-bg`,
56
- `--lr-chart-data-table-button-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
56
+ `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
57
+ `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
57
58
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
58
59
  `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — all inherited from `LyraChart`, identical in meaning and default (see
59
60
  `lr-chart` above); each of the eight variants below reads the same set, so one rule retunes them
@@ -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** `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 15 parts, 33 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 16 parts, 35 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
13
13
 
14
14
  ---
@@ -162,6 +162,14 @@ property).
162
162
  ignored without evaluating script or exposing prototype-pollution keys to the merge.
163
163
  - `showDataTable: boolean = false` (attribute `show-data-table`) — makes the always-available
164
164
  accessible data table visible rather than screen-reader-only
165
+ - `dataTableToggle: boolean = false` (attribute `data-table-toggle`, new in 10.1.0) — renders a
166
+ localized disclosure button (`part="data-table-toggle"`) above the data table so a *sighted*
167
+ reader can reveal the numbers on demand. `showDataTable` alone is all-or-nothing, which left
168
+ consumers wrapping a duplicated table in their own `<details>`. With the toggle on,
169
+ `showDataTable` becomes the disclosure's **initial** state rather than its whole behavior; the
170
+ table stays in the DOM in both states, so assistive technology never loses it, and the button
171
+ carries `aria-expanded` plus `aria-controls` pointing at the `data-table` wrapper. Unset, nothing
172
+ renders and behavior is identical to before.
165
173
  - `chartArea: LyraChartArea | undefined` (readonly) — current Chart.js chart-area geometry in
166
174
  canvas-local coordinates (`top`, `left`, `right`, `bottom`, `width`, `height`), when a chart is
167
175
  drawn
@@ -281,7 +289,7 @@ Chart.js escape hatch and is not rewritten by the simplified-surface sampler.
281
289
  wrapping DOM legend), `legend-item` (a dataset-visibility button), `legend-item-hidden` (added to
282
290
  that button while its dataset is hidden), `legend-swatch`,
283
291
  `reset-zoom-button`, `description`, `notices` (wrapper for nonfatal feature warnings and
284
- bounded-alternative truncation notices), `data-table`, `data-truncation` (the bounded-alternative
292
+ bounded-alternative truncation notices), `data-table`, `data-table-toggle` (the `dataTableToggle` disclosure button), `data-truncation` (the bounded-alternative
285
293
  notice), `feature-warning` (a nonfatal missing optional-feature warning), `center` (the
286
294
  chart-area-centered wrapper for the `center` slot), `error` (neutral visible message rendered in
287
295
  place of `canvas` when the optional `chart.js` peer dependency fails to load; the failure transition
@@ -301,7 +309,9 @@ ancestor, not a shadow-tree descendant, since custom properties only cascade dow
301
309
  `y2Label` title text reuses `--lr-chart-tick-color` too — there's no separate title-color token),
302
310
  legend text, and tooltip background/text respectively; plus
303
311
  `--lr-chart-legend-item-hover-bg` / `--lr-chart-legend-item-active-bg`,
304
- `--lr-chart-data-table-button-hover-bg` / `--lr-chart-data-table-button-active-bg`, and
312
+ `--lr-chart-data-table-button-hover-bg` / `--lr-chart-data-table-button-active-bg`,
313
+ `--lr-chart-data-table-toggle-hover-bg` / `--lr-chart-data-table-toggle-active-bg` (the
314
+ `dataTableToggle` disclosure button), and
305
315
  `--lr-chart-reset-zoom-button-hover-bg` / `--lr-chart-reset-zoom-button-active-bg` — independent
306
316
  background hooks for each DOM control's hover and pressed states. Hover defaults to
307
317
  `--lr-color-brand-quiet`; pressed defaults to its standard active color mix. Override one pair
@@ -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** 27 parts, 20 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 29 parts, 20 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Documented with** `lr-option` (same section below)
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
@@ -24,6 +24,24 @@ An `lr-option` row remains bounded by its owning listbox: the default label elli
24
24
  `start`/`end` (or `prefix`/`suffix`) adornment is capped at 40% of the row. Unbroken metadata
25
25
  therefore cannot widen a 320px LTR or RTL picker.
26
26
 
27
+ **Adornments in the popup (fixed in 10.1.0).** Before 10.1.0 this paragraph described behavior the
28
+ code did not have: `lr-combobox` builds its popup from normalized row *data* rather than from the
29
+ light-DOM nodes, so a slotted `start`/`end`/`prefix`/`suffix` adornment had nowhere to land and
30
+ simply never rendered — the documented slots and their documented parts were both dead inside the
31
+ one component `lr-option` exists to feed. They now render. The nodes are **cloned** into the row
32
+ (`option-start` / `option-end` parts, inert and `aria-hidden`, so they never join the option's
33
+ accessible name), which means the author's own `<lr-option>` subtree is left exactly where they put
34
+ it rather than being moved into a shadow root as a side effect of opening a dropdown:
35
+
36
+ ```html
37
+ <lr-combobox label="Country">
38
+ <lr-option value="fr"><lr-flag slot="start" country="fr"></lr-flag>France</lr-option>
39
+ <lr-option value="mt"><lr-flag slot="start" country="mt"></lr-flag>Malta</lr-option>
40
+ </lr-combobox>
41
+ ```
42
+
43
+ An async `source` row can carry the same two fields (`start`, `end`) alongside its existing `icon`.
44
+
27
45
  ### `lr-combobox`
28
46
 
29
47
  **Properties:**
@@ -90,8 +108,21 @@ therefore cannot widen a 320px LTR or RTL picker.
90
108
  mapped IDLs `inputmode` and `enterkeyhint` delegate to the corresponding camel-case native
91
109
  properties
92
110
  - `inputValue: string` — the live filter input text; programmatic writes are event-silent
93
- - `maxOptionsVisible: number = 3` (attribute `max-options-visible` — caps how many selected tags
94
- show before collapsing to `+N`)
111
+ - `maxOptionsVisible: number = 3` (attribute `max-options-visible` — caps how many selected **tags**
112
+ show before collapsing to `+N`; nothing to do with the suggestion list, see the three-caps note
113
+ below)
114
+ - `visibleOptions?: number` (attribute `visible-options`, new in 10.1.0) — bounds the popup to about
115
+ this many suggestion rows, leaving the rest reachable by scrolling. Purely presentational: every
116
+ row is still rendered. Measured from where row N actually starts rather than computed from a
117
+ token, because a row's height varies with `sub` lines, adornments and group labels. Unset imposes
118
+ no bound of its own and the listbox keeps exactly its previous max-height behavior; zero,
119
+ negative, and non-finite values normalize to unset rather than collapsing the popup
120
+
121
+ **The three caps, which are easy to confuse.** `visibleOptions` caps how many suggestion rows are
122
+ *visible* (presentation; the rest scroll). `maxRender` caps how many suggestion rows are *rendered
123
+ at all* (performance; the rest do not exist and are summarized by `option-overflow`).
124
+ `maxOptionsVisible` caps how many *selected tags* show in multi-select and never touches the
125
+ suggestion list.
95
126
  - `emptyText?: string` (attribute `empty-text`) — omission displays localized `noMatches` (`"No
96
127
  matches"` in the built-in English locale); any supplied string, including `''`, renders verbatim
97
128
  - `loadingText?: string` (attribute `loading-text`) — shown while a `source` fetch is in flight;
@@ -154,9 +185,12 @@ every selection change and a `form.reset()` — like a native control, only anot
154
185
  **8.0 migration:** the former camel-case string property `autoCorrect` is not retained as a public
155
186
  alias. Set the boolean `autocorrect` IDL, or use `autocorrect="on"` / `autocorrect="off"` in markup.
156
187
 
157
- `ComboboxSourceRow = { readonly value: string; readonly label: string; readonly sub?: string; readonly icon?: unknown; readonly badge?: string |
188
+ `ComboboxSourceRow = { readonly value: string; readonly label: string; readonly sub?: string; readonly icon?: unknown; readonly start?: unknown;
189
+ readonly end?: unknown; readonly badge?: string |
158
190
  number; accessibleLabel?: string; data?: unknown; dotColor?: string; group?: string; disabled?:
159
- boolean }` — the row shape used by the async `source` path. `icon` renders as a decorative leading
191
+ boolean }` — the row shape used by the async `source` path. `start` and `end` (new in 10.1.0) are
192
+ the async counterparts of `<lr-option>`'s `start`/`end` adornment slots and render as the
193
+ `option-start` / `option-end` parts, inert and aria-hidden exactly like `icon`. `icon` renders as a decorative leading
160
194
  visual whose rendered subtree stays visible but is inert and hidden from assistive technology;
161
195
  put independent actions outside it. `badge` renders as trailing metadata, `accessibleLabel` can
162
196
  provide richer spoken text than the visible label, and `data` is retained without being rendered
@@ -264,7 +298,9 @@ adornment-slot wrappers, each `hidden` while nothing is slotted into it), `tags`
264
298
  `lr-emoji-picker` so one rule styles every grouped list; it labels the `role="group"` wrapper here),
265
299
  `option`,
266
300
  `option-dot` (the leading status dot, when a row's `dotColor` is set), `option-icon` (the inert,
267
- aria-hidden decorative leading visual for an async row), `option-label`, `option-sub` (a row's
301
+ aria-hidden decorative leading visual for an async row), `option-start` and `option-end` (the inert,
302
+ aria-hidden adornments cloned from the source option's `start`/`prefix` and `end`/`suffix` slots, or
303
+ from an async row's `start`/`end`), `option-label`, `option-sub` (a row's
268
304
  secondary line, when `sub` is set), `option-badge` (an async row's trailing metadata),
269
305
  `option-overflow` (the "+N more" indicator from `maxRender`), `error`, `hint`
270
306
 
@@ -31,9 +31,22 @@ Arabic/Persian display round-trips to the same ISO value.
31
31
  Inline month-grid calendar, not form-associated (used standalone or embedded inside
32
32
  `lr-date-input`'s popover).
33
33
 
34
- **Properties (27):**
34
+ **Properties (28):**
35
35
 
36
36
  - `dayContent` (JS only): `LyraDatePickerDayContent | undefined`
37
+ - `presets: LyraDateRangePreset[] = []` (JS only, new in 10.1.0) —
38
+ `LyraDateRangePreset { label: string; start: string; end: string }`, where `start`/`end` are ISO
39
+ `YYYY-MM-DD`. Renders a `[part="presets"]` quick-range button row above the calendar, for the
40
+ dashboard time-filter shape (Today / Last 7 days / Last 30 days / This month / All time).
41
+ **Range mode only** — a preset names two dates, so it is ignored for a single-date picker rather
42
+ than rendering a row that cannot do anything; unset renders nothing at all. Applying one commits
43
+ through the same path a two-click selection uses, so the ISO serialization, the `min`/`max`
44
+ clamping and the `input`-then-`change` pair are identical and a consumer's change handler cannot
45
+ tell them apart. A reversed preset normalizes; a malformed one is ignored rather than clearing the
46
+ current value, so a bad entry in a config-driven list never reads as "the user picked nothing".
47
+ The active button carries `aria-pressed="true"` and `data-active`. Deliberately the same
48
+ `label`/`start`/`end` shape as `<lr-time-range>`'s `TimeRangePreset`, so the library has one
49
+ preset vocabulary rather than two — the only difference is the unit (ISO dates, not numbers)
37
50
  - `disabled: boolean = false` (reflected)
38
51
  - `disabledDates: string | string[] | Date[] = ''` (attribute `disabled-dates`)
39
52
  - `disabledDaysOfWeek: string = ''` (attribute `disabled-days-of-week`)
@@ -85,11 +98,13 @@ values. `lr-focus-day` carries `{ date: Date }`, and `lr-view-change` carries `{
85
98
 
86
99
  **Custom states:** `disabled`, `range`, and `readonly`.
87
100
 
88
- **CSS parts (35):** `date-picker` / permanent compatibility name `base` (tokens on the same
101
+ **CSS parts (37):** `date-picker` / permanent compatibility name `base` (tokens on the same
89
102
  visible shell; both names remain supported), `day`, `day-disabled`, `day-label`, `day-outside`,
90
103
  `day-placeholder`, `day-range-end`, `day-range-inner`, `day-range-preview`, `day-range-start`,
91
104
  `day-selected`, `day-today`, `day-weekend`, `footer`, `grid`, `header`, `month`, `month-label`,
92
105
  `months`, `nav`, `next`, `previous`, `title`, `view-cell`, `view-grid`, `view-item`,
106
+ `presets` (the quick-range row), `preset-button` (one quick-range button; carries `data-active`
107
+ while its range is the current value),
93
108
  `view-item-disabled`, `view-item-selected`, `view-item-today`, `view-row`, `weekday`, `weekdays`,
94
109
  `weeknumber`, and `weeknumbers`. Lyra additionally retains the existing `week` part.
95
110
 
@@ -331,6 +346,11 @@ and `dateTimeFormat(locale, options)`.
331
346
  `::part(previous):hover` still wins without `!important`.
332
347
  - `--lr-date-picker-nav-active-bg` — Pressed navigation background; defaults to the hover color
333
348
  mixed by `--lr-color-mix-active`.
349
+ - `--lr-date-picker-preset-hover-bg`, `--lr-date-picker-preset-active-bg`, and
350
+ `--lr-date-picker-preset-selected-bg` (new in 10.1.0) — hover, pressed, and
351
+ currently-selected paint for a `presets` quick-range button. Defaults are
352
+ `var(--lr-color-brand-quiet)`, that hover colour mixed by `--lr-color-mix-active`, and
353
+ `var(--lr-color-brand)` respectively.
334
354
  - `--lr-date-picker-title-hover-color`, `--lr-date-picker-title-active-color`,
335
355
  `--lr-date-picker-title-active-bg`, and `--lr-date-picker-title-active-radius` — Month-title
336
356
  hover/press paint and pressed shape; defaults to brand, brand, brand-quiet, and
@@ -8,7 +8,7 @@
8
8
  - **Status** `experimental` 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** 36 parts, 27 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 38 parts, 30 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Documented with** `lr-date-input` (same section below)
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
@@ -31,9 +31,22 @@ Arabic/Persian display round-trips to the same ISO value.
31
31
  Inline month-grid calendar, not form-associated (used standalone or embedded inside
32
32
  `lr-date-input`'s popover).
33
33
 
34
- **Properties (27):**
34
+ **Properties (28):**
35
35
 
36
36
  - `dayContent` (JS only): `LyraDatePickerDayContent | undefined`
37
+ - `presets: LyraDateRangePreset[] = []` (JS only, new in 10.1.0) —
38
+ `LyraDateRangePreset { label: string; start: string; end: string }`, where `start`/`end` are ISO
39
+ `YYYY-MM-DD`. Renders a `[part="presets"]` quick-range button row above the calendar, for the
40
+ dashboard time-filter shape (Today / Last 7 days / Last 30 days / This month / All time).
41
+ **Range mode only** — a preset names two dates, so it is ignored for a single-date picker rather
42
+ than rendering a row that cannot do anything; unset renders nothing at all. Applying one commits
43
+ through the same path a two-click selection uses, so the ISO serialization, the `min`/`max`
44
+ clamping and the `input`-then-`change` pair are identical and a consumer's change handler cannot
45
+ tell them apart. A reversed preset normalizes; a malformed one is ignored rather than clearing the
46
+ current value, so a bad entry in a config-driven list never reads as "the user picked nothing".
47
+ The active button carries `aria-pressed="true"` and `data-active`. Deliberately the same
48
+ `label`/`start`/`end` shape as `<lr-time-range>`'s `TimeRangePreset`, so the library has one
49
+ preset vocabulary rather than two — the only difference is the unit (ISO dates, not numbers)
37
50
  - `disabled: boolean = false` (reflected)
38
51
  - `disabledDates: string | string[] | Date[] = ''` (attribute `disabled-dates`)
39
52
  - `disabledDaysOfWeek: string = ''` (attribute `disabled-days-of-week`)
@@ -85,11 +98,13 @@ values. `lr-focus-day` carries `{ date: Date }`, and `lr-view-change` carries `{
85
98
 
86
99
  **Custom states:** `disabled`, `range`, and `readonly`.
87
100
 
88
- **CSS parts (35):** `date-picker` / permanent compatibility name `base` (tokens on the same
101
+ **CSS parts (37):** `date-picker` / permanent compatibility name `base` (tokens on the same
89
102
  visible shell; both names remain supported), `day`, `day-disabled`, `day-label`, `day-outside`,
90
103
  `day-placeholder`, `day-range-end`, `day-range-inner`, `day-range-preview`, `day-range-start`,
91
104
  `day-selected`, `day-today`, `day-weekend`, `footer`, `grid`, `header`, `month`, `month-label`,
92
105
  `months`, `nav`, `next`, `previous`, `title`, `view-cell`, `view-grid`, `view-item`,
106
+ `presets` (the quick-range row), `preset-button` (one quick-range button; carries `data-active`
107
+ while its range is the current value),
93
108
  `view-item-disabled`, `view-item-selected`, `view-item-today`, `view-row`, `weekday`, `weekdays`,
94
109
  `weeknumber`, and `weeknumbers`. Lyra additionally retains the existing `week` part.
95
110
 
@@ -331,6 +346,11 @@ and `dateTimeFormat(locale, options)`.
331
346
  `::part(previous):hover` still wins without `!important`.
332
347
  - `--lr-date-picker-nav-active-bg` — Pressed navigation background; defaults to the hover color
333
348
  mixed by `--lr-color-mix-active`.
349
+ - `--lr-date-picker-preset-hover-bg`, `--lr-date-picker-preset-active-bg`, and
350
+ `--lr-date-picker-preset-selected-bg` (new in 10.1.0) — hover, pressed, and
351
+ currently-selected paint for a `presets` quick-range button. Defaults are
352
+ `var(--lr-color-brand-quiet)`, that hover colour mixed by `--lr-color-mix-active`, and
353
+ `var(--lr-color-brand)` respectively.
334
354
  - `--lr-date-picker-title-hover-color`, `--lr-date-picker-title-active-color`,
335
355
  `--lr-date-picker-title-active-bg`, and `--lr-date-picker-title-active-radius` — Month-title
336
356
  hover/press paint and pressed shape; defaults to brand, brand, brand-quiet, and
@@ -98,7 +98,8 @@ chrome remains visible. The fallback order appears below.
98
98
  `<lr-tool-approval-dialog>`, whose own docs describe an identical detail shape, so one listener
99
99
  covers all of them. A listener calling `preventDefault()` vetoes the close. Also fired (with
100
100
  reason `'unmount'`, non-cancelable there) when the dialog is removed from the DOM while still
101
- open.
101
+ open. **But the name is not dialog-scoped** — see the target-filtering note above; nine
102
+ components emit `lr-close`, and several are routinely nested inside a dialog.
102
103
 
103
104
  The two `lr-after-*` events are never cancelable.
104
105
 
@@ -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** `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 15 parts, 33 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 16 parts, 35 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Documented with** `lr-line-chart`, `lr-bar-chart`, `lr-pie-chart`, `lr-radar-chart`, `lr-polar-area-chart`, `lr-bubble-chart`, `lr-scatter-chart` (same section below)
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
@@ -44,7 +44,7 @@ complete `hiddenDatasets` snapshot).
44
44
  **Slots:** default JSON configuration script, `data-table`, `center`.
45
45
 
46
46
  **CSS parts:** `base`, `plot`, `canvas`, `legend`, `legend-item`, `legend-item-hidden`, `legend-swatch`,
47
- `reset-zoom-button`, `description`, `notices`, `data-table`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
47
+ `reset-zoom-button`, `description`, `notices`, `data-table`, `data-table-toggle`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
48
48
  rendered in place of `canvas` when the optional `chart.js` peer dependency fails to load; the
49
49
  failure transition is announced through the shared document-level light-DOM assertive sink — see
50
50
  `llms/components/lr-chart.md`).
@@ -53,7 +53,8 @@ failure transition is announced through the shared document-level light-DOM asse
53
53
  `--lr-chart-tick-color`, `--lr-chart-legend-color`, `--lr-chart-tooltip-bg`,
54
54
  `--lr-chart-tooltip-text`, `--lr-chart-legend-item-hover-bg`,
55
55
  `--lr-chart-legend-item-active-bg`, `--lr-chart-data-table-button-hover-bg`,
56
- `--lr-chart-data-table-button-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
56
+ `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
57
+ `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
57
58
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
58
59
  `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — all inherited from `LyraChart`, identical in meaning and default (see
59
60
  `lr-chart` above); each of the eight variants below reads the same set, so one rule retunes them
@@ -74,8 +74,10 @@ rectangular corner radius), `--lr-flag-aspect-ratio` (default `4 / 3`), and
74
74
  image when `country` or `language` is used. Import
75
75
  `@aceshooting/lyra-ui/components/media/flag/flag-peer.js` once to opt into
76
76
  that resolver; a pre-resolved `src` works without the peer registration entry. If the peer is not
77
- installed, the component fails closed with localized visible `[part="error"]` text and a shared
78
- light-DOM assertive announcement (see gotchas).
77
+ installed or if `flag-peer.js` was simply never imported, which looks identical from the page —
78
+ the component fails closed with localized visible `[part="error"]` text, a shared light-DOM
79
+ assertive announcement, and a one-time `console.warn` naming the unresolved code and this import
80
+ (see gotchas).
79
81
 
80
82
  Also exported from the package root:
81
83
  `languageToCountry(language: string): string | undefined` and the `LANGUAGE_TO_COUNTRY` lookup
@@ -161,7 +163,12 @@ import "@aceshooting/lyra-ui/components/media/flag/flag-peer.js";
161
163
  `[data-lr-live-region="assertive"]` sink, so the shadow chrome itself is not live and identical
162
164
  retries remain separate additions. The failure also produces a one-time `console.warn`
163
165
  once the resolver rejects (lazy `import()`, cached module-wide so the warning fires only once per
164
- page even with many `<lr-flag>` instances). An _empty_ template is a different, non-error outcome:
166
+ page even with many `<lr-flag>` instances). A **separate** one-time `console.warn` covers the
167
+ commonest setup mistake — `country`/`language` set while no resolver was ever registered, i.e.
168
+ `flag-peer.js` was not imported. It names the offending code and that import path, because the
169
+ visible `[part="error"]` state alone is indistinguishable from missing flag data. It is armed
170
+ once per resolver-registration generation, so a table of many flags warns once.
171
+ An _empty_ template is a different, non-error outcome:
165
172
  the peer resolved fine but returned no URL for that code (e.g. `country="zz"`) — no `[part="error"]`,
166
173
  no `<img>`, no warning.
167
174
  - Rendering is async even when the peer _is_ installed: `src` resolves after an `import()` +
@@ -78,8 +78,26 @@ weekdayLabelText?: (jsWeekday:number)=>string|undefined; monthLabelText?:
78
78
  more here". `cellText` still carries the full label to the tooltip and the keyboard announcement.
79
79
  A malformed value is ignored rather than collapsing the gutter. Calendar mode is unaffected; it
80
80
  has its own fixed weekday gutter
81
- - `colLabelHeight?: number` (attribute `col-label-height`) height, in CSS px, of the matrix
82
- column-label band. Unset keeps the built-in `20`
81
+ - `colLabelHeight?: number | 'auto'` (attribute `col-label-height`, not reflected, `'auto'` new in
82
+ 10.1.0) — height, in CSS px, of the matrix column-label band, or `'auto'` to measure the labels
83
+ and size the band to fit them. Under a non-zero `colLabelRotation` the measurement projects each
84
+ label's width through the rotation, which is what makes a rotated axis usable without hand-tuning
85
+ a magic number. Never below the built-in `20`, and bounded above by a sanity ceiling so a
86
+ pathological label cannot produce an absurd canvas. Note this deliberately does **not** use
87
+ `rowLabelWidth`'s "40% of the host" rule: the row gutter steals width from the cells and so must
88
+ be bounded relative to them, whereas the canvas simply grows taller for this band and the cells
89
+ keep their size. Unset keeps the built-in `20`, so no existing chart reflows. A malformed value is
90
+ ignored
91
+ - `colLabelRotation?: number` (attribute `col-label-rotation`, new in 10.1.0) — rotation, in
92
+ degrees, applied to matrix column labels. Unset or `0` paints them horizontally exactly as before.
93
+ In a dense matrix the per-column width is far narrower than a typical label, so horizontal labels
94
+ collide with their neighbours; `45` or `90` is the standard remedy. Each label rotates about an
95
+ anchor at its own column's centre with the label's *end* at that anchor, so it leans back over the
96
+ columns to its left and the last column's label cannot overflow the canvas. Values outside
97
+ `[0, 90]` clamp into that range and non-finite values normalize to `0`. Pair with
98
+ `colLabelHeight="auto"` to have the band size itself to the rotated extent. **Not mirrored under
99
+ `dir="rtl"`** — both grid modes deliberately retain physical LTR geometry, so leaning one axis'
100
+ labels the other way would be incoherent
83
101
  - `maxCellSize?: number` (attribute `max-cell-size`) — ceiling, in CSS px, on the cell size
84
102
  `fitToWidth` derives from the host width, in **both** modes. Exists because `fitToWidth` divides
85
103
  the _whole_ host width across the grid, so a 5-week calendar or a 3-column matrix in a wide pane
@@ -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** `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 15 parts, 33 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 16 parts, 35 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
13
13
 
14
14
  ---
@@ -52,7 +52,7 @@ maxSamples?)` appends finite raw samples and optionally retains only the newest
52
52
  **Slots:** default JSON configuration script, `data-table`, `center`.
53
53
 
54
54
  **CSS parts:** `base`, `plot`, `canvas`, `legend`, `legend-item`, `legend-item-hidden`, `legend-swatch`,
55
- `reset-zoom-button`, `description`, `notices`, `data-table`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
55
+ `reset-zoom-button`, `description`, `notices`, `data-table`, `data-table-toggle`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
56
56
  rendered in place of `canvas` when the optional `chart.js` peer dependency fails to load; the
57
57
  failure transition is announced through the shared document-level light-DOM assertive sink —
58
58
  inherited from `LyraChart`, unaffected by the binning logic).
@@ -61,7 +61,8 @@ inherited from `LyraChart`, unaffected by the binning logic).
61
61
  `--lr-chart-tick-color`, `--lr-chart-legend-color`, `--lr-chart-tooltip-bg`,
62
62
  `--lr-chart-tooltip-text`, `--lr-chart-legend-item-hover-bg`,
63
63
  `--lr-chart-legend-item-active-bg`, `--lr-chart-data-table-button-hover-bg`,
64
- `--lr-chart-data-table-button-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
64
+ `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
65
+ `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
65
66
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
66
67
  `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — inherited from `LyraChart`, identical in meaning, together with the
67
68
  mirrored `--border-color-1`,
@@ -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** `chart.js`, `chartjs-plugin-annotation`, `chartjs-plugin-datalabels`, `chartjs-plugin-zoom` — see `llms/peers.md`
11
- - **Themeable via** 15 parts, 33 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 16 parts, 35 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Documented with** `lr-bar-chart`, `lr-pie-chart`, `lr-doughnut-chart`, `lr-radar-chart`, `lr-polar-area-chart`, `lr-bubble-chart`, `lr-scatter-chart` (same section below)
13
13
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
14
14
 
@@ -44,7 +44,7 @@ complete `hiddenDatasets` snapshot).
44
44
  **Slots:** default JSON configuration script, `data-table`, `center`.
45
45
 
46
46
  **CSS parts:** `base`, `plot`, `canvas`, `legend`, `legend-item`, `legend-item-hidden`, `legend-swatch`,
47
- `reset-zoom-button`, `description`, `notices`, `data-table`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
47
+ `reset-zoom-button`, `description`, `notices`, `data-table`, `data-table-toggle`, `data-truncation`, `feature-warning`, `center`, `error` (neutral visible message
48
48
  rendered in place of `canvas` when the optional `chart.js` peer dependency fails to load; the
49
49
  failure transition is announced through the shared document-level light-DOM assertive sink — see
50
50
  `llms/components/lr-chart.md`).
@@ -53,7 +53,8 @@ failure transition is announced through the shared document-level light-DOM asse
53
53
  `--lr-chart-tick-color`, `--lr-chart-legend-color`, `--lr-chart-tooltip-bg`,
54
54
  `--lr-chart-tooltip-text`, `--lr-chart-legend-item-hover-bg`,
55
55
  `--lr-chart-legend-item-active-bg`, `--lr-chart-data-table-button-hover-bg`,
56
- `--lr-chart-data-table-button-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
56
+ `--lr-chart-data-table-button-active-bg`, `--lr-chart-data-table-toggle-hover-bg`,
57
+ `--lr-chart-data-table-toggle-active-bg`, `--lr-chart-reset-zoom-button-hover-bg`,
57
58
  `--lr-chart-reset-zoom-button-active-bg`, `--lr-chart-canvas-hover-outline-width`, and
58
59
  `--lr-chart-pattern-step`, plus `--lr-chart-legend-side-max` — all inherited from `LyraChart`, identical in meaning and default (see
59
60
  `lr-chart` above); each of the eight variants below reads the same set, so one rule retunes them
@@ -59,7 +59,7 @@ omittedCount, truncatedLabelCount, truncated }` result for the latest assignment
59
59
  the bounded rows are complete.
60
60
  - `choropleth?: LyraMapChoroplethLayer` (attribute: false) — `LyraMapChoroplethLayer { sourceId:
61
61
  string; geojson: GeoJSON.FeatureCollection; field: string; stops: [number, string][]; interpolation?:
62
- 'linear' | 'logarithmic' }` (interpolated
62
+ 'linear' | 'logarithmic' | 'step'; stepBaseColor?: string }` (interpolated
63
63
  fill-color expression from `field`'s value against `stops`; `stops` must contain at least one
64
64
  `[value, color]` pair — an empty array is ignored, leaving whatever fill layer already exists, if
65
65
  any, untouched, rather than being applied).
@@ -71,7 +71,14 @@ string; geojson: GeoJSON.FeatureCollection; field: string; stops: [number, strin
71
71
  rather than adding one (maplibre has no `['log']` interpolation type; a sub-1 exponential base is
72
72
  the documented way to weight a ramp toward the low end). **`stops` stay in the data's own units
73
73
  under either mode**, so the legend keeps reading in real values instead of log units — no
74
- pre-transforming to log10 and hand-relabelling the legend back
74
+ pre-transforming to log10 and hand-relabelling the legend back.
75
+ `'step'` (new in 10.1.0) emits maplibre's `['step', …]` instead of `['interpolate', …]`, giving
76
+ **discrete bands rather than a continuous ramp**. Use it whenever the legend advertises a fixed
77
+ set of ranges with one swatch each: a ramp would put colours on the map that appear nowhere in the
78
+ legend, and would render two regions in the same advertised band as visibly different colours
79
+ (`legendGradient` covers the opposite case, a gradient legend). `stepBaseColor` is the colour for
80
+ values below the first threshold, which `['step', …]` requires; it defaults to the first stop's own
81
+ colour, so a legend whose first band starts at the data minimum needs no extra configuration
75
82
  - `markers: LyraMapMarker[] = []` (attribute: false) — `LyraMapMarker { id?: string; lngLat:
76
83
  [number, number]; color?: string; label?: string; unsafeHtml?: string }`; an explicit `id` is
77
84
  trimmed and must be nonempty, and the first marker for an explicit ID wins. Markers are reconciled
@@ -93,11 +100,21 @@ string; geojson: GeoJSON.FeatureCollection; field: string; stops: [number, strin
93
100
  - `dataLayers: LyraMapGeoJsonDataLayer[] = []` (attribute: false) —
94
101
  `LyraMapGeoJsonDataLayer { sourceId: string; geojson: GeoJSON.Feature |
95
102
  GeoJSON.FeatureCollection; tone?: 'accent' | 'success' | 'warning' |
96
- 'danger' | 'neutral' }`. `sourceId` is trimmed and must be nonempty; the first layer for a
103
+ 'danger' | 'neutral'; color?: string; strokeColor?: string }`. `sourceId` is trimmed and must be nonempty; the first layer for a
97
104
  `sourceId` wins and blank or later duplicate records are ignored. Each retained entry adds one
98
105
  GeoJSON source plus three geometry-filtered layers
99
106
  (fill, line, and circle, so a mixed `FeatureCollection` renders correctly), colored from the
100
- matching `--lr-color-*` token (`tone` defaults to `'accent'` → `--lr-color-brand`). The component
107
+ matching `--lr-color-*` token (`tone` defaults to `'accent'` → `--lr-color-brand`).
108
+ `color` and `strokeColor` (both new in 10.1.0) override that per surface — `color` paints the
109
+ polygon fill, `strokeColor` the line and circle layers, falling back to `color` and then to `tone`.
110
+ They are separable because a fill and its outline want opposite things on a
111
+ choropleth-plus-overlay map, and the difference is measurable rather than aesthetic: the fill
112
+ competes for area with the choropleth beside it and has to sit quiet, while the 1px outline
113
+ competes with nothing and is the only thing keeping a no-data region's shape readable once the
114
+ fill is that faint. Deriving one from the other measured 1.41:1 against a light basemap — under
115
+ WCAG 1.4.11's 3:1 floor for graphical objects. A `var(--lr-…)` reference is resolved against the
116
+ host before it reaches MapLibre, which paints to a WebGL canvas and never sees the CSS cascade.
117
+ The component
101
118
  assigns collision-free private MapLibre ids for those resources: `sourceId` is the stable
102
119
  declarative reconciliation key, **not** an id to retrieve from `map`. This prevents a data layer
103
120
  from overwriting or removing a same-named source supplied by `mapStyle`. Independent of