@aceshooting/lyra-ui 18.0.0 → 18.1.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 (42) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/custom-elements.json +1 -1
  3. package/design-tokens.json +1 -1
  4. package/dist/cli/migration-contract.json +1 -1
  5. package/dist/components/conversation/message-actions/message-actions.class.d.ts +2 -1
  6. package/dist/components/forms/combobox/combobox.styles.js +1 -1
  7. package/dist/components/forms/icon-button/icon-button.class.d.ts +18 -9
  8. package/dist/components/forms/select/select.class.d.ts +34 -5
  9. package/dist/components/forms/select/select.class.js +4 -4
  10. package/dist/components/forms/select/select.styles.js +1 -1
  11. package/dist/components/layout/filter-bar/filter-bar.class.d.ts +80 -8
  12. package/dist/components/layout/filter-bar/filter-bar.class.js +11 -3
  13. package/dist/components/layout/filter-bar/filter-bar.styles.js +1 -1
  14. package/dist/components/layout/virtual-list/virtual-list.class.d.ts +47 -16
  15. package/dist/components/layout/virtual-list/virtual-list.class.js +1 -1
  16. package/dist/components/media/map/map.class.d.ts +134 -5
  17. package/dist/components/media/map/map.class.js +48 -21
  18. package/dist/components/media/map/map.styles.js +1 -1
  19. package/dist/components/utility/copy-button/copy-button.class.d.ts +4 -3
  20. package/dist/custom-elements-jsx.d.ts +1 -1
  21. package/dist/events.d.ts +7 -1
  22. package/dist/internal/package-metadata.d.ts +1 -1
  23. package/dist/internal/package-metadata.js +1 -1
  24. package/dist/internal/tokens.styles.js +1 -1
  25. package/dist/lyra.d.ts +1 -1
  26. package/dist/styles/tokens-root.css +1 -1
  27. package/dist/svelte.d.ts +1 -1
  28. package/dist/testing/lyra-tag-event-map.js +1 -1
  29. package/dist/vue.d.ts +1 -1
  30. package/llms/components/lr-combobox.md +8 -4
  31. package/llms/components/lr-filter-bar.md +37 -4
  32. package/llms/components/lr-icon-button.md +15 -7
  33. package/llms/components/lr-map.md +68 -6
  34. package/llms/components/lr-option.md +8 -4
  35. package/llms/components/lr-select.md +30 -5
  36. package/llms/shared.md +41 -0
  37. package/llms/tokens.md +7 -4
  38. package/llms-full.txt +203 -25
  39. package/package.json +1 -1
  40. package/vscode-css-data.json +1 -1
  41. package/vscode-html-data.json +1 -1
  42. package/web-types.json +1 -1
@@ -37,7 +37,30 @@ readonly value?:string;
37
37
  * most 8192 characters. A glyph omission is not counted in `legendProjection` either, because
38
38
  * the row it belongs to still renders — only dropped rows are omissions.
39
39
  */
40
- readonly icon?:LyraMapPointIcon|Omit<LyraMapPointIcon,'value'>;}
40
+ readonly icon?:LyraMapPointIcon|Omit<LyraMapPointIcon,'value'>;
41
+ /**
42
+ * Optional section this row belongs to. A key describing two layers at once could previously
43
+ * only be one flat list, with nothing saying which rows belonged to which.
44
+ *
45
+ * **The grouping rule, which is pinned rather than inferred:** CONSECUTIVE entries sharing an
46
+ * identical `group` render as one section -- a visible heading plus a `role="group"` the heading
47
+ * names. An entry with no `group` keeps its DECLARED position: it is never hoisted above or sunk
48
+ * below a section, and a `group` that reappears after an interruption opens a SECOND section
49
+ * rather than reordering rows to merge them. Declaration order is the one thing the legend never
50
+ * rewrites, because the order is itself information about the map.
51
+ *
52
+ * It is caller-supplied DATA, so it renders verbatim and is never passed through the locale
53
+ * catalog. It is trimmed and bounded to 256 characters (ellipsized, since it is rendered prose
54
+ * rather than a matched key); a non-string, empty or whitespace-only value leaves no `group` key
55
+ * at all, so an empty string means "ungrouped" instead of an empty heading, and a legend that
56
+ * never used sections reads back exactly as it did before this field existed.
57
+ *
58
+ * Like the row-level `value`, it is NOT charged to the aggregate label budget: a budget bounds
59
+ * rendered text, and the rendered total here is already finite and stated -- at most one heading
60
+ * per rendered row, so at most 100 of them, each at most 256 characters. A section is also not a
61
+ * row: the 100-row cap and the `legend-limit` summary count rows, never sections.
62
+ */
63
+ readonly group?:string;}
41
64
  /**
42
65
  * One `[value, color]` stop of a continuous legend ramp — deliberately the same shape as
43
66
  * `LyraMapChoroplethLayer['stops']`, so a consumer passes the choropleth's own stops straight
@@ -349,7 +372,15 @@ readonly value:string;
349
372
  /** Proposed visibility of `value` after this toggle. */
350
373
  readonly visible:boolean;
351
374
  /** Complete canonical proposed hidden-category set, in the order it would be committed. */
352
- readonly hiddenCategories:readonly string[];}export interface LyraMapEventMap{'lr-map-load':CustomEvent<null>;'lr-map-marker-activate':CustomEvent<LyraMapMarkerActivationDetail>;'lr-map-legend-toggle':CustomEvent<LyraMapLegendToggleDetail>;'lr-map-click':CustomEvent<{readonly lngLat:readonly[number,number];readonly feature:Feature|undefined;
375
+ readonly hiddenCategories:readonly string[];}
376
+ /**
377
+ * Proposed disclosure state for the legend PANEL, which is a different thing from one category's
378
+ * visibility -- hence its own detail type rather than a reuse of `LyraMapLegendToggleDetail`.
379
+ * Frozen, and detached from the component's own state.
380
+ */
381
+ export interface LyraMapLegendPanelToggleDetail{
382
+ /** Proposed `legendOpen` after this activation. */
383
+ readonly open:boolean;}export interface LyraMapEventMap{'lr-map-load':CustomEvent<null>;'lr-map-marker-activate':CustomEvent<LyraMapMarkerActivationDetail>;'lr-map-legend-toggle':CustomEvent<LyraMapLegendToggleDetail>;'lr-map-legend-panel-toggle':CustomEvent<LyraMapLegendPanelToggleDetail>;'lr-map-click':CustomEvent<{readonly lngLat:readonly[number,number];readonly feature:Feature|undefined;
353
384
  /** Which layer `feature` was hit on, so a click is attributable when both a choropleth and
354
385
  * `dataLayers` are painted. `'cluster'` marks a hit on a clustered entry's aggregate circle,
355
386
  * whose `point_count`/`cluster_id` properties describe the group rather than one feature.
@@ -405,6 +436,14 @@ readonly sourceId:string|undefined;}>;}
405
436
  * before/after vocabulary would be permanent public surface nobody asked for. A programmatic
406
437
  * `hiddenCategories` assignment reconciles without emitting anything -- this event is a
407
438
  * DOM-interaction proposal only.
439
+ * @event lr-map-legend-panel-toggle - **Cancelable.** Fired once when the `legendCollapsible`
440
+ * disclosure is activated by pointer or by Enter/Space, carrying the immutable
441
+ * `detail: { open }` -- the proposed `legendOpen` value. It is the *panel's* disclosure, not a
442
+ * *category's* visibility, so it deliberately does not reuse `lr-map-legend-toggle`.
443
+ * `preventDefault()` is a real veto: `legendOpen` is not written, the rendered rows and the
444
+ * disclosure's `aria-expanded` do not change, which is what lets a host own the open state and
445
+ * write it itself. A programmatic `legendOpen` assignment reconciles without emitting anything,
446
+ * so a controlled host cannot loop.
408
447
  * @event lr-map-marker-activate - Fired once when an accepted declarative marker is activated by
409
448
  * pointer/click or by Enter/Space. The immutable detail carries its normalized `id`, validated
410
449
  * `lngLat`, accepted marker snapshot, and activation `source`.
@@ -421,6 +460,11 @@ readonly sourceId:string|undefined;}>;}
421
460
  * @slot legend - Custom legend content, rendered inside the legend panel's own layout so it stays
422
461
  * positioned with the map instead of floating beside it. Slotted content is never made
423
462
  * interactive by `legendInteractive`, which only reaches rows projected from `legend`.
463
+ * @slot legend-start - The same extension point at the TOP of the legend panel: it renders ahead
464
+ * of the gradient bar and every projected row, where `legend` renders after them. A panel header
465
+ * -- a title, a source note, a host-built control -- could previously only ever be a footer,
466
+ * because `legend` was the only slot. Content here alone opens the panel, exactly as `legend`
467
+ * content alone does, and it is never made interactive by `legendInteractive`.
424
468
  * @csspart legend - The map legend.
425
469
  * @csspart legend-swatch - A legend color swatch, or the entry's glyph when it carries an `icon`
426
470
  * — in which case the swatch drops its color block and pattern overlay, keeps the `pattern`
@@ -433,6 +477,18 @@ readonly sourceId:string|undefined;}>;}
433
477
  * @csspart legend-toggle-hidden - Second token carried alongside `legend-toggle` while that row's
434
478
  * category is in `hiddenCategories`. State lives in the part name rather than a separate
435
479
  * attribute, so `::part(legend-toggle-hidden)` is a reachable styling hook.
480
+ * @csspart legend-group - The `role="group"` wrapping one consecutive run of legend rows that
481
+ * share a `group`. Absent entirely when no admitted entry carries one, so an ungrouped legend's
482
+ * markup is unchanged.
483
+ * @csspart legend-group-heading - The visible heading naming a `legend-group`. It renders the
484
+ * caller-supplied `group` string verbatim and names the group through `aria-labelledby`.
485
+ * @csspart legend-disclosure - The `button` that collapses and expands the whole legend panel.
486
+ * Rendered only when `legendCollapsible` is set, so an unset map's legend markup is unchanged.
487
+ * It carries the localized panel name as its visible, accessible label plus `aria-expanded`
488
+ * rendered as the literal `"true"`/`"false"`, and it grows to the shared `--lr-icon-button-size`
489
+ * hit-area floor.
490
+ * @csspart legend-disclosure-icon - The decorative chevron inside `legend-disclosure`. It is the
491
+ * wrapping part that rotates (per the shared icon set's contract), including under RTL.
436
492
  * @csspart legend-gradient - The continuous ramp bar rendered from `legendGradient`.
437
493
  * @csspart legend-lo - The low endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`).
438
494
  * @csspart legend-hi - The high endpoint caption of the `legendGradient` bar (mirrors `lr-heatmap`).
@@ -520,7 +576,7 @@ renderWorldCopies?:boolean;
520
576
  maxBounds:LyraMapBounds|null;
521
577
  /** Required MapLibre style URL or peer-neutral style specification. No provider is contacted
522
578
  * unless a consumer assigns this property. */
523
- mapStyle?:Readonly<LyraMapStyleSpecification> |string;private _legend;private _legendProjection;
579
+ mapStyle?:Readonly<LyraMapStyleSpecification> |string;private _legend;private _legendProjection;private _legendGrouped;
524
580
  /** Immutable, bounded entries rendered in the optional map legend. A required pattern keeps
525
581
  * category identity available when authored colors collapse or are unavailable. */
526
582
  get legend():readonly LyraMapLegendEntry[];set legend(value:readonly LyraMapLegendEntry[]);
@@ -532,6 +588,9 @@ get legend():readonly LyraMapLegendEntry[];set legend(value:readonly LyraMapLege
532
588
  * it. `slotchange` still runs afterwards to track content added or removed later.
533
589
  */
534
590
  private hasLegendSlot;
591
+ /** The same presence flag for `slot="legend-start"`, tracked separately so a header alone opens
592
+ * the panel and so the two extension points never stand in for one another. */
593
+ private hasLegendStartSlot;
535
594
  /** Light-DOM probe for slotted legend content, valid before the slot itself has ever rendered. */
536
595
  private probeLegendSlot;private _legendGradient;
537
596
  /**
@@ -573,7 +632,50 @@ get legendProjection():LyraMapLegendProjection;
573
632
  * 100-series `lr-chart` legend does. Each row also grows to the `--lr-icon-button-size` hit-area
574
633
  * floor; the legend panel's own `max-block-size`/`overflow: auto` contains the taller list.
575
634
  */
576
- legendInteractive:boolean;private _hiddenCategories;
635
+ legendInteractive:boolean;
636
+ /**
637
+ * Renders a disclosure button inside the legend panel that collapses the key down to its header.
638
+ * Default `false`, and an unset map renders exactly the panel it rendered before this property
639
+ * existed -- no button, no `id` minted on the row list, and no `hidden` attribute anywhere.
640
+ *
641
+ * A collapsed panel hides the gradient bar, the rows, the `legend-limit` summary and the
642
+ * trailing `legend` slot; the `legend-start` slot and the disclosure itself stay visible, so a
643
+ * slotted header survives the collapse and the control that would restore the key is never the
644
+ * thing the collapse hides.
645
+ */
646
+ legendCollapsible:boolean;
647
+ /**
648
+ * Whether a `legendCollapsible` panel is expanded. Defaults **open**, so adding only
649
+ * `legendCollapsible` never hides an existing key; it does nothing at all while
650
+ * `legendCollapsible` is unset.
651
+ *
652
+ * It is a `true`-defaulting boolean, so it uses `trueDefaultBooleanConverter` rather than Lit's
653
+ * presence-based boolean converter, which cannot express `legend-open="false"` at all. The
654
+ * reflection follows the same converter: open (the default) reflects as an ABSENT attribute and
655
+ * collapsed reflects as `legend-open="false"`.
656
+ *
657
+ * Controlled public state, so -- exactly like `hiddenCategories` -- it deliberately survives a
658
+ * disconnect and reconnect: the "reset transient open-state in `disconnectedCallback()`" rule
659
+ * covers dropdown/preview/tooltip `@state`, not a documented property a host owns and re-reads.
660
+ * A programmatic assignment reconciles the rendered panel without emitting
661
+ * `lr-map-legend-panel-toggle`, so a controlled host cannot loop.
662
+ */
663
+ legendOpen:boolean;
664
+ /** True only when a collapsible panel is actually collapsed. `legendOpen` alone never hides
665
+ * anything, so an author who sets `legend-open="false"` without `legendCollapsible` -- and
666
+ * therefore renders no control to restore it -- still gets a readable key. */
667
+ private get legendCollapsed();
668
+ /**
669
+ * Flips the whole panel's disclosure from the `legendCollapsible` button.
670
+ *
671
+ * The veto is the absence of a write, not a write that is undone afterwards: a listener that
672
+ * owns the open state can assign its own `legendOpen` without this handler clobbering it.
673
+ */
674
+ private toggleLegendPanel;
675
+ /** The panel disclosure, or nothing at all when the panel cannot collapse. The chevron is
676
+ * decorative: the button's own visible, localized text carries its name, and `aria-expanded`
677
+ * carries the state. */
678
+ private renderLegendDisclosure;private _hiddenCategories;
577
679
  /**
578
680
  * Complete controlled set of muted category keys, mirroring `lr-chart`'s `hiddenDatasets`.
579
681
  * Clone-owned and frozen; non-string, empty, whitespace-only and duplicate entries are dropped,
@@ -812,4 +914,31 @@ private toggleLegendCategory;
812
914
  private announceLegendVisibility;
813
915
  /** Acquired lazily on the first toggle, and re-acquired against a new owner document, so a map
814
916
  * that never renders an interactive legend never mounts a live region at all. */
815
- private syncLegendAnnouncementSink;private releaseLegendAnnouncementSink;private renderLegendGradient;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-map':LyraMap;}}
917
+ private syncLegendAnnouncementSink;private releaseLegendAnnouncementSink;
918
+ /**
919
+ * One legend row. Extracted verbatim from the list template so the grouped and ungrouped section
920
+ * paths below render the same node rather than two copies that can drift.
921
+ *
922
+ * `aria-posinset`/`aria-setsize` deliberately stay whole-key values inside a section too.
923
+ * `aria-setsize` already reports the *input* count rather than the rendered one, so a bounded key
924
+ * stays honest; per-section input counts do not exist, because a row dropped by the bound carries
925
+ * no attributable group. A section adds a labelled sub-region; it does not renumber the key.
926
+ */
927
+ private renderLegendRow;
928
+ /**
929
+ * The row list's children: bare rows when no admitted entry carries a `group`, and otherwise one
930
+ * `role="group"` per CONSECUTIVE run sharing a group name, with ungrouped rows left exactly where
931
+ * they were declared. The ungrouped branch is literally the expression this list has always been,
932
+ * so a legend that uses no sections keeps rendering the markup it rendered before they existed.
933
+ *
934
+ * `group` is caller-supplied data: the heading renders it verbatim and never resolves it through
935
+ * the locale catalog.
936
+ *
937
+ * Each section owns its OWN `role="list"` rather than the sections sitting directly inside the
938
+ * outer one. `list` requires `listitem` children, and a `group` is not one -- axe reports both
939
+ * `aria-required-children` on the outer list and `aria-required-parent` on every row inside the
940
+ * group, critical, which is how this shape was caught. So a grouped legend renders one list per
941
+ * run (including each ungrouped run) and the outer element drops its own `role`, while an
942
+ * ungrouped legend keeps the single `role="list"` it has always had.
943
+ */
944
+ private renderLegendRows;private renderLegendGradient;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-map':LyraMap;}}