@ixfx/components 0.8.6 → 0.8.8

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 (76) hide show
  1. package/bundle/index.d.ts +570 -389
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +1033 -200
  4. package/bundle/index.js.map +1 -1
  5. package/dist/crumbs.d.ts +1 -1
  6. package/dist/crumbs.js +2 -2
  7. package/dist/{data-grid-D-z7bx5-.d.ts → data-grid-BKa9i86q.d.ts} +15 -2
  8. package/dist/data-grid-BKa9i86q.d.ts.map +1 -0
  9. package/dist/data-grid.d.ts +3 -2
  10. package/dist/data-grid.js +95 -5
  11. package/dist/data-grid.js.map +1 -1
  12. package/dist/{detail-list-_ZJHYEBr.d.ts → detail-list-CHTomlbR.d.ts} +22 -5
  13. package/dist/detail-list-CHTomlbR.d.ts.map +1 -0
  14. package/dist/detail-list.d.ts +4 -3
  15. package/dist/detail-list.js +103 -3
  16. package/dist/detail-list.js.map +1 -1
  17. package/dist/{grid-list-j5C7qtlG.js → grid-list-C8oMxLl-.js} +77 -164
  18. package/dist/grid-list-C8oMxLl-.js.map +1 -0
  19. package/dist/{grid-list-x550wJ0X.d.ts → grid-list-CsZcXxMC.d.ts} +259 -109
  20. package/dist/grid-list-CsZcXxMC.d.ts.map +1 -0
  21. package/dist/grid-list.d.ts +3 -2
  22. package/dist/grid-list.js +1 -1
  23. package/dist/incr-search.d.ts +1 -1
  24. package/dist/{index-h6gxtfHH.d.ts → index-Dgrx-DIA.d.ts} +2 -2
  25. package/dist/{index-h6gxtfHH.d.ts.map → index-Dgrx-DIA.d.ts.map} +1 -1
  26. package/dist/index.d.ts +190 -252
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +8 -7
  29. package/dist/index.js.map +1 -1
  30. package/dist/{interaction-B9AAlsFO.js → interaction-BskmlA9t.js} +1 -1
  31. package/dist/list-drag-types-kpaXz2pZ.d.ts +42 -0
  32. package/dist/list-drag-types-kpaXz2pZ.d.ts.map +1 -0
  33. package/dist/{list-item-animation-DuiwgN3l.js → list-item-animation-BUoEKi5s.js} +29 -10
  34. package/dist/list-item-animation-BUoEKi5s.js.map +1 -0
  35. package/dist/list-native-drag-controller-DrY3qeJM.js +555 -0
  36. package/dist/list-native-drag-controller-DrY3qeJM.js.map +1 -0
  37. package/dist/{menu-HMoxCPY2.js → menu-CMXhIaNZ.js} +3 -3
  38. package/dist/{menu-HMoxCPY2.js.map → menu-CMXhIaNZ.js.map} +1 -1
  39. package/dist/{menu-item-BQDYxk5A.js → menu-item-BYGQzyCe.js} +2 -2
  40. package/dist/{menu-item-BQDYxk5A.js.map → menu-item-BYGQzyCe.js.map} +1 -1
  41. package/dist/menu.js +2 -2
  42. package/dist/miller.d.ts +2 -2
  43. package/dist/miller.js +1 -1
  44. package/dist/narrowed-text.js +1 -1
  45. package/dist/select-horiz.js +1 -1
  46. package/dist/{tree-DTQon838.js → tree-DSMn566I.js} +90 -27
  47. package/dist/tree-DSMn566I.js.map +1 -0
  48. package/dist/{tree-component-F6qZ0Gdv.d.ts → tree-component-nPP5Y-WS.d.ts} +12 -2
  49. package/dist/tree-component-nPP5Y-WS.d.ts.map +1 -0
  50. package/dist/tree.d.ts +3 -2
  51. package/dist/tree.d.ts.map +1 -1
  52. package/dist/tree.js +1 -1
  53. package/dist/{vertical-list-CFuFDygi.d.ts → vertical-list-A6oWfivZ.d.ts} +21 -4
  54. package/dist/vertical-list-A6oWfivZ.d.ts.map +1 -0
  55. package/dist/vertical-list.d.ts +3 -2
  56. package/dist/vertical-list.js +103 -3
  57. package/dist/vertical-list.js.map +1 -1
  58. package/docs-user/README.md +1 -0
  59. package/docs-user/data-grid.md +30 -0
  60. package/docs-user/data-table.md +104 -0
  61. package/docs-user/detail-list.md +29 -0
  62. package/docs-user/grid-list.md +34 -4
  63. package/docs-user/index.json +7 -2
  64. package/docs-user/llms.txt +1 -0
  65. package/docs-user/tree.md +5 -4
  66. package/docs-user/vertical-list.md +30 -1
  67. package/llms.txt +1 -0
  68. package/package.json +1 -1
  69. package/dist/data-grid-D-z7bx5-.d.ts.map +0 -1
  70. package/dist/detail-list-_ZJHYEBr.d.ts.map +0 -1
  71. package/dist/grid-list-j5C7qtlG.js.map +0 -1
  72. package/dist/grid-list-x550wJ0X.d.ts.map +0 -1
  73. package/dist/list-item-animation-DuiwgN3l.js.map +0 -1
  74. package/dist/tree-DTQon838.js.map +0 -1
  75. package/dist/tree-component-F6qZ0Gdv.d.ts.map +0 -1
  76. package/dist/vertical-list-CFuFDygi.d.ts.map +0 -1
@@ -3,9 +3,10 @@ import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrA
3
3
  import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.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-DrY3qeJM.js";
6
7
  import { r as ListDragSelectController, t as ListSelectionController } from "./list-selection-controller-SA4piSBi.js";
7
- import { i as listItemFadeKeyframes } from "./list-item-animation-DuiwgN3l.js";
8
- import "./interaction-B9AAlsFO.js";
8
+ import { i as listItemFadeKeyframes } from "./list-item-animation-BUoEKi5s.js";
9
+ import "./interaction-BskmlA9t.js";
9
10
  import { t as scrollFadeStyles } from "./scroll-fade-CAs1EabA.js";
10
11
  import { LitElement, css, html } from "lit";
11
12
  import { property, query, state } from "lit/decorators.js";
@@ -597,12 +598,50 @@ let GridListElement = class GridListElement extends LitElement {
597
598
  },
598
599
  onStateChange: () => this._syncItemStates(),
599
600
  itemWrap: this.#itemWrap,
600
- hoverDisabled: () => this.disableHoverTickle || this.#dragSelect.isDragging
601
+ hoverDisabled: () => this.disableHoverTickle || this.#dragSelect.isDragging || this.#nativeDrag.isDragging
601
602
  });
602
603
  this.#marqueePreview = /* @__PURE__ */ new Set();
603
604
  this.#nativeDragging = false;
604
605
  this.#dragOriginKey = void 0;
605
606
  this.#postDragSuppressTimer = 0;
607
+ this.#nativeDrag = new ListNativeDragController(this, {
608
+ source: `grid-list`,
609
+ isEnabled: () => this.itemsDraggable && this.selectionMode !== `none` && this.#source.count > 0,
610
+ resolveEventToKey: (target) => {
611
+ if (target instanceof Element) {
612
+ const key = (target.closest?.(`.cell`))?.dataset.key;
613
+ if (key) return key;
614
+ const keyed = (target.closest?.(`[data-key]`))?.dataset.key ?? target.dataset?.key ?? keyForElement(target);
615
+ if (keyed) return keyed;
616
+ }
617
+ },
618
+ prepareSelection: (originKey) => this.#prepareNativeDrag(originKey),
619
+ getMetrics: () => ({
620
+ itemSize: this.itemSize,
621
+ captionStyle: this.captionStyle,
622
+ captionHeight: this.captionHeight,
623
+ rowHeight: this.#rowHeight()
624
+ }),
625
+ getRenderer: () => this.dragPreviewRenderer,
626
+ dispatch: (detail) => this._dispatch(`list-native-drag-start`, detail, true),
627
+ onActiveChange: (active, originKey) => {
628
+ this.#nativeDragging = active;
629
+ this.#dragOriginKey = active ? originKey : void 0;
630
+ this.toggleAttribute(`data-native-dragging`, active);
631
+ if (active) {
632
+ const count = [...this.selection.selectedKeys].filter((k) => !isSyntheticKey(k)).length;
633
+ this.setAttribute(`aria-label`, count <= 1 ? `Dragging 1 item` : `Dragging ${count} items`);
634
+ } else this.removeAttribute(`aria-label`);
635
+ this.requestUpdate();
636
+ },
637
+ onEnd: () => {
638
+ this.#clearNativeDragState();
639
+ this.#startPostDragSuppressTimer();
640
+ },
641
+ syncLightDomDraggable: () => {
642
+ for (const child of this.children) if (child instanceof HTMLElement) child.draggable = this.itemsDraggable;
643
+ }
644
+ });
606
645
  this.#activeCaptionPan = null;
607
646
  this.#dragSelect = new ListDragSelectController(this, {
608
647
  getSurface: () => this.#viewportRef.value,
@@ -648,23 +687,6 @@ let GridListElement = class GridListElement extends LitElement {
648
687
  this.#emitViewportChange();
649
688
  });
650
689
  };
651
- this.#onDragStart = (e, key) => {
652
- this.#doDragStart(key, () => e.preventDefault(), e);
653
- };
654
- this.#onSlottedDragStart = (e) => {
655
- if (!this.itemsDraggable) return;
656
- let cell = e.composedPath().find((n) => n instanceof Element && n.classList.contains(`cell`));
657
- if (!cell && e.target instanceof Element) cell = e.target.closest?.(`.cell`);
658
- if (!cell) return;
659
- const key = cell.dataset.key;
660
- if (!key) return;
661
- if (e instanceof DragEvent) this.#doDragStart(key, () => e.preventDefault(), e);
662
- else this.#doDragStart(key, () => {});
663
- };
664
- this.#onDragEnd = () => {
665
- this.#clearNativeDragState();
666
- this.#startPostDragSuppressTimer();
667
- };
668
690
  this._onKeyDown = (e) => {
669
691
  if ((e.ctrlKey || e.metaKey) && e.key === `f`) return;
670
692
  if ((e.ctrlKey || e.metaKey) && e.key === `a`) {
@@ -1101,6 +1123,35 @@ let GridListElement = class GridListElement extends LitElement {
1101
1123
  #dragOriginKey;
1102
1124
  /** Timer handle for post-drag click suppression. */
1103
1125
  #postDragSuppressTimer;
1126
+ #nativeDrag;
1127
+ /** Origin rule + display-ordered entry resolution for native drag-out (both modes). */
1128
+ #prepareNativeDrag(originKey) {
1129
+ const index = this.#source.indexOfKey(originKey);
1130
+ if (index < 0 || !this.#source.isSelectable(index)) return void 0;
1131
+ if (!this.selection.selectedKeys.has(originKey)) this.selection.replace(originKey);
1132
+ const ordered = this.#source.keys().filter((k) => !isSyntheticKey(k) && this.selection.selectedKeys.has(k));
1133
+ const selected = [];
1134
+ for (const key of ordered) {
1135
+ const entryIndex = this.#source.indexOfKey(key);
1136
+ if (entryIndex < 0) continue;
1137
+ const data = this.#source.resolveKeyToData(key);
1138
+ const element = this.#source.resolveKeyToElement(key);
1139
+ const item = data ?? element;
1140
+ if (item === void 0) continue;
1141
+ selected.push({
1142
+ key,
1143
+ index: entryIndex,
1144
+ item,
1145
+ ...element ? { element } : {}
1146
+ });
1147
+ }
1148
+ const origin = selected.find((entry) => entry.key === originKey);
1149
+ if (!origin) return void 0;
1150
+ return {
1151
+ origin,
1152
+ selected
1153
+ };
1154
+ }
1104
1155
  /**
1105
1156
  * The single caption pan-text currently scrolling. At most one caption is
1106
1157
  * a pan-text in loop mode at a time — when tickle moves, the old one is
@@ -1233,7 +1284,7 @@ let GridListElement = class GridListElement extends LitElement {
1233
1284
  clearTimeout(this.#reflowTimer);
1234
1285
  this.#reflowTimer = 0;
1235
1286
  }
1236
- if (this.#nativeDragging) this.#clearNativeDragState();
1287
+ if (this.#nativeDragging || this.#nativeDrag.isDragging) this.#clearNativeDragState();
1237
1288
  }
1238
1289
  #onChildrenChanged(records) {
1239
1290
  const previousLength = this.#items.length;
@@ -1314,7 +1365,7 @@ let GridListElement = class GridListElement extends LitElement {
1314
1365
  this.#measureViewport(false);
1315
1366
  this.#syncItems();
1316
1367
  this.requestUpdate();
1317
- this.#initSlottedDragInterceptor();
1368
+ this.#nativeDrag.refreshDraggable();
1318
1369
  }
1319
1370
  /** (Re)construct {@link #source} for the current mode and re-apply the filters. */
1320
1371
  #rebuildSource() {
@@ -1404,7 +1455,7 @@ let GridListElement = class GridListElement extends LitElement {
1404
1455
  this.selection.clearAnchor();
1405
1456
  this.#syncAriaMultiselectable();
1406
1457
  }
1407
- if (changed.has(`itemsDraggable`)) this.#syncSlottedDraggable();
1458
+ if (changed.has(`itemsDraggable`)) this.#nativeDrag.refreshDraggable();
1408
1459
  if (changed.has(`orientation`)) {
1409
1460
  const vp = this.#viewportRef.value;
1410
1461
  if (vp) {
@@ -1823,8 +1874,6 @@ let GridListElement = class GridListElement extends LitElement {
1823
1874
  @click=${(e) => this.#onCellClick(e, key)}
1824
1875
  @dblclick=${() => this.#onCellActivate(key)}
1825
1876
  @pointerenter=${() => this.tickled.handlePointerEnter(key)}
1826
- @dragstart=${(e) => this.#onDragStart(e, key)}
1827
- @dragend=${() => this.#onDragEnd()}
1828
1877
  >
1829
1878
  <div class="content" part="content">${this.#source.renderCellContent(index)}</div>
1830
1879
  ${showCaption ? this.#renderCaption(caption, captionCss, tickled) : ``}
@@ -1909,8 +1958,6 @@ let GridListElement = class GridListElement extends LitElement {
1909
1958
  @click=${(e) => this.#onCellClick(e, key)}
1910
1959
  @dblclick=${() => this.#onCellActivate(key)}
1911
1960
  @pointerenter=${() => this.tickled.handlePointerEnter(key)}
1912
- @dragstart=${(e) => this.#onDragStart(e, key)}
1913
- @dragend=${() => this.#onDragEnd()}
1914
1961
  >
1915
1962
  <div class="thumb" part="thumb" style=${thumbStyle}>
1916
1963
  ${this.#source.renderCellContent(index)}
@@ -1927,145 +1974,10 @@ let GridListElement = class GridListElement extends LitElement {
1927
1974
  }
1928
1975
  }
1929
1976
  #onCellClick(e, key) {
1930
- if (this.#dragSelect.isDragging || this.#nativeDragging || this.#postDragSuppressTimer !== 0) return;
1977
+ if (this.#dragSelect.isDragging || this.#nativeDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
1931
1978
  this.selection.handleClick(key, e);
1932
1979
  this.#emitItemEvent(`list-item-click`, key);
1933
1980
  }
1934
- #doDragStart(key, cancelled, dragEvent) {
1935
- if (!this.itemsDraggable) return false;
1936
- const index = this.#source.indexOfKey(key);
1937
- if (index < 0 || !this.#source.isSelectable(index)) return false;
1938
- if (!this.selection.selectedKeys.has(key)) this.selection.replace(key);
1939
- const selectedKeys = this.#source.keys().filter((k) => !isSyntheticKey(k)).filter((k) => this.selection.selectedKeys.has(k));
1940
- const detail = {
1941
- key,
1942
- index: this.#source.indexOfKey(key),
1943
- item: this.#source.resolveKeyToData(key) ?? this.#source.resolveKeyToElement(key),
1944
- selectedKeys
1945
- };
1946
- if (!this._dispatch(`grid-list-native-drag-start`, detail, true)) {
1947
- cancelled();
1948
- return false;
1949
- }
1950
- this.#nativeDragging = true;
1951
- this.#dragOriginKey = key;
1952
- this.toggleAttribute(`data-native-dragging`, true);
1953
- const count = selectedKeys.length;
1954
- this.setAttribute(`aria-label`, count === 1 ? `Dragging 1 item` : `Dragging ${count} items`);
1955
- if (dragEvent && count > 1) this.#setMultiItemDragImage(dragEvent, selectedKeys);
1956
- return true;
1957
- }
1958
- #setMultiItemDragImage(e, selectedKeys) {
1959
- const preview = this.#createMultiItemPreview(selectedKeys);
1960
- document.body.appendChild(preview);
1961
- const rect = preview.getBoundingClientRect();
1962
- e.dataTransfer?.setDragImage(preview, rect.width / 2, rect.height / 2);
1963
- requestAnimationFrame(() => preview.remove());
1964
- }
1965
- #createMultiItemPreview(selectedKeys) {
1966
- const preview = document.createElement(`div`);
1967
- preview.style.cssText = `
1968
- position: fixed;
1969
- top: -9999px;
1970
- left: -9999px;
1971
- display: flex;
1972
- flex-direction: column;
1973
- gap: 4px;
1974
- padding: 8px;
1975
- background: var(--surface-4, #333);
1976
- border: 1px solid var(--border, #555);
1977
- border-radius: 8px;
1978
- box-shadow: 0 4px 16px rgba(0,0,0,0.3);
1979
- font-family: system-ui, sans-serif;
1980
- font-size: 12px;
1981
- color: var(--surface-text, #fff);
1982
- max-width: 200px;
1983
- z-index: 999999;
1984
- `;
1985
- const header = document.createElement(`div`);
1986
- header.style.cssText = `
1987
- font-weight: 600;
1988
- padding-bottom: 4px;
1989
- border-bottom: 1px solid var(--border, #555);
1990
- margin-bottom: 4px;
1991
- `;
1992
- header.textContent = `${selectedKeys.length} items`;
1993
- preview.appendChild(header);
1994
- for (const key of selectedKeys.slice(0, 5)) {
1995
- const row = this.#createPreviewRow(key);
1996
- if (row) preview.appendChild(row);
1997
- }
1998
- if (selectedKeys.length > 5) {
1999
- const more = document.createElement(`div`);
2000
- more.style.cssText = `opacity: 0.6; text-align: center;`;
2001
- more.textContent = `+${selectedKeys.length - 5} more`;
2002
- preview.appendChild(more);
2003
- }
2004
- return preview;
2005
- }
2006
- #createPreviewRow(key) {
2007
- const el = this.#source.resolveKeyToElement(key);
2008
- if (!el) return null;
2009
- const row = document.createElement(`div`);
2010
- row.style.cssText = `
2011
- display: flex;
2012
- align-items: center;
2013
- gap: 6px;
2014
- `;
2015
- const thumb = document.createElement(`div`);
2016
- thumb.style.cssText = `
2017
- width: 32px;
2018
- height: 32px;
2019
- border-radius: 4px;
2020
- overflow: hidden;
2021
- background: var(--surface-5, #444);
2022
- flex-shrink: 0;
2023
- display: flex;
2024
- align-items: center;
2025
- justify-content: center;
2026
- `;
2027
- const slottedImg = el.querySelector(`img`);
2028
- const slottedSvg = el.querySelector(`svg`);
2029
- const slottedPlaceholder = el.querySelector(`.placeholder`);
2030
- if (slottedImg) {
2031
- const img = slottedImg.cloneNode(true);
2032
- img.style.cssText = `width: 100%; height: 100%; object-fit: cover;`;
2033
- thumb.appendChild(img);
2034
- } else if (slottedSvg) {
2035
- const svg = slottedSvg.cloneNode(true);
2036
- svg.style.cssText = `width: 70%; height: 70%; opacity: 0.8;`;
2037
- thumb.appendChild(svg);
2038
- } else if (slottedPlaceholder) thumb.textContent = slottedPlaceholder.textContent || `?`;
2039
- const label = document.createElement(`span`);
2040
- label.style.cssText = `
2041
- flex: 1;
2042
- overflow: hidden;
2043
- text-overflow: ellipsis;
2044
- white-space: nowrap;
2045
- `;
2046
- label.textContent = el.getAttribute(`data-label`) || key;
2047
- row.appendChild(thumb);
2048
- row.appendChild(label);
2049
- return row;
2050
- }
2051
- #onDragStart;
2052
- #onSlottedDragStart;
2053
- #initSlottedDragInterceptor() {
2054
- this.renderRoot.addEventListener(`dragstart`, this.#onSlottedDragStart, { capture: true });
2055
- const observer = new MutationObserver(() => this.#syncSlottedDraggable());
2056
- observer.observe(this, {
2057
- childList: true,
2058
- subtree: true
2059
- });
2060
- this.#slottedDragObserver = observer;
2061
- this.#syncSlottedDraggable();
2062
- }
2063
- #slottedDragObserver;
2064
- #syncSlottedDraggable() {
2065
- const draggable = this.itemsDraggable;
2066
- for (const child of this.children) if (child instanceof HTMLElement) child.draggable = draggable;
2067
- }
2068
- #onDragEnd;
2069
1981
  #startPostDragSuppressTimer() {
2070
1982
  if (this.#postDragSuppressTimer) clearTimeout(this.#postDragSuppressTimer);
2071
1983
  this.#postDragSuppressTimer = window.setTimeout(() => {
@@ -2140,6 +2052,7 @@ __decorate([property({
2140
2052
  attribute: `items-draggable`,
2141
2053
  reflect: true
2142
2054
  })], GridListElement.prototype, "itemsDraggable", void 0);
2055
+ __decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewRenderer", void 0);
2143
2056
  __decorate([property({
2144
2057
  type: String,
2145
2058
  attribute: `search-modes`,
@@ -2155,4 +2068,4 @@ GridListElement = __decorate([safeCustomElement(`ixfx-grid-list`)], GridListElem
2155
2068
  //#endregion
2156
2069
  export { PanTextElement as n, GridListElement as t };
2157
2070
 
2158
- //# sourceMappingURL=grid-list-j5C7qtlG.js.map
2071
+ //# sourceMappingURL=grid-list-C8oMxLl-.js.map