@ixfx/components 0.9.7 → 0.10.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 (155) hide show
  1. package/bundle/index.d.ts +839 -68
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +16398 -13118
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +2 -2
  6. package/dist/ac-text.d.ts +1 -1
  7. package/dist/ac-text.js +2 -2
  8. package/dist/{ac-token-TCLAZeVg.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
  9. package/dist/{ac-token-TCLAZeVg.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
  10. package/dist/ac-token.d.ts +1 -1
  11. package/dist/ac-token.js +2 -2
  12. package/dist/button.d.ts +1 -1
  13. package/dist/button.d.ts.map +1 -1
  14. package/dist/checkbox.js +1 -1
  15. package/dist/{colour-picker-CSxwUmtE.js → colour-picker-R73i0QTP.js} +2 -2
  16. package/dist/{colour-picker-CSxwUmtE.js.map → colour-picker-R73i0QTP.js.map} +1 -1
  17. package/dist/colour-picker.d.ts +1 -1
  18. package/dist/colour-picker.js +1 -1
  19. package/dist/crumbs.d.ts +2 -2
  20. package/dist/crumbs.js +2 -2
  21. package/dist/data-display.js +1 -1
  22. package/dist/{data-grid-8N0Kd5-6.d.ts → data-grid-C5hk_pzK.d.ts} +34 -4
  23. package/dist/data-grid-C5hk_pzK.d.ts.map +1 -0
  24. package/dist/data-grid.d.ts +2 -2
  25. package/dist/data-grid.js +126 -18
  26. package/dist/data-grid.js.map +1 -1
  27. package/dist/{detail-list-CQguZg9h.d.ts → detail-list-CxPpv89T.d.ts} +6 -5
  28. package/dist/detail-list-CxPpv89T.d.ts.map +1 -0
  29. package/dist/detail-list.d.ts +3 -3
  30. package/dist/detail-list.js +5 -3
  31. package/dist/detail-list.js.map +1 -1
  32. package/dist/editable-label.js +1 -1
  33. package/dist/{fallbacks-BcKGq-2F.js → fallbacks-DQ_5OsmR.js} +2 -2
  34. package/dist/{fallbacks-BcKGq-2F.js.map → fallbacks-DQ_5OsmR.js.map} +1 -1
  35. package/dist/{grid-list-CSw1VMXT.d.ts → grid-list-BGvoWbZz.d.ts} +30 -69
  36. package/dist/grid-list-BGvoWbZz.d.ts.map +1 -0
  37. package/dist/{grid-list-mL0GJTQR.js → grid-list-DSnYOGh7.js} +64 -233
  38. package/dist/grid-list-DSnYOGh7.js.map +1 -0
  39. package/dist/grid-list.d.ts +2 -2
  40. package/dist/grid-list.js +1 -1
  41. package/dist/{grouped-item-lister-CEZ72VOs.d.ts → grouped-item-lister-fdZHVxFM.d.ts} +2 -2
  42. package/dist/{grouped-item-lister-CEZ72VOs.d.ts.map → grouped-item-lister-fdZHVxFM.d.ts.map} +1 -1
  43. package/dist/grouped-item-lister.d.ts +1 -1
  44. package/dist/{icon-Dy33gu4Z.js → icon-BCJJYEpm.js} +2 -2
  45. package/dist/{icon-Dy33gu4Z.js.map → icon-BCJJYEpm.js.map} +1 -1
  46. package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +2 -2
  47. package/dist/icon-CDGprSdE.d.ts.map +1 -0
  48. package/dist/icons.d.ts +2 -2
  49. package/dist/icons.js +1 -1
  50. package/dist/incr-search.d.ts +1 -1
  51. package/dist/{index--qnhBWZJ.d.ts → index--5BSdbnL.d.ts} +2 -2
  52. package/dist/{index--qnhBWZJ.d.ts.map → index--5BSdbnL.d.ts.map} +1 -1
  53. package/dist/{index-C59-JEPl.d.ts → index-9AhaHIT2.d.ts} +3 -3
  54. package/dist/{index-C59-JEPl.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
  55. package/dist/{index-DsjpDksO.d.ts → index-CS9yM8L-.d.ts} +2 -2
  56. package/dist/{index-DsjpDksO.d.ts.map → index-CS9yM8L-.d.ts.map} +1 -1
  57. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
  58. package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
  59. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +2 -2
  60. package/dist/{index-CJ5fshD3.d.ts.map → index-UvnoZUAo.d.ts.map} +1 -1
  61. package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -2
  62. package/dist/{index-BOUaDIW-.d.ts.map → index-tq6f8007.d.ts.map} +1 -1
  63. package/dist/index.d.ts +648 -22
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +4815 -2323
  66. package/dist/index.js.map +1 -1
  67. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
  68. package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
  69. package/dist/labelled-radial-input.d.ts +2 -2
  70. package/dist/labelled-radial-input.d.ts.map +1 -1
  71. package/dist/labelled-radial-input.js +2 -2
  72. package/dist/labelled-range-input.d.ts +1 -1
  73. package/dist/{labelled-slider-input-aEYDvW2S.js → labelled-slider-input-CF2RtzgG.js} +3 -3
  74. package/dist/{labelled-slider-input-aEYDvW2S.js.map → labelled-slider-input-CF2RtzgG.js.map} +1 -1
  75. package/dist/labelled-slider-input.d.ts +1 -1
  76. package/dist/labelled-slider-input.js +1 -1
  77. package/dist/{list-native-drag-controller-B0hWdbtM.js → list-native-drag-controller-D97TYjn1.js} +36 -5
  78. package/dist/list-native-drag-controller-D97TYjn1.js.map +1 -0
  79. package/dist/{list-native-drag-controller-Cmpx7jnx.d.ts → list-native-drag-controller-DWiXQZou.d.ts} +3 -2
  80. package/dist/list-native-drag-controller-DWiXQZou.d.ts.map +1 -0
  81. package/dist/{menu-CMXhIaNZ.js → menu-C8a-84S5.js} +4 -4
  82. package/dist/{menu-CMXhIaNZ.js.map → menu-C8a-84S5.js.map} +1 -1
  83. package/dist/{menu-item-ZmkXNjek.d.ts → menu-item-CZi9vy5O.d.ts} +2 -2
  84. package/dist/{menu-item-ZmkXNjek.d.ts.map → menu-item-CZi9vy5O.d.ts.map} +1 -1
  85. package/dist/{menu-item-BYGQzyCe.js → menu-item-DzizkMH-.js} +3 -3
  86. package/dist/{menu-item-BYGQzyCe.js.map → menu-item-DzizkMH-.js.map} +1 -1
  87. package/dist/menu.d.ts +2 -2
  88. package/dist/menu.js +2 -2
  89. package/dist/miller.d.ts +2 -2
  90. package/dist/miller.js +1 -1
  91. package/dist/narrowed-text.js +1 -1
  92. package/dist/notifier.js +1 -1
  93. package/dist/pan-text-CoYmt2qd.d.ts +67 -0
  94. package/dist/pan-text-CoYmt2qd.d.ts.map +1 -0
  95. package/dist/pan-text-CqtvjPyK.js +235 -0
  96. package/dist/pan-text-CqtvjPyK.js.map +1 -0
  97. package/dist/panel.d.ts +1 -1
  98. package/dist/panel.js +1 -1
  99. package/dist/polar-pad.js +1 -1
  100. package/dist/{radial-input-DyxfbNzD.js → radial-input-KMVltQfe.js} +2 -2
  101. package/dist/{radial-input-DyxfbNzD.js.map → radial-input-KMVltQfe.js.map} +1 -1
  102. package/dist/radial-input.js +1 -1
  103. package/dist/range-input.js +1 -1
  104. package/dist/range.js +1 -1
  105. package/dist/select-horiz.js +1 -1
  106. package/dist/{slider-input-Cb5uSV42.js → slider-input-ByHdotzp.js} +2 -2
  107. package/dist/{slider-input-Cb5uSV42.js.map → slider-input-ByHdotzp.js.map} +1 -1
  108. package/dist/slider-input.js +1 -1
  109. package/dist/snackbar.js +1 -1
  110. package/dist/{split-layout-Bx0g8k8-.js → split-layout-3yBOEVZW.js} +2 -2
  111. package/dist/{split-layout-Bx0g8k8-.js.map → split-layout-3yBOEVZW.js.map} +1 -1
  112. package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-JK3xWVX2.d.ts} +2 -2
  113. package/dist/{split-layout-C5SYbDrq.d.ts.map → split-layout-JK3xWVX2.d.ts.map} +1 -1
  114. package/dist/split-layout.d.ts +1 -1
  115. package/dist/split-layout.js +1 -1
  116. package/dist/style.css +2 -2
  117. package/dist/swipe.js +1 -1
  118. package/dist/{tab-list-DbMIL520.d.ts → tab-list-CGyPt07Z.d.ts} +2 -2
  119. package/dist/{tab-list-DbMIL520.d.ts.map → tab-list-CGyPt07Z.d.ts.map} +1 -1
  120. package/dist/tabs.d.ts +1 -1
  121. package/dist/tabs.js +1 -1
  122. package/dist/{timeline-THyvH8xy.js → timeline-CFlBFFGZ.js} +2 -2
  123. package/dist/{timeline-THyvH8xy.js.map → timeline-CFlBFFGZ.js.map} +1 -1
  124. package/dist/timeline.js +1 -1
  125. package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +2 -2
  126. package/dist/{titlebar-B5zSTZnF.d.ts.map → titlebar-Tqu-VvMU.d.ts.map} +1 -1
  127. package/dist/titlebar.d.ts +1 -1
  128. package/dist/titlebar.js +2 -2
  129. package/dist/{tree-DAFBO_MF.js → tree-C25xYUa6.js} +5 -3
  130. package/dist/tree-C25xYUa6.js.map +1 -0
  131. package/dist/{tree-component-BW2iCFq9.d.ts → tree-component-mw8x-n2Y.d.ts} +4 -2
  132. package/dist/tree-component-mw8x-n2Y.d.ts.map +1 -0
  133. package/dist/tree.d.ts +4 -3
  134. package/dist/tree.d.ts.map +1 -1
  135. package/dist/tree.js +1 -1
  136. package/dist/{vertical-list-CHrXmmQ3.d.ts → vertical-list--tFanQwM.d.ts} +92 -4
  137. package/dist/vertical-list--tFanQwM.d.ts.map +1 -0
  138. package/dist/vertical-list.d.ts +2 -2
  139. package/dist/vertical-list.js +618 -29
  140. package/dist/vertical-list.js.map +1 -1
  141. package/dist/xy-pad.js +1 -1
  142. package/docs-user/data-grid.md +59 -0
  143. package/docs-user/grid-list.md +14 -0
  144. package/docs-user/index.json +2 -2
  145. package/package.json +1 -1
  146. package/dist/data-grid-8N0Kd5-6.d.ts.map +0 -1
  147. package/dist/detail-list-CQguZg9h.d.ts.map +0 -1
  148. package/dist/grid-list-CSw1VMXT.d.ts.map +0 -1
  149. package/dist/grid-list-mL0GJTQR.js.map +0 -1
  150. package/dist/icon-DR_3rSyZ.d.ts.map +0 -1
  151. package/dist/list-native-drag-controller-B0hWdbtM.js.map +0 -1
  152. package/dist/list-native-drag-controller-Cmpx7jnx.d.ts.map +0 -1
  153. package/dist/tree-DAFBO_MF.js.map +0 -1
  154. package/dist/tree-component-BW2iCFq9.d.ts.map +0 -1
  155. package/dist/vertical-list-CHrXmmQ3.d.ts.map +0 -1
@@ -1,7 +1,8 @@
1
- import { L as ListNativeDragStartEvent, P as ListDragPreviewRenderer } from "./tree-component-BW2iCFq9.js";
2
- import { S as ListSearchController } from "./index--qnhBWZJ.js";
1
+ import { F as ListDragPreviewSourceResolver, P as ListDragPreviewRenderer, R as ListNativeDragStartEvent } from "./tree-component-mw8x-n2Y.js";
2
+ import { S as ListSearchController } from "./index--5BSdbnL.js";
3
+ import "./pan-text-CoYmt2qd.js";
3
4
  import { i as ListInteractionMode, l as ListSelectionMode } from "./list-selection-types-B5ioL-dG.js";
4
- import "./list-native-drag-controller-Cmpx7jnx.js";
5
+ import "./list-native-drag-controller-DWiXQZou.js";
5
6
  import { i as TickledItem, n as TickledController } from "./tickled-controller-C1ZsHpyg.js";
6
7
  import { LitElement, PropertyValues, ReactiveController, ReactiveControllerHost, html } from "lit";
7
8
  import { CommandRegistry } from "@clinth/ui-commands";
@@ -365,70 +366,6 @@ interface GridListFullElementEventMap extends GridListElementEventMap {
365
366
  'list-native-drag-start': ListNativeDragStartEvent;
366
367
  }
367
368
  //#endregion
368
- //#region src/pan-text/pan-text.d.ts
369
- type PanTextMode = `hover` | `loop`;
370
- declare class PanTextElement extends LitElement {
371
- direction: `start` | `end`;
372
- disabled: boolean;
373
- /**
374
- * Interaction mode.
375
- * - `hover` (default): pans once while hovered.
376
- * - `loop`: pans repeatedly — dwell 2s at the end, reset to the start,
377
- * and pan again — until `stopLoop()` is called. Auto-starts when set.
378
- */
379
- mode: PanTextMode;
380
- private _isOverflowing;
381
- private _isHovering;
382
- private _loopActive;
383
- private _loopAtEnd;
384
- private _textEl;
385
- private _overflow;
386
- private _resizeObserver;
387
- private _loopTimer;
388
- connectedCallback(): void;
389
- disconnectedCallback(): void;
390
- firstUpdated(): void;
391
- protected updated(changed: PropertyValues<this>): void;
392
- /**
393
- * Whether a loop pan is currently active (between `startLoop()` and `stopLoop()`).
394
- */
395
- get looping(): boolean;
396
- /**
397
- * Begin looping: pan to the end, dwell there for 2 seconds, reset to the
398
- * start and pan again, repeating until `stopLoop()` is called. A no-op when
399
- * `disabled`, when there is nothing to reveal, or under reduced-motion.
400
- */
401
- startLoop(): void;
402
- /**
403
- * Stop a loop started with `startLoop()` and snap back to the rest position.
404
- */
405
- stopLoop(): void;
406
- private _prefersReducedMotion;
407
- private _panDuration;
408
- private _clearLoopTimer;
409
- private _scheduleLoopPan;
410
- private _onMouseEnter;
411
- private _onMouseLeave;
412
- /**
413
- * Measures how far the slotted text overflows its container. The measurement
414
- * is taken on the inner `.text` span (which clips with an ellipsis), not on
415
- * the host — the host never overflows, so measuring it always yielded zero
416
- * and the hover interaction never activated.
417
- *
418
- * Skipped while hovering, because the hover styles switch `.text` to
419
- * `overflow: visible` and the measurement would collapse to zero mid-pan.
420
- */
421
- private _measure;
422
- private _textStyle;
423
- protected render(): import("lit").TemplateResult<1>;
424
- static styles: import("lit").CSSResult[];
425
- }
426
- declare global {
427
- interface HTMLElementTagNameMap {
428
- 'ixfx-pan-text': PanTextElement;
429
- }
430
- }
431
- //#endregion
432
369
  //#region src/grid-list/grid-list.d.ts
433
370
  declare class GridListElement<T = unknown> extends LitElement {
434
371
  #private;
@@ -511,7 +448,31 @@ declare class GridListElement<T = unknown> extends LitElement {
511
448
  * as selection changes. Defaults to the shared built-in preview.
512
449
  */
513
450
  dragPreviewRenderer: ListDragPreviewRenderer<T> | undefined;
451
+ /**
452
+ * Optional synchronous resolver that supplies an already-loaded
453
+ * `CanvasImageSource` for each drag entry's preview thumbnail.
454
+ *
455
+ * Called before the default descendant-`<img>` lookup. Must return an
456
+ * already-decoded image (e.g. `<img>`, `<canvas>`, `<video>`, `ImageBitmap`)
457
+ * or `undefined`. Returning `undefined` defers to standard DOM discovery.
458
+ * The consumer owns the returned source and its lifetime.
459
+ *
460
+ * This allows consumers to provide images that live inside their own shadow
461
+ * roots or other encapsulated contexts without grid-list needing to
462
+ * traverse those boundaries.
463
+ */
464
+ dragPreviewSource: ListDragPreviewSourceResolver<T> | undefined;
514
465
  searchModes: string | undefined;
466
+ /**
467
+ * Opt-in scroll snapping for `row` / `column` orientations (no effect in
468
+ * `grid`). Cells are virtualized — only the visible window is ever in the
469
+ * DOM, absolutely positioned via transform — so native CSS
470
+ * `scroll-snap-type` can't be used (it can only snap to boxes that actually
471
+ * exist, and the snap target would pop in/out as the window shifts).
472
+ * Instead, once scrolling settles, the viewport is nudged with a smooth
473
+ * `scrollTo` to the nearest item/row boundary.
474
+ */
475
+ snapToItem: boolean;
515
476
  /**
516
477
  * Data items for data-backed mode. When set along with `itemAdapter`, the
517
478
  * component operates in data mode instead of element mode.
@@ -644,5 +605,5 @@ interface GridListElement {
644
605
  addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
645
606
  }
646
607
  //#endregion
647
- export { ListSelectionModes as A, TreeKeyboardNavCallbacks as C, ListSelectionController as D, TreeKeyboardNavItemId as E, DragSelectRect as M, ListDragSelectController as N, ListSelectionControllerConfig as O, ListDragSelectControllerConfig as P, GridListViewportChangeEvent as S, TreeKeyboardNavControllerConfig as T, GridListSelectDetail as _, GridListActivateEvent as a, GridListTickleEvent as b, GridListCaptionPosition as c, GridListElementEventMap as d, GridListFullElementEventMap as f, GridListOrientation as g, GridListItemEventDetail as h, GridListActivateDetail as i, isMultiMode as j, ListSelectionGesture as k, GridListCaptionStyle as l, GridListItemClickEvent as m, PanTextElement as n, GridListCaptionAlign as o, GridListItemClickDetail as p, PanTextMode as r, GridListCaptionBackdrop as s, GridListElement as t, GridListDataAdapter as u, GridListSelectEvent as v, TreeKeyboardNavController as w, GridListViewportChangeDetail as x, GridListTickleDetail as y };
648
- //# sourceMappingURL=grid-list-CSw1VMXT.d.ts.map
608
+ export { DragSelectRect as A, TreeKeyboardNavControllerConfig as C, ListSelectionGesture as D, ListSelectionControllerConfig as E, ListDragSelectControllerConfig as M, ListSelectionModes as O, TreeKeyboardNavController as S, ListSelectionController as T, GridListTickleDetail as _, GridListCaptionBackdrop as a, GridListViewportChangeEvent as b, GridListDataAdapter as c, GridListItemClickDetail as d, GridListItemClickEvent as f, GridListSelectEvent as g, GridListSelectDetail as h, GridListCaptionAlign as i, ListDragSelectController as j, isMultiMode as k, GridListElementEventMap as l, GridListOrientation as m, GridListActivateDetail as n, GridListCaptionPosition as o, GridListItemEventDetail as p, GridListActivateEvent as r, GridListCaptionStyle as s, GridListElement as t, GridListFullElementEventMap as u, GridListTickleEvent as v, TreeKeyboardNavItemId as w, TreeKeyboardNavCallbacks as x, GridListViewportChangeDetail as y };
609
+ //# sourceMappingURL=grid-list-BGvoWbZz.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-list-BGvoWbZz.d.ts","names":[],"sources":["../src/interaction/list-drag-select-controller.ts","../src/interaction/list-selection-controller.ts","../src/interaction/tree-keyboard-controller.ts","../src/grid-list/types.ts","../src/grid-list/grid-list.ts"],"mappings":"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"}
@@ -1,19 +1,19 @@
1
1
  import { t as TickledController } from "./tickled-controller-Dh1Uh_vG.js";
2
2
  import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
3
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
3
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
4
4
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
5
5
  import { c as createElementListSearchAdapter, d as createDataListSearchAdapter, i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, u as keyForElement } from "./incr-search-C05WjbZh.js";
6
- import { t as ListNativeDragController } from "./list-native-drag-controller-B0hWdbtM.js";
6
+ import { t as ListNativeDragController } from "./list-native-drag-controller-D97TYjn1.js";
7
7
  import { r as ListDragSelectController, t as ListSelectionController } from "./list-selection-controller-SA4piSBi.js";
8
8
  import { i as listItemFadeKeyframes } from "./list-item-animation-BUoEKi5s.js";
9
9
  import "./interaction-BskmlA9t.js";
10
10
  import { t as scrollFadeStyles } from "./scroll-fade-CAs1EabA.js";
11
+ import "./pan-text-CqtvjPyK.js";
11
12
  import { LitElement, css, html } from "lit";
12
- import { property, query, state } from "lit/decorators.js";
13
+ import { property, state } from "lit/decorators.js";
13
14
  import { createCommandRegistry } from "@clinth/ui-commands";
14
15
  import { repeat } from "lit/directives/repeat.js";
15
16
  import { createRef, ref } from "lit/directives/ref.js";
16
- import { classMap } from "lit/directives/class-map.js";
17
17
  //#region src/grid-list/grid-list-source.ts
18
18
  const ITEM_SELECTOR$1 = `:scope > *`;
19
19
  const SYNTHETIC_PREFIX = `gl-auto-`;
@@ -234,236 +234,11 @@ var DataGridListSource = class {
234
234
  }
235
235
  };
236
236
  //#endregion
237
- //#region src/pan-text/pan-text.ts
238
- const SPEED = 45;
239
- const END_PADDING = 4;
240
- const START_DELAY = 300;
241
- const END_DWELL = 2e3;
242
- const RESET_DURATION = 400;
243
- const PAN_EASING = `cubic-bezier(0.25, 0.46, 0.45, 0.94)`;
244
- let PanTextElement = class PanTextElement extends LitElement {
245
- constructor(..._args) {
246
- super(..._args);
247
- this.direction = `end`;
248
- this.disabled = false;
249
- this.mode = `hover`;
250
- this._isOverflowing = false;
251
- this._isHovering = false;
252
- this._loopActive = false;
253
- this._loopAtEnd = false;
254
- this._overflow = 0;
255
- this._resizeObserver = null;
256
- this._loopTimer = 0;
257
- this._onMouseEnter = () => {
258
- this._isHovering = true;
259
- };
260
- this._onMouseLeave = () => {
261
- this._isHovering = false;
262
- };
263
- this._measure = () => {
264
- if (this._isHovering || this._loopAtEnd) return;
265
- const el = this._textEl;
266
- if (!el) return;
267
- this._overflow = Math.max(0, el.scrollWidth - el.clientWidth);
268
- const overflowing = this._overflow > 0;
269
- this.classList.toggle(`is-overflowing`, overflowing);
270
- if (overflowing !== this._isOverflowing) this._isOverflowing = overflowing;
271
- if (this._loopActive && this.mode === `loop` && !this.disabled && overflowing && this._loopTimer === 0) this._scheduleLoopPan(START_DELAY);
272
- if (!overflowing && this._loopAtEnd) {
273
- this._loopAtEnd = false;
274
- this.requestUpdate();
275
- }
276
- };
277
- }
278
- connectedCallback() {
279
- super.connectedCallback();
280
- this._resizeObserver = new ResizeObserver(() => this._measure());
281
- this.addEventListener(`mouseenter`, this._onMouseEnter);
282
- this.addEventListener(`mouseleave`, this._onMouseLeave);
283
- }
284
- disconnectedCallback() {
285
- super.disconnectedCallback();
286
- this._clearLoopTimer();
287
- this._loopActive = false;
288
- this._loopAtEnd = false;
289
- this._resizeObserver?.disconnect();
290
- this._resizeObserver = null;
291
- this.removeEventListener(`mouseenter`, this._onMouseEnter);
292
- this.removeEventListener(`mouseleave`, this._onMouseLeave);
293
- }
294
- firstUpdated() {
295
- this._measure();
296
- this._resizeObserver?.observe(this);
297
- document.fonts?.ready.then(() => this._measure());
298
- if (this.mode === `loop`) this.startLoop();
299
- }
300
- updated(changed) {
301
- if (changed.has(`mode`)) {
302
- if (this.mode === `loop`) this.startLoop();
303
- else this.stopLoop();
304
- }
305
- if (changed.has(`disabled`) && this.disabled) this.stopLoop();
306
- this._measure();
307
- }
308
- /**
309
- * Whether a loop pan is currently active (between `startLoop()` and `stopLoop()`).
310
- */
311
- get looping() {
312
- return this._loopActive;
313
- }
314
- /**
315
- * Begin looping: pan to the end, dwell there for 2 seconds, reset to the
316
- * start and pan again, repeating until `stopLoop()` is called. A no-op when
317
- * `disabled`, when there is nothing to reveal, or under reduced-motion.
318
- */
319
- startLoop() {
320
- if (this.disabled || this._prefersReducedMotion()) return;
321
- this._loopActive = true;
322
- this._loopAtEnd = false;
323
- this.requestUpdate();
324
- if (this._isOverflowing && this._loopTimer === 0) this._scheduleLoopPan(START_DELAY);
325
- }
326
- /**
327
- * Stop a loop started with `startLoop()` and snap back to the rest position.
328
- */
329
- stopLoop() {
330
- if (!this._loopActive && !this._loopAtEnd && this._loopTimer === 0) return;
331
- this._clearLoopTimer();
332
- this._loopActive = false;
333
- this._loopAtEnd = false;
334
- this.requestUpdate();
335
- }
336
- _prefersReducedMotion() {
337
- return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches ?? false;
338
- }
339
- _panDuration() {
340
- return Math.max(1.5, (this._overflow + END_PADDING) / SPEED);
341
- }
342
- _clearLoopTimer() {
343
- if (this._loopTimer !== 0) {
344
- clearTimeout(this._loopTimer);
345
- this._loopTimer = 0;
346
- }
347
- }
348
- _scheduleLoopPan(delay) {
349
- this._clearLoopTimer();
350
- this._loopTimer = window.setTimeout(() => {
351
- this._loopTimer = 0;
352
- if (!this._loopActive || this.disabled || !this._isOverflowing) return;
353
- this._loopAtEnd = true;
354
- this.requestUpdate();
355
- const dwell = this._panDuration() * 1e3 + END_DWELL;
356
- this._loopTimer = window.setTimeout(() => {
357
- this._loopTimer = 0;
358
- if (!this._loopActive) return;
359
- this._loopAtEnd = false;
360
- this.requestUpdate();
361
- this._scheduleLoopPan(700);
362
- }, dwell);
363
- }, delay);
364
- }
365
- _textStyle() {
366
- if (!this._isOverflowing) return ``;
367
- const distance = this._overflow + END_PADDING;
368
- const duration = Math.max(1.5, distance / SPEED);
369
- const revealEnd = this.direction === `end`;
370
- const restX = revealEnd ? 0 : -distance;
371
- const hoverX = revealEnd ? -distance : 0;
372
- if (this._loopActive && this.mode === `loop`) {
373
- if (this._loopAtEnd) return [
374
- `transform: translateX(${hoverX}px)`,
375
- `transition: transform ${duration}s ${PAN_EASING}`,
376
- `overflow: visible`,
377
- `text-overflow: clip`
378
- ].join(`; `);
379
- return [
380
- `transform: translateX(${restX}px)`,
381
- `transition: transform ${RESET_DURATION}ms ${PAN_EASING}`,
382
- revealEnd ? `` : `overflow: visible; text-overflow: clip`
383
- ].filter(Boolean).join(`; `);
384
- }
385
- if (this._isHovering) return [
386
- `transform: translateX(${hoverX}px)`,
387
- `transition: transform ${duration}s ${PAN_EASING} ${START_DELAY}ms`,
388
- `overflow: visible`,
389
- `text-overflow: clip`
390
- ].join(`; `);
391
- return [
392
- `transform: translateX(${restX}px)`,
393
- `transition: transform 400ms ${PAN_EASING}`,
394
- revealEnd ? `` : `overflow: visible; text-overflow: clip`
395
- ].filter(Boolean).join(`; `);
396
- }
397
- render() {
398
- const textClasses = {
399
- "is-overflowing": this._isOverflowing,
400
- "is-hovering": this._isHovering
401
- };
402
- return html`
403
- <span class="text ${classMap(textClasses)}" part="text" style=${this._textStyle()}>
404
- <slot @slotchange=${this._measure}></slot>
405
- </span>
406
- `;
407
- }
408
- static {
409
- this.styles = [themeFallbacks, css`
410
- /* Renders like plain inline text: no colours, border, padding or margin
411
- of its own — it only adds the clipping needed to pan on hover. */
412
- :host {
413
- display: inline-block;
414
- overflow: hidden;
415
- white-space: nowrap;
416
- max-width: 100%;
417
- box-sizing: border-box;
418
- font: inherit;
419
- color: inherit;
420
- }
421
-
422
- :host([disabled]) {
423
- opacity: var(--disabled-opacity, 0.5);
424
- pointer-events: none;
425
- }
426
-
427
- .text {
428
- display: block;
429
- overflow: hidden;
430
- text-overflow: ellipsis;
431
- white-space: nowrap;
432
- will-change: transform;
433
- }
434
-
435
- @media (prefers-reduced-motion: reduce) {
436
- .text {
437
- transition: none !important;
438
- transform: none !important;
439
- }
440
- }
441
- `];
442
- }
443
- };
444
- __decorate([property({
445
- type: String,
446
- attribute: `direction`
447
- })], PanTextElement.prototype, "direction", void 0);
448
- __decorate([property({
449
- type: Boolean,
450
- attribute: `disabled`
451
- })], PanTextElement.prototype, "disabled", void 0);
452
- __decorate([property({
453
- type: String,
454
- attribute: `mode`,
455
- reflect: true
456
- })], PanTextElement.prototype, "mode", void 0);
457
- __decorate([state()], PanTextElement.prototype, "_isOverflowing", void 0);
458
- __decorate([state()], PanTextElement.prototype, "_isHovering", void 0);
459
- __decorate([state()], PanTextElement.prototype, "_loopActive", void 0);
460
- __decorate([state()], PanTextElement.prototype, "_loopAtEnd", void 0);
461
- __decorate([query(`.text`)], PanTextElement.prototype, "_textEl", void 0);
462
- PanTextElement = __decorate([safeCustomElement(`ixfx-pan-text`)], PanTextElement);
463
- //#endregion
464
237
  //#region src/grid-list/grid-list.ts
465
238
  const ITEM_SELECTOR = `:scope > *`;
466
239
  const MIN_ITEM_SIZE = 16;
240
+ /** How long scrolling must be idle before `snap-to-item` settles the viewport. */
241
+ const SNAP_DEBOUNCE_MS = 120;
467
242
  /**
468
243
  * How long the host keeps the `[reflowing]` attribute after items are inserted
469
244
  * mid-list — long enough for the cell move-transition and the enter animation
@@ -558,6 +333,7 @@ let GridListElement = class GridListElement extends LitElement {
558
333
  this.itemWrap = `stop`;
559
334
  this.itemsDraggable = false;
560
335
  this.marqueeFromCellBlank = false;
336
+ this.snapToItem = false;
561
337
  this.items = [];
562
338
  this._scrollTop = 0;
563
339
  this._scrollLeft = 0;
@@ -565,6 +341,7 @@ let GridListElement = class GridListElement extends LitElement {
565
341
  this._viewportWidth = 0;
566
342
  this.#viewportRef = createRef();
567
343
  this.#scrollRaf = 0;
344
+ this.#snapTimer = 0;
568
345
  this.#items = [];
569
346
  this.#itemWrap = `stop`;
570
347
  this.#entering = /* @__PURE__ */ new Set();
@@ -624,6 +401,7 @@ let GridListElement = class GridListElement extends LitElement {
624
401
  rowHeight: this.#rowHeight()
625
402
  }),
626
403
  getRenderer: () => this.dragPreviewRenderer,
404
+ getDragPreviewSourceResolver: () => this.dragPreviewSource,
627
405
  dispatch: (detail) => this._dispatch(`list-native-drag-start`, detail, true),
628
406
  onActiveChange: (active, originKey) => {
629
407
  this.#nativeDragging = active;
@@ -689,6 +467,7 @@ let GridListElement = class GridListElement extends LitElement {
689
467
  this._scrollLeft = el.scrollLeft;
690
468
  this.#emitViewportChange();
691
469
  });
470
+ this.#scheduleSnap();
692
471
  };
693
472
  this._onKeyDown = (e) => {
694
473
  if ((e.ctrlKey || e.metaKey) && e.key === `f`) return;
@@ -799,6 +578,7 @@ let GridListElement = class GridListElement extends LitElement {
799
578
  }
800
579
  .viewport {
801
580
  position: relative;
581
+ box-sizing: border-box;
802
582
  height: 100%;
803
583
  overflow-y: auto;
804
584
  overflow-x: hidden;
@@ -1104,6 +884,8 @@ let GridListElement = class GridListElement extends LitElement {
1104
884
  #resizeObserver;
1105
885
  #mutationObserver;
1106
886
  #scrollRaf;
887
+ /** Debounce handle for {@link snapToItem} — fires once scrolling settles. */
888
+ #snapTimer;
1107
889
  #items;
1108
890
  #itemWrap;
1109
891
  /** Items added mid-list that are still playing their enter animation. */
@@ -1310,6 +1092,7 @@ let GridListElement = class GridListElement extends LitElement {
1310
1092
  this.#resizeObserver = void 0;
1311
1093
  this.#mutationObserver?.disconnect();
1312
1094
  this.#cancelScrollRaf();
1095
+ this.#cancelSnapTimer();
1313
1096
  this.#unregisterSearchCommands?.();
1314
1097
  this.#unregisterSearchCommands = void 0;
1315
1098
  this.#searchRegistry = void 0;
@@ -2006,6 +1789,48 @@ let GridListElement = class GridListElement extends LitElement {
2006
1789
  this.#scrollRaf = 0;
2007
1790
  }
2008
1791
  }
1792
+ #cancelSnapTimer() {
1793
+ if (this.#snapTimer !== 0) {
1794
+ clearTimeout(this.#snapTimer);
1795
+ this.#snapTimer = 0;
1796
+ }
1797
+ }
1798
+ #scheduleSnap() {
1799
+ if (!this.snapToItem || this.orientation !== `row` && this.orientation !== `column`) return;
1800
+ this.#cancelSnapTimer();
1801
+ this.#snapTimer = window.setTimeout(() => {
1802
+ this.#snapTimer = 0;
1803
+ this.#snapToNearestLine();
1804
+ }, SNAP_DEBOUNCE_MS);
1805
+ }
1806
+ /**
1807
+ * Settle the viewport on the nearest item (`row` orientation) or row
1808
+ * (`column` orientation) boundary, using the same stride arithmetic as
1809
+ * {@link computeGridWindow} — no DOM measurement needed since off-screen
1810
+ * lines are never rendered.
1811
+ */
1812
+ #snapToNearestLine() {
1813
+ const vp = this.#viewportRef.value;
1814
+ if (!vp) return;
1815
+ const win = this.#currentWindow();
1816
+ const horizontal = win.horizontal;
1817
+ const stride = horizontal ? win.colStride : win.rowStride;
1818
+ if (stride <= 0) return;
1819
+ const offset = horizontal ? vp.scrollLeft : vp.scrollTop;
1820
+ const extent = horizontal ? win.totalWidth : win.totalHeight;
1821
+ const viewportExtent = horizontal ? this._viewportWidth : this._viewportHeight;
1822
+ const maxScroll = Math.max(0, extent - viewportExtent);
1823
+ const index = Math.round(offset / stride);
1824
+ const target = Math.min(maxScroll, Math.max(0, index * stride));
1825
+ if (Math.abs(target - offset) < .5) return;
1826
+ vp.scrollTo(horizontal ? {
1827
+ left: target,
1828
+ behavior: `smooth`
1829
+ } : {
1830
+ top: target,
1831
+ behavior: `smooth`
1832
+ });
1833
+ }
2009
1834
  #onCellClick(e, key) {
2010
1835
  if (this.#dragSelect.isDragging || this.#nativeDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
2011
1836
  this.selection.handleClick(key, e);
@@ -2091,11 +1916,17 @@ __decorate([property({
2091
1916
  reflect: true
2092
1917
  })], GridListElement.prototype, "marqueeFromCellBlank", void 0);
2093
1918
  __decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewRenderer", void 0);
1919
+ __decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewSource", void 0);
2094
1920
  __decorate([property({
2095
1921
  type: String,
2096
1922
  attribute: `search-modes`,
2097
1923
  reflect: true
2098
1924
  })], GridListElement.prototype, "searchModes", void 0);
1925
+ __decorate([property({
1926
+ type: Boolean,
1927
+ attribute: `snap-to-item`,
1928
+ reflect: true
1929
+ })], GridListElement.prototype, "snapToItem", void 0);
2099
1930
  __decorate([property({ attribute: false })], GridListElement.prototype, "items", void 0);
2100
1931
  __decorate([property({ attribute: false })], GridListElement.prototype, "itemAdapter", void 0);
2101
1932
  __decorate([state()], GridListElement.prototype, "_scrollTop", void 0);
@@ -2104,6 +1935,6 @@ __decorate([state()], GridListElement.prototype, "_viewportHeight", void 0);
2104
1935
  __decorate([state()], GridListElement.prototype, "_viewportWidth", void 0);
2105
1936
  GridListElement = __decorate([safeCustomElement(`ixfx-grid-list`)], GridListElement);
2106
1937
  //#endregion
2107
- export { PanTextElement as n, GridListElement as t };
1938
+ export { GridListElement as t };
2108
1939
 
2109
- //# sourceMappingURL=grid-list-mL0GJTQR.js.map
1940
+ //# sourceMappingURL=grid-list-DSnYOGh7.js.map