@aceshooting/lyra-ui 7.0.0 → 7.2.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 (81) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +12 -4
  3. package/custom-elements.json +885 -40
  4. package/dist/components/charts/chart/chart.class.d.ts +9 -3
  5. package/dist/components/charts/chart/chart.class.d.ts.map +1 -1
  6. package/dist/components/charts/chart/chart.class.js +31 -3
  7. package/dist/components/charts/chart/chart.class.js.map +1 -1
  8. package/dist/components/charts/chart/lite-chart.class.d.ts +24 -1
  9. package/dist/components/charts/chart/lite-chart.class.d.ts.map +1 -1
  10. package/dist/components/charts/chart/lite-chart.class.js +53 -3
  11. package/dist/components/charts/chart/lite-chart.class.js.map +1 -1
  12. package/dist/components/forms/button/button.class.d.ts +10 -4
  13. package/dist/components/forms/button/button.class.d.ts.map +1 -1
  14. package/dist/components/forms/button/button.class.js +21 -5
  15. package/dist/components/forms/button/button.class.js.map +1 -1
  16. package/dist/components/forms/checkbox/checkbox.class.d.ts +5 -3
  17. package/dist/components/forms/checkbox/checkbox.class.d.ts.map +1 -1
  18. package/dist/components/forms/checkbox/checkbox.class.js +13 -3
  19. package/dist/components/forms/checkbox/checkbox.class.js.map +1 -1
  20. package/dist/components/forms/icon-button/icon-button.class.d.ts +11 -4
  21. package/dist/components/forms/icon-button/icon-button.class.d.ts.map +1 -1
  22. package/dist/components/forms/icon-button/icon-button.class.js +21 -5
  23. package/dist/components/forms/icon-button/icon-button.class.js.map +1 -1
  24. package/dist/components/forms/icon-button/icon-button.styles.js +1 -1
  25. package/dist/components/layout/menu/menu.class.d.ts +4 -1
  26. package/dist/components/layout/menu/menu.class.d.ts.map +1 -1
  27. package/dist/components/layout/menu/menu.class.js +4 -1
  28. package/dist/components/layout/menu/menu.class.js.map +1 -1
  29. package/dist/components/media/map/map-loader.d.ts +2 -2
  30. package/dist/components/media/map/map-loader.js +2 -2
  31. package/dist/components/media/map/map.class.d.ts +2 -2
  32. package/dist/components/media/map/map.class.js +2 -2
  33. package/dist/components/overlays/overlay/popover.class.d.ts +7 -0
  34. package/dist/components/overlays/overlay/popover.class.d.ts.map +1 -1
  35. package/dist/components/overlays/overlay/popover.class.js +13 -2
  36. package/dist/components/overlays/overlay/popover.class.js.map +1 -1
  37. package/dist/components/overlays/overlay/tooltip.class.d.ts +9 -0
  38. package/dist/components/overlays/overlay/tooltip.class.d.ts.map +1 -1
  39. package/dist/components/overlays/overlay/tooltip.class.js +43 -3
  40. package/dist/components/overlays/overlay/tooltip.class.js.map +1 -1
  41. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.d.ts +10 -2
  42. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.d.ts.map +1 -1
  43. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +7 -2
  44. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js.map +1 -1
  45. package/dist/internal/aria-controls.d.ts +11 -2
  46. package/dist/internal/aria-controls.d.ts.map +1 -1
  47. package/dist/internal/aria-controls.js +35 -11
  48. package/dist/internal/aria-controls.js.map +1 -1
  49. package/dist/internal/localization.d.ts +1 -1
  50. package/dist/internal/localization.d.ts.map +1 -1
  51. package/dist/internal/localization.js +4 -0
  52. package/dist/internal/localization.js.map +1 -1
  53. package/dist/localization.d.ts +9 -0
  54. package/dist/localization.d.ts.map +1 -0
  55. package/dist/localization.js +8 -0
  56. package/dist/localization.js.map +1 -0
  57. package/dist/lyra.d.ts +3 -3
  58. package/dist/lyra.d.ts.map +1 -1
  59. package/dist/lyra.js +1 -1
  60. package/dist/lyra.js.map +1 -1
  61. package/llms/components/lr-button.md +7 -4
  62. package/llms/components/lr-chart.md +8 -5
  63. package/llms/components/lr-checkbox.md +6 -3
  64. package/llms/components/lr-dropdown-item.md +10 -1
  65. package/llms/components/lr-dropdown.md +2 -0
  66. package/llms/components/lr-geojson-view.md +4 -3
  67. package/llms/components/lr-icon-button.md +11 -6
  68. package/llms/components/lr-knowledge-graph-explorer.md +5 -0
  69. package/llms/components/lr-lite-chart.md +12 -0
  70. package/llms/components/lr-map.md +5 -4
  71. package/llms/components/lr-menu-item.md +10 -1
  72. package/llms/components/lr-menu.md +10 -1
  73. package/llms/components/lr-popover.md +7 -0
  74. package/llms/components/lr-tooltip.md +8 -0
  75. package/llms/peers.md +1 -1
  76. package/llms/shared.md +15 -8
  77. package/llms-full.txt +99 -33
  78. package/package.json +4 -3
  79. package/vscode-css-data.json +7 -0
  80. package/vscode-html-data.json +40 -19
  81. package/web-types.json +41 -20
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@aceshooting/lyra-ui",
4
- "version": "7.0.0",
4
+ "version": "7.2.0",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -1633,7 +1633,7 @@
1633
1633
  },
1634
1634
  {
1635
1635
  "name": "stack-totals",
1636
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
1636
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
1637
1637
  "value": {
1638
1638
  "type": [
1639
1639
  "boolean"
@@ -2038,7 +2038,7 @@
2038
2038
  },
2039
2039
  {
2040
2040
  "name": "stack-totals",
2041
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
2041
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
2042
2042
  "value": {
2043
2043
  "type": [
2044
2044
  "boolean"
@@ -2103,7 +2103,7 @@
2103
2103
  },
2104
2104
  {
2105
2105
  "name": "lr-button",
2106
- "description": "`<lr-button>` — a generic action-button primitive. Renders an internal native\n`<button part=\"base\">`. `type=\"submit\"`/`type=\"reset\"`\nare handled by this component itself via the host's own `closest('form')` — a shadow-internal\nnative `<button type=\"submit\">` does not participate in an ancestor light-DOM form's submission\non its own, since form-submitter semantics don't cross the shadow boundary.\n\nWhen `href` is set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set) the root\nrenders as a real `<a part=\"base\" href=…>` instead — for a link styled\nas a button (e.g. a CTA). Native navigation is then the anchor's own activation, so the\nsubmit/reset click handler and `type` (submit/reset) have no effect in that mode. When the\nbutton is disabled (its own `disabled` or an ancestor `<fieldset disabled>`) the anchor renders\nwith `aria-disabled=\"true\"` and **no `href`** — an href-less anchor is not focusable or\nnavigable, so a disabled link button genuinely cannot be activated (unlike a bare\n`aria-disabled` on a still-navigable link). An unsafe/unparseable `href` falls back to the\nnative `<button>`.\n\n`accessibleLabel` (attribute `aria-label`) is forwarded reactively to the internal button/anchor\nas a literal string (for an icon-only button with no visible label); external\n`aria-labelledby`/`aria-describedby` idrefs are not copied across the shadow boundary.\nHost `aria-haspopup` and `aria-expanded` values are likewise forwarded to the internal semantic\ncontrol. When host `aria-controls` names elements in the host's own root, the controls\nrelationship is resolved onto the internal control through the reflected element-reference API\nso it remains valid across this component's shadow boundary; browsers without that API retain\nthe forwarded string attribute as a best-effort fallback.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Default slot: the button's label content. |\n| `end` | Trailing icon/content, rendered after the label. |\n| `start` | Leading icon/content, rendered before the label. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The internal native `<button>` (or an `<a>` when `href` resolves to a safe link). |\n| `end` | The `end` slot wrapper. |\n| `label` | The default-slot label wrapper. |\n| `spinner` | The loading spinner, present only while `loading` is `true`. |\n| `start` | The `start` slot wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-button-width` (default: `100%`) — Inline size of the internal button. The host defaults it to `100%` so the native button follows the host's own width; override to `auto` (or any other value) for a compact inline composition.\n- `--lr-button-hover-brightness` (default: `1.08`) — `filter: brightness()` multiplier applied while hovering a non-disabled button.\n- `--lr-button-active-scale` (default: `0.9875`) — `transform: scale()` factor applied while a non-disabled button is pressed.\n- `--lr-button-spinner-duration` (default: `var(--lr-transition-ambient)`) — Timing of the `loading` spinner.\n- `--lr-button-accent` (default: `var(--lr-color-text)`) — Text/glyph color for the chrome-less appearances (`outlined`, `plain`, `link`). Swapped per `variant` to that variant's semantic color.\n- `--lr-button-fill` (default: `var(--lr-color-surface)`) — Background of `appearance=\"filled\"`. Swapped per `variant` to that variant's semantic color.\n- `--lr-button-on-fill` (default: `var(--lr-color-text)`) — Text color on top of `--lr-button-fill`. Swapped per `variant` to that variant's `on-*` color.\n- `--lr-button-accent-fill` (default: `var(--lr-color-neutral)`) — Background of `appearance=\"accent\"` (and its border color). Swapped per `variant` to that variant's semantic color.\n- `--lr-button-accent-on-fill` (default: `var(--lr-color-on-neutral)`) — Text color on top of `--lr-button-accent-fill`. Swapped per `variant` to that variant's `on-*` color.\n- `--lr-button-border` (default: `var(--lr-color-border)`) — Border color of the internal button. Swapped per `variant` to that variant's semantic color.\n- `--lr-button-outlined-border` (default: `var(--lr-color-border-strong)`) — Border color of `appearance=\"outlined\"`, which overrides `--lr-button-border`.\n- `--lr-button-outlined-fill` (default: `transparent`) — Background of `appearance=\"outlined\"`. Transparent by default; set it to tint the button (e.g. a faint surface wash behind the outline) without a `::part(base)` rule. Like `--lr-button-quiet-*`, it is deliberately *not* swapped per `variant`. Note that the `:hover` `filter: brightness()` applies to whatever fill is set, so a tinted outlined button now visibly brightens on hover where a transparent one did not.\n- `--lr-button-quiet-border` (default: `var(--lr-color-border)`) — Border color of `appearance=\"quiet\"`.\n- `--lr-button-quiet-text` (default: `var(--lr-color-text-quiet)`) — Text color of `appearance=\"quiet\"`.\n- `--lr-button-size-2xs` (default: `var(--lr-size-1-25rem)`) — `min-block-size` at `size=\"2xs\"`.\n- `--lr-button-size-xs` (default: `var(--lr-size-1-5rem)`) — `min-block-size` at `size=\"xs\"`.\n- `--lr-button-size-s` (default: `var(--lr-size-1-875rem)`) — `min-block-size` at `size=\"s\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own `size=\"s\"` control height.\n- `--lr-button-size-m` (default: `var(--lr-size-2-5rem)`) — `min-block-size` at `size=\"m\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own default control height, so a default-size button sitting next to a default-size input/select/combobox in the same row lines up.\n- `--lr-button-size-l` (default: `var(--lr-size-3rem)`) — `min-block-size` at `size=\"l\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own `size=\"l\"` control height.\n- `--lr-button-size-xl` (default: `var(--lr-size-3-5rem)`) — `min-block-size` at `size=\"xl\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own `size=\"xl\"` control height.\n- `--lr-button-padding-block` (default: `var(--lr-space-xs)`) — Block padding of the internal button, re-assigned per `size` tier (the default is the `m` tier's value). Override it to retune a tier without a `::part(base)` rule; `appearance=\"link\"` ignores it (it renders with zero padding).\n- `--lr-button-padding-inline` (default: `var(--lr-space-m)`) — Inline padding of the internal button, re-assigned per `size` tier (the default is the `m` tier's value). `appearance=\"link\"` ignores it.\n- `--lr-button-font-size` (default: `var(--lr-font-size-m)`) — Font size of the internal button, re-assigned per `size` tier (the default is the `m` tier's value). `appearance=\"link\"` ignores it and inherits the ambient font instead.\n- `--lr-button-min-height` (default: `var(--lr-button-size-m)`) — The active tier's `min-block-size` floor. Re-assigned per `size` tier to that tier's own `--lr-button-size-*` token, and used as the fallback when `--lr-button-height` is unset.\n- `--lr-button-height` — Exact height of the internal button. **Undeclared by default** — so the button keeps the active tier's `min-block-size` floor and an `auto` height, exactly as before. Set it (e.g. to pin the button to a fixed toolbar row) to both floor *and* cap the height. Never declare it as `auto`: a declared value wins over the `var()` fallback arm and would make every tier's floor dead code. `appearance=\"link\"` ignores it.\n- `--lr-button-gap` (default: `var(--lr-space-2xs)`) — Gap between the icon/label and any slotted content in the internal button. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(base)` rule.\n- `--lr-button-radius` (default: `var(--lr-radius)`) — Corner radius of the internal button. Does not vary by `size` tier. `appearance=\"link\"` ignores it (it renders with zero radius).\n- `--lr-button-shadow` — Box shadow of the internal button. **Undeclared by default**, so `box-shadow` falls back to `none` — byte-identical to before this property existed. Set it (e.g. an elevated/floating action button) without a `::part(base)` rule.",
2106
+ "description": "`<lr-button>` — a generic action-button primitive. Renders an internal native\n`<button part=\"base\">`. `type=\"submit\"`/`type=\"reset\"`\nare handled by this component itself via the host's own `closest('form')` — a shadow-internal\nnative `<button type=\"submit\">` does not participate in an ancestor light-DOM form's submission\non its own, since form-submitter semantics don't cross the shadow boundary.\n\nWhen `href` is set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set) the root\nrenders as a real `<a part=\"base\" href=…>` instead — for a link styled\nas a button (e.g. a CTA). Native navigation is then the anchor's own activation, so the\nsubmit/reset click handler and `type` (submit/reset) have no effect in that mode. When the\nbutton is disabled (its own `disabled` or an ancestor `<fieldset disabled>`) the anchor renders\nwith `aria-disabled=\"true\"` and **no `href`** — an href-less anchor is not focusable or\nnavigable, so a disabled link button genuinely cannot be activated (unlike a bare\n`aria-disabled` on a still-navigable link). An unsafe/unparseable `href` falls back to the\nnative `<button>`.\n\n`accessibleLabel` (attribute `aria-label`) is forwarded reactively to the internal button/anchor\nas a literal string (for an icon-only button with no visible label). Host `aria-describedby`\nIDREFs are resolved through `ariaDescribedByElements`; external `aria-labelledby` is not copied\nacross the shadow boundary.\nHost `aria-haspopup` and `aria-expanded` values are likewise forwarded to the internal semantic\ncontrol. When host `aria-controls` names elements in the host's own root, the controls\nrelationship is resolved onto the internal control through the reflected element-reference API\nso it remains valid across this component's shadow boundary. Assigning that relationship\nintentionally clears the serialized `aria-controls` value; read `ariaControlsElements` in a\nsupporting browser. Browsers without that API retain the forwarded string attribute as a\nbest-effort fallback.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Default slot: the button's label content. |\n| `end` | Trailing icon/content, rendered after the label. |\n| `start` | Leading icon/content, rendered before the label. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The internal native `<button>` (or an `<a>` when `href` resolves to a safe link). |\n| `end` | The `end` slot wrapper. |\n| `label` | The default-slot label wrapper. |\n| `spinner` | The loading spinner, present only while `loading` is `true`. |\n| `start` | The `start` slot wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-button-width` (default: `100%`) — Inline size of the internal button. The host defaults it to `100%` so the native button follows the host's own width; override to `auto` (or any other value) for a compact inline composition.\n- `--lr-button-hover-brightness` (default: `1.08`) — `filter: brightness()` multiplier applied while hovering a non-disabled button.\n- `--lr-button-active-scale` (default: `0.9875`) — `transform: scale()` factor applied while a non-disabled button is pressed.\n- `--lr-button-spinner-duration` (default: `var(--lr-transition-ambient)`) — Timing of the `loading` spinner.\n- `--lr-button-accent` (default: `var(--lr-color-text)`) — Text/glyph color for the chrome-less appearances (`outlined`, `plain`, `link`). Swapped per `variant` to that variant's semantic color.\n- `--lr-button-fill` (default: `var(--lr-color-surface)`) — Background of `appearance=\"filled\"`. Swapped per `variant` to that variant's semantic color.\n- `--lr-button-on-fill` (default: `var(--lr-color-text)`) — Text color on top of `--lr-button-fill`. Swapped per `variant` to that variant's `on-*` color.\n- `--lr-button-accent-fill` (default: `var(--lr-color-neutral)`) — Background of `appearance=\"accent\"` (and its border color). Swapped per `variant` to that variant's semantic color.\n- `--lr-button-accent-on-fill` (default: `var(--lr-color-on-neutral)`) — Text color on top of `--lr-button-accent-fill`. Swapped per `variant` to that variant's `on-*` color.\n- `--lr-button-border` (default: `var(--lr-color-border)`) — Border color of the internal button. Swapped per `variant` to that variant's semantic color.\n- `--lr-button-outlined-border` (default: `var(--lr-color-border-strong)`) — Border color of `appearance=\"outlined\"`, which overrides `--lr-button-border`.\n- `--lr-button-outlined-fill` (default: `transparent`) — Background of `appearance=\"outlined\"`. Transparent by default; set it to tint the button (e.g. a faint surface wash behind the outline) without a `::part(base)` rule. Like `--lr-button-quiet-*`, it is deliberately *not* swapped per `variant`. Note that the `:hover` `filter: brightness()` applies to whatever fill is set, so a tinted outlined button now visibly brightens on hover where a transparent one did not.\n- `--lr-button-quiet-border` (default: `var(--lr-color-border)`) — Border color of `appearance=\"quiet\"`.\n- `--lr-button-quiet-text` (default: `var(--lr-color-text-quiet)`) — Text color of `appearance=\"quiet\"`.\n- `--lr-button-size-2xs` (default: `var(--lr-size-1-25rem)`) — `min-block-size` at `size=\"2xs\"`.\n- `--lr-button-size-xs` (default: `var(--lr-size-1-5rem)`) — `min-block-size` at `size=\"xs\"`.\n- `--lr-button-size-s` (default: `var(--lr-size-1-875rem)`) — `min-block-size` at `size=\"s\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own `size=\"s\"` control height.\n- `--lr-button-size-m` (default: `var(--lr-size-2-5rem)`) — `min-block-size` at `size=\"m\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own default control height, so a default-size button sitting next to a default-size input/select/combobox in the same row lines up.\n- `--lr-button-size-l` (default: `var(--lr-size-3rem)`) — `min-block-size` at `size=\"l\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own `size=\"l\"` control height.\n- `--lr-button-size-xl` (default: `var(--lr-size-3-5rem)`) — `min-block-size` at `size=\"xl\"`. Matches `lr-input`/`lr-select`/`lr-combobox`'s own `size=\"xl\"` control height.\n- `--lr-button-padding-block` (default: `var(--lr-space-xs)`) — Block padding of the internal button, re-assigned per `size` tier (the default is the `m` tier's value). Override it to retune a tier without a `::part(base)` rule; `appearance=\"link\"` ignores it (it renders with zero padding).\n- `--lr-button-padding-inline` (default: `var(--lr-space-m)`) — Inline padding of the internal button, re-assigned per `size` tier (the default is the `m` tier's value). `appearance=\"link\"` ignores it.\n- `--lr-button-font-size` (default: `var(--lr-font-size-m)`) — Font size of the internal button, re-assigned per `size` tier (the default is the `m` tier's value). `appearance=\"link\"` ignores it and inherits the ambient font instead.\n- `--lr-button-min-height` (default: `var(--lr-button-size-m)`) — The active tier's `min-block-size` floor. Re-assigned per `size` tier to that tier's own `--lr-button-size-*` token, and used as the fallback when `--lr-button-height` is unset.\n- `--lr-button-height` — Exact height of the internal button. **Undeclared by default** — so the button keeps the active tier's `min-block-size` floor and an `auto` height, exactly as before. Set it (e.g. to pin the button to a fixed toolbar row) to both floor *and* cap the height. Never declare it as `auto`: a declared value wins over the `var()` fallback arm and would make every tier's floor dead code. `appearance=\"link\"` ignores it.\n- `--lr-button-gap` (default: `var(--lr-space-2xs)`) — Gap between the icon/label and any slotted content in the internal button. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(base)` rule.\n- `--lr-button-radius` (default: `var(--lr-radius)`) — Corner radius of the internal button. Does not vary by `size` tier. `appearance=\"link\"` ignores it (it renders with zero radius).\n- `--lr-button-shadow` — Box shadow of the internal button. **Undeclared by default**, so `box-shadow` falls back to `none` — byte-identical to before this property existed. Set it (e.g. an elevated/floating action button) without a `::part(base)` rule.",
2107
2107
  "attributes": [
2108
2108
  {
2109
2109
  "name": "appearance",
@@ -2118,6 +2118,10 @@
2118
2118
  "name": "aria-controls",
2119
2119
  "description": "Type: `string | null` \nDefault: `null`"
2120
2120
  },
2121
+ {
2122
+ "name": "aria-describedby",
2123
+ "description": "Type: `string | null` \nDefault: `null`"
2124
+ },
2121
2125
  {
2122
2126
  "name": "aria-expanded",
2123
2127
  "description": "Type: `string | null` \nDefault: `null`"
@@ -2634,7 +2638,7 @@
2634
2638
  },
2635
2639
  {
2636
2640
  "name": "stack-totals",
2637
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
2641
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
2638
2642
  "value": {
2639
2643
  "type": [
2640
2644
  "boolean"
@@ -3012,7 +3016,7 @@
3012
3016
  },
3013
3017
  {
3014
3018
  "name": "lr-checkbox",
3015
- "description": "`<lr-checkbox>` — a boolean form control. Structurally the same idea as\n`<lr-switch>` (form-associated via `ElementInternals`, click and\nSpace both toggle) but with checkbox semantics: `role=\"checkbox\"` +\nan `aria-checked` that can also be `\"mixed\"`, and a visual box/checkmark\ninstead of a track/thumb.\n\n`checked` is not a plain string, so this attaches `ElementInternals`\ndirectly and implements its own `updateValidity()` rather than using the\n`FormAssociated` mixin — see `<lr-combobox>` for the same\ndirect-`ElementInternals` shape with a non-string value.\n\nDeliberately no hint/error chrome of its own -- the default slot already carries real, visible\nlabel text (see `@slot` below), so a labeled-field frame built around `label`/`hint`/`errorText`\nprops has nothing to add here. A consumer needing hint/error messaging composes it in their own\nwrapper (e.g. `<lr-tool-param-form>` folds a boolean field's validation error into adjacent\ndescription text / `aria-label` rather than a `<lr-checkbox>`-owned slot), the same way a\nnative `<input type=\"checkbox\">` plus `<label>` pairs with an externally-owned error node.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Label text, rendered next to the box. Clicking it toggles the checkbox, the same as clicking a native checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the control still has an accessible name. A host `aria-describedby` attribute is forwarded to the internal `role=\"checkbox\"` so externally-owned descriptions can be associated with this individual control. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The whole interactive control (`role=\"checkbox\"`); wraps the box and label. |\n| `box` | The small square that shows the checkmark/indeterminate dash. |\n| `checkmark` | The checkmark (or indeterminate dash) glyph inside the box. |\n| `label` | The wrapper around the default slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-checkbox-label-indent` (default: `calc(min(var(--lr-icon-button-size), 1.75rem) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the box's own floor plus the gap next to it. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-checkbox` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size` and `--lr-theme-space-s`, which you control.\n- `--lr-checkbox-checked-bg` (default: `var(--lr-color-brand)`) — Background of `[part='box']` while `checked` or `indeterminate`. Retint just this control's checked fill without touching the shared `--lr-color-brand` token every other component also reads.\n- `--lr-checkbox-checked-border` (default: `var(--lr-color-brand)`) — Border color of `[part='box']` while `checked` or `indeterminate`.",
3019
+ "description": "`<lr-checkbox>` — a boolean form control. Structurally the same idea as\n`<lr-switch>` (form-associated via `ElementInternals`, click and\nSpace both toggle) but with checkbox semantics: `role=\"checkbox\"` +\nan `aria-checked` that can also be `\"mixed\"`, and a visual box/checkmark\ninstead of a track/thumb.\n\n`checked` is not a plain string, so this attaches `ElementInternals`\ndirectly and implements its own `updateValidity()` rather than using the\n`FormAssociated` mixin — see `<lr-combobox>` for the same\ndirect-`ElementInternals` shape with a non-string value.\n\nDeliberately no hint/error chrome of its own -- the default slot already carries real, visible\nlabel text (see `@slot` below), so a labeled-field frame built around `label`/`hint`/`errorText`\nprops has nothing to add here. A consumer needing hint/error messaging composes it in their own\nwrapper (e.g. `<lr-tool-param-form>` folds a boolean field's validation error into adjacent\ndescription text / `aria-label` rather than a `<lr-checkbox>`-owned slot), the same way a\nnative `<input type=\"checkbox\">` plus `<label>` pairs with an externally-owned error node.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Label text, rendered next to the box. Clicking it toggles the checkbox, the same as clicking a native checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the control still has an accessible name. A host `aria-describedby` attribute is resolved onto the internal `role=\"checkbox\"` through `ariaDescribedByElements` so externally-owned descriptions remain valid across the shadow boundary. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The whole interactive control (`role=\"checkbox\"`); wraps the box and label. |\n| `box` | The small square that shows the checkmark/indeterminate dash. |\n| `checkmark` | The checkmark (or indeterminate dash) glyph inside the box. |\n| `label` | The wrapper around the default slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-checkbox-label-indent` (default: `calc(min(var(--lr-icon-button-size), 1.75rem) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the box's own floor plus the gap next to it. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-checkbox` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size` and `--lr-theme-space-s`, which you control.\n- `--lr-checkbox-checked-bg` (default: `var(--lr-color-brand)`) — Background of `[part='box']` while `checked` or `indeterminate`. Retint just this control's checked fill without touching the shared `--lr-color-brand` token every other component also reads.\n- `--lr-checkbox-checked-border` (default: `var(--lr-color-brand)`) — Border color of `[part='box']` while `checked` or `indeterminate`.",
3016
3020
  "attributes": [
3017
3021
  {
3018
3022
  "name": "checked",
@@ -6029,7 +6033,7 @@
6029
6033
  },
6030
6034
  {
6031
6035
  "name": "stack-totals",
6032
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
6036
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
6033
6037
  "value": {
6034
6038
  "type": [
6035
6039
  "boolean"
@@ -8400,7 +8404,7 @@
8400
8404
  },
8401
8405
  {
8402
8406
  "name": "stack-totals",
8403
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
8407
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
8404
8408
  "value": {
8405
8409
  "type": [
8406
8410
  "boolean"
@@ -8549,12 +8553,16 @@
8549
8553
  },
8550
8554
  {
8551
8555
  "name": "lr-icon-button",
8552
- "description": "`<lr-icon-button>` — an accessible icon-only action button.\n\nSet `icon` for one of `<lr-icon>`'s named glyphs, or slot your own content instead. Slotted\ncontent is a **sibling** of the built-in glyph rather than being piped through `<lr-icon>`, so\nany complete element — an `<svg>`, an `<img>`, an `<lr-flag>` — renders at its own natural\naspect ratio instead of being forced into a 1:1 box. Bare SVG geometry (`<path>`, `<circle>`,\nand a handful of other raw primitives) with no enclosing `<svg>` of its own is detected and\ncloned into a real, internal SVG-namespaced element so it still paints — the same fallback\n`<lr-icon>`'s own custom-content slot uses, but narrowly scoped so a custom element (e.g. a\nslotted `<lr-flag>`) is never run through it.\n\nHost `aria-haspopup` and `aria-expanded` values are forwarded reactively to the shadow-internal\nnative button. When host `aria-controls` names elements in the host's own root, the controls\nrelationship is resolved onto that focused control through the reflected element-reference API\nso it remains valid across this component's shadow boundary; browsers without that API retain\nthe forwarded string attribute as a best-effort fallback.\n\nForm-associated (mirroring `<lr-button>`'s identical shape): discoverable through\n`form.elements`, and `type=\"submit\"`/`type=\"reset\"` are handled by this component itself via\nthe host's own `closest('form')` — a shadow-internal native `<button type=\"submit\">` does not\nparticipate in an ancestor light-DOM form's submission on its own, since form-submitter\nsemantics don't cross the shadow boundary.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Optional custom icon content, rendered beside (not inside) the `icon` glyph. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `button` | Native button. |\n| `fallback` | The internal SVG-namespaced clone target for slotted bare geometry. Carries the same `fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"` defaults `<lr-icon>`'s own wrapper svg does, so bare stroke-style geometry (no fill/stroke of its own) renders outlined instead of as a solid shape; an explicit `fill`/`stroke`/etc. already present on the slotted node still wins for that node. Only present in the DOM while at least one top-level slotted element needs it; a complete `<svg>`, `<img>`, or custom element never mounts it. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-icon-button-size` (default: `2.5rem`) — Minimum tappable inline and block size of the native button — a **floor**, not a fixed size: content larger than it grows the button and keeps its own aspect ratio, while a small glyph pads out to it. A library-wide token (declared on `:root` by `tokens.styles.ts`, and the shared minimum tappable size several other components size their icon controls against), so overriding it globally resizes all of them together.\n- `--lr-icon-button-radius` (default: `var(--lr-radius)`) — Corner radius of the native button.\n- `--lr-icon-button-background` (default: `transparent`) — Background fill of the native button.\n- `--lr-icon-button-background-hover` (default: `var(--lr-color-surface)`) — Background fill on hover.\n- `--lr-icon-button-color` (default: `inherit`) — Icon/text color of the native button.\n- `--lr-icon-button-color-hover` (default: `var(--lr-icon-button-color, inherit)`) — Icon/text color on hover.\n- `--lr-icon-button-border` (default: `0`) — Complete border shorthand of the native button.",
8556
+ "description": "`<lr-icon-button>` — an accessible icon-only action button.\n\nSet `icon` for one of `<lr-icon>`'s named glyphs, or slot your own content instead. Slotted\ncontent is a **sibling** of the built-in glyph rather than being piped through `<lr-icon>`, so\nany complete element — an `<svg>`, an `<img>`, an `<lr-flag>` — renders at its own natural\naspect ratio instead of being forced into a 1:1 box. Bare SVG geometry (`<path>`, `<circle>`,\nand a handful of other raw primitives) with no enclosing `<svg>` of its own is detected and\ncloned into a real, internal SVG-namespaced element so it still paints — the same fallback\n`<lr-icon>`'s own custom-content slot uses, but narrowly scoped so a custom element (e.g. a\nslotted `<lr-flag>`) is never run through it.\n\nHost `aria-haspopup` and `aria-expanded` values are forwarded reactively to the shadow-internal\nnative button. Host `aria-describedby` IDREFs are resolved through `ariaDescribedByElements`.\nWhen host `aria-controls` names elements in the host's own root, the controls relationship is\nresolved onto that focused control through the reflected element-reference API so it remains\nvalid across this component's shadow boundary. Assigning that relationship intentionally clears\nthe serialized `aria-controls` value; read `ariaControlsElements` in a supporting browser.\nBrowsers without that API retain the forwarded string attribute as a best-effort fallback.\n\nForm-associated (mirroring `<lr-button>`'s identical shape): discoverable through\n`form.elements`, and `type=\"submit\"`/`type=\"reset\"` are handled by this component itself via\nthe host's own `closest('form')` — a shadow-internal native `<button type=\"submit\">` does not\nparticipate in an ancestor light-DOM form's submission on its own, since form-submitter\nsemantics don't cross the shadow boundary.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Optional custom icon content, rendered beside (not inside) the `icon` glyph. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `button` | Native button. |\n| `fallback` | The internal SVG-namespaced clone target for slotted bare geometry. Carries the same `fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"` defaults `<lr-icon>`'s own wrapper svg does, so bare stroke-style geometry (no fill/stroke of its own) renders outlined instead of as a solid shape; an explicit `fill`/`stroke`/etc. already present on the slotted node still wins for that node. Only present in the DOM while at least one top-level slotted element needs it; a complete `<svg>`, `<img>`, or custom element never mounts it. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-icon-button-size` (default: `2.5rem`) — Minimum tappable inline and block size of the native button — a **floor**, not a fixed size: content larger than it grows the button and keeps its own aspect ratio, while a small glyph pads out to it. A library-wide token (declared on `:root` by `tokens.styles.ts`, and the shared minimum tappable size several other components size their icon controls against), so overriding it globally resizes all of them together.\n- `--lr-icon-button-radius` (default: `var(--lr-radius)`) — Corner radius of the native button.\n- `--lr-icon-button-background` (default: `transparent`) — Background fill of the native button.\n- `--lr-icon-button-background-hover` (default: `var(--lr-color-surface)`) — Background fill on hover.\n- `--lr-icon-button-color` (default: `inherit`) — Icon/text color of the native button.\n- `--lr-icon-button-color-hover` (default: `var(--lr-icon-button-color, inherit)`) — Icon/text color on hover.\n- `--lr-icon-button-border` (default: `0`) — Complete border shorthand of the native button.\n- `--lr-icon-button-border-hover` (default: `var(--lr-icon-button-border, 0)`) — Complete border shorthand on hover.",
8553
8557
  "attributes": [
8554
8558
  {
8555
8559
  "name": "aria-controls",
8556
8560
  "description": "Type: `string | null` \nDefault: `null`"
8557
8561
  },
8562
+ {
8563
+ "name": "aria-describedby",
8564
+ "description": "Type: `string | null` \nDefault: `null`"
8565
+ },
8558
8566
  {
8559
8567
  "name": "aria-expanded",
8560
8568
  "description": "Type: `string | null` \nDefault: `null`"
@@ -9224,7 +9232,7 @@
9224
9232
  },
9225
9233
  {
9226
9234
  "name": "lr-knowledge-graph-explorer",
9227
- "description": "`<lr-knowledge-graph-explorer>` — an orchestration-level surface for exploring a knowledge\ngraph: the `lr-graph` canvas plus entity search, type filters, neighborhood expansion, pinned\nnodes, path finding between pins, node selection, and a details overlay. Composes existing\nprimitives rather than re-implementing graph rendering: `lr-graph` (canvas/pan-zoom/selection),\n`lr-graph-legend` (type filters), `lr-entity-card` (the details popover's default content),\n`lr-neighbor-list` (the selected entity's relationships), `lr-path-strip` (a found path), and\n`lr-popover.showAt()` (the details overlay itself).\n\n**How the details popover finds its viewport position.** `lr-graph.getNodePosition()` and the\n`lr-node-click` event's `{ x, y }` are in the graph's own *local drawing space* (pre pan/zoom),\nnever viewport pixels -- passing them straight to `showAt()` would anchor the popover at the\nwrong place as soon as the graph has panned or zoomed even once. A direct node click resolves\nthe correct viewport rect the way this library's own documented `lr-graph` + `lr-popover.showAt()`\ncomposition does: for `renderer=\"svg\"` (the default), `event.composedPath()` (the native `click`\nthat bubbles out of `lr-graph`'s shadow root) locates the actual clicked `[part=\"node\"]` element,\nwhose `getBoundingClientRect()` is already viewport-relative; for `renderer=\"canvas\"` (no\nper-node DOM element to find), the click event's own `clientX`/`clientY` are used directly, since\ncanvas hit-testing already treats those as viewport coordinates internally. While the popover\nstays open after an `renderer=\"svg\"` click, this component re-reads that same resolved node\nelement's `getBoundingClientRect()` and re-calls `showAt()` every time the composed `lr-graph`\nemits its own `lr-viewport-change` (a frame-coalesced pan/zoom/simulation-tick signal) --\nschedules no `requestAnimationFrame` loop of its own, unlike an idle popover polling the DOM on\nevery frame regardless of whether anything actually moved. Selecting a node any other\nway -- a search result, a neighbor row, a path-strip element, keyboard Enter/Space on a graph\nnode (which never dispatches a native `click`) -- has no click event to read a rect from, so it\ninstead calls the public `lr-graph.focusNode(id)` (which centers that node in the viewport) and\nthen anchors the popover at the graph element's own `getBoundingClientRect()` center once that\nsettles; no continuous tracking applies to that path.\n\n**Controlled vs. self-managed state.** `nodes`/`links`/`nodeTypes`/`communities`/`entityDetails`/\n`path` are purely host-supplied data, rendered as given. `hiddenTypes`/`selectedNodeId`/\n`searchQuery`/`pinnedNodeIds` are this component's own genuinely new contribution: it wires them\ninto `lr-graph`'s existing controlled props (`hiddenTypes`, `selectedNodeIds`, `dimmedNodeIds`,\n`dimmedLinkIds`) itself, toggling its own copy on interaction (the same self-toggle-then-emit\ncontract `lr-graph-legend` already uses) so every feature works with zero host wiring, while\nstill being presettable/observable properties and emitting events (`lr-pin-change`,\n`lr-path-request`, plus every composed primitive's own event bubbling straight through\nunmodified) for a host that wants to persist or react to them.\n\n`highlight` controls what drives that dimming, on top of the always-active search-match\ndimming: `'selection'` (the default) dims by the selected node's immediate neighborhood;\n`'hover'` also dims by whichever node is currently pointer-hovered (falling back to the selected\nnode's neighborhood while nothing is hovered); `'none'` turns this component's own dimming off\nentirely, forwarding empty `dimmedNodeIds`/`dimmedLinkIds` regardless of search/selection state\n-- for a host that wants to drive `lr-graph`'s dimming through a different composition instead.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `details` | Overrides the details popover's default content (an `lr-entity-card` with a nested `lr-neighbor-list` and a pin toggle). Receives no data -- a consumer overriding this slot reads the selected entity from `selectedNodeId`/`nodes` itself. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root `role=\"group\"` wrapper. |\n| `detail-card` | The default-content `lr-entity-card`, only present while `selectedNodeId` resolves to a node. |\n| `detail-popover` | The composed `lr-popover` hosting the details overlay. |\n| `graph` | The composed `lr-graph`. |\n| `legend` | The composed `lr-graph-legend`. |\n| `path` | The composed `lr-path-strip`, only rendered while `path` is non-empty. |\n| `pinned` | The pinned-nodes row, only rendered while `pinnedNodeIds` is non-empty. |\n| `pinned-heading` | The pinned-nodes row's leading label. |\n| `search` | The composed `lr-entity-card` search `lr-input`. |\n| `search-empty` | The \"no matches\" message, shown when `searchQuery` is non-empty but no node matches. |\n| `search-result` | One search-match row (`role=\"listitem\"`, wrapping a `<button>`). |\n| `search-results` | The search-match list, only rendered while `searchQuery` is non-empty. |\n| `toolbar` | The row wrapping the search input and the type-filter legend. |",
9235
+ "description": "`<lr-knowledge-graph-explorer>` — an orchestration-level surface for exploring a knowledge\ngraph: the `lr-graph` canvas plus entity search, type filters, neighborhood expansion, pinned\nnodes, path finding between pins, node selection, and a details overlay. Composes existing\nprimitives rather than re-implementing graph rendering: `lr-graph` (canvas/pan-zoom/selection),\n`lr-graph-legend` (type filters), `lr-entity-card` (the details popover's default content),\n`lr-neighbor-list` (the selected entity's relationships), `lr-path-strip` (a found path), and\n`lr-popover.showAt()` (the details overlay itself).\n\n**How the details popover finds its viewport position.** `lr-graph.getNodePosition()` and the\n`lr-node-click` event's `{ x, y }` are in the graph's own *local drawing space* (pre pan/zoom),\nnever viewport pixels -- passing them straight to `showAt()` would anchor the popover at the\nwrong place as soon as the graph has panned or zoomed even once. A direct node click resolves\nthe correct viewport rect the way this library's own documented `lr-graph` + `lr-popover.showAt()`\ncomposition does: for `renderer=\"svg\"` (the default), `event.composedPath()` (the native `click`\nthat bubbles out of `lr-graph`'s shadow root) locates the actual clicked `[part=\"node\"]` element,\nwhose `getBoundingClientRect()` is already viewport-relative; for `renderer=\"canvas\"` (no\nper-node DOM element to find), the click event's own `clientX`/`clientY` are used directly, since\ncanvas hit-testing already treats those as viewport coordinates internally. While the popover\nstays open after an `renderer=\"svg\"` click, this component re-reads that same resolved node\nelement's `getBoundingClientRect()` and re-calls `showAt()` every time the composed `lr-graph`\nemits its own `lr-viewport-change` (a frame-coalesced pan/zoom/simulation-tick signal) --\nschedules no `requestAnimationFrame` loop of its own, unlike an idle popover polling the DOM on\nevery frame regardless of whether anything actually moved. Selecting a node any other\nway -- a search result, a neighbor row, a path-strip element, keyboard Enter/Space on a graph\nnode (which never dispatches a native `click`) -- has no click event to read a rect from, so it\ninstead calls the public `lr-graph.focusNode(id)` (which centers that node in the viewport) and\nthen anchors the popover at the graph element's own `getBoundingClientRect()` center once that\nsettles; no continuous tracking applies to that path.\n\n**Controlled vs. self-managed state.** `nodes`/`links`/`nodeTypes`/`communities`/`entityDetails`/\n`path` are purely host-supplied data, rendered as given. `hiddenTypes`/`selectedNodeId`/\n`searchQuery`/`pinnedNodeIds` are this component's own genuinely new contribution: it wires them\ninto `lr-graph`'s existing controlled props (`hiddenTypes`, `selectedNodeIds`, `dimmedNodeIds`,\n`dimmedLinkIds`) itself, toggling its own copy on interaction (the same self-toggle-then-emit\ncontract `lr-graph-legend` already uses) so every feature works with zero host wiring, while\nstill being presettable/observable properties and emitting events (`lr-selection-change`,\n`lr-pin-change`, `lr-path-request`, plus every composed primitive's own event bubbling straight through\nunmodified) for a host that wants to persist or react to them.\n\n`highlight` controls what drives that dimming, on top of the always-active search-match\ndimming: `'selection'` (the default) dims by the selected node's immediate neighborhood;\n`'hover'` also dims by whichever node is currently pointer-hovered (falling back to the selected\nnode's neighborhood while nothing is hovered); `'none'` turns this component's own dimming off\nentirely, forwarding empty `dimmedNodeIds`/`dimmedLinkIds` regardless of search/selection state\n-- for a host that wants to drive `lr-graph`'s dimming through a different composition instead.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `details` | Overrides the details popover's default content (an `lr-entity-card` with a nested `lr-neighbor-list` and a pin toggle). Receives no data -- a consumer overriding this slot reads the selected entity from `selectedNodeId`/`nodes` itself. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root `role=\"group\"` wrapper. |\n| `detail-card` | The default-content `lr-entity-card`, only present while `selectedNodeId` resolves to a node. |\n| `detail-popover` | The composed `lr-popover` hosting the details overlay. |\n| `graph` | The composed `lr-graph`. |\n| `legend` | The composed `lr-graph-legend`. |\n| `path` | The composed `lr-path-strip`, only rendered while `path` is non-empty. |\n| `pinned` | The pinned-nodes row, only rendered while `pinnedNodeIds` is non-empty. |\n| `pinned-heading` | The pinned-nodes row's leading label. |\n| `search` | The composed `lr-entity-card` search `lr-input`. |\n| `search-empty` | The \"no matches\" message, shown when `searchQuery` is non-empty but no node matches. |\n| `search-result` | One search-match row (`role=\"listitem\"`, wrapping a `<button>`). |\n| `search-results` | The search-match list, only rendered while `searchQuery` is non-empty. |\n| `toolbar` | The row wrapping the search input and the type-filter legend. |",
9228
9236
  "attributes": [
9229
9237
  {
9230
9238
  "name": "height",
@@ -9627,7 +9635,7 @@
9627
9635
  },
9628
9636
  {
9629
9637
  "name": "stack-totals",
9630
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
9638
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
9631
9639
  "value": {
9632
9640
  "type": [
9633
9641
  "boolean"
@@ -9692,7 +9700,7 @@
9692
9700
  },
9693
9701
  {
9694
9702
  "name": "lr-lite-chart",
9695
- "description": "`<lr-lite-chart>` — a dependency-free bar/line chart, plain SVG/DOM\nrendering with zero peer dependencies (unlike `lr-chart`, which wraps\n`chart.js`). For a project whose architecture forbids a charting\ndependency outright, this covers the common bar/line case: grouped or\nstacked bars, multi-series lines, per-point click, and hover tooltips\n(native SVG `<title>`, no positioning JS needed) — not a full `lr-chart`\nreplacement (no zoom/pan, no pie/doughnut/radar/scatter/bubble types, no\nhorizontal/dual-y-axis, no raw-config passthrough).\n\nBecause this renders real DOM (not canvas), it reuses `lr-chart`'s\n`--lr-chart-*` theme tokens directly via CSS `var()` — no\n`getComputedStyle()`-based re-theming step is needed the way `chart.ts`\nneeds one for its canvas.\n\nBy default (`layout=\"fit\"`) the plot always squeezes to the measured host\nwidth. Three independent, opt-in escape hatches for dense/aligned data:\n`layout=\"scroll\"` (+ `barWidth`) gives every bar a fixed pixel width and\nlets the plot overflow the host horizontally (scrollable) instead of\nsqueezing; `maxLabels` decimates which x-axis text labels render (bars\nalways still render) once there are more categories than that; and\n`barX` lets a consumer hand in its own per-category x-coordinate function\n— e.g. to pixel-align this chart's bars with a sibling `lr-heatmap`'s\ncalendar columns — overriding the internal slot math for both bars and\ntheir labels. All three are additive and no-ops when left unset.\n\nSeven further additive, opt-in properties: `pointText` overrides the\nper-bar/per-point `<title>`/`aria-label` tooltip text (mirrors\n`lr-heatmap`'s `cellText` hook), falling back to the built-in raw-value\ntemplate when unset; `roundedBars` draws bars as a rounded-top path\ninstead of a square-cornered rect; `skipZero` omits a bar entirely (not\njust zero-height) for an exactly-`0` value; `padLeft`/`barGapRatio`\noverride the internal `PAD_LEFT`/`BAR_GROUP_GAP` layout constants; `scale`\n(`type=\"bar\"` only) switches the bar-height mapping from the default\nlinear `niceDomain` fraction to a `Math.sqrt(value / domainMax)`\ncompression (mirroring `lr-heatmap`'s matrix-mode `sqrt` scale) so a\nskewed dataset's smaller bars don't get washed out by one dominant value\n— gridlines/tick labels stay on the linear domain regardless, only the bar\nmarks' own height changes, and `type=\"line\"` ignores `scale` entirely; and\n`hideAxis` suppresses `renderGrid()`'s gridlines/tick labels altogether\n(x-axis category labels, rendered separately, are unaffected). An eighth,\n`legendText`, appends a formatter-supplied string after each series' label in the\nbuilt-in legend row (e.g. a value or share) — no-op while `legend` is unset, matching the same\nfallback-to-unchanged convention as every other hook here;\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `axis-label` | Each axis tick label. |\n| `axis-title` | The x/y axis title text, when set. |\n| `bar` | Each bar rect (type=\"bar\"). Carries `data-selected` and `aria-pressed=\"true\"` when its category index is in `selectedIndex`. |\n| `base` | The host's flex layout wrapper. |\n| `data-list` | A visually hidden list of all plotted data points (single-series only). |\n| `data-table` | A visually hidden category×series data table, rendered instead of `data-list` when there is more than one dataset so a screen-reader user hears series grouping rather than one flattened N×M sequence. |\n| `grid-line` | Each horizontal gridline. |\n| `legend` | The legend row, when `legend` is set. |\n| `legend-item` | Each legend entry. |\n| `legend-swatch` | Each legend entry's color swatch. |\n| `legend-text` | Extra per-item text after the series label, rendered only when `legendText` is set. |\n| `line` | Each series' stroked line path (type=\"line\"). |\n| `live-region` | The current mark announcement for keyboard users. |\n| `point` | Each series' per-point keyboard target (type=\"line\"). Carries `data-selected` and explicit `aria-pressed` state. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-lite-chart-selected-outline-color` (default: `var(--lr-color-brand)`) — Stroke for a bar/point whose category index is in `selectedIndex`.",
9703
+ "description": "`<lr-lite-chart>` — a dependency-free bar/line chart, plain SVG/DOM\nrendering with zero peer dependencies (unlike `lr-chart`, which wraps\n`chart.js`). For a project whose architecture forbids a charting\ndependency outright, this covers the common bar/line case: grouped or\nstacked bars, multi-series lines, per-point click, and hover tooltips\n(native SVG `<title>`, no positioning JS needed) — not a full `lr-chart`\nreplacement (no zoom/pan, no pie/doughnut/radar/scatter/bubble types, no\nhorizontal/dual-y-axis, no raw-config passthrough).\n\nBecause this renders real DOM (not canvas), it reuses `lr-chart`'s\n`--lr-chart-*` theme tokens directly via CSS `var()` — no\n`getComputedStyle()`-based re-theming step is needed the way `chart.ts`\nneeds one for its canvas.\n\nBy default (`layout=\"fit\"`) the plot always squeezes to the measured host\nwidth. Three independent, opt-in escape hatches for dense/aligned data:\n`layout=\"scroll\"` (+ `barWidth`) gives every bar a fixed pixel width and\nlets the plot overflow the host horizontally (scrollable) instead of\nsqueezing; `maxLabels` decimates which x-axis text labels render (bars\nalways still render) once there are more categories than that; and\n`barX` lets a consumer hand in its own per-category x-coordinate function\n— e.g. to pixel-align this chart's bars with a sibling `lr-heatmap`'s\ncalendar columns — overriding the internal slot math for both bars and\ntheir labels. All three are additive and no-ops when left unset.\n\nSeven further additive, opt-in properties: `pointText` overrides the\nper-bar/per-point `<title>`/`aria-label` tooltip text (mirrors\n`lr-heatmap`'s `cellText` hook), falling back to the built-in raw-value\ntemplate when unset; `roundedBars` draws bars as a rounded-top path\ninstead of a square-cornered rect; `skipZero` omits a bar entirely (not\njust zero-height) for an exactly-`0` value; `padLeft`/`barGapRatio`\noverride the internal `PAD_LEFT`/`BAR_GROUP_GAP` layout constants; `scale`\n(`type=\"bar\"` only) switches the bar-height mapping from the default\nlinear `niceDomain` fraction to a `Math.sqrt(value / domainMax)`\ncompression (mirroring `lr-heatmap`'s matrix-mode `sqrt` scale) so a\nskewed dataset's smaller bars don't get washed out by one dominant value\n— gridlines/tick labels stay on the linear domain regardless, only the bar\nmarks' own height changes, and `type=\"line\"` ignores `scale` entirely; and\n`hideAxis` suppresses `renderGrid()`'s gridlines/tick labels altogether\n(x-axis category labels, rendered separately, are unaffected). An eighth,\n`legendText`, appends a formatter-supplied string after each series' label in the\nbuilt-in legend row (e.g. a value or share) — no-op while `legend` is unset, matching the same\nfallback-to-unchanged convention as every other hook here. The built-in multi-series accessible\ntable can independently format its finite numeric cells through `tableCellFormatter`; for a\nstacked bar chart, `tableTotals` adds an opt-in localized total column. Both are no-ops when\nunset.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `axis-label` | Each axis tick label. |\n| `axis-title` | The x/y axis title text, when set. |\n| `bar` | Each bar rect (type=\"bar\"). Carries `data-selected` and `aria-pressed=\"true\"` when its category index is in `selectedIndex`. |\n| `base` | The host's flex layout wrapper. |\n| `data-list` | A visually hidden list of all plotted data points (single-series only). |\n| `data-table` | A visually hidden category×series data table, rendered instead of `data-list` when there is more than one dataset so a screen-reader user hears series grouping rather than one flattened N×M sequence. |\n| `grid-line` | Each horizontal gridline. |\n| `legend` | The legend row, when `legend` is set. |\n| `legend-item` | Each legend entry. |\n| `legend-swatch` | Each legend entry's color swatch. |\n| `legend-text` | Extra per-item text after the series label, rendered only when `legendText` is set. |\n| `line` | Each series' stroked line path (type=\"line\"). |\n| `live-region` | The current mark announcement for keyboard users. |\n| `point` | Each series' per-point keyboard target (type=\"line\"). Carries `data-selected` and explicit `aria-pressed` state. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-lite-chart-selected-outline-color` (default: `var(--lr-color-brand)`) — Stroke for a bar/point whose category index is in `selectedIndex`.",
9696
9704
  "attributes": [
9697
9705
  {
9698
9706
  "name": "accessible-label",
@@ -9813,6 +9821,15 @@
9813
9821
  ]
9814
9822
  }
9815
9823
  },
9824
+ {
9825
+ "name": "table-totals",
9826
+ "description": "Adds a localized total column to the built-in multi-series accessible table for a stacked\nbar chart. Ignored for grouped bars and line charts.\n\nType: `boolean` \nDefault: `false`",
9827
+ "value": {
9828
+ "type": [
9829
+ "boolean"
9830
+ ]
9831
+ }
9832
+ },
9816
9833
  {
9817
9834
  "name": "type",
9818
9835
  "description": "Type: `LyraLiteChartType` \nDefault: `'bar'`",
@@ -9982,7 +9999,7 @@
9982
9999
  },
9983
10000
  {
9984
10001
  "name": "lr-map",
9985
- "description": "`<lr-map>` — a maplibre-gl wrapper with a declarative legend, choropleth\nGeoJSON layer, markers, and additive `dataLayers` GeoJSON overlays\n(arbitrary shapes rendered as a source plus fill/line/circle layers,\nindependent of `choropleth`'s field/stops color-interpolation), plus a raw\n`map` escape hatch. Requires the optional peer dep `maplibre-gl`\n(consumers also import its CSS and configure its module-worker URL once).\nMapLibre v6 is ESM-only and requires WebGL2.\n\nThe underlying `maplibregl.Map` — and the WebGL context it opens — isn't\nconstructed until this element is first visible in the viewport (tracked\nvia `IntersectionObserver`), even once the `maplibre-gl` peer dependency\nhas finished loading. Browsers hard-cap concurrent WebGL contexts per\npage, so a grid/dashboard of many `<lr-map>` instances only constructs\nthe ones actually on-screen instead of racing to exhaust that budget the\ninstant each one mounts. `map` stays `undefined` (and `lr-map-load`\ndoesn't fire) until construction actually happens.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The map wrapper. |\n| `container` | The maplibre container. |\n| `error` | `role=\"alert\"` message shown instead of `container` if the optional `maplibre-gl` peer dependency fails to load (e.g. not installed). ⚠️ The default `mapStyle` (when unset) uses OpenStreetMap's demo tile server, which is not suitable for production traffic — see the `DEFAULT_STYLE` doc comment above. Always pass an explicit `mapStyle` in production. |\n| `legend` | The map legend. |\n| `legend-swatch` | A legend color swatch. |",
10002
+ "description": "`<lr-map>` — a maplibre-gl wrapper with a declarative legend, choropleth\nGeoJSON layer, markers, and additive `dataLayers` GeoJSON overlays\n(arbitrary shapes rendered as a source plus fill/line/circle layers,\nindependent of `choropleth`'s field/stops color-interpolation), plus a raw\n`map` escape hatch. Requires the optional peer dep `maplibre-gl`\nv5 or v6 (consumers also import its CSS). MapLibre v6 is ESM-only, requires WebGL2, and needs\nits module-worker URL configured once; v5's standard build includes its worker.\n\nThe underlying `maplibregl.Map` — and the WebGL context it opens — isn't\nconstructed until this element is first visible in the viewport (tracked\nvia `IntersectionObserver`), even once the `maplibre-gl` peer dependency\nhas finished loading. Browsers hard-cap concurrent WebGL contexts per\npage, so a grid/dashboard of many `<lr-map>` instances only constructs\nthe ones actually on-screen instead of racing to exhaust that budget the\ninstant each one mounts. `map` stays `undefined` (and `lr-map-load`\ndoesn't fire) until construction actually happens.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The map wrapper. |\n| `container` | The maplibre container. |\n| `error` | `role=\"alert\"` message shown instead of `container` if the optional `maplibre-gl` peer dependency fails to load (e.g. not installed). ⚠️ The default `mapStyle` (when unset) uses OpenStreetMap's demo tile server, which is not suitable for production traffic — see the `DEFAULT_STYLE` doc comment above. Always pass an explicit `mapStyle` in production. |\n| `legend` | The map legend. |\n| `legend-swatch` | A legend color swatch. |",
9986
10003
  "attributes": [
9987
10004
  {
9988
10005
  "name": "center",
@@ -10467,7 +10484,7 @@
10467
10484
  },
10468
10485
  {
10469
10486
  "name": "lr-menu",
10470
- "description": "`<lr-menu>` — an anchored dropdown of `<lr-menu-item>` actions, opened\nfrom a consumer-supplied trigger (typically an icon button). A close, drop-\nin-shaped replacement for reaching outside this library for a third-party\ndropdown to build a gear menu, an avatar menu, or a history row's overflow\nmenu: click the trigger, a positioned menu appears, clicking an item both\nperforms the action *and* closes the menu.\n\n**ARIA pattern — `role=\"menu\"`/`role=\"menuitem\"` with real roving DOM\nfocus, not a listbox.** Two coherent, mutually-exclusive shapes were\navailable here: (a) `role=\"listbox\"`/`role=\"option\"` with\n`aria-activedescendant`, the pattern `<lr-select>`'s trigger-button +\npopup listbox uses, where DOM focus never leaves the trigger; or (b)\n`role=\"menu\"`/`role=\"menuitem\"` with real focus moving between actual\nfocusable rows, the WAI-ARIA \"menu button\" pattern. This picks (b):\n`<lr-menu-item>` rows are real, independently-focusable elements (see\nthat class's own doc), which is the more natural fit for a menu\nspecifically — unlike a listbox's rows, a menu's rows are conventionally\nbutton-/link-shaped, and every well-known native/OS menu (and this\nfamily's own `<lr-tree>`/`<lr-tree-node>` pair, which this component's\nroving-tabindex plumbing directly mirrors) already moves real focus rather\nthan merely a virtual `aria-activedescendant` pointer. `role`/`tabIndex`\nare consistently the menu-button shape throughout — never mixed with\nlistbox/option.\n\nInteraction contract (mirrors the WAI-ARIA APG \"menu button\" pattern):\n- Click the trigger (or Enter/Space on it, via the trigger's own native\n `click` activation) toggles the menu, moving focus to the first\n non-disabled item on open.\n- ArrowDown/ArrowUp on the trigger while closed also open it, focusing the\n first/last non-disabled item respectively.\n- Once open, ArrowDown/ArrowUp move the roving focus among non-disabled\n items (wrapping past either end — the recommended, and more common,\n menu-widget behavior, unlike `<lr-select>`'s clamped listbox nav).\n Home/End jump to the first/last non-disabled item. Enter/Space activate\n the focused item. Escape closes and returns focus to the trigger. A\n printable keypress runs type-ahead: roving focus jumps to the next\n non-disabled item whose text starts with the accumulated buffer, cycling\n from just after the active item (mirrors `<lr-select>`'s identical\n listbox type-ahead). All of the above (except Escape and Tab) only\n respond to keydowns from a real `<lr-menu-item>` target, so a slotted\n non-item control (e.g. a date input) keeps its own full default keyboard\n behavior.\n- Tab never traps focus and never calls `preventDefault()` — the browser's\n own Tab navigation always proceeds untouched. It closes the menu only\n when focus is on its way *out* of the popup: with a focusable in the\n `header`/`footer` region on the far side of the keypress, the menu stays\n open so native Tab can carry focus there instead. With neither region\n filled, Tab closes exactly as it always has. Tabbing past the popup's\n last focusable in either direction closes it too, including from slotted\n non-item content — which previously left the menu open while focus\n walked away.\n- Escape from `header`/`footer` content closes the menu and refocuses the\n trigger unconditionally, mirroring `<lr-popover>`'s handling of arbitrary\n popup content. `closeOnEscapeAnywhere` governs only the *legacy* shape —\n non-item content slotted into the **default** slot — and defaults to\n `false`, so existing consumers keep today's behavior unchanged.\n- A click outside both the trigger and the open popup closes it (mirrors\n `<lr-select>`'s `onDocPointer` exactly) — this does *not* refocus the\n trigger, since the outside click itself already moved focus somewhere\n the user chose; Escape and a committed selection *do* refocus the\n trigger, since those are dismissals with nowhere else for focus to go.\n\n`show(focus?)` and `hide(options?)` are the public imperative pair, for the cases the trigger\ncan't express: a slotted \"Apply\"/\"Done\" button inside the menu, a keyboard shortcut, a parent\nrestoring UI state. `hide({ focusTrigger: true })` is the one that also returns DOM focus to the\ntrigger — use it whenever the interaction that closed the menu hasn't already put focus\nsomewhere the user chose. Writing `open` directly still works and is fully equivalent apart from\nthe focus moves: the roving-tabindex reset is centralized in `updated()`, so `el.open = false`\nnever leaves a stale `tabindex=\"0\"` tab stop on the last active item.\n\nThe trigger element itself is read from the `trigger` slot's assigned element (first one, if\nseveral are assigned) and enhanced imperatively with\n`aria-haspopup=\"menu\"`/`aria-expanded`/`aria-controls` — the same \"reach into a consumer-owned\nlight-DOM element to complete its a11y wiring\" approach `<lr-dialog>` documents for its own\nheading detection. `aria-controls` targets this menu host (which receives a stable generated\n`id` only when the consumer did not supply one), rather than a shadow-private popup id, so the\nrelationship is resolvable from the trigger's root. `<lr-button>` and `<lr-icon-button>` observe\nthose attributes, forward the popup/expanded values to their shadow-internal native controls,\nand resolve the controls element-reference onto that focused control.\n\nThe popup is always rendered (never `display:none`) so `.focus()` calls on\nits content work synchronously the instant it opens — visually hidden via\n`visibility`/`opacity` instead (identical to `<lr-select>`'s own\n`[part=\"listbox\"]`). `visibility` is an inherited CSS property that\npierces the `<slot>` projection boundary, so every closed-state\n`<lr-menu-item>` is automatically excluded from sequential (Tab-key)\nnavigation with no separate JS bookkeeping.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | `<lr-menu-item>` elements, plus optionally plain `<hr>` dividers between groups (native `<hr>` already carries an implicit `separator` role, matching what `role=\"menu\"` expects between item groups). Arbitrary non-item content still renders here for backward compatibility, but the `header`/`footer` slots below are the supported place for it. |\n| `footer` | Same as `header`, rendered below the items — an \"Apply\"/\"Done\" button, a link to a fuller settings page, a count. |\n| `header` | Composed content rendered above the items and *outside* the `role=\"menu\"` list — a filter/search field, a section title, a summary row. Keeps its own full default keyboard behavior, is reachable with Tab from the items, and is ARIA-valid (arbitrary content inside `role=\"menu\"` is not). Collapses to no box at all while unfilled. |\n| `trigger` | The consumer's own trigger element (typically an icon button). Clicking it toggles the menu; it's positioned against via `internal/positioner.js`'s `place()`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `footer` | The wrapper around the `footer` slot, below the list and outside `role=\"menu\"`. `display: none` while the slot is unfilled. |\n| `header` | The wrapper around the `header` slot, above the list and outside `role=\"menu\"`. `display: none` while the slot is unfilled. |\n| `list` | The `role=\"menu\"` container wrapping the default slot. |\n| `popup` | The positioned floating panel. |\n| `trigger` | The wrapper around the `trigger` slot (the positioning anchor). |",
10487
+ "description": "`<lr-menu>` — an anchored dropdown of `<lr-menu-item>` actions, opened\nfrom a consumer-supplied trigger (typically an icon button). A close, drop-\nin-shaped replacement for reaching outside this library for a third-party\ndropdown to build a gear menu, an avatar menu, or a history row's overflow\nmenu: click the trigger, a positioned menu appears, clicking an item both\nperforms the action *and* closes the menu.\n\n**ARIA pattern — `role=\"menu\"`/`role=\"menuitem\"` with real roving DOM\nfocus, not a listbox.** Two coherent, mutually-exclusive shapes were\navailable here: (a) `role=\"listbox\"`/`role=\"option\"` with\n`aria-activedescendant`, the pattern `<lr-select>`'s trigger-button +\npopup listbox uses, where DOM focus never leaves the trigger; or (b)\n`role=\"menu\"`/`role=\"menuitem\"` with real focus moving between actual\nfocusable rows, the WAI-ARIA \"menu button\" pattern. This picks (b):\n`<lr-menu-item>` rows are real, independently-focusable elements (see\nthat class's own doc), which is the more natural fit for a menu\nspecifically — unlike a listbox's rows, a menu's rows are conventionally\nbutton-/link-shaped, and every well-known native/OS menu (and this\nfamily's own `<lr-tree>`/`<lr-tree-node>` pair, which this component's\nroving-tabindex plumbing directly mirrors) already moves real focus rather\nthan merely a virtual `aria-activedescendant` pointer. `role`/`tabIndex`\nare consistently the menu-button shape throughout — never mixed with\nlistbox/option.\n\nInteraction contract (mirrors the WAI-ARIA APG \"menu button\" pattern):\n- Click the trigger (or Enter/Space on it, via the trigger's own native\n `click` activation) toggles the menu, moving focus to the first\n non-disabled item on open.\n- ArrowDown/ArrowUp on the trigger while closed also open it, focusing the\n first/last non-disabled item respectively.\n- Once open, ArrowDown/ArrowUp move the roving focus among non-disabled\n items (wrapping past either end — the recommended, and more common,\n menu-widget behavior, unlike `<lr-select>`'s clamped listbox nav).\n Home/End jump to the first/last non-disabled item. Enter/Space activate\n the focused item. Escape closes and returns focus to the trigger. A\n printable keypress runs type-ahead: roving focus jumps to the next\n non-disabled item whose text starts with the accumulated buffer, cycling\n from just after the active item (mirrors `<lr-select>`'s identical\n listbox type-ahead). All of the above (except Escape and Tab) only\n respond to keydowns from a real `<lr-menu-item>` target, so a slotted\n non-item control (e.g. a date input) keeps its own full default keyboard\n behavior.\n- Tab never traps focus and never calls `preventDefault()` — the browser's\n own Tab navigation always proceeds untouched. It closes the menu only\n when focus is on its way *out* of the popup: with a focusable in the\n `header`/`footer` region on the far side of the keypress, the menu stays\n open so native Tab can carry focus there instead. With neither region\n filled, Tab closes exactly as it always has. Tabbing past the popup's\n last focusable in either direction closes it too, including from slotted\n non-item content — which previously left the menu open while focus\n walked away.\n- Escape from `header`/`footer` content closes the menu and refocuses the\n trigger unconditionally, mirroring `<lr-popover>`'s handling of arbitrary\n popup content. `closeOnEscapeAnywhere` governs only the *legacy* shape —\n non-item content slotted into the **default** slot — and defaults to\n `false`, so existing consumers keep today's behavior unchanged.\n- A click outside both the trigger and the open popup closes it (mirrors\n `<lr-select>`'s `onDocPointer` exactly) — this does *not* refocus the\n trigger, since the outside click itself already moved focus somewhere\n the user chose; Escape and a committed selection *do* refocus the\n trigger, since those are dismissals with nowhere else for focus to go.\n\n`show(focus?)` and `hide(options?)` are the public imperative pair, for the cases the trigger\ncan't express: a slotted \"Apply\"/\"Done\" button inside the menu, a keyboard shortcut, a parent\nrestoring UI state. `hide({ focusTrigger: true })` is the one that also returns DOM focus to the\ntrigger — use it whenever the interaction that closed the menu hasn't already put focus\nsomewhere the user chose. Writing `open` directly still works and is fully equivalent apart from\nthe focus moves: the roving-tabindex reset is centralized in `updated()`, so `el.open = false`\nnever leaves a stale `tabindex=\"0\"` tab stop on the last active item.\n\nThe trigger element itself is read from the `trigger` slot's assigned element (first one, if\nseveral are assigned) and enhanced imperatively with\n`aria-haspopup=\"menu\"`/`aria-expanded`/`aria-controls` — the same \"reach into a consumer-owned\nlight-DOM element to complete its a11y wiring\" approach `<lr-dialog>` documents for its own\nheading detection. `aria-controls` targets this menu host (which receives a stable generated\n`id` only when the consumer did not supply one), rather than a shadow-private popup id, so the\nrelationship is resolvable from the trigger's root. `<lr-button>` and `<lr-icon-button>` observe\nthose attributes, forward the popup/expanded values to their shadow-internal native controls,\nand resolve the controls element-reference onto that focused control. In supporting browsers,\nassigning the element reference intentionally clears the internal control's serialized\n`aria-controls` value; `ariaControlsElements` is the relationship's source of truth. Browsers\nwithout the reflected element-reference API retain the string as a best-effort fallback.\n\nThe popup is always rendered (never `display:none`) so `.focus()` calls on\nits content work synchronously the instant it opens — visually hidden via\n`visibility`/`opacity` instead (identical to `<lr-select>`'s own\n`[part=\"listbox\"]`). `visibility` is an inherited CSS property that\npierces the `<slot>` projection boundary, so every closed-state\n`<lr-menu-item>` is automatically excluded from sequential (Tab-key)\nnavigation with no separate JS bookkeeping.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | `<lr-menu-item>` elements, plus optionally plain `<hr>` dividers between groups (native `<hr>` already carries an implicit `separator` role, matching what `role=\"menu\"` expects between item groups). Arbitrary non-item content still renders here for backward compatibility, but the `header`/`footer` slots below are the supported place for it. |\n| `footer` | Same as `header`, rendered below the items — an \"Apply\"/\"Done\" button, a link to a fuller settings page, a count. |\n| `header` | Composed content rendered above the items and *outside* the `role=\"menu\"` list — a filter/search field, a section title, a summary row. Keeps its own full default keyboard behavior, is reachable with Tab from the items, and is ARIA-valid (arbitrary content inside `role=\"menu\"` is not). Collapses to no box at all while unfilled. |\n| `trigger` | The consumer's own trigger element (typically an icon button). Clicking it toggles the menu; it's positioned against via `internal/positioner.js`'s `place()`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `footer` | The wrapper around the `footer` slot, below the list and outside `role=\"menu\"`. `display: none` while the slot is unfilled. |\n| `header` | The wrapper around the `header` slot, above the list and outside `role=\"menu\"`. `display: none` while the slot is unfilled. |\n| `list` | The `role=\"menu\"` container wrapping the default slot. |\n| `popup` | The positioned floating panel. |\n| `trigger` | The wrapper around the `trigger` slot (the positioning anchor). |",
10471
10488
  "attributes": [
10472
10489
  {
10473
10490
  "name": "close-on-escape-anywhere",
@@ -12024,7 +12041,7 @@
12024
12041
  },
12025
12042
  {
12026
12043
  "name": "stack-totals",
12027
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
12044
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
12028
12045
  "value": {
12029
12046
  "type": [
12030
12047
  "boolean"
@@ -12261,7 +12278,7 @@
12261
12278
  },
12262
12279
  {
12263
12280
  "name": "stack-totals",
12264
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
12281
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
12265
12282
  "value": {
12266
12283
  "type": [
12267
12284
  "boolean"
@@ -12378,7 +12395,7 @@
12378
12395
  },
12379
12396
  {
12380
12397
  "name": "lr-popover",
12381
- "description": "`<lr-popover>` — a click-triggered, light-dismiss floating surface.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Popover content. |\n| `trigger` | The interactive element that toggles the popover. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `content` | The content wrapper. |\n| `popup` | The positioned popup. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-overlay-max-inline-size` — Maximum inline size of the popup (default `--lr-size-20rem`).",
12398
+ "description": "`<lr-popover>` — a click-triggered, light-dismiss floating surface.\n\nThe slotted trigger receives `aria-haspopup`, `aria-expanded`, and `aria-controls`.\n`aria-controls` targets this public host (which receives a stable generated `id` when the\nconsumer did not supply one), not the shadow-private popup. That keeps the relationship\nresolvable for native triggers and lets `<lr-button>`/`<lr-icon-button>` reflect the host onto\ntheir focused shadow-internal controls through `ariaControlsElements`.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Popover content. |\n| `trigger` | The interactive element that toggles the popover. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `content` | The content wrapper. |\n| `popup` | The positioned popup. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-overlay-max-inline-size` — Maximum inline size of the popup (default `--lr-size-20rem`).",
12382
12399
  "attributes": [
12383
12400
  {
12384
12401
  "name": "aria-label",
@@ -13081,7 +13098,7 @@
13081
13098
  },
13082
13099
  {
13083
13100
  "name": "stack-totals",
13084
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
13101
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
13085
13102
  "value": {
13086
13103
  "type": [
13087
13104
  "boolean"
@@ -14330,7 +14347,7 @@
14330
14347
  },
14331
14348
  {
14332
14349
  "name": "stack-totals",
14333
- "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. Unset (the default) draws nothing.\n\nType: `boolean` \nDefault: `false`",
14350
+ "description": "When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean` \nDefault: `false`",
14334
14351
  "value": {
14335
14352
  "type": [
14336
14353
  "boolean"
@@ -17713,7 +17730,7 @@
17713
17730
  },
17714
17731
  {
17715
17732
  "name": "lr-tooltip",
17716
- "description": "`<lr-tooltip>` — a localized, hover/focus tooltip for a consumer-owned trigger.\nPlain content uses tooltip semantics. When the default slot contains an actionable descendant,\nthe popup promotes to a named dialog and remains open while pointer or focus is inside so its\ncontrols can be reached. Prefer `<lr-popover>` when click-to-open ownership is desired.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Tooltip content. |\n| `trigger` | The element that receives hover/focus listeners. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `popup` | The tooltip popup. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tooltip-max-inline-size` — Maximum inline size of the tooltip (default `--lr-size-20rem`).\n- `--lr-tooltip-background` — Tooltip background color (default `--lr-color-neutral`).\n- `--lr-tooltip-color` — Tooltip text color (default `--lr-color-on-neutral`).",
17733
+ "description": "`<lr-tooltip>` — a localized, hover/focus tooltip for a consumer-owned trigger.\nPlain content uses tooltip semantics. When the default slot contains an actionable descendant,\nthe popup promotes to a named dialog and remains open while pointer or focus is inside so its\ncontrols can be reached. Prefer `<lr-popover>` when click-to-open ownership is desired.\n\nWhile open, the trigger's `aria-describedby` targets a hidden text proxy in this component's\nlight DOM rather than the shadow-private popup. Native triggers can resolve that ID directly;\n`<lr-button>` and `<lr-icon-button>` reflect it onto their focused internal controls through\n`ariaDescribedByElements`, where the serialized internal attribute is intentionally empty.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Tooltip content. |\n| `trigger` | The element that receives hover/focus listeners. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `popup` | The tooltip popup. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tooltip-max-inline-size` — Maximum inline size of the tooltip (default `--lr-size-20rem`).\n- `--lr-tooltip-background` — Tooltip background color (default `--lr-color-neutral`).\n- `--lr-tooltip-color` — Tooltip text color (default `--lr-color-on-neutral`).",
17717
17734
  "attributes": [
17718
17735
  {
17719
17736
  "name": "aria-label",
@@ -20056,6 +20073,10 @@
20056
20073
  "name": "--lr-icon-button-border",
20057
20074
  "description": "**`<lr-icon-button>`** (default: `0`) — Complete border shorthand of the native button."
20058
20075
  },
20076
+ {
20077
+ "name": "--lr-icon-button-border-hover",
20078
+ "description": "**`<lr-icon-button>`** (default: `var(--lr-icon-button-border, 0)`) — Complete border shorthand on hover."
20079
+ },
20059
20080
  {
20060
20081
  "name": "--lr-icon-button-color",
20061
20082
  "description": "**`<lr-icon-button>`** (default: `inherit`) — Icon/text color of the native button."