@ixfx/components 0.16.0 → 0.16.2

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 (90) hide show
  1. package/bundle/index.d.ts +290 -66
  2. package/bundle/index.js +412 -327
  3. package/dist/ac-text.d.ts +1 -1
  4. package/dist/{ac-token-qEs3FsQv.d.ts → ac-token-Cq7lsYf-.d.ts} +1 -1
  5. package/dist/ac-token.d.ts +1 -1
  6. package/dist/ac-token.js +1 -1
  7. package/dist/{button-N92DKoWb.d.ts → button-D1sPDUCM.d.ts} +1 -1
  8. package/dist/button.d.ts +1 -1
  9. package/dist/colour-picker.d.ts +1 -1
  10. package/dist/{crumb-navigation-YnFVFqrx.js → crumb-navigation-D3ndPgFg.js} +2 -2
  11. package/dist/{crumb-navigation-BbqfmkYs.d.ts → crumb-navigation-nnr881n-.d.ts} +1 -1
  12. package/dist/crumbs.d.ts +1 -1
  13. package/dist/crumbs.js +1 -1
  14. package/dist/{data-grid-CIG2DVip.d.ts → data-grid-BAEpfTkb.d.ts} +32 -5
  15. package/dist/{data-grid-rMkLX2qo.js → data-grid-CaPLWt5E.js} +159 -60
  16. package/dist/data-grid.d.ts +2 -2
  17. package/dist/data-grid.js +1 -1
  18. package/dist/{detail-list-C4pDSoI8.js → detail-list-C3XKTRmE.js} +86 -21
  19. package/dist/{detail-list-6iMTNP4N.d.ts → detail-list-DK49TsJd.d.ts} +26 -4
  20. package/dist/detail-list.d.ts +2 -2
  21. package/dist/detail-list.js +1 -1
  22. package/dist/{flat-list-JPgQSmLW.d.ts → flat-list-Bv4-qfjp.d.ts} +9 -4
  23. package/dist/flat-list.d.ts +1 -1
  24. package/dist/flat-list.js +6 -3
  25. package/dist/{grid-list-CdEkScn-.js → grid-list-51XsR2X2.js} +56 -18
  26. package/dist/{grid-list-D6n7WH8l.d.ts → grid-list-DaeSHv9P.d.ts} +58 -14
  27. package/dist/grid-list.d.ts +2 -2
  28. package/dist/grid-list.js +1 -1
  29. package/dist/{grouped-item-lister-DETte0Dh.d.ts → grouped-item-lister-DZIjo9nO.d.ts} +2 -2
  30. package/dist/grouped-item-lister.d.ts +1 -1
  31. package/dist/{icon-CDGprSdE.d.ts → icon-DR_3rSyZ.d.ts} +1 -1
  32. package/dist/icons.d.ts +2 -2
  33. package/dist/{incr-search-JIhwB49y.js → incr-search-2YaxUUA9.js} +150 -11
  34. package/dist/incr-search.d.ts +1 -1
  35. package/dist/incr-search.js +1 -1
  36. package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +1 -1
  37. package/dist/{index-Dr80Zdl6.d.ts → index-BjRoPrwj.d.ts} +31 -4
  38. package/dist/{index-DN2BWctP.d.ts → index-Bz3loIAf.d.ts} +1 -1
  39. package/dist/{index-UvnoZUAo.d.ts → index-CJ5fshD3.d.ts} +1 -1
  40. package/dist/{index-DxyyVqzA.d.ts → index-DM9OLgTH.d.ts} +3 -2
  41. package/dist/{index-CYRc6Dah.d.ts → index-DXDz60XH.d.ts} +20 -1
  42. package/dist/{index-CYndvTWH.d.ts → index-garxxqgV.d.ts} +1 -1
  43. package/dist/{index-Bx0BXPxI.d.ts → index-vdbbGE7N.d.ts} +1 -1
  44. package/dist/index.d.ts +57 -28
  45. package/dist/index.js +58 -35
  46. package/dist/item-appearance-Bl6rMIID.js +60 -0
  47. package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +1 -1
  48. package/dist/labelled-radial-input.d.ts +2 -2
  49. package/dist/labelled-range-input.d.ts +1 -1
  50. package/dist/labelled-slider-input.d.ts +1 -1
  51. package/dist/list-group-header.d.ts +1 -1
  52. package/dist/{list-selection-controller-5L0Nj9tR.js → list-selection-controller-CJDdjH7E.js} +192 -54
  53. package/dist/list-selection-types-hj9Njei3.d.ts +83 -0
  54. package/dist/{menu-CU9KAm8s.js → menu-BX1FHxY8.js} +16 -1
  55. package/dist/{menu-item-bF6narIz.d.ts → menu-item-B0zqw2xp.d.ts} +1 -1
  56. package/dist/{menu-item-BUv8An2k.js → menu-item-oxU1VKiJ.js} +34 -9
  57. package/dist/menu.d.ts +2 -2
  58. package/dist/menu.js +2 -2
  59. package/dist/{miller-BFRfn0ve.js → miller-BfrTcujx.js} +142 -18
  60. package/dist/miller.d.ts +1 -1
  61. package/dist/miller.js +1 -1
  62. package/dist/narrowed-text.js +1 -1
  63. package/dist/panel.d.ts +1 -1
  64. package/dist/{split-layout-CophkNeU.d.ts → split-layout-ChZ0Glrs.d.ts} +1 -1
  65. package/dist/split-layout.d.ts +1 -1
  66. package/dist/sunburst-tree.d.ts +1 -1
  67. package/dist/sunburst-tree.js +1 -1
  68. package/dist/{sunbursttree-list-B_VxOHlo.js → sunbursttree-list-906G33ME.js} +1 -1
  69. package/dist/{sunbursttree-list-D6j5BxVQ.d.ts → sunbursttree-list-BAS0KrDG.d.ts} +1 -1
  70. package/dist/{tab-list-Df371rqw.d.ts → tab-list-wC0xNz1b.d.ts} +1 -1
  71. package/dist/tabs.d.ts +1 -1
  72. package/dist/{titlebar-Tqu-VvMU.d.ts → titlebar-B5zSTZnF.d.ts} +1 -1
  73. package/dist/titlebar.d.ts +1 -1
  74. package/dist/{tree-Crdpl4nc.js → tree-C_H1COTf.js} +1 -1
  75. package/dist/tree.d.ts +1 -1
  76. package/dist/tree.js +1 -1
  77. package/dist/{vertical-list-BPDmZx6T.d.ts → vertical-list-od4050Bo.d.ts} +11 -2
  78. package/dist/{vertical-list-1V1Vg2O5.js → vertical-list-qMRIxZIT.js} +54 -20
  79. package/dist/vertical-list.d.ts +2 -2
  80. package/dist/vertical-list.js +1 -1
  81. package/docs-user/data-grid.md +23 -7
  82. package/docs-user/detail-list.md +16 -1
  83. package/docs-user/dock.md +12 -3
  84. package/docs-user/grid-list.md +9 -3
  85. package/docs-user/index.json +2 -2
  86. package/docs-user/menu.md +11 -1
  87. package/docs-user/vertical-list.md +9 -1
  88. package/package.json +2 -2
  89. package/dist/item-appearance-BjcMyauw.js +0 -29
  90. package/dist/list-selection-types-PjKdhF-a.d.ts +0 -45
@@ -1,10 +1,10 @@
1
1
  import { L as ListDragPreviewRenderer, R as ListDragPreviewSourceResolver, V as ListNativeDragStartEvent } from "./tree-component-DgfkxmVY.js";
2
2
  import { a as ViewStateBase, t as GetViewStateOptions } from "./types-LU1u0CB8.js";
3
3
  import "./index-9ttcdwlL.js";
4
- import { S as ListSearchController } from "./index-Dr80Zdl6.js";
4
+ import { f as ListSelectIntentSource, i as ListInteractionMode, l as ListSelectIntentDetail, m as ListSelectionMode } from "./list-selection-types-hj9Njei3.js";
5
+ import { S as ListSearchController } from "./index-BjRoPrwj.js";
5
6
  import "./pan-text-CoYmt2qd.js";
6
7
  import { i as ListGroupChangeEvent, n as ListGroupBy, o as ListGroupInfo, s as ListGroupLabel, u as ListGroupToggleEvent } from "./grouping-CUKgmkMm.js";
7
- import { i as ListInteractionMode, l as ListSelectionMode } from "./list-selection-types-PjKdhF-a.js";
8
8
  import "./list-group-header.js";
9
9
  import "./list-native-drag-controller-D_UrXipS.js";
10
10
  import { i as TickledItem, n as TickledController } from "./tickled-controller-DodxD3eQ.js";
@@ -86,10 +86,12 @@ type ListDragSelectControllerConfig<T> = {
86
86
  /**
87
87
  * Fired once on release with the final set. Host applies it to its
88
88
  * selection. `additive` is `true` when the drag ran with Shift (add) or
89
- * Cmd / Ctrl (invert) held.
89
+ * Cmd / Ctrl (invert) held. `covered` is the set the marquee itself hit,
90
+ * before combining with the base selection.
90
91
  */
91
92
  onCommit: (finalSet: ReadonlySet<T>, info: {
92
93
  additive: boolean;
94
+ covered: ReadonlySet<T>;
93
95
  }) => void;
94
96
  /** Optional: scroll the surface when the pointer nears an edge during a drag. */
95
97
  autoScroll?: (dx: number, dy: number) => void;
@@ -133,7 +135,11 @@ type ListSelectionGesture = {
133
135
  readonly ctrlKey: boolean;
134
136
  readonly metaKey: boolean;
135
137
  readonly shiftKey: boolean;
138
+ /** `PointerEvent.pointerType`, when known; a `touch` tap reports source `touch`. */
139
+ readonly pointerType?: string;
136
140
  };
141
+ /** Capture the modifier / pointer-type state of a click for `handleClick`. */
142
+ declare function gestureOf(e: MouseEvent): ListSelectionGesture;
137
143
  type ListSelectionModes = {
138
144
  readonly selectionMode: ListSelectionMode;
139
145
  readonly interactionMode: ListInteractionMode;
@@ -157,6 +163,13 @@ type ListSelectionControllerConfig<T> = {
157
163
  * requests an update.
158
164
  */
159
165
  readonly onChange: (selected: ReadonlySet<T>, previous: ReadonlySet<T>) => void;
166
+ /**
167
+ * Optional: called with the intent behind a gesture (or `selectAll()`)
168
+ * before the selection changes. Return `true` when the caller took over
169
+ * (`preventDefault()`); the controller then leaves the selection alone but
170
+ * still moves the range anchor.
171
+ */
172
+ readonly onIntent?: (intent: ListSelectIntentDetail) => boolean;
160
173
  /**
161
174
  * Optional: derive a stable string key for an item. Enables `selectedKeys`
162
175
  * and `selectKeys()`. When omitted, `selectedKeys` is always empty.
@@ -225,8 +238,11 @@ declare class ListSelectionController<T> {
225
238
  rangeTo(item: T): void;
226
239
  /** Clear the selection. No change event when the selection is already empty. */
227
240
  clear(): void;
228
- /** Select every ordered item that passes `isSelectable`. */
229
- selectAll(): void;
241
+ /**
242
+ * Select every ordered item that passes `isSelectable`. Fires an `all`
243
+ * intent first; the caller may take over.
244
+ */
245
+ selectAll(source?: ListSelectIntentSource): void;
230
246
  /**
231
247
  * Replace the selection with many items at once. Requires
232
248
  * `selectionMode="multiple"`, throws otherwise. Updates the anchor.
@@ -248,24 +264,29 @@ declare class ListSelectionController<T> {
248
264
  * non-empty selection (e.g. a Cmd-drag that toggles everything off) but is
249
265
  * a no-op when nothing is selected.
250
266
  */
251
- applyDragSelection(items: Iterable<T>): void;
267
+ applyDragSelection(items: Iterable<T>, info?: {
268
+ additive: boolean;
269
+ covered: Iterable<T>;
270
+ }): void;
252
271
  /** Remove a single item from the selection. */
253
272
  deselect(item: T): void;
254
273
  /**
255
274
  * Replace the selection with the items resolved from `keys`. Keys that
256
- * `resolve` cannot map, or that resolve to a non-selectable item, are
257
- * ignored. `selectionMode="none"` is a no-op. When multi-select is not
258
- * available, only the last resolvable key is kept. `onChange` fires once.
275
+ * `resolve` cannot map yet are kept pending and selected when their items
276
+ * appear (see `resolvePending()`); keys that resolve to a non-selectable
277
+ * item are ignored. `selectionMode="none"` is a no-op. When multi-select is
278
+ * not available, only the last key is kept. `onChange` fires once.
259
279
  */
260
280
  selectKeys(keys: Iterable<string>, resolve: (key: string) => T | undefined): void;
261
281
  /**
262
282
  * Add the items resolved from `keys` to the selection (multi-select only;
263
- * a no-op otherwise). `onChange` fires once if anything changed.
283
+ * a no-op otherwise). Keys not present yet are kept pending. `onChange`
284
+ * fires once if anything changed.
264
285
  */
265
286
  addKeys(keys: Iterable<string>, resolve: (key: string) => T | undefined): void;
266
287
  /**
267
- * Remove the items resolved from `keys` from the selection. `onChange`
268
- * fires once if anything changed.
288
+ * Remove the items resolved from `keys` from the selection, and drop them
289
+ * from the pending keys. `onChange` fires once if anything changed.
269
290
  */
270
291
  removeKeys(keys: Iterable<string>, resolve: (key: string) => T | undefined): void;
271
292
  /** Selected keys waiting for their items to appear. */
@@ -291,10 +312,25 @@ declare class ListSelectionController<T> {
291
312
  demote(items: Iterable<T>): boolean;
292
313
  /** Drop pending keys without touching the live selection. */
293
314
  clearPending(): void;
294
- /** Route a click on `item` according to the current interaction mode. */
315
+ /**
316
+ * Route a click on `item` according to the current interaction mode. In
317
+ * `manual` mode nothing is selected, but the intent is still reported so
318
+ * the caller can apply it.
319
+ */
295
320
  handleClick(item: T, gesture: ListSelectionGesture): void;
296
321
  /** Route a Space keypress on `item` according to the current interaction mode. */
297
322
  handleSpace(item: T): void;
323
+ /** Route a checkbox (checked-mode) toggle on `item`. */
324
+ handleCheckbox(item: T, source?: ListSelectIntentSource): void;
325
+ /** Route a plain "select only this" gesture (Enter, double-click) on `item`. */
326
+ handleReplace(item: T, source?: ListSelectIntentSource): void;
327
+ /** Route Shift+Arrow: extend the range from the anchor to the cursor `item`. */
328
+ handleExtend(item: T): void;
329
+ /**
330
+ * Route Escape / empty-space click: clear the selection. `reportOnly`
331
+ * suppresses the default action in `manual` mode (the caller owns it).
332
+ */
333
+ handleClear(source?: ListSelectIntentSource, reportOnly?: boolean): void;
298
334
  /** Drop the range-selection anchor (e.g. when the interaction mode changes). */
299
335
  clearAnchor(): void;
300
336
  /**
@@ -773,6 +809,14 @@ declare class GridListElement<T = unknown> extends LitElement {
773
809
  * Auto-assigned keyless-item keys are omitted.
774
810
  */
775
811
  visibleKeys(): string[];
812
+ /**
813
+ * Cells shown as *partially* selected (a part of the resource is selected):
814
+ * `data-partial` / `part="item partial"` and an accessible description.
815
+ * Independent of `selectedKeys` — a key in both counts as selected.
816
+ * Replace-on-set; keys without a cell are kept for when it appears.
817
+ */
818
+ get partialKeys(): ReadonlySet<string>;
819
+ set partialKeys(keys: Iterable<string>);
776
820
  /**
777
821
  * Mirror cursor / selection onto the light-DOM items as `data-tickled` /
778
822
  * `data-selected`. Only the items whose state changed are touched, so a
@@ -795,4 +839,4 @@ interface GridListElement {
795
839
  addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
796
840
  }
797
841
  //#endregion
798
- export { isMultiMode as A, capKeys as B, TreeKeyboardNavController as C, ListSelectionControllerConfig as D, ListSelectionController as E, EMPTY_KEYS as F, partitionFlags as G, flagsToRecord as H, MAX_PENDING_KEYS as I, partitionKeys as K, PendingFlags as L, ListDragSelectController as M, ListDragSelectControllerConfig as N, ListSelectionGesture as O, EMPTY_FLAGS as P, PendingKeys as R, TreeKeyboardNavCallbacks as S, TreeKeyboardNavItemId as T, keysAsFlags as U, flagsFromRecord as V, keysToArray as W, GridListSelectEvent as _, GridListCaptionAlign as a, GridListViewportChangeDetail as b, GridListCaptionStyle as c, GridListFullElementEventMap as d, GridListItemClickDetail as f, GridListSelectDetail as g, GridListOrientation as h, GridListActivateEvent as i, DragSelectRect as j, ListSelectionModes as k, GridListDataAdapter as l, GridListItemEventDetail as m, GridListViewState as n, GridListCaptionBackdrop as o, GridListItemClickEvent as p, withoutFlag as q, GridListActivateDetail as r, GridListCaptionPosition as s, GridListElement as t, GridListElementEventMap as u, GridListTickleDetail as v, TreeKeyboardNavControllerConfig as w, GridListViewportChangeEvent as x, GridListTickleEvent as y, capFlags as z };
842
+ export { gestureOf as A, capFlags as B, TreeKeyboardNavController as C, ListSelectionControllerConfig as D, ListSelectionController as E, EMPTY_FLAGS as F, keysToArray as G, flagsFromRecord as H, EMPTY_KEYS as I, withoutFlag as J, partitionFlags as K, MAX_PENDING_KEYS as L, DragSelectRect as M, ListDragSelectController as N, ListSelectionGesture as O, ListDragSelectControllerConfig as P, PendingFlags as R, TreeKeyboardNavCallbacks as S, TreeKeyboardNavItemId as T, flagsToRecord as U, capKeys as V, keysAsFlags as W, GridListSelectEvent as _, GridListCaptionAlign as a, GridListViewportChangeDetail as b, GridListCaptionStyle as c, GridListFullElementEventMap as d, GridListItemClickDetail as f, GridListSelectDetail as g, GridListOrientation as h, GridListActivateEvent as i, isMultiMode as j, ListSelectionModes as k, GridListDataAdapter as l, GridListItemEventDetail as m, GridListViewState as n, GridListCaptionBackdrop as o, GridListItemClickEvent as p, partitionKeys as q, GridListActivateDetail as r, GridListCaptionPosition as s, GridListElement as t, GridListElementEventMap as u, GridListTickleDetail as v, TreeKeyboardNavControllerConfig as w, GridListViewportChangeEvent as x, GridListTickleEvent as y, PendingKeys as z };
@@ -1,5 +1,5 @@
1
1
  import { B as ListNativeDragStartDetail, F as ListDragPreview, I as ListDragPreviewContext, L as ListDragPreviewRenderer, P as ListDragEntry, V as ListNativeDragStartEvent, z as ListDragSource } from "./tree-component-DgfkxmVY.js";
2
- import { _ as GridListSelectEvent, a as GridListCaptionAlign, b as GridListViewportChangeDetail, c as GridListCaptionStyle, d as GridListFullElementEventMap, f as GridListItemClickDetail, g as GridListSelectDetail, h as GridListOrientation, i as GridListActivateEvent, l as GridListDataAdapter, m as GridListItemEventDetail, n as GridListViewState, o as GridListCaptionBackdrop, p as GridListItemClickEvent, r as GridListActivateDetail, s as GridListCaptionPosition, t as GridListElement, u as GridListElementEventMap, v as GridListTickleDetail, x as GridListViewportChangeEvent, y as GridListTickleEvent } from "./grid-list-D6n7WH8l.js";
2
+ import { _ as GridListSelectEvent, a as GridListCaptionAlign, b as GridListViewportChangeDetail, c as GridListCaptionStyle, d as GridListFullElementEventMap, f as GridListItemClickDetail, g as GridListSelectDetail, h as GridListOrientation, i as GridListActivateEvent, l as GridListDataAdapter, m as GridListItemEventDetail, n as GridListViewState, o as GridListCaptionBackdrop, p as GridListItemClickEvent, r as GridListActivateDetail, s as GridListCaptionPosition, t as GridListElement, u as GridListElementEventMap, v as GridListTickleDetail, x as GridListViewportChangeEvent, y as GridListTickleEvent } from "./grid-list-DaeSHv9P.js";
3
+ import { i as ListInteractionMode, m as ListSelectionMode } from "./list-selection-types-hj9Njei3.js";
3
4
  import { i as ListGroupChangeEvent, l as ListGroupToggleDetail, n as ListGroupBy, o as ListGroupInfo, r as ListGroupChangeDetail, s as ListGroupLabel, u as ListGroupToggleEvent } from "./grouping-CUKgmkMm.js";
4
- import { i as ListInteractionMode, l as ListSelectionMode } from "./list-selection-types-PjKdhF-a.js";
5
5
  export { type GridListActivateDetail, type GridListActivateEvent, type GridListCaptionAlign, type GridListCaptionBackdrop, type GridListCaptionPosition, type GridListCaptionStyle, type GridListDataAdapter, GridListElement, type GridListElementEventMap, type GridListFullElementEventMap, type GridListItemClickDetail, type GridListItemClickEvent, type GridListItemEventDetail, type GridListOrientation, type GridListSelectDetail, type GridListSelectEvent, type GridListTickleDetail, type GridListTickleEvent, type GridListViewState, type GridListViewportChangeDetail, type GridListViewportChangeEvent, type ListDragEntry, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListGroupBy, type ListGroupChangeDetail, type ListGroupChangeEvent, type ListGroupInfo, type ListGroupLabel, type ListGroupToggleDetail, type ListGroupToggleEvent, type ListInteractionMode, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListSelectionMode };
package/dist/grid-list.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import "./list-group-header.js";
2
- import { t as GridListElement } from "./grid-list-CdEkScn-.js";
2
+ import { t as GridListElement } from "./grid-list-51XsR2X2.js";
3
3
  export { GridListElement };
@@ -1,5 +1,5 @@
1
1
  import { r as IDataProvider } from "./data-provider-BAn_-oR1.js";
2
- import { l as ListSelectionMode } from "./list-selection-types-PjKdhF-a.js";
2
+ import { m as ListSelectionMode } from "./list-selection-types-hj9Njei3.js";
3
3
  import "./panel.js";
4
4
  import { LitElement, PropertyValues, nothing } from "lit";
5
5
  import { CommandId } from "@clinth/ui-commands";
@@ -106,7 +106,7 @@ declare class GroupedItemListerElement<T = unknown> extends LitElement {
106
106
  connectedCallback(): void;
107
107
  disconnectedCallback(): void;
108
108
  protected updated(changed: PropertyValues): void;
109
- protected render(): typeof nothing | import("lit").TemplateResult<1>;
109
+ protected render(): import("lit").TemplateResult<1> | typeof nothing;
110
110
  }
111
111
  declare global {
112
112
  interface HTMLElementTagNameMap {
@@ -1,2 +1,2 @@
1
- import { a as IGroupedSubComponent, c as SubComponentActivateEvent, d as SubComponentItemClickEvent, f as SubComponentSelectDetail, h as SubComponentTickleEvent, i as GroupedSelectEvent, l as SubComponentFactory, m as SubComponentTickleDetail, n as GroupedItemListerElementEventMap, o as IGroupedSubComponentEventMap, p as SubComponentSelectEvent, r as GroupedSelectDetail, s as SubComponentActivateDetail, t as GroupedItemListerElement, u as SubComponentItemClickDetail } from "./grouped-item-lister-DETte0Dh.js";
1
+ import { a as IGroupedSubComponent, c as SubComponentActivateEvent, d as SubComponentItemClickEvent, f as SubComponentSelectDetail, h as SubComponentTickleEvent, i as GroupedSelectEvent, l as SubComponentFactory, m as SubComponentTickleDetail, n as GroupedItemListerElementEventMap, o as IGroupedSubComponentEventMap, p as SubComponentSelectEvent, r as GroupedSelectDetail, s as SubComponentActivateDetail, t as GroupedItemListerElement, u as SubComponentItemClickDetail } from "./grouped-item-lister-DZIjo9nO.js";
2
2
  export { GroupedItemListerElement, type GroupedItemListerElementEventMap, type GroupedSelectDetail, type GroupedSelectEvent, type IGroupedSubComponent, type IGroupedSubComponentEventMap, type SubComponentActivateDetail, type SubComponentActivateEvent, type SubComponentFactory, type SubComponentItemClickDetail, type SubComponentItemClickEvent, type SubComponentSelectDetail, type SubComponentSelectEvent, type SubComponentTickleDetail, type SubComponentTickleEvent };
@@ -9,7 +9,7 @@ declare class IxfxIconElement extends LitElement {
9
9
  rotate: string;
10
10
  connectedCallback(): void;
11
11
  disconnectedCallback(): void;
12
- protected render(): typeof nothing | import("lit").TemplateResult<1>;
12
+ protected render(): import("lit").TemplateResult<1> | typeof nothing;
13
13
  protected updated(changed: Map<string, unknown>): void;
14
14
  static styles: import("lit").CSSResult[];
15
15
  }
package/dist/icons.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { t as IxfxIconElement } from "./icon-CDGprSdE.js";
2
- import { a as getIconEntry, c as iconBus, d as setIconFont, f as svgToDataUri, g as ICON_CLOSE, h as ICON_CHEVRON_DOWN, i as getIcon, l as registerFontIcon, m as ICON_CHECK, n as IconChangedEvent, o as getIconFont, p as ICON_CARET_RIGHT, r as IconEntry, s as hasIcon, t as IconChangedDetail, u as registerIcon } from "./index-CYndvTWH.js";
1
+ import { t as IxfxIconElement } from "./icon-DR_3rSyZ.js";
2
+ import { a as getIconEntry, c as iconBus, d as setIconFont, f as svgToDataUri, g as ICON_CLOSE, h as ICON_CHEVRON_DOWN, i as getIcon, l as registerFontIcon, m as ICON_CHECK, n as IconChangedEvent, o as getIconFont, p as ICON_CARET_RIGHT, r as IconEntry, s as hasIcon, t as IconChangedDetail, u as registerIcon } from "./index-garxxqgV.js";
3
3
  export { ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, type IconChangedDetail, type IconChangedEvent, type IconEntry, IxfxIconElement, getIcon, getIconEntry, getIconFont, hasIcon, iconBus, registerFontIcon, registerIcon, setIconFont, svgToDataUri };
@@ -288,6 +288,15 @@ function createDataListSearchAdapter(host, options) {
288
288
  function keyForElement(el) {
289
289
  return el.getAttribute(`data-key`) ?? el.getAttribute(`data-value`) ?? void 0;
290
290
  }
291
+ /** The stable keys of a set of item elements (items without a key are omitted). */
292
+ function keysOfElements(els) {
293
+ const out = /* @__PURE__ */ new Set();
294
+ for (const el of els) {
295
+ const key = keyForElement(el);
296
+ if (key !== void 0) out.add(key);
297
+ }
298
+ return out;
299
+ }
291
300
  /**
292
301
  * A lazily-built key → element index over a container. Rebuilt on first use
293
302
  * and after any child-list mutation under `root`; `invalidate()` forces a
@@ -572,6 +581,8 @@ var ListSearchController = class {
572
581
  #matches = [];
573
582
  /** Whether a filter has been pushed to the adapter and still needs undoing. */
574
583
  #filterActive = false;
584
+ /** A filter committed with Enter (sticky) that stays applied while the popover is closed. */
585
+ #kept = false;
575
586
  constructor(host, options) {
576
587
  this.#host = host;
577
588
  this.#adapter = options.adapter;
@@ -579,6 +590,7 @@ var ListSearchController = class {
579
590
  this.#modes = LIST_SEARCH_MODES.filter((m) => requested.has(m));
580
591
  this.#mode = this.#modes[0] ?? `filter`;
581
592
  this.#placeholder = options.placeholder ?? `Search…`;
593
+ this.stickyFilter = options.stickyFilter ?? false;
582
594
  this.#search = createIncrSearch({
583
595
  selector: (i) => i.label,
584
596
  fzf: options.fzf
@@ -605,6 +617,7 @@ var ListSearchController = class {
605
617
  this.#modes = LIST_SEARCH_MODES.filter((m) => set.has(m));
606
618
  if (!this.#modes.includes(this.#mode)) {
607
619
  if (this.#open) this.close();
620
+ this.clearFilter();
608
621
  this.#mode = this.#modes[0] ?? `filter`;
609
622
  }
610
623
  this.#host.requestUpdate();
@@ -624,6 +637,10 @@ var ListSearchController = class {
624
637
  get matchIndex() {
625
638
  return this.#matchIndex;
626
639
  }
640
+ /** The query of a filter kept applied after the popover closed (see {@link stickyFilter}). */
641
+ get keptFilter() {
642
+ return this.#kept ? this.#query : void 0;
643
+ }
627
644
  hostConnected() {
628
645
  const container = this.#adapter.container?.();
629
646
  if (container) {
@@ -633,29 +650,47 @@ var ListSearchController = class {
633
650
  subtree: false
634
651
  });
635
652
  }
653
+ this.#host.addEventListener(`keydown`, this.#onHostKeydown);
636
654
  this.refresh();
637
655
  }
638
656
  hostDisconnected() {
639
657
  this.#observer?.disconnect();
640
658
  this.#observer = void 0;
641
- if (this.#open) this.#teardownEffects();
659
+ this.#host.removeEventListener(`keydown`, this.#onHostKeydown);
660
+ if (this.#open || this.#kept) this.#teardownEffects();
642
661
  this.#open = false;
662
+ this.#kept = false;
643
663
  this.#unsub?.();
644
664
  this.#unsub = void 0;
645
665
  this.#search.dispose();
646
666
  }
647
- /** Open the popover in `mode` (clamped to the available set). */
667
+ /**
668
+ * Open the popover in `mode` (clamped to the available set). When it is
669
+ * already open the query is kept: the mode switches if it differs and the
670
+ * input is refocused with its text selected.
671
+ */
648
672
  open(mode) {
649
673
  if (!this.enabled) return;
674
+ if (this.#open) {
675
+ this.switchMode(this.#modes.includes(mode) ? mode : this.#mode);
676
+ this.focus();
677
+ return;
678
+ }
650
679
  this.#mode = this.#modes.includes(mode) ? mode : this.#modes[0];
651
680
  this.#open = true;
652
- this.#query = ``;
681
+ const resume = this.#kept;
682
+ this.#kept = false;
683
+ if (!resume) this.#query = ``;
653
684
  this.#matchIndex = 0;
654
685
  this.#matches = [];
686
+ if (resume && this.#mode !== `filter` && this.#filterActive) {
687
+ this.#adapter.applyFilter(void 0);
688
+ this.#filterActive = false;
689
+ }
655
690
  this.refresh();
656
- this.#search.setQuery(``);
691
+ this.#search.setQuery(this.#query);
657
692
  this.#host.requestUpdate();
658
- this.#host.updateComplete.then(() => this.#focusInput());
693
+ this.#host.updateComplete.then(() => this.#focusInput(resume));
659
694
  }
660
695
  /** Close the popover, restoring any live filter. Selection / cursor stay put. */
661
696
  close() {
@@ -668,6 +703,16 @@ var ListSearchController = class {
668
703
  this.#host.requestUpdate();
669
704
  this.#host.focus();
670
705
  }
706
+ /** Remove a filter kept by {@link stickyFilter}. No-op when none is kept. */
707
+ clearFilter() {
708
+ if (!this.#kept) return;
709
+ this.#kept = false;
710
+ this.#teardownEffects();
711
+ this.#query = ``;
712
+ this.#matches = [];
713
+ this.#search.clearQuery();
714
+ this.#host.requestUpdate();
715
+ }
671
716
  setQuery(query) {
672
717
  this.#query = query;
673
718
  this.#matchIndex = 0;
@@ -685,6 +730,21 @@ var ListSearchController = class {
685
730
  this.#host.requestUpdate();
686
731
  this.#host.updateComplete.then(() => this.#focusInput());
687
732
  }
733
+ /**
734
+ * Step through {@link registeredModes} (wrapping) and switch to the result.
735
+ * Bound to Tab / Shift+Tab in the popover input.
736
+ */
737
+ cycleMode(delta) {
738
+ const n = this.#modes.length;
739
+ if (n < 2) return;
740
+ const index = this.#modes.indexOf(this.#mode);
741
+ this.switchMode(this.#modes[(index + delta + n) % n]);
742
+ }
743
+ /** Refocus the popover input (text selected) without touching the query. No-op when closed. */
744
+ focus() {
745
+ if (!this.#open) return;
746
+ this.#host.updateComplete.then(() => this.#focusInput(true));
747
+ }
688
748
  /** One-shot: turn the current match set into the selection, staying in the current mode. */
689
749
  selectMatches() {
690
750
  if (!this.#modes.includes(`select`)) return;
@@ -697,8 +757,19 @@ var ListSearchController = class {
697
757
  prevMatch() {
698
758
  this.#cycle(-1);
699
759
  }
700
- /** Enter: in `navigate` activate the current match; then close. */
760
+ /**
761
+ * Enter: in `navigate` activate the current match; then close. In `filter`
762
+ * with {@link stickyFilter} and a query, close but keep the filter.
763
+ */
701
764
  commit() {
765
+ if (this.#mode === `filter` && this.stickyFilter && this.#filterActive) {
766
+ this.#open = false;
767
+ this.#kept = true;
768
+ clearHighlights({ key: this.#highlightKey });
769
+ this.#host.requestUpdate();
770
+ this.#host.focus();
771
+ return;
772
+ }
702
773
  if (this.#mode === `navigate`) {
703
774
  const item = this.#itemFor(this.#matches[this.#matchIndex]);
704
775
  if (item) {
@@ -729,6 +800,7 @@ var ListSearchController = class {
729
800
  /** Popover markup. Pair with `listSearchStyles` in the host's `static styles`. */
730
801
  renderField() {
731
802
  if (!this.enabled) return nothing;
803
+ if (this.#kept) return this.#renderKeptFilter();
732
804
  const hasQuery = this.#query.trim().length > 0;
733
805
  const others = this.#modes.filter((m) => m !== this.#mode);
734
806
  const showSelectMatches = this.#modes.includes(`select`) && this.#mode !== `select`;
@@ -754,15 +826,33 @@ var ListSearchController = class {
754
826
  </div>
755
827
  ${others.length > 0 || showSelectMatches ? html`
756
828
  <div class="list-search-switch">
757
- ${others.map((m) => html`<button class="list-search-btn" @click=${() => this.switchMode(m)}>${m}</button>`)}
829
+ ${others.map((m) => html`<button class="list-search-btn" title=${this.#switchTitle(m)} @click=${() => this.switchMode(m)}>${m}</button>`)}
758
830
  ${showSelectMatches ? html`<button class="list-search-btn" @click=${() => this.selectMatches()}>Select matches</button>` : nothing}
759
831
  </div>
760
832
  ` : nothing}
761
833
  </div>
762
834
  `;
763
835
  }
764
- #focusInput() {
765
- this.#host.renderRoot?.querySelector(`.${INPUT_CLASS}`)?.focus();
836
+ #renderKeptFilter() {
837
+ return html`
838
+ <div class="list-search list-search-kept" part="search-kept">
839
+ <button class="list-search-kept-label" title="Edit filter" @click=${() => this.open(`filter`)}>
840
+ Filtered: <strong>${this.#query}</strong> <span class="list-search-count">(${this.#matches.length})</span>
841
+ </button>
842
+ <button class="list-search-icon-btn" title="Clear filter (Esc)" @click=${() => this.clearFilter()}><ixfx-icon name="close" size="14"></ixfx-icon></button>
843
+ </div>
844
+ `;
845
+ }
846
+ #focusInput(selectText = false) {
847
+ const input = this.#host.renderRoot?.querySelector(`.${INPUT_CLASS}`);
848
+ input?.focus();
849
+ if (selectText) input?.select();
850
+ }
851
+ /** Switch-row button title, naming the Tab chord that reaches `mode`. */
852
+ #switchTitle(mode) {
853
+ const n = this.#modes.length;
854
+ const index = this.#modes.indexOf(this.#mode);
855
+ return `Switch to ${mode} (${[this.#modes[(index + 1) % n] === mode ? `Tab` : void 0, this.#modes[(index - 1 + n) % n] === mode ? `Shift+Tab` : void 0].filter((k) => k !== void 0).join(` / `)})`;
766
856
  }
767
857
  #onInput = (e) => {
768
858
  this.setQuery(e.target.value);
@@ -779,6 +869,13 @@ var ListSearchController = class {
779
869
  e.stopPropagation();
780
870
  this.commit();
781
871
  break;
872
+ case `Tab`:
873
+ if (this.#modes.length > 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
874
+ e.preventDefault();
875
+ e.stopPropagation();
876
+ this.cycleMode(e.shiftKey ? -1 : 1);
877
+ }
878
+ break;
782
879
  case `ArrowDown`:
783
880
  if (this.#mode === `navigate`) {
784
881
  e.preventDefault();
@@ -791,6 +888,13 @@ var ListSearchController = class {
791
888
  }
792
889
  }
793
890
  };
891
+ /** Escape on the host clears a kept filter (the open popover's input handles its own Escape). */
892
+ #onHostKeydown = (e) => {
893
+ if (!this.#kept || this.#open || e.key !== `Escape` || e.defaultPrevented) return;
894
+ e.preventDefault();
895
+ e.stopPropagation();
896
+ this.clearFilter();
897
+ };
794
898
  #cycle(delta) {
795
899
  if (this.#matches.length === 0) return;
796
900
  const n = this.#matches.length;
@@ -808,9 +912,14 @@ var ListSearchController = class {
808
912
  return this.#adapter.highlightKey ?? DEFAULT_HIGHLIGHT_KEY;
809
913
  }
810
914
  #onState(state) {
811
- if (!this.#open) return;
915
+ if (!this.#open && !this.#kept) return;
812
916
  const hasQuery = state.query.trim().length > 0;
813
917
  this.#matches = hasQuery ? [...state.results] : [];
918
+ if (!this.#open) {
919
+ this.#adapter.applyFilter(new Set(this.#matches.map((m) => m.item.key)));
920
+ this.#host.requestUpdate();
921
+ return;
922
+ }
814
923
  if (this.#matchIndex >= this.#matches.length) this.#matchIndex = 0;
815
924
  this.#applyMode();
816
925
  this.#host.requestUpdate();
@@ -970,6 +1079,36 @@ const listSearchStyles = css`
970
1079
  .list-search-icon-btn:hover {
971
1080
  color: inherit;
972
1081
  }
1082
+
1083
+ .list-search-kept {
1084
+ flex-direction: row;
1085
+ align-items: center;
1086
+ padding: 2px 4px 2px 6px;
1087
+ }
1088
+
1089
+ .list-search-kept-label {
1090
+ padding: 0;
1091
+ background: transparent;
1092
+ border: none;
1093
+ color: inherit;
1094
+ cursor: pointer;
1095
+ font: inherit;
1096
+ white-space: nowrap;
1097
+ }
1098
+
1099
+ .list-search-kept-label:hover strong {
1100
+ text-decoration: underline;
1101
+ }
1102
+
1103
+ /* Matched characters for hosts that paint highlights inside their own shadow
1104
+ root, which a page-level ::highlight() rule cannot reach. Light-DOM items
1105
+ (e.g. detail-list rows) still need a page-level rule. */
1106
+ ::highlight(incr-search-highlight),
1107
+ ::highlight(grid-list-search),
1108
+ ::highlight(data-grid-search) {
1109
+ background: var(--search-highlight-bg, var(--accent, #60a5fa));
1110
+ color: var(--search-highlight-color, var(--accent-text, #000));
1111
+ }
973
1112
  `;
974
1113
  //#endregion
975
1114
  //#region src/incr-search/tree-list-search-adapter.ts
@@ -1017,4 +1156,4 @@ function createTreeListSearchAdapter(host, options = {}) {
1017
1156
  };
1018
1157
  }
1019
1158
  //#endregion
1020
- export { LIST_SEARCH_COMMAND_IDS as a, createElementListSearchAdapter as c, createDataListSearchAdapter as d, IncrSearchTreeController as f, createFuzzySearch as h, ListSearchController as i, KeyedElementIndex as l, createAcCompletionProvider as m, listSearchStyles as n, registerListSearchCommands as o, createIncrSearch as p, LIST_SEARCH_MODES as r, createElementIncrSearch as s, createTreeListSearchAdapter as t, keyForElement as u };
1159
+ export { LIST_SEARCH_COMMAND_IDS as a, createElementListSearchAdapter as c, keysOfElements as d, createDataListSearchAdapter as f, createFuzzySearch as g, createAcCompletionProvider as h, ListSearchController as i, KeyedElementIndex as l, createIncrSearch as m, listSearchStyles as n, registerListSearchCommands as o, IncrSearchTreeController as p, LIST_SEARCH_MODES as r, createElementIncrSearch as s, createTreeListSearchAdapter as t, keyForElement as u };
@@ -1,2 +1,2 @@
1
- import { A as FuzzySearch, C as ListSearchControllerOptions, D as IncrSearchTreeOptions, E as IncrSearchTreeController, F as IncrSearchChangeCallback, I as IncrSearchOptions, L as IncrSearchResult, M as HighlightOptions, N as HighlightTarget, O as createAcCompletionProvider, P as IncrSearch, R as IncrSearchState, S as ListSearchController, T as ListSearchMode, _ as DataListSearchAdapterOptions, a as RegisterListSearchCommandsOptions, b as LIST_SEARCH_MODES, c as applyHighlights, d as createFuzzySearch, f as ElementIncrSearch, g as createElementListSearchAdapter, h as ElementListSearchHost, i as LIST_SEARCH_COMMAND_IDS, j as FuzzySearchOptions, k as ElementIncrSearchOptions, l as buildHighlightTargets, m as ElementListSearchAdapterOptions, n as createTreeListSearchAdapter, o as registerListSearchCommands, p as createElementIncrSearch, r as listSearchStyles, s as createIncrSearch, t as TreeListSearchAdapterOptions, u as clearHighlights, v as DataListSearchItem, w as ListSearchHost, x as ListSearchAdapter, y as createDataListSearchAdapter } from "./index-Dr80Zdl6.js";
1
+ import { A as FuzzySearch, C as ListSearchControllerOptions, D as IncrSearchTreeOptions, E as IncrSearchTreeController, F as IncrSearchChangeCallback, I as IncrSearchOptions, L as IncrSearchResult, M as HighlightOptions, N as HighlightTarget, O as createAcCompletionProvider, P as IncrSearch, R as IncrSearchState, S as ListSearchController, T as ListSearchMode, _ as DataListSearchAdapterOptions, a as RegisterListSearchCommandsOptions, b as LIST_SEARCH_MODES, c as applyHighlights, d as createFuzzySearch, f as ElementIncrSearch, g as createElementListSearchAdapter, h as ElementListSearchHost, i as LIST_SEARCH_COMMAND_IDS, j as FuzzySearchOptions, k as ElementIncrSearchOptions, l as buildHighlightTargets, m as ElementListSearchAdapterOptions, n as createTreeListSearchAdapter, o as registerListSearchCommands, p as createElementIncrSearch, r as listSearchStyles, s as createIncrSearch, t as TreeListSearchAdapterOptions, u as clearHighlights, v as DataListSearchItem, w as ListSearchHost, x as ListSearchAdapter, y as createDataListSearchAdapter } from "./index-BjRoPrwj.js";
2
2
  export { type DataListSearchAdapterOptions, type DataListSearchItem, type ElementIncrSearch, type ElementIncrSearchOptions, type ElementListSearchAdapterOptions, type ElementListSearchHost, type FuzzySearch, type FuzzySearchOptions, type HighlightOptions, type HighlightTarget, type IncrSearch, type IncrSearchChangeCallback, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, type IncrSearchTreeOptions as IncrSearchMillerOptions, type IncrSearchTreeOptions, type IncrSearchOptions, type IncrSearchResult, type IncrSearchState, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, type ListSearchAdapter, ListSearchController, type ListSearchControllerOptions, type ListSearchHost, type ListSearchMode, type RegisterListSearchCommandsOptions, type TreeListSearchAdapterOptions, applyHighlights, buildHighlightTargets, clearHighlights, createAcCompletionProvider, createDataListSearchAdapter, createElementIncrSearch, createElementListSearchAdapter, createFuzzySearch, createIncrSearch, createTreeListSearchAdapter, listSearchStyles, registerListSearchCommands };
@@ -1,3 +1,3 @@
1
1
  import { n as buildHighlightTargets, r as clearHighlights, t as applyHighlights } from "./highlight-B-eQrhhb.js";
2
- import { a as LIST_SEARCH_COMMAND_IDS, c as createElementListSearchAdapter, d as createDataListSearchAdapter, f as IncrSearchTreeController, h as createFuzzySearch, i as ListSearchController, m as createAcCompletionProvider, n as listSearchStyles, o as registerListSearchCommands, p as createIncrSearch, r as LIST_SEARCH_MODES, s as createElementIncrSearch, t as createTreeListSearchAdapter } from "./incr-search-JIhwB49y.js";
2
+ import { a as LIST_SEARCH_COMMAND_IDS, c as createElementListSearchAdapter, f as createDataListSearchAdapter, g as createFuzzySearch, h as createAcCompletionProvider, i as ListSearchController, m as createIncrSearch, n as listSearchStyles, o as registerListSearchCommands, p as IncrSearchTreeController, r as LIST_SEARCH_MODES, s as createElementIncrSearch, t as createTreeListSearchAdapter } from "./incr-search-2YaxUUA9.js";
3
3
  export { IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, ListSearchController, applyHighlights, buildHighlightTargets, clearHighlights, createAcCompletionProvider, createDataListSearchAdapter, createElementIncrSearch, createElementListSearchAdapter, createFuzzySearch, createIncrSearch, createTreeListSearchAdapter, listSearchStyles, registerListSearchCommands };
@@ -1,4 +1,4 @@
1
- import { t as LabelledInputBase } from "./labelled-input-base-DiTme1JO.js";
1
+ import { t as LabelledInputBase } from "./labelled-input-base-Dp_9KP0G.js";
2
2
  import { CSSResultGroup } from "lit";
3
3
  //#region src/labelled-range-input/labelled-range-input.d.ts
4
4
  declare class LabelledRangeInput extends LabelledInputBase {
@@ -1,4 +1,4 @@
1
- import "./icon-CDGprSdE.js";
1
+ import "./icon-DR_3rSyZ.js";
2
2
  import { E as TreeSearchHost } from "./tree-component-DgfkxmVY.js";
3
3
  import { o as TreeNode } from "./types-Jky6oNAp.js";
4
4
  import { ReactiveController, ReactiveControllerHost, TemplateResult, nothing } from "lit";
@@ -143,7 +143,8 @@ declare class IncrSearchTreeController {
143
143
  * - `navigate` — move the cursor to the best match; ↑/↓ cycle between matches;
144
144
  * Enter activates the current match and closes.
145
145
  * - `select` — (re)select every item whose label matches, live as you type.
146
- * - `filter` — hide items that don't match; restored when the popover closes.
146
+ * - `filter` — hide items that don't match; restored when the popover closes
147
+ * (unless `stickyFilter` keeps it on Enter).
147
148
  */
148
149
  type ListSearchMode = `navigate` | `select` | `filter`;
149
150
  /** Canonical order — used for the switch-row and to normalise a requested set. */
@@ -196,6 +197,8 @@ interface ListSearchControllerOptions<TItem> {
196
197
  modes?: readonly ListSearchMode[];
197
198
  fzf?: Partial<FzfOptions<SearchItem>>;
198
199
  placeholder?: string;
200
+ /** Initial {@link ListSearchController.stickyFilter}. Default false. */
201
+ stickyFilter?: boolean;
199
202
  }
200
203
  type ListSearchHost = ReactiveControllerHost & HTMLElement & {
201
204
  renderRoot?: DocumentFragment | HTMLElement;
@@ -208,6 +211,12 @@ type ListSearchHost = ReactiveControllerHost & HTMLElement & {
208
211
  */
209
212
  declare class ListSearchController<TItem> implements ReactiveController {
210
213
  #private;
214
+ /**
215
+ * When true, Enter in `filter` mode closes the popover but keeps the filter,
216
+ * shown as a "Filtered: …" chip. Clear it with the chip's ×, Escape on the
217
+ * host, or {@link clearFilter}; click the chip to edit the query.
218
+ */
219
+ stickyFilter: boolean;
211
220
  constructor(host: ListSearchHost, options: ListSearchControllerOptions<TItem>);
212
221
  /** `false` when no modes are available — the host should register no commands and render no field. */
213
222
  get enabled(): boolean;
@@ -225,20 +234,38 @@ declare class ListSearchController<TItem> implements ReactiveController {
225
234
  get query(): string;
226
235
  get matchCount(): number;
227
236
  get matchIndex(): number;
237
+ /** The query of a filter kept applied after the popover closed (see {@link stickyFilter}). */
238
+ get keptFilter(): string | undefined;
228
239
  hostConnected(): void;
229
240
  hostDisconnected(): void;
230
- /** Open the popover in `mode` (clamped to the available set). */
241
+ /**
242
+ * Open the popover in `mode` (clamped to the available set). When it is
243
+ * already open the query is kept: the mode switches if it differs and the
244
+ * input is refocused with its text selected.
245
+ */
231
246
  open(mode: ListSearchMode): void;
232
247
  /** Close the popover, restoring any live filter. Selection / cursor stay put. */
233
248
  close(): void;
249
+ /** Remove a filter kept by {@link stickyFilter}. No-op when none is kept. */
250
+ clearFilter(): void;
234
251
  setQuery(query: string): void;
235
252
  /** Re-interpret the current query under a new mode (undoing the old mode's effect). */
236
253
  switchMode(next: ListSearchMode): void;
254
+ /**
255
+ * Step through {@link registeredModes} (wrapping) and switch to the result.
256
+ * Bound to Tab / Shift+Tab in the popover input.
257
+ */
258
+ cycleMode(delta: 1 | -1): void;
259
+ /** Refocus the popover input (text selected) without touching the query. No-op when closed. */
260
+ focus(): void;
237
261
  /** One-shot: turn the current match set into the selection, staying in the current mode. */
238
262
  selectMatches(): void;
239
263
  nextMatch(): void;
240
264
  prevMatch(): void;
241
- /** Enter: in `navigate` activate the current match; then close. */
265
+ /**
266
+ * Enter: in `navigate` activate the current match; then close. In `filter`
267
+ * with {@link stickyFilter} and a query, close but keep the filter.
268
+ */
242
269
  commit(): void;
243
270
  /** Rebuild the searchable item set from the adapter. Called on open and on container mutation. */
244
271
  refresh(): void;
@@ -1,4 +1,4 @@
1
- import "./index-CoqtMSd9.js";
1
+ import "./index-BUB5SICW.js";
2
2
  import { CSSResultGroup, LitElement, PropertyValues } from "lit";
3
3
  import { Colour } from "@ixfx/visual";
4
4
  //#region src/colour-picker/types.d.ts
@@ -1,4 +1,4 @@
1
- import { t as LabelledInputBase } from "./labelled-input-base-DiTme1JO.js";
1
+ import { t as LabelledInputBase } from "./labelled-input-base-Dp_9KP0G.js";
2
2
  import { n as EditableLabel } from "./editable-label-rzXkjf1H.js";
3
3
  import { n as WheelNudgeConsumer, t as WheelDirection } from "./wheel-nudge-By5s_ioH.js";
4
4
  import { f as SliderMarkerStyle, m as SliderSingleStyle } from "./slider-input-BxURAAmD.js";
@@ -1,6 +1,6 @@
1
- import "./icon-CDGprSdE.js";
1
+ import "./icon-DR_3rSyZ.js";
2
2
  import { o as TreeNode } from "./types-Jky6oNAp.js";
3
- import { i as MenuContainer, n as MenuTrigger, r as MenuTriggerCommandDetail, t as MenuItem } from "./menu-item-bF6narIz.js";
3
+ import { i as MenuContainer, n as MenuTrigger, r as MenuTriggerCommandDetail, t as MenuItem } from "./menu-item-B0zqw2xp.js";
4
4
  import { LitElement, TemplateResult } from "lit";
5
5
  import { CommandRegistry, KeyboardManager } from "@clinth/ui-commands";
6
6
  //#region src/menu/menu-bar.d.ts
@@ -11,6 +11,7 @@ declare class MenuBar extends LitElement {
11
11
  disconnectedCallback(): void;
12
12
  private _setInputMode;
13
13
  private _handlePointerMove;
14
+ private _handlePointerOver;
14
15
  private _getTriggers;
15
16
  private _handleTriggerOpen;
16
17
  private _handleTriggerClose;