@aceshooting/lyra-ui 24.0.0 → 24.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 (98) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +4 -11
  3. package/custom-elements.json +1 -1
  4. package/dist/components/conversation/agent-workspace/agent-workspace.class.d.ts +11 -1
  5. package/dist/components/conversation/agent-workspace/agent-workspace.class.js +1 -1
  6. package/dist/components/data/table/table.class.d.ts +14 -3
  7. package/dist/components/data/table/table.class.js +8 -6
  8. package/dist/components/data/table/table.styles.js +1 -1
  9. package/dist/components/forms/swatch-picker/swatch-picker.class.d.ts +3 -1
  10. package/dist/components/forms/swatch-picker/swatch-picker.class.js +1 -1
  11. package/dist/components/overlays/overlay/popover.class.d.ts +11 -3
  12. package/dist/components/overlays/overlay/popover.class.js +1 -1
  13. package/dist/framework-types.d.ts +1 -1
  14. package/dist/internal/default-strings.generated.d.ts +1 -1
  15. package/dist/internal/default-strings.generated.js +1 -1
  16. package/dist/internal/localization-types.d.ts +1 -1
  17. package/dist/internal/localization.js +1 -1
  18. package/dist/internal/package-metadata.d.ts +1 -1
  19. package/dist/internal/package-metadata.js +1 -1
  20. package/dist/internal/positioner.js +1 -1
  21. package/dist/translations/am/data.js +1 -1
  22. package/dist/translations/ar/data.js +1 -1
  23. package/dist/translations/bho/data.js +1 -1
  24. package/dist/translations/bn/data.js +1 -1
  25. package/dist/translations/cs/data.js +1 -1
  26. package/dist/translations/da/data.js +1 -1
  27. package/dist/translations/de/data.js +1 -1
  28. package/dist/translations/el/data.js +1 -1
  29. package/dist/translations/es/data.js +1 -1
  30. package/dist/translations/fa/data.js +1 -1
  31. package/dist/translations/fa-AF/data.js +1 -1
  32. package/dist/translations/fi/data.js +1 -1
  33. package/dist/translations/fr/data.js +1 -1
  34. package/dist/translations/gu/data.js +1 -1
  35. package/dist/translations/ha/data.js +1 -1
  36. package/dist/translations/he/data.js +1 -1
  37. package/dist/translations/hi/data.js +1 -1
  38. package/dist/translations/hr/data.js +1 -1
  39. package/dist/translations/hu/data.js +1 -1
  40. package/dist/translations/id/data.js +1 -1
  41. package/dist/translations/ig/data.js +1 -1
  42. package/dist/translations/it/data.js +1 -1
  43. package/dist/translations/ja/data.js +1 -1
  44. package/dist/translations/jv/data.js +1 -1
  45. package/dist/translations/kk/data.js +1 -1
  46. package/dist/translations/kn/data.js +1 -1
  47. package/dist/translations/ko/data.js +1 -1
  48. package/dist/translations/ln/data.js +1 -1
  49. package/dist/translations/ml/data.js +1 -1
  50. package/dist/translations/mr/data.js +1 -1
  51. package/dist/translations/ms/data.js +1 -1
  52. package/dist/translations/my/data.js +1 -1
  53. package/dist/translations/nb/data.js +1 -1
  54. package/dist/translations/ne/data.js +1 -1
  55. package/dist/translations/nl/data.js +1 -1
  56. package/dist/translations/nn/data.js +1 -1
  57. package/dist/translations/om/data.js +1 -1
  58. package/dist/translations/or/data.js +1 -1
  59. package/dist/translations/pa/data.js +1 -1
  60. package/dist/translations/pcm/data.js +1 -1
  61. package/dist/translations/pl/data.js +1 -1
  62. package/dist/translations/pnb/data.js +1 -1
  63. package/dist/translations/ps/data.js +1 -1
  64. package/dist/translations/pt-BR/data.js +1 -1
  65. package/dist/translations/pt-PT/data.js +1 -1
  66. package/dist/translations/ro/data.js +1 -1
  67. package/dist/translations/ru/data.js +1 -1
  68. package/dist/translations/sd/data.js +1 -1
  69. package/dist/translations/sl/data.js +1 -1
  70. package/dist/translations/su/data.js +1 -1
  71. package/dist/translations/sv/data.js +1 -1
  72. package/dist/translations/sw/data.js +1 -1
  73. package/dist/translations/ta/data.js +1 -1
  74. package/dist/translations/te/data.js +1 -1
  75. package/dist/translations/th/data.js +1 -1
  76. package/dist/translations/tl/data.js +1 -1
  77. package/dist/translations/tr/data.js +1 -1
  78. package/dist/translations/uk/data.js +1 -1
  79. package/dist/translations/ur/data.js +1 -1
  80. package/dist/translations/uz/data.js +1 -1
  81. package/dist/translations/vi/data.js +1 -1
  82. package/dist/translations/yo/data.js +1 -1
  83. package/dist/translations/zh-CN/data.js +1 -1
  84. package/dist/translations/zh-TW/data.js +1 -1
  85. package/dist/translations/zu/data.js +1 -1
  86. package/llms/components/lr-agent-workspace.md +23 -1
  87. package/llms/components/lr-popover.md +15 -5
  88. package/llms/components/lr-swatch-picker.md +3 -2
  89. package/llms/components/lr-table.md +14 -1
  90. package/llms/shared/events-and-types.md +8 -8
  91. package/llms/shared/styles-and-tokens.md +97 -0
  92. package/llms/shared/testing-and-utilities.md +4 -1
  93. package/llms/shared.md +109 -9
  94. package/locales.json +138 -138
  95. package/package.json +2 -2
  96. package/registrations.json +1 -1
  97. package/vscode-html-data.json +1 -1
  98. package/web-types.json +1 -1
@@ -24,7 +24,7 @@ Every one of those names is also typed — per component through its own event m
24
24
  through `@aceshooting/lyra-ui/events` for listeners on an ancestor, `document` or `window`. See
25
25
  "TypeScript" below.
26
26
 
27
- For the manually reviewed, retained event-detail compatibility fields in the v23-to-v24 upgrade,
27
+ For event-detail compatibility fields removed in the v23-to-v24 upgrade,
28
28
  use step 7 of the [migration checklist](v23-to-v24-migration.md#migrate-a-project-in-reviewable-steps).
29
29
  Those nested detail fields are separate from deprecated event names and are not automatic renames.
30
30
 
@@ -36,7 +36,7 @@ Those nested detail fields are separate from deprecated event names and are not
36
36
  ```ts
37
37
  import { LyraTable } from "@aceshooting/lyra-ui/components/data/table/table.class.js";
38
38
  const table = document.querySelector("lr-table") as LyraTable;
39
- table.addEventListener("lr-sort", (event) => event.detail.key); // typed
39
+ table.addEventListener("lr-sort", (event) => event.detail.sortKey); // typed
40
40
  ```
41
41
  - **`HTMLElementTagNameMap`** is augmented in the `.class.d.ts` files. `document.querySelector('lr-table')`
42
42
  is only typed as `LyraTable` when that class module is in the type graph — importing just the
@@ -75,13 +75,13 @@ Those nested detail fields are separate from deprecated event names and are not
75
75
  `LyraGlobalEventMap` is exported as well, for writing your own typed helper over it.
76
76
 
77
77
  - **The surface is per-event type aliases, not runtime event classes.** `LyraSortEvent` and its
78
- generated siblings are `type` aliases over the owning component's own map entry
79
- (`LyraTableEventMap['lr-sort']`) — there is nothing to `new`, and `instanceof LyraSortEvent` is
80
- not a thing. The module compiles to `export {};`: shipping runtime event subclasses to type a
81
- listener would cost every consumer runtime bytes for a compile-time concern, so it deliberately
82
- costs zero.
78
+ generated siblings are `type` aliases over component event-map entries. `LyraSortEvent` unions
79
+ the `lr-sort` entries for document-library, eval-dataset and table. These aliases have no runtime
80
+ constructor and cannot be used with `new` or `instanceof`. The module compiles to `export {};`:
81
+ shipping runtime event subclasses to type a listener would cost every consumer runtime bytes for
82
+ a compile-time concern, so it deliberately costs zero.
83
83
  - **A shared event name narrows to the union of its dispatchers.** One name can come from several
84
- components with different details — `lr-select` from five, `lr-selection-change` from five — so
84
+ components with different details, such as `lr-select` and `lr-selection-change`, so
85
85
  its global entry is the _union_ of their entries, and `event.detail` there exposes only what all
86
86
  of them share. Index the owning component's own map when you need one component's exact detail:
87
87
 
@@ -73,6 +73,103 @@ See [Where an override actually reaches](#where-an-override-actually-reaches) be
73
73
  inheritance rules, including the one documented exception (per-component `--lr-<component>-*`
74
74
  hooks, layer 3, which do inherit through wrappers).
75
75
 
76
+ ### Lyra signature starter
77
+
78
+ Use this application profile for new projects unless explicit branding or user choices override it.
79
+ It is a composition recommendation, not a change to Lyra's runtime defaults. Existing applications
80
+ adopt it only during an authorized migration or redesign; valid saved style and locale choices win.
81
+
82
+ ```css
83
+ @import "@aceshooting/lyra-ui/theme.css";
84
+ @import "@aceshooting/lyra-ui/tokens-root.css";
85
+ @import "@aceshooting/lyra-ui/looks/shadcn.css";
86
+ @import "@aceshooting/lyra-ui/surfaces/glass.css";
87
+ @import "@aceshooting/lyra-ui/accents.css";
88
+ ```
89
+
90
+ The first-use choices are independent axes:
91
+
92
+ ```ts
93
+ import { setLyraStyle } from '@aceshooting/lyra-ui/theme.js';
94
+
95
+ // Apply only when initializing the application's unsaved choices.
96
+ setLyraStyle({ look: 'shadcn', surface: 'glass', accent: 'emerald', mode: 'system' });
97
+ ```
98
+
99
+ Do not run that assignment unconditionally on every visit. Restore saved choices through the
100
+ published style runtime; use `parseLyraStyleRecord()` when validating a persisted record, and
101
+ `setLyraStyle()` to normalize browser color inputs. Preserve valid custom accents, semantic-role
102
+ palettes, runtime looks, overrides, and historical v1 records. Fill missing or invalid choices from
103
+ the application profile without overwriting independently saved axes. An application Reset action
104
+ restores this profile: `resetLyraStyle()` alone restores the library's defaults instead.
105
+
106
+ For first paint, run the synchronous `lyraThemeBootstrap`, then apply the application's unsaved-axis
107
+ fallback attributes, then load the blocking stylesheets. Use the documented CSP-safe embedding or
108
+ classic-script asset. With empty storage, the bootstrap writes Lyra's library defaults and would
109
+ overwrite earlier Shadcn/glass/Emerald attributes; it has no application-defaults option. With
110
+ denied storage, still apply the application fallbacks after it. Retain valid restored axes and
111
+ record which fallbacks were used, then apply those same choices through `setLyraStyle()` during
112
+ runtime initialization. A later module assignment alone cannot prevent a color flash. Test fresh,
113
+ malformed, partial, legacy, and storage-denied records before modules load and after hydration,
114
+ alongside valid saved choices. Do not copy Lyra's bootstrap, normalizer, or ownership internals.
115
+
116
+ Keep spotlights in application CSS, independent of the chosen control look. The public root-token
117
+ stylesheet makes this static recipe follow both light/dark mode and the current accent:
118
+
119
+ ```css
120
+ body { isolation: isolate; min-block-size: 100svh; background: var(--lr-color-surface); }
121
+ body::before {
122
+ content: '';
123
+ position: fixed;
124
+ inset: 0;
125
+ z-index: -1;
126
+ pointer-events: none;
127
+ background:
128
+ radial-gradient(ellipse 46rem 30rem at 8% 4%, color-mix(in srgb, var(--lr-color-brand) 16%, transparent), transparent 60%),
129
+ radial-gradient(ellipse 40rem 30rem at 96% 22%, color-mix(in srgb, var(--lr-color-brand) 12%, transparent), transparent 58%),
130
+ radial-gradient(ellipse 44rem 32rem at 78% 96%, color-mix(in srgb, var(--lr-color-brand) 9%, transparent), transparent 60%),
131
+ var(--lr-color-surface);
132
+ }
133
+ html[data-lr-contrast='more'] body::before { background: var(--lr-color-surface); }
134
+ @media (forced-colors: active) { body::before { background: Canvas; } }
135
+ ```
136
+
137
+ These are decorative application backgrounds, not an `accentBackground` value: that style field
138
+ accepts absolute colors used as contrast reference surfaces, not gradients or image URLs. Use
139
+ semantic surface/text pairings for content and keep the decorative layer behind it.
140
+
141
+ Use the existing [gemstoneAccentPicker composition](../components/lr-swatch-picker.md#gemstoneaccentpicker--the-signature-accent-selector),
142
+ with its localized caption, nine canonical gemstones, and shared selected-glyph treatment. Keep
143
+ `--lr-swatch-picker-wrap: nowrap`: desktop hit size `1.75rem` and gap `.25rem`; at widths up to
144
+ `30rem`, hit size `1.5rem` and gap `.125rem` (28/4px and 24/2px at a 16px root). Leave its fill size
145
+ unset. Bound the palette to the viewport and provide horizontal overflow for unusually narrow
146
+ allocations or enlarged text; keyboard focus must bring every swatch into view. Do not shrink
147
+ below the component's 24px floor or replace its Arrow/Home/End and RTL behavior.
148
+
149
+ The four separate topbar controls—gemstone, mode, design, language—stay square `2.75rem` targets
150
+ (44px at a 16px root), with localized names and tooltips. Use gemstone, sun/moon and horizontal-slider
151
+ icons, and a country flag for language. Dense gemstone options do not reduce
152
+ those launcher targets. Set the locale picker's `--lr-locale-picker-trigger-height: 2.75rem` and
153
+ use its public flag-only trigger with readable menu entries:
154
+
155
+ ```ts
156
+ import '@aceshooting/lyra-ui/components/lr-locale-picker.js';
157
+ import '@aceshooting/lyra-ui/components/media/flag/flag-peer.js';
158
+ ```
159
+
160
+ ```html
161
+ <lr-locale-picker top-layer trigger-display="flag" option-display="label"
162
+ aria-label="Localized language action"></lr-locale-picker>
163
+ ```
164
+
165
+ Install the optional `@aceshooting/lyra-flags` peer; the granular resolver import loads requested
166
+ flags without a bulk flag import. Leave `withoutFlags` false. Assign `locales` as a property with
167
+ `{ tag, label, country? }` entries: provide readable localized language names and an explicit ISO
168
+ country for regional entries when known, such as `en-US` → `US`. Keep flags as supplementary cues,
169
+ never the only accessible names, and preserve a valid saved locale in the controlled `value`.
170
+ Use the component's flag resolver rather than emoji, invented flag SVGs, or guessed display APIs.
171
+ Verify 320px and desktop, light/dark, RTL, enlarged text, keyboard focus, and saved preferences.
172
+
76
173
  ### Reading the resolved tokens from your own components — `tokens-root.css`
77
174
 
78
175
  The paragraph above is a real problem for any application that has custom elements of its own: they
@@ -320,7 +320,10 @@ void`, and `virtualAnchorFromRect()`** — thin wrapper over `@floating-ui/dom`'
320
320
  `computePosition` + `autoUpdate`. Forces `strategy: 'fixed'` (matching the
321
321
  popup's own `position: fixed` CSS — otherwise it lands offset by the page scroll), middleware
322
322
  `offset(opts.offset ?? 4)`, `flip()`, `shift({ padding: 8 })`, default `placement: 'bottom-start'`.
323
- Returns a cleanup function that stops the `autoUpdate` loop — call it in `disconnectedCallback()`.
323
+ Returns a cleanup function that stops observation and queued updates — call it in `disconnectedCallback()`.
324
+ For `place()`, element-resize notifications coalesce into the next animation frame; initial
325
+ computation, scrolling and layout-shift updates begin immediately. Cleanup cancels a pending
326
+ resize frame.
324
327
  `trackRect()` reports the target's initial viewport rect exactly once before returning, follows
325
328
  later layout/viewport changes, and returns the same cleanup shape.
326
329
  `virtualAnchorFromRect()` adapts a live rectangle provider to the exported `VirtualAnchor`
package/llms/shared.md CHANGED
@@ -394,7 +394,7 @@ Every one of those names is also typed — per component through its own event m
394
394
  through `@aceshooting/lyra-ui/events` for listeners on an ancestor, `document` or `window`. See
395
395
  "TypeScript" below.
396
396
 
397
- For the manually reviewed, retained event-detail compatibility fields in the v23-to-v24 upgrade,
397
+ For event-detail compatibility fields removed in the v23-to-v24 upgrade,
398
398
  use step 7 of the [migration checklist](v23-to-v24-migration.md#migrate-a-project-in-reviewable-steps).
399
399
  Those nested detail fields are separate from deprecated event names and are not automatic renames.
400
400
 
@@ -406,7 +406,7 @@ Those nested detail fields are separate from deprecated event names and are not
406
406
  ```ts
407
407
  import { LyraTable } from "@aceshooting/lyra-ui/components/data/table/table.class.js";
408
408
  const table = document.querySelector("lr-table") as LyraTable;
409
- table.addEventListener("lr-sort", (event) => event.detail.key); // typed
409
+ table.addEventListener("lr-sort", (event) => event.detail.sortKey); // typed
410
410
  ```
411
411
  - **`HTMLElementTagNameMap`** is augmented in the `.class.d.ts` files. `document.querySelector('lr-table')`
412
412
  is only typed as `LyraTable` when that class module is in the type graph — importing just the
@@ -445,13 +445,13 @@ Those nested detail fields are separate from deprecated event names and are not
445
445
  `LyraGlobalEventMap` is exported as well, for writing your own typed helper over it.
446
446
 
447
447
  - **The surface is per-event type aliases, not runtime event classes.** `LyraSortEvent` and its
448
- generated siblings are `type` aliases over the owning component's own map entry
449
- (`LyraTableEventMap['lr-sort']`) — there is nothing to `new`, and `instanceof LyraSortEvent` is
450
- not a thing. The module compiles to `export {};`: shipping runtime event subclasses to type a
451
- listener would cost every consumer runtime bytes for a compile-time concern, so it deliberately
452
- costs zero.
448
+ generated siblings are `type` aliases over component event-map entries. `LyraSortEvent` unions
449
+ the `lr-sort` entries for document-library, eval-dataset and table. These aliases have no runtime
450
+ constructor and cannot be used with `new` or `instanceof`. The module compiles to `export {};`:
451
+ shipping runtime event subclasses to type a listener would cost every consumer runtime bytes for
452
+ a compile-time concern, so it deliberately costs zero.
453
453
  - **A shared event name narrows to the union of its dispatchers.** One name can come from several
454
- components with different details — `lr-select` from five, `lr-selection-change` from five — so
454
+ components with different details, such as `lr-select` and `lr-selection-change`, so
455
455
  its global entry is the _union_ of their entries, and `event.detail` there exposes only what all
456
456
  of them share. Index the owning component's own map when you need one component's exact detail:
457
457
 
@@ -881,6 +881,103 @@ See [Where an override actually reaches](#where-an-override-actually-reaches) be
881
881
  inheritance rules, including the one documented exception (per-component `--lr-<component>-*`
882
882
  hooks, layer 3, which do inherit through wrappers).
883
883
 
884
+ ### Lyra signature starter
885
+
886
+ Use this application profile for new projects unless explicit branding or user choices override it.
887
+ It is a composition recommendation, not a change to Lyra's runtime defaults. Existing applications
888
+ adopt it only during an authorized migration or redesign; valid saved style and locale choices win.
889
+
890
+ ```css
891
+ @import "@aceshooting/lyra-ui/theme.css";
892
+ @import "@aceshooting/lyra-ui/tokens-root.css";
893
+ @import "@aceshooting/lyra-ui/looks/shadcn.css";
894
+ @import "@aceshooting/lyra-ui/surfaces/glass.css";
895
+ @import "@aceshooting/lyra-ui/accents.css";
896
+ ```
897
+
898
+ The first-use choices are independent axes:
899
+
900
+ ```ts
901
+ import { setLyraStyle } from '@aceshooting/lyra-ui/theme.js';
902
+
903
+ // Apply only when initializing the application's unsaved choices.
904
+ setLyraStyle({ look: 'shadcn', surface: 'glass', accent: 'emerald', mode: 'system' });
905
+ ```
906
+
907
+ Do not run that assignment unconditionally on every visit. Restore saved choices through the
908
+ published style runtime; use `parseLyraStyleRecord()` when validating a persisted record, and
909
+ `setLyraStyle()` to normalize browser color inputs. Preserve valid custom accents, semantic-role
910
+ palettes, runtime looks, overrides, and historical v1 records. Fill missing or invalid choices from
911
+ the application profile without overwriting independently saved axes. An application Reset action
912
+ restores this profile: `resetLyraStyle()` alone restores the library's defaults instead.
913
+
914
+ For first paint, run the synchronous `lyraThemeBootstrap`, then apply the application's unsaved-axis
915
+ fallback attributes, then load the blocking stylesheets. Use the documented CSP-safe embedding or
916
+ classic-script asset. With empty storage, the bootstrap writes Lyra's library defaults and would
917
+ overwrite earlier Shadcn/glass/Emerald attributes; it has no application-defaults option. With
918
+ denied storage, still apply the application fallbacks after it. Retain valid restored axes and
919
+ record which fallbacks were used, then apply those same choices through `setLyraStyle()` during
920
+ runtime initialization. A later module assignment alone cannot prevent a color flash. Test fresh,
921
+ malformed, partial, legacy, and storage-denied records before modules load and after hydration,
922
+ alongside valid saved choices. Do not copy Lyra's bootstrap, normalizer, or ownership internals.
923
+
924
+ Keep spotlights in application CSS, independent of the chosen control look. The public root-token
925
+ stylesheet makes this static recipe follow both light/dark mode and the current accent:
926
+
927
+ ```css
928
+ body { isolation: isolate; min-block-size: 100svh; background: var(--lr-color-surface); }
929
+ body::before {
930
+ content: '';
931
+ position: fixed;
932
+ inset: 0;
933
+ z-index: -1;
934
+ pointer-events: none;
935
+ background:
936
+ radial-gradient(ellipse 46rem 30rem at 8% 4%, color-mix(in srgb, var(--lr-color-brand) 16%, transparent), transparent 60%),
937
+ radial-gradient(ellipse 40rem 30rem at 96% 22%, color-mix(in srgb, var(--lr-color-brand) 12%, transparent), transparent 58%),
938
+ radial-gradient(ellipse 44rem 32rem at 78% 96%, color-mix(in srgb, var(--lr-color-brand) 9%, transparent), transparent 60%),
939
+ var(--lr-color-surface);
940
+ }
941
+ html[data-lr-contrast='more'] body::before { background: var(--lr-color-surface); }
942
+ @media (forced-colors: active) { body::before { background: Canvas; } }
943
+ ```
944
+
945
+ These are decorative application backgrounds, not an `accentBackground` value: that style field
946
+ accepts absolute colors used as contrast reference surfaces, not gradients or image URLs. Use
947
+ semantic surface/text pairings for content and keep the decorative layer behind it.
948
+
949
+ Use the existing [gemstoneAccentPicker composition](../components/lr-swatch-picker.md#gemstoneaccentpicker--the-signature-accent-selector),
950
+ with its localized caption, nine canonical gemstones, and shared selected-glyph treatment. Keep
951
+ `--lr-swatch-picker-wrap: nowrap`: desktop hit size `1.75rem` and gap `.25rem`; at widths up to
952
+ `30rem`, hit size `1.5rem` and gap `.125rem` (28/4px and 24/2px at a 16px root). Leave its fill size
953
+ unset. Bound the palette to the viewport and provide horizontal overflow for unusually narrow
954
+ allocations or enlarged text; keyboard focus must bring every swatch into view. Do not shrink
955
+ below the component's 24px floor or replace its Arrow/Home/End and RTL behavior.
956
+
957
+ The four separate topbar controls—gemstone, mode, design, language—stay square `2.75rem` targets
958
+ (44px at a 16px root), with localized names and tooltips. Use gemstone, sun/moon and horizontal-slider
959
+ icons, and a country flag for language. Dense gemstone options do not reduce
960
+ those launcher targets. Set the locale picker's `--lr-locale-picker-trigger-height: 2.75rem` and
961
+ use its public flag-only trigger with readable menu entries:
962
+
963
+ ```ts
964
+ import '@aceshooting/lyra-ui/components/lr-locale-picker.js';
965
+ import '@aceshooting/lyra-ui/components/media/flag/flag-peer.js';
966
+ ```
967
+
968
+ ```html
969
+ <lr-locale-picker top-layer trigger-display="flag" option-display="label"
970
+ aria-label="Localized language action"></lr-locale-picker>
971
+ ```
972
+
973
+ Install the optional `@aceshooting/lyra-flags` peer; the granular resolver import loads requested
974
+ flags without a bulk flag import. Leave `withoutFlags` false. Assign `locales` as a property with
975
+ `{ tag, label, country? }` entries: provide readable localized language names and an explicit ISO
976
+ country for regional entries when known, such as `en-US` → `US`. Keep flags as supplementary cues,
977
+ never the only accessible names, and preserve a valid saved locale in the controlled `value`.
978
+ Use the component's flag resolver rather than emoji, invented flag SVGs, or guessed display APIs.
979
+ Verify 320px and desktop, light/dark, RTL, enlarged text, keyboard focus, and saved preferences.
980
+
884
981
  ### Reading the resolved tokens from your own components — `tokens-root.css`
885
982
 
886
983
  The paragraph above is a real problem for any application that has custom elements of its own: they
@@ -2755,7 +2852,10 @@ void`, and `virtualAnchorFromRect()`** — thin wrapper over `@floating-ui/dom`'
2755
2852
  `computePosition` + `autoUpdate`. Forces `strategy: 'fixed'` (matching the
2756
2853
  popup's own `position: fixed` CSS — otherwise it lands offset by the page scroll), middleware
2757
2854
  `offset(opts.offset ?? 4)`, `flip()`, `shift({ padding: 8 })`, default `placement: 'bottom-start'`.
2758
- Returns a cleanup function that stops the `autoUpdate` loop — call it in `disconnectedCallback()`.
2855
+ Returns a cleanup function that stops observation and queued updates — call it in `disconnectedCallback()`.
2856
+ For `place()`, element-resize notifications coalesce into the next animation frame; initial
2857
+ computation, scrolling and layout-shift updates begin immediately. Cleanup cancels a pending
2858
+ resize frame.
2759
2859
  `trackRect()` reports the target's initial viewport rect exactly once before returning, follows
2760
2860
  later layout/viewport changes, and returns the same cleanup shape.
2761
2861
  `virtualAnchorFromRect()` adapts a live rectangle provider to the exported `VirtualAnchor`