@ixfx/components 0.8.7 → 0.8.9
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.
- package/bundle/index.d.ts +743 -383
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +2093 -222
- package/bundle/index.js.map +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/crumbs.js +2 -2
- package/dist/{data-grid-CYVPSUwh.d.ts → data-grid-C588pTgt.d.ts} +15 -2
- package/dist/data-grid-C588pTgt.d.ts.map +1 -0
- package/dist/data-grid.d.ts +3 -2
- package/dist/data-grid.js +95 -5
- package/dist/data-grid.js.map +1 -1
- package/dist/{detail-list-vH56z7WE.d.ts → detail-list-IKl76Wnp.d.ts} +22 -5
- package/dist/detail-list-IKl76Wnp.d.ts.map +1 -0
- package/dist/detail-list.d.ts +4 -3
- package/dist/detail-list.js +103 -3
- package/dist/detail-list.js.map +1 -1
- package/dist/{grid-list-Cq8ga2WZ.d.ts → grid-list-BUlUnisU.d.ts} +214 -112
- package/dist/grid-list-BUlUnisU.d.ts.map +1 -0
- package/dist/{grid-list-j5C7qtlG.js → grid-list-D18FNJRH.js} +77 -164
- package/dist/grid-list-D18FNJRH.js.map +1 -0
- package/dist/grid-list.d.ts +3 -2
- package/dist/grid-list.js +1 -1
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-DDREWqMm.d.ts → index--qnhBWZJ.d.ts} +2 -2
- package/dist/{index-DDREWqMm.d.ts.map → index--qnhBWZJ.d.ts.map} +1 -1
- package/dist/index.d.ts +212 -253
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/{interaction-B9AAlsFO.js → interaction-BskmlA9t.js} +1 -1
- package/dist/{labelled-slider-input-BCH9968c.js → labelled-slider-input-aEYDvW2S.js} +2 -2
- package/dist/{labelled-slider-input-BCH9968c.js.map → labelled-slider-input-aEYDvW2S.js.map} +1 -1
- package/dist/labelled-slider-input.js +1 -1
- package/dist/{list-item-animation-DuiwgN3l.js → list-item-animation-BUoEKi5s.js} +29 -10
- package/dist/list-item-animation-BUoEKi5s.js.map +1 -0
- package/dist/list-native-drag-controller-CFyrkKUj.d.ts +61 -0
- package/dist/list-native-drag-controller-CFyrkKUj.d.ts.map +1 -0
- package/dist/list-native-drag-controller-DxD6Yjci.js +567 -0
- package/dist/list-native-drag-controller-DxD6Yjci.js.map +1 -0
- package/dist/{menu-HMoxCPY2.js → menu-CMXhIaNZ.js} +3 -3
- package/dist/{menu-HMoxCPY2.js.map → menu-CMXhIaNZ.js.map} +1 -1
- package/dist/{menu-item-BQDYxk5A.js → menu-item-BYGQzyCe.js} +2 -2
- package/dist/{menu-item-BQDYxk5A.js.map → menu-item-BYGQzyCe.js.map} +1 -1
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +2 -2
- package/dist/miller.js +1 -1
- package/dist/narrowed-text.js +1 -1
- package/dist/plots.js +1 -1
- package/dist/select-horiz.js +1 -1
- package/dist/slider-input-BxURAAmD.d.ts.map +1 -1
- package/dist/{slider-input-WR8_RwHg.js → slider-input-Cb5uSV42.js} +78 -11
- package/dist/slider-input-Cb5uSV42.js.map +1 -0
- package/dist/slider-input.js +1 -1
- package/dist/{tree-CozQj01a.js → tree-a14n9y7i.js} +1055 -32
- package/dist/tree-a14n9y7i.js.map +1 -0
- package/dist/{tree-component-BMpxpdTi.d.ts → tree-component-BW2iCFq9.d.ts} +108 -4
- package/dist/tree-component-BW2iCFq9.d.ts.map +1 -0
- package/dist/tree.d.ts +102 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -2
- package/dist/{vertical-list-BGn9nyKh.d.ts → vertical-list-CHrXmmQ3.d.ts} +21 -4
- package/dist/vertical-list-CHrXmmQ3.d.ts.map +1 -0
- package/dist/vertical-list.d.ts +3 -2
- package/dist/vertical-list.js +103 -3
- package/dist/vertical-list.js.map +1 -1
- package/dist/{xy-axis-CrrVdDFe.js → xy-axis-COKw338Q.js} +2 -2
- package/dist/xy-axis-COKw338Q.js.map +1 -0
- package/dist/xy-axis-DQqd2yXJ.d.ts.map +1 -1
- package/docs-user/data-grid.md +30 -0
- package/docs-user/detail-list.md +29 -0
- package/docs-user/grid-list.md +34 -4
- package/docs-user/index.json +2 -2
- package/docs-user/tree.md +76 -1
- package/docs-user/vertical-list.md +30 -1
- package/package.json +1 -1
- package/dist/data-grid-CYVPSUwh.d.ts.map +0 -1
- package/dist/detail-list-vH56z7WE.d.ts.map +0 -1
- package/dist/grid-list-Cq8ga2WZ.d.ts.map +0 -1
- package/dist/grid-list-j5C7qtlG.js.map +0 -1
- package/dist/list-item-animation-DuiwgN3l.js.map +0 -1
- package/dist/slider-input-WR8_RwHg.js.map +0 -1
- package/dist/tree-CozQj01a.js.map +0 -1
- package/dist/tree-component-BMpxpdTi.d.ts.map +0 -1
- package/dist/vertical-list-BGn9nyKh.d.ts.map +0 -1
- package/dist/xy-axis-CrrVdDFe.js.map +0 -1
package/bundle/index.js
CHANGED
|
@@ -5686,13 +5686,370 @@ __decorate([state()], RadioGroup.prototype, "_icons", void 0);
|
|
|
5686
5686
|
__decorate([query(`slot`)], RadioGroup.prototype, "_slot", void 0);
|
|
5687
5687
|
RadioGroup = __decorate([safeCustomElement(`ixfx-radio-group`)], RadioGroup);
|
|
5688
5688
|
//#endregion
|
|
5689
|
+
//#region src/interaction/list-drag-preview-default.ts
|
|
5690
|
+
const CARD_DEFAULT = 72;
|
|
5691
|
+
const CARD_MIN = 48;
|
|
5692
|
+
const CARD_MAX = 96;
|
|
5693
|
+
const LIST_WIDTH = 220;
|
|
5694
|
+
const LIST_MAX_ROWS = 5;
|
|
5695
|
+
const MAX_CANVAS_DIM = 1024;
|
|
5696
|
+
function cssVar(style, name, fallback) {
|
|
5697
|
+
try {
|
|
5698
|
+
return style.getPropertyValue(name)?.trim() || fallback;
|
|
5699
|
+
} catch {
|
|
5700
|
+
return fallback;
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
function fontOf(style) {
|
|
5704
|
+
try {
|
|
5705
|
+
const font = style.font?.trim();
|
|
5706
|
+
if (font) return font;
|
|
5707
|
+
} catch {}
|
|
5708
|
+
return `12px system-ui, sans-serif`;
|
|
5709
|
+
}
|
|
5710
|
+
/** Caption for a drag entry — element labels win, then string items, then common object fields, then the key. */
|
|
5711
|
+
function captionForEntry(entry) {
|
|
5712
|
+
const el = entry.element ?? (entry.item instanceof Element ? entry.item : void 0);
|
|
5713
|
+
if (el) {
|
|
5714
|
+
const labelled = el.getAttribute(`data-label`) ?? el.querySelector(`[data-grid-list-caption]`)?.textContent?.trim() ?? el.getAttribute(`data-search-label`) ?? el.querySelector(`.cell`)?.textContent?.trim();
|
|
5715
|
+
if (labelled) return labelled.slice(0, 80);
|
|
5716
|
+
const text = el.textContent?.trim();
|
|
5717
|
+
if (text) return text.slice(0, 80);
|
|
5718
|
+
}
|
|
5719
|
+
const item = entry.item;
|
|
5720
|
+
if (typeof item === `string` && item.length > 0) return item.slice(0, 80);
|
|
5721
|
+
if (item !== null && typeof item === `object` && !(item instanceof Element)) {
|
|
5722
|
+
const record = item;
|
|
5723
|
+
for (const field of [
|
|
5724
|
+
`label`,
|
|
5725
|
+
`name`,
|
|
5726
|
+
`title`,
|
|
5727
|
+
`text`
|
|
5728
|
+
]) {
|
|
5729
|
+
const value = record[field];
|
|
5730
|
+
if (typeof value === `string` && value.length > 0) return value.slice(0, 80);
|
|
5731
|
+
}
|
|
5732
|
+
}
|
|
5733
|
+
return entry.key;
|
|
5734
|
+
}
|
|
5735
|
+
function glyphFor(caption) {
|
|
5736
|
+
const first = caption.trim().at(0);
|
|
5737
|
+
return first ? first.toLocaleUpperCase() : `?`;
|
|
5738
|
+
}
|
|
5739
|
+
/** A decoded `<img>` ready for `drawImage`, if the entry's element has one. */
|
|
5740
|
+
function decodedImage(entry) {
|
|
5741
|
+
const scope = entry.element ?? (entry.item instanceof Element ? entry.item : void 0);
|
|
5742
|
+
if (!scope || typeof scope.querySelector !== `function`) return void 0;
|
|
5743
|
+
if (scope instanceof HTMLImageElement) {
|
|
5744
|
+
if (scope.complete && scope.naturalWidth > 0) return scope;
|
|
5745
|
+
return;
|
|
5746
|
+
}
|
|
5747
|
+
try {
|
|
5748
|
+
const img = scope.querySelector(`img`);
|
|
5749
|
+
if (img instanceof HTMLImageElement && img.complete && img.naturalWidth > 0) return img;
|
|
5750
|
+
} catch {}
|
|
5751
|
+
}
|
|
5752
|
+
function cardSize(metrics) {
|
|
5753
|
+
if (metrics.itemSize !== void 0 && Number.isFinite(metrics.itemSize)) return Math.max(CARD_MIN, Math.min(CARD_MAX, Math.round(metrics.itemSize)));
|
|
5754
|
+
return CARD_DEFAULT;
|
|
5755
|
+
}
|
|
5756
|
+
function rowHeight(metrics) {
|
|
5757
|
+
const raw = metrics.rowHeight;
|
|
5758
|
+
if (raw !== void 0 && Number.isFinite(raw)) return Math.max(24, Math.min(36, Math.round(raw)));
|
|
5759
|
+
return 28;
|
|
5760
|
+
}
|
|
5761
|
+
function thumbCell(doc, caption, img, size) {
|
|
5762
|
+
const well = doc.createElement(`div`);
|
|
5763
|
+
well.setAttribute(`data-thumb`, ``);
|
|
5764
|
+
well.style.cssText = `width:${size}px;height:${size}px;border-radius:4px;overflow:hidden;background:var(--surface-5, rgba(128,128,128,0.25));flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:${Math.round(size * .4)}px;font-weight:600;`;
|
|
5765
|
+
if (img) try {
|
|
5766
|
+
const clone = img.cloneNode(true);
|
|
5767
|
+
clone.style.cssText = `width:100%;height:100%;object-fit:cover;`;
|
|
5768
|
+
clone.removeAttribute(`id`);
|
|
5769
|
+
well.appendChild(clone);
|
|
5770
|
+
} catch {
|
|
5771
|
+
well.textContent = glyphFor(caption);
|
|
5772
|
+
}
|
|
5773
|
+
else well.textContent = glyphFor(caption);
|
|
5774
|
+
return well;
|
|
5775
|
+
}
|
|
5776
|
+
function buildCardsElement(ctx, captions, images) {
|
|
5777
|
+
const doc = document;
|
|
5778
|
+
const size = cardSize(ctx.metrics);
|
|
5779
|
+
const gap = 6;
|
|
5780
|
+
const pad = 8;
|
|
5781
|
+
const root = doc.createElement(`div`);
|
|
5782
|
+
root.setAttribute(`data-preview`, `cards`);
|
|
5783
|
+
root.setAttribute(`part`, `drag-preview`);
|
|
5784
|
+
root.style.cssText = `position:fixed;top:-9999px;left:-9999px;display:flex;flex-direction:row;gap:${gap}px;padding:${pad}px;background:var(--surface-4, #333);color:var(--surface-4-text, #fff);border:1px solid var(--border-subtle, #555);border-radius:var(--radius-m, 8px);box-shadow:0 4px 16px rgba(0,0,0,0.3);font-family:system-ui,sans-serif;font-size:11px;max-width:320px;z-index:999999;pointer-events:none;`;
|
|
5785
|
+
const n = ctx.selected.length;
|
|
5786
|
+
for (let i = 0; i < n; i++) {
|
|
5787
|
+
const card = doc.createElement(`div`);
|
|
5788
|
+
card.setAttribute(`data-card`, ``);
|
|
5789
|
+
card.style.cssText = `display:flex;flex-direction:column;gap:4px;align-items:center;width:${size}px;`;
|
|
5790
|
+
card.appendChild(thumbCell(doc, captions[i], images[i], Math.round(size * .72)));
|
|
5791
|
+
const label = doc.createElement(`span`);
|
|
5792
|
+
label.setAttribute(`data-caption`, ``);
|
|
5793
|
+
label.style.cssText = `max-width:${size}px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;opacity:0.9;`;
|
|
5794
|
+
label.textContent = captions[i];
|
|
5795
|
+
card.appendChild(label);
|
|
5796
|
+
root.appendChild(card);
|
|
5797
|
+
}
|
|
5798
|
+
return root;
|
|
5799
|
+
}
|
|
5800
|
+
function buildListElement(ctx, captions, images) {
|
|
5801
|
+
const doc = document;
|
|
5802
|
+
const rh = rowHeight(ctx.metrics);
|
|
5803
|
+
const thumb = Math.round(rh * .78);
|
|
5804
|
+
const root = doc.createElement(`div`);
|
|
5805
|
+
root.setAttribute(`data-preview`, `list`);
|
|
5806
|
+
root.setAttribute(`part`, `drag-preview`);
|
|
5807
|
+
root.style.cssText = `position:fixed;top:-9999px;left:-9999px;display:flex;flex-direction:column;gap:4px;padding:8px;background:var(--surface-4, #333);color:var(--surface-4-text, #fff);border:1px solid var(--border-subtle, #555);border-radius:var(--radius-m, 8px);box-shadow:0 4px 16px rgba(0,0,0,0.3);font-family:system-ui,sans-serif;font-size:12px;width:${LIST_WIDTH}px;max-width:${LIST_WIDTH}px;z-index:999999;pointer-events:none;`;
|
|
5808
|
+
const header = doc.createElement(`div`);
|
|
5809
|
+
header.setAttribute(`data-header`, ``);
|
|
5810
|
+
header.style.cssText = `font-weight:600;padding-bottom:4px;border-bottom:1px solid var(--border-subtle, #555);margin-bottom:4px;`;
|
|
5811
|
+
header.textContent = `${ctx.selected.length} items`;
|
|
5812
|
+
root.appendChild(header);
|
|
5813
|
+
for (let i = 0; i < Math.min(LIST_MAX_ROWS, captions.length); i++) {
|
|
5814
|
+
const row = doc.createElement(`div`);
|
|
5815
|
+
row.setAttribute(`data-row`, ``);
|
|
5816
|
+
row.style.cssText = `display:flex;align-items:center;gap:6px;height:${rh}px;overflow:hidden;`;
|
|
5817
|
+
row.appendChild(thumbCell(doc, captions[i], images[i], thumb));
|
|
5818
|
+
const label = doc.createElement(`span`);
|
|
5819
|
+
label.setAttribute(`data-caption`, ``);
|
|
5820
|
+
label.style.cssText = `flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;`;
|
|
5821
|
+
label.textContent = captions[i];
|
|
5822
|
+
row.appendChild(label);
|
|
5823
|
+
root.appendChild(row);
|
|
5824
|
+
}
|
|
5825
|
+
if (captions.length > LIST_MAX_ROWS) {
|
|
5826
|
+
const more = doc.createElement(`div`);
|
|
5827
|
+
more.setAttribute(`data-more`, ``);
|
|
5828
|
+
more.style.cssText = `opacity:0.6;text-align:center;`;
|
|
5829
|
+
more.textContent = `+${captions.length - LIST_MAX_ROWS} more`;
|
|
5830
|
+
root.appendChild(more);
|
|
5831
|
+
}
|
|
5832
|
+
return root;
|
|
5833
|
+
}
|
|
5834
|
+
function paletteOf(style) {
|
|
5835
|
+
const bg = cssVar(style, `--surface-4`, `#333333`);
|
|
5836
|
+
const fg = cssVar(style, `--surface-4-text`, `#ffffff`);
|
|
5837
|
+
const subtle = cssVar(style, `--border-subtle`, `#555555`);
|
|
5838
|
+
const accent = cssVar(style, `--accent`, `#4da3ff`);
|
|
5839
|
+
const radiusRaw = cssVar(style, `--radius-m`, `8`);
|
|
5840
|
+
return {
|
|
5841
|
+
bg,
|
|
5842
|
+
fg,
|
|
5843
|
+
subtle,
|
|
5844
|
+
accent,
|
|
5845
|
+
radius: Number.parseFloat(radiusRaw) || 8,
|
|
5846
|
+
font: fontOf(style)
|
|
5847
|
+
};
|
|
5848
|
+
}
|
|
5849
|
+
function fitCanvas(canvas, cssW, cssH) {
|
|
5850
|
+
let scale = Math.max(1, Math.min(3, typeof devicePixelRatio === `number` && devicePixelRatio > 0 ? devicePixelRatio : 1));
|
|
5851
|
+
const maxScaleW = MAX_CANVAS_DIM / Math.max(1, cssW);
|
|
5852
|
+
const maxScaleH = MAX_CANVAS_DIM / Math.max(1, cssH);
|
|
5853
|
+
scale = Math.min(scale, maxScaleW, maxScaleH);
|
|
5854
|
+
canvas.width = Math.max(1, Math.round(cssW * scale));
|
|
5855
|
+
canvas.height = Math.max(1, Math.round(cssH * scale));
|
|
5856
|
+
canvas.style.width = `${cssW}px`;
|
|
5857
|
+
canvas.style.height = `${cssH}px`;
|
|
5858
|
+
return {
|
|
5859
|
+
scale,
|
|
5860
|
+
dpr: scale
|
|
5861
|
+
};
|
|
5862
|
+
}
|
|
5863
|
+
function roundRectPath(context, x, y, w, h, r) {
|
|
5864
|
+
const radius = Math.max(0, Math.min(r, w / 2, h / 2));
|
|
5865
|
+
if (typeof context.roundRect === `function`) {
|
|
5866
|
+
context.beginPath();
|
|
5867
|
+
context.roundRect(x, y, w, h, radius);
|
|
5868
|
+
return;
|
|
5869
|
+
}
|
|
5870
|
+
context.beginPath();
|
|
5871
|
+
context.moveTo(x + radius, y);
|
|
5872
|
+
context.arcTo(x + w, y, x + w, y + h, radius);
|
|
5873
|
+
context.arcTo(x + w, y + h, x, y + h, radius);
|
|
5874
|
+
context.arcTo(x, y + h, x, y, radius);
|
|
5875
|
+
context.arcTo(x, y, x + w, y, radius);
|
|
5876
|
+
context.closePath();
|
|
5877
|
+
}
|
|
5878
|
+
function paintCards(context, scale, palette, captions, images, size, cssW, cssH) {
|
|
5879
|
+
context.save();
|
|
5880
|
+
context.scale(scale, scale);
|
|
5881
|
+
roundRectPath(context, 0, 0, cssW, cssH, palette.radius);
|
|
5882
|
+
context.fillStyle = palette.bg;
|
|
5883
|
+
context.fill();
|
|
5884
|
+
context.strokeStyle = palette.subtle;
|
|
5885
|
+
context.lineWidth = 1;
|
|
5886
|
+
context.stroke();
|
|
5887
|
+
context.clip();
|
|
5888
|
+
const gap = 6;
|
|
5889
|
+
const pad = 8;
|
|
5890
|
+
const wellSize = Math.round(size * .72);
|
|
5891
|
+
context.font = palette.font;
|
|
5892
|
+
context.textBaseline = `middle`;
|
|
5893
|
+
for (let i = 0; i < captions.length; i++) {
|
|
5894
|
+
const x = pad + i * (size + gap);
|
|
5895
|
+
const wellX = x + (size - wellSize) / 2;
|
|
5896
|
+
const wellY = pad;
|
|
5897
|
+
roundRectPath(context, wellX, wellY, wellSize, wellSize, 4);
|
|
5898
|
+
context.fillStyle = palette.subtle;
|
|
5899
|
+
context.globalAlpha = .35;
|
|
5900
|
+
context.fill();
|
|
5901
|
+
context.globalAlpha = 1;
|
|
5902
|
+
const img = images[i];
|
|
5903
|
+
if (img) try {
|
|
5904
|
+
context.save();
|
|
5905
|
+
context.clip();
|
|
5906
|
+
context.drawImage(img, wellX, wellY, wellSize, wellSize);
|
|
5907
|
+
context.restore();
|
|
5908
|
+
} catch {}
|
|
5909
|
+
else {
|
|
5910
|
+
context.fillStyle = palette.fg;
|
|
5911
|
+
context.globalAlpha = .9;
|
|
5912
|
+
context.font = `600 ${Math.round(wellSize * .4)}px system-ui, sans-serif`;
|
|
5913
|
+
context.textAlign = `center`;
|
|
5914
|
+
context.fillText(glyphFor(captions[i]), wellX + wellSize / 2, wellY + wellSize / 2 + 1);
|
|
5915
|
+
context.globalAlpha = 1;
|
|
5916
|
+
context.textAlign = `left`;
|
|
5917
|
+
context.font = palette.font;
|
|
5918
|
+
}
|
|
5919
|
+
context.fillStyle = palette.fg;
|
|
5920
|
+
context.globalAlpha = .9;
|
|
5921
|
+
context.font = palette.font;
|
|
5922
|
+
const label = captions[i].length > 12 ? `${captions[i].slice(0, 11)}…` : captions[i];
|
|
5923
|
+
const textWidth = context.measureText(label).width;
|
|
5924
|
+
context.fillText(label, x + (size - Math.min(size, textWidth)) / 2, wellY + wellSize + 10, size);
|
|
5925
|
+
context.globalAlpha = 1;
|
|
5926
|
+
}
|
|
5927
|
+
context.restore();
|
|
5928
|
+
}
|
|
5929
|
+
function paintList(context, scale, palette, captions, images, rh, cssW, cssH) {
|
|
5930
|
+
context.save();
|
|
5931
|
+
context.scale(scale, scale);
|
|
5932
|
+
roundRectPath(context, 0, 0, cssW, cssH, palette.radius);
|
|
5933
|
+
context.fillStyle = palette.bg;
|
|
5934
|
+
context.fill();
|
|
5935
|
+
context.strokeStyle = palette.subtle;
|
|
5936
|
+
context.lineWidth = 1;
|
|
5937
|
+
context.stroke();
|
|
5938
|
+
context.clip();
|
|
5939
|
+
const pad = 8;
|
|
5940
|
+
context.fillStyle = palette.fg;
|
|
5941
|
+
context.font = `600 ${palette.font}`;
|
|
5942
|
+
context.textBaseline = `middle`;
|
|
5943
|
+
context.fillText(`${captions.length} items`, pad, 16, cssW - 16);
|
|
5944
|
+
context.strokeStyle = palette.subtle;
|
|
5945
|
+
context.beginPath();
|
|
5946
|
+
context.moveTo(pad, 28);
|
|
5947
|
+
context.lineTo(cssW - pad, 28);
|
|
5948
|
+
context.stroke();
|
|
5949
|
+
const thumb = Math.round(rh * .78);
|
|
5950
|
+
const rows = Math.min(LIST_MAX_ROWS, captions.length);
|
|
5951
|
+
context.font = palette.font;
|
|
5952
|
+
for (let i = 0; i < rows; i++) {
|
|
5953
|
+
const y = 32 + i * rh;
|
|
5954
|
+
roundRectPath(context, pad, y + (rh - thumb) / 2, thumb, thumb, 4);
|
|
5955
|
+
context.fillStyle = palette.subtle;
|
|
5956
|
+
context.globalAlpha = .35;
|
|
5957
|
+
context.fill();
|
|
5958
|
+
context.globalAlpha = 1;
|
|
5959
|
+
const img = images[i];
|
|
5960
|
+
if (img) try {
|
|
5961
|
+
context.save();
|
|
5962
|
+
context.clip();
|
|
5963
|
+
context.drawImage(img, pad, y + (rh - thumb) / 2, thumb, thumb);
|
|
5964
|
+
context.restore();
|
|
5965
|
+
} catch {}
|
|
5966
|
+
else {
|
|
5967
|
+
context.fillStyle = palette.fg;
|
|
5968
|
+
context.font = `600 ${Math.round(thumb * .45)}px system-ui, sans-serif`;
|
|
5969
|
+
context.textAlign = `center`;
|
|
5970
|
+
context.fillText(glyphFor(captions[i]), pad + thumb / 2, y + rh / 2 + 1);
|
|
5971
|
+
context.textAlign = `left`;
|
|
5972
|
+
context.font = palette.font;
|
|
5973
|
+
}
|
|
5974
|
+
context.fillStyle = palette.fg;
|
|
5975
|
+
context.globalAlpha = .92;
|
|
5976
|
+
const maxText = cssW - 16 - thumb - 6;
|
|
5977
|
+
context.fillText(captions[i], pad + thumb + 6, y + rh / 2 + 1, Math.max(8, maxText));
|
|
5978
|
+
context.globalAlpha = 1;
|
|
5979
|
+
}
|
|
5980
|
+
if (captions.length > LIST_MAX_ROWS) {
|
|
5981
|
+
context.fillStyle = palette.fg;
|
|
5982
|
+
context.globalAlpha = .6;
|
|
5983
|
+
context.textAlign = `center`;
|
|
5984
|
+
context.fillText(`+${captions.length - LIST_MAX_ROWS} more`, cssW / 2, cssH - pad - 6, cssW - 16);
|
|
5985
|
+
context.textAlign = `left`;
|
|
5986
|
+
context.globalAlpha = 1;
|
|
5987
|
+
}
|
|
5988
|
+
context.restore();
|
|
5989
|
+
}
|
|
5990
|
+
/**
|
|
5991
|
+
* Uniform built-in HTML+canvas drag preview for all four list components.
|
|
5992
|
+
*
|
|
5993
|
+
* - ≤5 selected → a row of small cards (thumbnail well + caption).
|
|
5994
|
+
* - >5 selected → a compact list (`N items` header, up to 5 rows, `+N more`).
|
|
5995
|
+
*
|
|
5996
|
+
* Always returns an offscreen `element` for `DataTransfer.setDragImage()` and,
|
|
5997
|
+
* when a 2D context is available, a DPR-aware painted `canvas` for native
|
|
5998
|
+
* hosts. Colours track the active theme via `ctx.hostStyle` CSS variables.
|
|
5999
|
+
*/
|
|
6000
|
+
function createDefaultListDragPreview(ctx) {
|
|
6001
|
+
const entries = ctx.selected;
|
|
6002
|
+
const captions = entries.map((entry) => captionForEntry(entry));
|
|
6003
|
+
const images = entries.map((entry) => decodedImage(entry));
|
|
6004
|
+
const isCards = entries.length <= 5;
|
|
6005
|
+
let element;
|
|
6006
|
+
let cssW;
|
|
6007
|
+
let cssH;
|
|
6008
|
+
if (isCards) {
|
|
6009
|
+
const size = cardSize(ctx.metrics);
|
|
6010
|
+
cssW = entries.length * size + Math.max(0, entries.length - 1) * 6 + 16;
|
|
6011
|
+
cssH = Math.round(size * .72) + 22 + 16;
|
|
6012
|
+
element = buildCardsElement(ctx, captions, images);
|
|
6013
|
+
} else {
|
|
6014
|
+
const rh = rowHeight(ctx.metrics);
|
|
6015
|
+
const rows = Math.min(LIST_MAX_ROWS, entries.length);
|
|
6016
|
+
const more = entries.length > LIST_MAX_ROWS ? 18 : 0;
|
|
6017
|
+
cssW = 236;
|
|
6018
|
+
cssH = 40 + rows * rh + more;
|
|
6019
|
+
element = buildListElement(ctx, captions, images);
|
|
6020
|
+
}
|
|
6021
|
+
let canvas;
|
|
6022
|
+
try {
|
|
6023
|
+
const candidate = document.createElement(`canvas`);
|
|
6024
|
+
const paint = candidate.getContext(`2d`);
|
|
6025
|
+
if (paint) {
|
|
6026
|
+
const { scale } = fitCanvas(candidate, cssW, cssH);
|
|
6027
|
+
const palette = paletteOf(ctx.hostStyle);
|
|
6028
|
+
if (isCards) paintCards(paint, scale, palette, captions, images, cardSize(ctx.metrics), cssW, cssH);
|
|
6029
|
+
else paintList(paint, scale, palette, captions, images, rowHeight(ctx.metrics), cssW, cssH);
|
|
6030
|
+
canvas = candidate;
|
|
6031
|
+
}
|
|
6032
|
+
} catch {
|
|
6033
|
+
canvas = void 0;
|
|
6034
|
+
}
|
|
6035
|
+
return {
|
|
6036
|
+
element,
|
|
6037
|
+
hotspot: {
|
|
6038
|
+
x: 16,
|
|
6039
|
+
y: 16
|
|
6040
|
+
},
|
|
6041
|
+
...canvas ? { canvas } : {},
|
|
6042
|
+
dispose: () => {}
|
|
6043
|
+
};
|
|
6044
|
+
}
|
|
6045
|
+
//#endregion
|
|
5689
6046
|
//#region src/interaction/list-drag-select-controller.ts
|
|
5690
6047
|
const DEFAULT_POINTER_TYPES = [`mouse`, `pen`];
|
|
5691
6048
|
const DEFAULT_THRESHOLD = 4;
|
|
5692
6049
|
/** Pointer distance (px) from an edge that triggers auto-scroll. */
|
|
5693
6050
|
const EDGE_ZONE = 28;
|
|
5694
6051
|
/** Max auto-scroll speed in px per frame. */
|
|
5695
|
-
const MAX_SCROLL_SPEED = 16;
|
|
6052
|
+
const MAX_SCROLL_SPEED$1 = 16;
|
|
5696
6053
|
/**
|
|
5697
6054
|
* Shared pointer-drag (marquee / rubber-band) selection for list components.
|
|
5698
6055
|
*
|
|
@@ -5958,10 +6315,10 @@ var ListDragSelectController = class {
|
|
|
5958
6315
|
const py = this.#currentClientY - box.top;
|
|
5959
6316
|
let dx = 0;
|
|
5960
6317
|
let dy = 0;
|
|
5961
|
-
if (px < EDGE_ZONE) dx = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, px) / EDGE_ZONE));
|
|
5962
|
-
else if (px > box.width - EDGE_ZONE) dx = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, box.width - px) / EDGE_ZONE));
|
|
5963
|
-
if (py < EDGE_ZONE) dy = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, py) / EDGE_ZONE));
|
|
5964
|
-
else if (py > box.height - EDGE_ZONE) dy = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, box.height - py) / EDGE_ZONE));
|
|
6318
|
+
if (px < EDGE_ZONE) dx = -Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, px) / EDGE_ZONE));
|
|
6319
|
+
else if (px > box.width - EDGE_ZONE) dx = Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, box.width - px) / EDGE_ZONE));
|
|
6320
|
+
if (py < EDGE_ZONE) dy = -Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, py) / EDGE_ZONE));
|
|
6321
|
+
else if (py > box.height - EDGE_ZONE) dy = Math.ceil(MAX_SCROLL_SPEED$1 * (1 - Math.max(0, box.height - py) / EDGE_ZONE));
|
|
5965
6322
|
if (dx === 0 && dy === 0) return;
|
|
5966
6323
|
const autoScroll = this.#config.autoScroll;
|
|
5967
6324
|
if (!autoScroll) return;
|
|
@@ -6075,25 +6432,251 @@ function animateListItemIn(el, options = {}) {
|
|
|
6075
6432
|
easing
|
|
6076
6433
|
});
|
|
6077
6434
|
}
|
|
6435
|
+
function outResult(finished, animation) {
|
|
6436
|
+
return Object.assign(finished, { animation });
|
|
6437
|
+
}
|
|
6078
6438
|
/**
|
|
6079
|
-
*
|
|
6080
|
-
*
|
|
6081
|
-
*
|
|
6082
|
-
*
|
|
6439
|
+
* Start the collapse + fade-out animation for `el` and return the handle.
|
|
6440
|
+
* Returns `undefined` when no animation was started (reduced motion or zero
|
|
6441
|
+
* size). The caller owns the handle and must `cancel()` it if the removal is
|
|
6442
|
+
* reversed — a retained `fill: forwards` frame otherwise keeps overriding the
|
|
6443
|
+
* element's ordinary CSS indefinitely.
|
|
6083
6444
|
*/
|
|
6084
|
-
function
|
|
6085
|
-
if (prefersReducedMotion()) return
|
|
6445
|
+
function startListItemOutAnimation(el, options = {}) {
|
|
6446
|
+
if (prefersReducedMotion()) return void 0;
|
|
6086
6447
|
const { axis = `block`, easing = `ease` } = options;
|
|
6087
6448
|
const duration = resolveDuration(el, options.duration);
|
|
6088
6449
|
const size = measure(el, axis);
|
|
6089
|
-
if (size <= 0) return
|
|
6450
|
+
if (size <= 0) return void 0;
|
|
6090
6451
|
return el.animate([fullFrame(size, axis), collapsedFrame(axis)], {
|
|
6091
6452
|
duration,
|
|
6092
6453
|
easing,
|
|
6093
6454
|
fill: `forwards`
|
|
6094
|
-
})
|
|
6455
|
+
});
|
|
6456
|
+
}
|
|
6457
|
+
/**
|
|
6458
|
+
* Collapse + fade `el` out. Resolves once the animation finishes (or straight
|
|
6459
|
+
* away under reduced motion); the caller detaches the element after. The final
|
|
6460
|
+
* collapsed state is held (`fill: forwards`) so there's no flash back to full
|
|
6461
|
+
* size in the gap before removal.
|
|
6462
|
+
*
|
|
6463
|
+
* The returned promise carries an `.animation` handle. If the removal is
|
|
6464
|
+
* reversed (the same key becomes visible again), cancel that handle so its
|
|
6465
|
+
* filled final frame stops overriding the reused element's style.
|
|
6466
|
+
*/
|
|
6467
|
+
function animateListItemOut(el, options = {}) {
|
|
6468
|
+
const animation = startListItemOutAnimation(el, options);
|
|
6469
|
+
if (!animation) return outResult(Promise.resolve(), void 0);
|
|
6470
|
+
return outResult(animation.finished.then(() => void 0, () => void 0), animation);
|
|
6095
6471
|
}
|
|
6096
6472
|
//#endregion
|
|
6473
|
+
//#region src/interaction/list-native-drag-controller.ts
|
|
6474
|
+
/**
|
|
6475
|
+
* Shared native item/row drag-out for list components.
|
|
6476
|
+
*
|
|
6477
|
+
* Owns capture-phase `dragstart` / `dragend` listeners on the host and its
|
|
6478
|
+
* render root, a `MutationObserver` that keeps light-DOM / slotted item `draggable`
|
|
6479
|
+
* attributes in sync, and a single post-dispatch disposal on
|
|
6480
|
+
* `requestAnimationFrame`. All DOM / selection knowledge lives in the host
|
|
6481
|
+
* config callbacks.
|
|
6482
|
+
*/
|
|
6483
|
+
var ListNativeDragController = class {
|
|
6484
|
+
#host;
|
|
6485
|
+
#config;
|
|
6486
|
+
#dragging = false;
|
|
6487
|
+
#boundRoot;
|
|
6488
|
+
#boundHost = false;
|
|
6489
|
+
#seenDragStarts = /* @__PURE__ */ new WeakSet();
|
|
6490
|
+
#observer;
|
|
6491
|
+
constructor(host, config) {
|
|
6492
|
+
this.#host = host;
|
|
6493
|
+
this.#config = config;
|
|
6494
|
+
host.addController(this);
|
|
6495
|
+
}
|
|
6496
|
+
get isDragging() {
|
|
6497
|
+
return this.#dragging;
|
|
6498
|
+
}
|
|
6499
|
+
/** `"true"` when enabled, else `"false"` — for shadow-row template bindings. */
|
|
6500
|
+
get draggableAttr() {
|
|
6501
|
+
try {
|
|
6502
|
+
return this.#config.isEnabled() ? `true` : `false`;
|
|
6503
|
+
} catch {
|
|
6504
|
+
return `false`;
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6507
|
+
/** Re-run the light-DOM `draggable` sync (e.g. after `itemsDraggable` flips). */
|
|
6508
|
+
refreshDraggable() {
|
|
6509
|
+
try {
|
|
6510
|
+
this.#config.syncLightDomDraggable?.();
|
|
6511
|
+
} catch {}
|
|
6512
|
+
}
|
|
6513
|
+
hostConnected() {
|
|
6514
|
+
this.#bind();
|
|
6515
|
+
this.#observer ??= new MutationObserver(() => this.refreshDraggable());
|
|
6516
|
+
try {
|
|
6517
|
+
this.#observer.observe(this.#host, {
|
|
6518
|
+
childList: true,
|
|
6519
|
+
subtree: true
|
|
6520
|
+
});
|
|
6521
|
+
} catch {}
|
|
6522
|
+
this.refreshDraggable();
|
|
6523
|
+
}
|
|
6524
|
+
/** `renderRoot` does not exist yet at `hostConnected` for a shadow-DOM host — rebind once it does. */
|
|
6525
|
+
hostUpdated() {
|
|
6526
|
+
this.#bind();
|
|
6527
|
+
}
|
|
6528
|
+
hostDisconnected() {
|
|
6529
|
+
this.#unbind();
|
|
6530
|
+
try {
|
|
6531
|
+
this.#observer?.disconnect();
|
|
6532
|
+
} catch {}
|
|
6533
|
+
this.#dragging = false;
|
|
6534
|
+
}
|
|
6535
|
+
#renderRoot() {
|
|
6536
|
+
return this.#host.renderRoot ?? this.#host;
|
|
6537
|
+
}
|
|
6538
|
+
#bind() {
|
|
6539
|
+
const root = this.#renderRoot();
|
|
6540
|
+
if (root !== this.#boundRoot) {
|
|
6541
|
+
this.#unbind();
|
|
6542
|
+
this.#boundRoot = root;
|
|
6543
|
+
root.addEventListener(`dragstart`, this.#onDragStart, { capture: true });
|
|
6544
|
+
root.addEventListener(`dragend`, this.#onDragEnd, { capture: true });
|
|
6545
|
+
}
|
|
6546
|
+
if (!this.#boundHost) {
|
|
6547
|
+
this.#boundHost = true;
|
|
6548
|
+
this.#host.addEventListener(`dragstart`, this.#onDragStart, { capture: true });
|
|
6549
|
+
this.#host.addEventListener(`dragend`, this.#onDragEnd, { capture: true });
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
#unbind() {
|
|
6553
|
+
this.#boundRoot?.removeEventListener(`dragstart`, this.#onDragStart, { capture: true });
|
|
6554
|
+
this.#boundRoot?.removeEventListener(`dragend`, this.#onDragEnd, { capture: true });
|
|
6555
|
+
this.#boundRoot = void 0;
|
|
6556
|
+
if (this.#boundHost) {
|
|
6557
|
+
this.#boundHost = false;
|
|
6558
|
+
this.#host.removeEventListener(`dragstart`, this.#onDragStart, { capture: true });
|
|
6559
|
+
this.#host.removeEventListener(`dragend`, this.#onDragEnd, { capture: true });
|
|
6560
|
+
}
|
|
6561
|
+
}
|
|
6562
|
+
#onDragStart = (event) => {
|
|
6563
|
+
if (!(event instanceof DragEvent)) return;
|
|
6564
|
+
if (this.#seenDragStarts.has(event)) return;
|
|
6565
|
+
let enabled = false;
|
|
6566
|
+
try {
|
|
6567
|
+
enabled = this.#config.isEnabled();
|
|
6568
|
+
} catch {
|
|
6569
|
+
return;
|
|
6570
|
+
}
|
|
6571
|
+
if (!enabled) return;
|
|
6572
|
+
let originKey;
|
|
6573
|
+
try {
|
|
6574
|
+
originKey = this.#config.resolveEventToKey(event.target);
|
|
6575
|
+
} catch {
|
|
6576
|
+
return;
|
|
6577
|
+
}
|
|
6578
|
+
if (originKey) this.#seenDragStarts.add(event);
|
|
6579
|
+
if (!originKey) return;
|
|
6580
|
+
let prepared;
|
|
6581
|
+
try {
|
|
6582
|
+
prepared = this.#config.prepareSelection(originKey);
|
|
6583
|
+
} catch {
|
|
6584
|
+
return;
|
|
6585
|
+
}
|
|
6586
|
+
if (!prepared || prepared.selected.length === 0) return;
|
|
6587
|
+
const { origin, selected } = prepared;
|
|
6588
|
+
let hostStyle;
|
|
6589
|
+
try {
|
|
6590
|
+
hostStyle = getComputedStyle(this.#host);
|
|
6591
|
+
} catch {
|
|
6592
|
+
hostStyle = document.createElement(`div`).style;
|
|
6593
|
+
}
|
|
6594
|
+
let metrics = {};
|
|
6595
|
+
try {
|
|
6596
|
+
metrics = this.#config.getMetrics() ?? {};
|
|
6597
|
+
} catch {
|
|
6598
|
+
metrics = {};
|
|
6599
|
+
}
|
|
6600
|
+
const context = {
|
|
6601
|
+
source: this.#config.source,
|
|
6602
|
+
origin,
|
|
6603
|
+
selected,
|
|
6604
|
+
metrics,
|
|
6605
|
+
hostStyle
|
|
6606
|
+
};
|
|
6607
|
+
let renderer;
|
|
6608
|
+
try {
|
|
6609
|
+
renderer = this.#config.getRenderer();
|
|
6610
|
+
} catch {
|
|
6611
|
+
renderer = void 0;
|
|
6612
|
+
}
|
|
6613
|
+
let preview;
|
|
6614
|
+
try {
|
|
6615
|
+
preview = renderer ? renderer(context) : createDefaultListDragPreview(context);
|
|
6616
|
+
} catch {
|
|
6617
|
+
preview = createDefaultListDragPreview(context);
|
|
6618
|
+
}
|
|
6619
|
+
try {
|
|
6620
|
+
document.body.appendChild(preview.element);
|
|
6621
|
+
} catch {}
|
|
6622
|
+
const detail = {
|
|
6623
|
+
key: origin.key,
|
|
6624
|
+
index: origin.index,
|
|
6625
|
+
item: origin.item,
|
|
6626
|
+
selectedKeys: selected.map((entry) => entry.key),
|
|
6627
|
+
selected,
|
|
6628
|
+
preview
|
|
6629
|
+
};
|
|
6630
|
+
let notCancelled = true;
|
|
6631
|
+
try {
|
|
6632
|
+
notCancelled = this.#config.dispatch(detail);
|
|
6633
|
+
} catch {
|
|
6634
|
+
notCancelled = true;
|
|
6635
|
+
}
|
|
6636
|
+
if (notCancelled) {
|
|
6637
|
+
if (event.dataTransfer) {
|
|
6638
|
+
try {
|
|
6639
|
+
if (event.dataTransfer.effectAllowed === `none` || event.dataTransfer.effectAllowed === `uninitialized`) event.dataTransfer.effectAllowed = `copyMove`;
|
|
6640
|
+
} catch {}
|
|
6641
|
+
try {
|
|
6642
|
+
this.#config.writeDataTransfer?.(event.dataTransfer, detail);
|
|
6643
|
+
} catch {}
|
|
6644
|
+
}
|
|
6645
|
+
const hotspot = preview.hotspot ?? {
|
|
6646
|
+
x: 16,
|
|
6647
|
+
y: 16
|
|
6648
|
+
};
|
|
6649
|
+
try {
|
|
6650
|
+
event.dataTransfer?.setDragImage(preview.element, hotspot.x, hotspot.y);
|
|
6651
|
+
} catch {}
|
|
6652
|
+
} else try {
|
|
6653
|
+
event.preventDefault();
|
|
6654
|
+
} catch {}
|
|
6655
|
+
this.#dragging = true;
|
|
6656
|
+
try {
|
|
6657
|
+
this.#config.onActiveChange(true, origin.key);
|
|
6658
|
+
} catch {}
|
|
6659
|
+
requestAnimationFrame(() => {
|
|
6660
|
+
try {
|
|
6661
|
+
preview.element.remove();
|
|
6662
|
+
} catch {}
|
|
6663
|
+
try {
|
|
6664
|
+
preview.dispose?.();
|
|
6665
|
+
} catch {}
|
|
6666
|
+
});
|
|
6667
|
+
};
|
|
6668
|
+
#onDragEnd = () => {
|
|
6669
|
+
if (!this.#dragging) return;
|
|
6670
|
+
this.#dragging = false;
|
|
6671
|
+
try {
|
|
6672
|
+
this.#config.onActiveChange(false);
|
|
6673
|
+
} catch {}
|
|
6674
|
+
try {
|
|
6675
|
+
this.#config.onEnd();
|
|
6676
|
+
} catch {}
|
|
6677
|
+
};
|
|
6678
|
+
};
|
|
6679
|
+
//#endregion
|
|
6097
6680
|
//#region src/interaction/list-selection-controller.ts
|
|
6098
6681
|
/** Whether the interaction mode allows building a multi-item selection. */
|
|
6099
6682
|
function isMultiMode(mode) {
|
|
@@ -9165,15 +9748,138 @@ async function collectDataResult(result, signal) {
|
|
|
9165
9748
|
return result;
|
|
9166
9749
|
}
|
|
9167
9750
|
//#endregion
|
|
9168
|
-
//#region src/common/tree-
|
|
9751
|
+
//#region src/common/tree-drop-apply.ts
|
|
9169
9752
|
function findNode$1(root, key) {
|
|
9170
9753
|
if (root.item.key === key) return root;
|
|
9171
|
-
|
|
9172
|
-
for (const child of root.children) {
|
|
9754
|
+
for (const child of root.children ?? []) {
|
|
9173
9755
|
const found = findNode$1(child, key);
|
|
9174
9756
|
if (found) return found;
|
|
9175
9757
|
}
|
|
9176
9758
|
}
|
|
9759
|
+
function findParent(root, key, parent = void 0) {
|
|
9760
|
+
for (const child of root.children ?? []) {
|
|
9761
|
+
if (child.item.key === key) return parent === void 0 ? root : parent;
|
|
9762
|
+
const found = findParent(child, key, child);
|
|
9763
|
+
if (found) return found;
|
|
9764
|
+
}
|
|
9765
|
+
}
|
|
9766
|
+
/** True when `key` is `ancestorKey`, or a descendant of it. */
|
|
9767
|
+
function isSelfOrDescendant(root, ancestorKey, key) {
|
|
9768
|
+
const ancestor = findNode$1(root, ancestorKey);
|
|
9769
|
+
return ancestor !== void 0 && findNode$1(ancestor, key) !== void 0;
|
|
9770
|
+
}
|
|
9771
|
+
/** Remove every node whose key is in `keys` (with its whole subtree), in one pass. */
|
|
9772
|
+
function removeKeys(node, keys) {
|
|
9773
|
+
if (!node.children) return node;
|
|
9774
|
+
return {
|
|
9775
|
+
...node,
|
|
9776
|
+
children: node.children.filter((c) => !keys.has(c.item.key)).map((c) => removeKeys(c, keys))
|
|
9777
|
+
};
|
|
9778
|
+
}
|
|
9779
|
+
function childrenOf(root, parentKey) {
|
|
9780
|
+
if (parentKey === void 0) return root.children ?? [];
|
|
9781
|
+
return findNode$1(root, parentKey)?.children ?? [];
|
|
9782
|
+
}
|
|
9783
|
+
/** Return a new root with `parentKey`'s children replaced (root itself when `parentKey` is undefined). */
|
|
9784
|
+
function withChildren(node, parentKey, children) {
|
|
9785
|
+
if (parentKey === void 0) return {
|
|
9786
|
+
...node,
|
|
9787
|
+
children
|
|
9788
|
+
};
|
|
9789
|
+
if (node.item.key === parentKey) return {
|
|
9790
|
+
...node,
|
|
9791
|
+
children
|
|
9792
|
+
};
|
|
9793
|
+
if (!node.children) return node;
|
|
9794
|
+
return {
|
|
9795
|
+
...node,
|
|
9796
|
+
children: node.children.map((c) => withChildren(c, parentKey, children))
|
|
9797
|
+
};
|
|
9798
|
+
}
|
|
9799
|
+
function clamp$5(n, min, max) {
|
|
9800
|
+
return Math.max(min, Math.min(max, n));
|
|
9801
|
+
}
|
|
9802
|
+
/**
|
|
9803
|
+
* Drop keys whose ancestor is also being dragged — only the top-most selected
|
|
9804
|
+
* nodes move; their subtrees travel with them. Preserves input order.
|
|
9805
|
+
*/
|
|
9806
|
+
function pruneDraggedDescendants(root, keys) {
|
|
9807
|
+
const set = new Set(keys);
|
|
9808
|
+
return keys.filter((key) => {
|
|
9809
|
+
let parent = findParent(root, key);
|
|
9810
|
+
while (parent) {
|
|
9811
|
+
if (set.has(parent.item.key)) return false;
|
|
9812
|
+
parent = findParent(root, parent.item.key);
|
|
9813
|
+
}
|
|
9814
|
+
return true;
|
|
9815
|
+
});
|
|
9816
|
+
}
|
|
9817
|
+
/**
|
|
9818
|
+
* Framework-agnostic drop application. Given the current immutable `root` and a
|
|
9819
|
+
* resolved drop context, returns a **new** root with the drop applied, or the
|
|
9820
|
+
* unchanged `root` when the drop is invalid (dragged node into its own subtree,
|
|
9821
|
+
* missing reference, empty payload). Never throws, never mutates.
|
|
9822
|
+
*
|
|
9823
|
+
* The insertion point is re-derived from `target.referenceKey` + `target.position`
|
|
9824
|
+
* against the post-removal tree, so same-parent reorders are off-by-one-safe and
|
|
9825
|
+
* multi-node drops land as siblings in drag order. `target.index` is honoured only
|
|
9826
|
+
* for `position: 'inside'` (0 = first child, large = append).
|
|
9827
|
+
*/
|
|
9828
|
+
function applyTreeDrop(root, ctx) {
|
|
9829
|
+
const { target, source } = ctx;
|
|
9830
|
+
let nodes;
|
|
9831
|
+
let removeSet = /* @__PURE__ */ new Set();
|
|
9832
|
+
if (source === `internal`) {
|
|
9833
|
+
const keys = pruneDraggedDescendants(root, [...ctx.draggedKeys]);
|
|
9834
|
+
if (keys.length === 0) return root;
|
|
9835
|
+
if (target.parentKey !== void 0) {
|
|
9836
|
+
for (const key of keys) if (isSelfOrDescendant(root, key, target.parentKey)) return root;
|
|
9837
|
+
}
|
|
9838
|
+
if (target.position !== `inside`) {
|
|
9839
|
+
for (const key of keys) if (isSelfOrDescendant(root, key, target.referenceKey)) return root;
|
|
9840
|
+
}
|
|
9841
|
+
const resolved = keys.map((k) => findNode$1(root, k));
|
|
9842
|
+
if (resolved.includes(void 0)) return root;
|
|
9843
|
+
nodes = resolved;
|
|
9844
|
+
removeSet = new Set(keys);
|
|
9845
|
+
} else {
|
|
9846
|
+
nodes = (ctx.dragged ?? []).map((n) => ({ ...n }));
|
|
9847
|
+
if (nodes.length === 0) return root;
|
|
9848
|
+
}
|
|
9849
|
+
const afterRemoval = removeSet.size > 0 ? removeKeys(root, removeSet) : root;
|
|
9850
|
+
let parentKey;
|
|
9851
|
+
let index;
|
|
9852
|
+
if (target.position === `inside`) {
|
|
9853
|
+
if (findNode$1(afterRemoval, target.referenceKey) === void 0) return root;
|
|
9854
|
+
parentKey = target.referenceKey;
|
|
9855
|
+
const kids = childrenOf(afterRemoval, parentKey);
|
|
9856
|
+
index = clamp$5(target.index, 0, kids.length);
|
|
9857
|
+
} else {
|
|
9858
|
+
parentKey = findParent(afterRemoval, target.referenceKey)?.item.key;
|
|
9859
|
+
const refIdx = childrenOf(afterRemoval, parentKey).findIndex((c) => c.item.key === target.referenceKey);
|
|
9860
|
+
if (refIdx < 0) return root;
|
|
9861
|
+
index = target.position === `before` ? refIdx : refIdx + 1;
|
|
9862
|
+
}
|
|
9863
|
+
const kids = [...childrenOf(afterRemoval, parentKey)];
|
|
9864
|
+
const next = [
|
|
9865
|
+
...kids.slice(0, index),
|
|
9866
|
+
...nodes,
|
|
9867
|
+
...kids.slice(index)
|
|
9868
|
+
];
|
|
9869
|
+
return withChildren(afterRemoval, parentKey, next);
|
|
9870
|
+
}
|
|
9871
|
+
/** Build a synthetic `TreeDropTarget` for programmatic moves (see `TreeDataModel`). */
|
|
9872
|
+
function dropTargetFor(referenceKey, position, index = position === `inside` ? Number.MAX_SAFE_INTEGER : 0) {
|
|
9873
|
+
return {
|
|
9874
|
+
referenceKey,
|
|
9875
|
+
position,
|
|
9876
|
+
index,
|
|
9877
|
+
parentKey: position === `inside` ? referenceKey : void 0,
|
|
9878
|
+
depth: 0
|
|
9879
|
+
};
|
|
9880
|
+
}
|
|
9881
|
+
//#endregion
|
|
9882
|
+
//#region src/common/tree-data-model.ts
|
|
9177
9883
|
/** Return a new root with the node at `key` replaced by `replacer(node)`. */
|
|
9178
9884
|
function mapNode(root, key, replacer) {
|
|
9179
9885
|
if (root.item.key === key) return replacer(root);
|
|
@@ -9198,11 +9904,23 @@ function removeNodeFrom(root, key) {
|
|
|
9198
9904
|
children: root.children.filter((c) => c.item.key !== key).map((c) => removeNodeFrom(c, key))
|
|
9199
9905
|
};
|
|
9200
9906
|
}
|
|
9201
|
-
/** Return a new root with
|
|
9202
|
-
function
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9907
|
+
/** Return a new root with `newChild` inserted at `index` among the children of `parentKey`. */
|
|
9908
|
+
function insertChildAt(root, parentKey, newChild, index) {
|
|
9909
|
+
return mapNode(root, parentKey, (parent) => {
|
|
9910
|
+
const children = parent.children ?? [];
|
|
9911
|
+
const clampedIndex = Math.max(0, Math.min(index, children.length));
|
|
9912
|
+
return {
|
|
9913
|
+
item: parent.item,
|
|
9914
|
+
children: [
|
|
9915
|
+
...children.slice(0, clampedIndex),
|
|
9916
|
+
newChild,
|
|
9917
|
+
...children.slice(clampedIndex)
|
|
9918
|
+
]
|
|
9919
|
+
};
|
|
9920
|
+
});
|
|
9921
|
+
}
|
|
9922
|
+
function getRootChildren(root) {
|
|
9923
|
+
return root.children ?? [];
|
|
9206
9924
|
}
|
|
9207
9925
|
/**
|
|
9208
9926
|
* Manages tree data for tree-like components.
|
|
@@ -9330,10 +10048,80 @@ var TreeDataModel = class {
|
|
|
9330
10048
|
}
|
|
9331
10049
|
/**
|
|
9332
10050
|
* Moves the node with the given key to become a child of `newParentKey`.
|
|
10051
|
+
* When `index` is provided, inserts at that position; otherwise appends.
|
|
10052
|
+
* Returns the new root (connected components are notified automatically).
|
|
10053
|
+
*/
|
|
10054
|
+
moveNode(key, newParentKey, index) {
|
|
10055
|
+
const next = applyTreeDrop(this.#root, {
|
|
10056
|
+
source: `internal`,
|
|
10057
|
+
draggedKeys: [key],
|
|
10058
|
+
target: dropTargetFor(newParentKey, `inside`, index ?? Number.MAX_SAFE_INTEGER)
|
|
10059
|
+
});
|
|
10060
|
+
if (next !== this.#root) {
|
|
10061
|
+
this.#root = next;
|
|
10062
|
+
this.#notify({
|
|
10063
|
+
type: `root`,
|
|
10064
|
+
root: this.#root
|
|
10065
|
+
});
|
|
10066
|
+
}
|
|
10067
|
+
return this.#root;
|
|
10068
|
+
}
|
|
10069
|
+
/**
|
|
10070
|
+
* Moves the node with the given key to become a sibling of `referenceKey`,
|
|
10071
|
+
* positioned `before` or `after` it. A no-op (returns the unchanged root) when
|
|
10072
|
+
* `key` is `referenceKey`, an ancestor of it, or either is missing.
|
|
10073
|
+
* Returns the new root (connected components are notified automatically).
|
|
10074
|
+
*/
|
|
10075
|
+
moveNodeRelative(key, referenceKey, position) {
|
|
10076
|
+
const next = applyTreeDrop(this.#root, {
|
|
10077
|
+
source: `internal`,
|
|
10078
|
+
draggedKeys: [key],
|
|
10079
|
+
target: dropTargetFor(referenceKey, position)
|
|
10080
|
+
});
|
|
10081
|
+
if (next !== this.#root) {
|
|
10082
|
+
this.#root = next;
|
|
10083
|
+
this.#notify({
|
|
10084
|
+
type: `root`,
|
|
10085
|
+
root: this.#root
|
|
10086
|
+
});
|
|
10087
|
+
}
|
|
10088
|
+
return this.#root;
|
|
10089
|
+
}
|
|
10090
|
+
/**
|
|
10091
|
+
* Applies a resolved drop (from `ixfx-tree-list`'s `tree-drop` event or a
|
|
10092
|
+
* hand-built context) to the current root. No-op when the drop is invalid.
|
|
10093
|
+
* Returns the new root (connected components are notified automatically).
|
|
10094
|
+
*/
|
|
10095
|
+
applyDrop(ctx) {
|
|
10096
|
+
const next = applyTreeDrop(this.#root, ctx);
|
|
10097
|
+
if (next !== this.#root) {
|
|
10098
|
+
this.#root = next;
|
|
10099
|
+
this.#notify({
|
|
10100
|
+
type: `root`,
|
|
10101
|
+
root: this.#root
|
|
10102
|
+
});
|
|
10103
|
+
}
|
|
10104
|
+
return this.#root;
|
|
10105
|
+
}
|
|
10106
|
+
/**
|
|
10107
|
+
* Inserts `node` as a child of `parentKey` (or at the root level when `parentKey` is undefined).
|
|
10108
|
+
* When `index` is provided, inserts at that position; otherwise appends.
|
|
9333
10109
|
* Returns the new root (connected components are notified automatically).
|
|
9334
10110
|
*/
|
|
9335
|
-
|
|
9336
|
-
|
|
10111
|
+
insertNode(parentKey, node, index) {
|
|
10112
|
+
if (parentKey === void 0) {
|
|
10113
|
+
const children = getRootChildren(this.#root);
|
|
10114
|
+
const clampedIndex = Math.max(0, Math.min(index ?? children.length, children.length));
|
|
10115
|
+
this.#root = {
|
|
10116
|
+
...this.#root,
|
|
10117
|
+
children: [
|
|
10118
|
+
...children.slice(0, clampedIndex),
|
|
10119
|
+
node,
|
|
10120
|
+
...children.slice(clampedIndex)
|
|
10121
|
+
]
|
|
10122
|
+
};
|
|
10123
|
+
} else if (index !== void 0) this.#root = insertChildAt(this.#root, parentKey, node, index);
|
|
10124
|
+
else this.#root = addChildTo(this.#root, parentKey, node);
|
|
9337
10125
|
this.#notify({
|
|
9338
10126
|
type: `root`,
|
|
9339
10127
|
root: this.#root
|
|
@@ -13115,6 +13903,7 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
13115
13903
|
this.allowGrouping = false;
|
|
13116
13904
|
this.crossGroupSelection = false;
|
|
13117
13905
|
this.columnMenu = `auto`;
|
|
13906
|
+
this.itemsDraggable = false;
|
|
13118
13907
|
this._columnFormatters = /* @__PURE__ */ new Map();
|
|
13119
13908
|
this._selectedKeys = /* @__PURE__ */ new Set();
|
|
13120
13909
|
this._scrollTop = 0;
|
|
@@ -13132,7 +13921,45 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
13132
13921
|
id: k,
|
|
13133
13922
|
enabled: true
|
|
13134
13923
|
})),
|
|
13135
|
-
onStateChange: () => this.requestUpdate()
|
|
13924
|
+
onStateChange: () => this.requestUpdate(),
|
|
13925
|
+
hoverDisabled: () => this.#nativeDrag.isDragging
|
|
13926
|
+
});
|
|
13927
|
+
this.#nativeDragging = false;
|
|
13928
|
+
this.#postDragSuppressTimer = 0;
|
|
13929
|
+
this.#nativeDrag = new ListNativeDragController(this, {
|
|
13930
|
+
source: `data-grid`,
|
|
13931
|
+
isEnabled: () => this.itemsDraggable && this.selectionMode !== `none` && this._flat.some((f) => f.type === `row`),
|
|
13932
|
+
resolveEventToKey: (target) => {
|
|
13933
|
+
if (!(target instanceof Element)) return void 0;
|
|
13934
|
+
if (target.closest?.(`.header-cell`)) return void 0;
|
|
13935
|
+
return (target.closest?.(`.row`))?.dataset.key;
|
|
13936
|
+
},
|
|
13937
|
+
prepareSelection: (originKey) => this.#prepareNativeDrag(originKey),
|
|
13938
|
+
getMetrics: () => ({ rowHeight: this.rowHeight }),
|
|
13939
|
+
getRenderer: () => this.dragPreviewRenderer,
|
|
13940
|
+
dispatch: (detail) => this.dispatchEvent(new CustomEvent(`list-native-drag-start`, {
|
|
13941
|
+
detail,
|
|
13942
|
+
bubbles: true,
|
|
13943
|
+
composed: true,
|
|
13944
|
+
cancelable: true
|
|
13945
|
+
})),
|
|
13946
|
+
onActiveChange: (active, originKey) => {
|
|
13947
|
+
this.#nativeDragging = active;
|
|
13948
|
+
this.#dragOriginKey = active ? originKey : void 0;
|
|
13949
|
+
this.toggleAttribute(`data-native-dragging`, active);
|
|
13950
|
+
if (active) {
|
|
13951
|
+
const count = this._selectedKeys.size;
|
|
13952
|
+
this.setAttribute(`aria-label`, count <= 1 ? `Dragging 1 item` : `Dragging ${count} items`);
|
|
13953
|
+
} else this.removeAttribute(`aria-label`);
|
|
13954
|
+
this.requestUpdate();
|
|
13955
|
+
},
|
|
13956
|
+
onEnd: () => {
|
|
13957
|
+
this.#nativeDragging = false;
|
|
13958
|
+
this.#dragOriginKey = void 0;
|
|
13959
|
+
this.toggleAttribute(`data-native-dragging`, false);
|
|
13960
|
+
this.removeAttribute(`aria-label`);
|
|
13961
|
+
this.#startPostDragSuppressTimer();
|
|
13962
|
+
}
|
|
13136
13963
|
});
|
|
13137
13964
|
this._sortedRows = [];
|
|
13138
13965
|
this._flat = [];
|
|
@@ -13404,6 +14231,7 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
13404
14231
|
.row.item.tickled { background: var(--item-bg-tickled); border: var(--item-border-tickled); color: var(--item-text-tickled); }
|
|
13405
14232
|
.row.item.selected { background: var(--item-bg-selected); border: var(--item-border-selected); color: var(--item-text-selected); }
|
|
13406
14233
|
.row.item.selected.tickled { background: var(--item-bg-selected-tickled); }
|
|
14234
|
+
.row.item.dragging-origin { opacity: 0.6; }
|
|
13407
14235
|
|
|
13408
14236
|
/* Insertion / removal animation. Only while [reflowing] — the ~0.3s after
|
|
13409
14237
|
the row set changes — do rows slide (their top transitions) to make or
|
|
@@ -13449,6 +14277,43 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
13449
14277
|
`
|
|
13450
14278
|
];
|
|
13451
14279
|
}
|
|
14280
|
+
#nativeDragging;
|
|
14281
|
+
#dragOriginKey;
|
|
14282
|
+
#postDragSuppressTimer;
|
|
14283
|
+
#nativeDrag;
|
|
14284
|
+
#prepareNativeDrag(originKey) {
|
|
14285
|
+
const rows = this._flat.filter((f) => f.type === `row`);
|
|
14286
|
+
if (!rows.some((f) => f.key === originKey)) return void 0;
|
|
14287
|
+
if (!this._selectedKeys.has(originKey)) this._replaceSelection(originKey);
|
|
14288
|
+
const selected = [];
|
|
14289
|
+
let displayIndex = 0;
|
|
14290
|
+
for (const entry of rows) {
|
|
14291
|
+
if (!this._selectedKeys.has(entry.key)) {
|
|
14292
|
+
displayIndex++;
|
|
14293
|
+
continue;
|
|
14294
|
+
}
|
|
14295
|
+
const rowEl = this.renderRoot.querySelector(`.row[data-key="${CSS.escape(entry.key)}"]`) ?? void 0;
|
|
14296
|
+
selected.push({
|
|
14297
|
+
key: entry.key,
|
|
14298
|
+
index: displayIndex,
|
|
14299
|
+
item: entry.row,
|
|
14300
|
+
...rowEl ? { element: rowEl } : {}
|
|
14301
|
+
});
|
|
14302
|
+
displayIndex++;
|
|
14303
|
+
}
|
|
14304
|
+
const origin = selected.find((entry) => entry.key === originKey);
|
|
14305
|
+
if (!origin) return void 0;
|
|
14306
|
+
return {
|
|
14307
|
+
origin,
|
|
14308
|
+
selected
|
|
14309
|
+
};
|
|
14310
|
+
}
|
|
14311
|
+
#startPostDragSuppressTimer() {
|
|
14312
|
+
if (this.#postDragSuppressTimer) clearTimeout(this.#postDragSuppressTimer);
|
|
14313
|
+
this.#postDragSuppressTimer = window.setTimeout(() => {
|
|
14314
|
+
this.#postDragSuppressTimer = 0;
|
|
14315
|
+
}, 0);
|
|
14316
|
+
}
|
|
13452
14317
|
#searchRegistry;
|
|
13453
14318
|
#unregisterSearchCommands;
|
|
13454
14319
|
#searchKeyByRow;
|
|
@@ -13525,6 +14390,10 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
13525
14390
|
clearTimeout(this.#rowReflowTimer);
|
|
13526
14391
|
this.#rowReflowTimer = 0;
|
|
13527
14392
|
}
|
|
14393
|
+
if (this.#postDragSuppressTimer) {
|
|
14394
|
+
clearTimeout(this.#postDragSuppressTimer);
|
|
14395
|
+
this.#postDragSuppressTimer = 0;
|
|
14396
|
+
}
|
|
13528
14397
|
}
|
|
13529
14398
|
/**
|
|
13530
14399
|
* Dispatch a command to this grid — routes through the command registry so
|
|
@@ -13707,6 +14576,7 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
13707
14576
|
}));
|
|
13708
14577
|
}
|
|
13709
14578
|
_onRowClick(rowKey, col, e) {
|
|
14579
|
+
if (this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
13710
14580
|
if (col && col.selectable === false) return;
|
|
13711
14581
|
if (this.selectionMode === `none` && this.interactionMode !== `checked` && this.interactionMode !== `sticky`) return;
|
|
13712
14582
|
if (this.interactionMode === `manual`) return;
|
|
@@ -14366,8 +15236,9 @@ let DataGridElement = class DataGridElement extends i {
|
|
|
14366
15236
|
const selected = this._selectedKeys.has(rowKey);
|
|
14367
15237
|
const tickled = this._tickled.isTickled(rowKey);
|
|
14368
15238
|
return b`
|
|
14369
|
-
<div class="row item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${this.#enteringRowKeys.has(rowKey) ? `entering` : ``}" style="top:${absIdx * rh}px; height:${rh}px"
|
|
15239
|
+
<div class="row item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${this.#enteringRowKeys.has(rowKey) ? `entering` : ``} ${this.#nativeDragging && rowKey === this.#dragOriginKey ? `dragging-origin` : ``}" style="top:${absIdx * rh}px; height:${rh}px"
|
|
14370
15240
|
data-key=${rowKey}
|
|
15241
|
+
draggable=${this.#nativeDrag.draggableAttr}
|
|
14371
15242
|
@click=${(e) => {
|
|
14372
15243
|
this._onRowClick(rowKey, null, e);
|
|
14373
15244
|
this.dispatchEvent(new CustomEvent(`datagrid-cell-click`, {
|
|
@@ -14550,6 +15421,12 @@ __decorate([property({
|
|
|
14550
15421
|
attribute: `search-modes`,
|
|
14551
15422
|
reflect: true
|
|
14552
15423
|
})], DataGridElement.prototype, "searchModes", void 0);
|
|
15424
|
+
__decorate([property({
|
|
15425
|
+
type: Boolean,
|
|
15426
|
+
attribute: `items-draggable`,
|
|
15427
|
+
reflect: true
|
|
15428
|
+
})], DataGridElement.prototype, "itemsDraggable", void 0);
|
|
15429
|
+
__decorate([property({ attribute: false })], DataGridElement.prototype, "dragPreviewRenderer", void 0);
|
|
14553
15430
|
__decorate([state()], DataGridElement.prototype, "_selectedKeys", void 0);
|
|
14554
15431
|
__decorate([state()], DataGridElement.prototype, "_scrollTop", void 0);
|
|
14555
15432
|
__decorate([state()], DataGridElement.prototype, "_scrollLeft", void 0);
|
|
@@ -14584,6 +15461,7 @@ let DataTableElement = class DataTableElement extends i {
|
|
|
14584
15461
|
this.styles = [
|
|
14585
15462
|
tickledStyles,
|
|
14586
15463
|
tickledItemStyles,
|
|
15464
|
+
popupSurfaceStyles,
|
|
14587
15465
|
i$3`
|
|
14588
15466
|
:host {
|
|
14589
15467
|
display: block;
|
|
@@ -14723,7 +15601,6 @@ let DataTableElement = class DataTableElement extends i {
|
|
|
14723
15601
|
width: max-content;
|
|
14724
15602
|
max-width: 100cqi;
|
|
14725
15603
|
padding: var(--space-xs);
|
|
14726
|
-
background: var(--surface-2);
|
|
14727
15604
|
visibility: hidden;
|
|
14728
15605
|
transform: translateY(-4px);
|
|
14729
15606
|
pointer-events: none;
|
|
@@ -14802,7 +15679,7 @@ let DataTableElement = class DataTableElement extends i {
|
|
|
14802
15679
|
?data-full=${r.fullWidth}
|
|
14803
15680
|
@pointerenter=${() => this.#handlePointerEnter(i)}
|
|
14804
15681
|
@click=${() => this.#select(i)}
|
|
14805
|
-
><div class="key">${r.label}</div><div class="value"><span class="value-text">${typeof r.value === `boolean` ? r.value ? `Yes` : `No` : r.value}</span>${r.detail === void 0 ? A : b`<div class="detail" part="detail">${r.detail}</div>`}</div></div>`)}</div>`;
|
|
15682
|
+
><div class="key">${r.label}</div><div class="value"><span class="value-text">${typeof r.value === `boolean` ? r.value ? `Yes` : `No` : r.value}</span>${r.detail === void 0 ? A : b`<div class="detail popup-surface" part="detail">${r.detail}</div>`}</div></div>`)}</div>`;
|
|
14806
15683
|
}
|
|
14807
15684
|
};
|
|
14808
15685
|
__decorate([property({
|
|
@@ -14846,6 +15723,7 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
14846
15723
|
this.iconProperty = ``;
|
|
14847
15724
|
this.keyProperty = ``;
|
|
14848
15725
|
this.itemWrap = `stop`;
|
|
15726
|
+
this.itemsDraggable = false;
|
|
14849
15727
|
this.#itemData = /* @__PURE__ */ new WeakMap();
|
|
14850
15728
|
this.#grid = [];
|
|
14851
15729
|
this.#positions = /* @__PURE__ */ new Map();
|
|
@@ -14881,7 +15759,41 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
14881
15759
|
},
|
|
14882
15760
|
onStateChange: () => this._syncItemStates(),
|
|
14883
15761
|
itemWrap: this.itemWrap,
|
|
14884
|
-
hoverDisabled: () => this.#dragSelect.isDragging
|
|
15762
|
+
hoverDisabled: () => this.#dragSelect.isDragging || this.#nativeDrag.isDragging
|
|
15763
|
+
});
|
|
15764
|
+
this.#nativeDragging = false;
|
|
15765
|
+
this.#postDragSuppressTimer = 0;
|
|
15766
|
+
this.#nativeDrag = new ListNativeDragController(this, {
|
|
15767
|
+
source: `detail-list`,
|
|
15768
|
+
isEnabled: () => this.itemsDraggable && this.selectionMode !== `none` && this._getVisibleItems().length > 0,
|
|
15769
|
+
resolveEventToKey: (target) => {
|
|
15770
|
+
if (!(target instanceof Element)) return void 0;
|
|
15771
|
+
const li = target.closest?.(`li`);
|
|
15772
|
+
if (!li || !this.contains(li)) return void 0;
|
|
15773
|
+
return keyForElement(li);
|
|
15774
|
+
},
|
|
15775
|
+
prepareSelection: (originKey) => this.#prepareNativeDrag(originKey),
|
|
15776
|
+
getMetrics: () => ({}),
|
|
15777
|
+
getRenderer: () => this.dragPreviewRenderer,
|
|
15778
|
+
dispatch: (detail) => this._dispatchCancelable(`list-native-drag-start`, detail),
|
|
15779
|
+
onActiveChange: (active, originKey) => {
|
|
15780
|
+
this.#nativeDragging = active;
|
|
15781
|
+
this.toggleAttribute(`data-native-dragging`, active);
|
|
15782
|
+
for (const el of this.querySelectorAll(`li`)) el.toggleAttribute(`data-drag-origin`, active && originKey !== void 0 && keyForElement(el) === originKey);
|
|
15783
|
+
if (active) {
|
|
15784
|
+
const count = this.selection.selected.size;
|
|
15785
|
+
this.setAttribute(`aria-label`, count <= 1 ? `Dragging 1 item` : `Dragging ${count} items`);
|
|
15786
|
+
} else this.removeAttribute(`aria-label`);
|
|
15787
|
+
this.requestUpdate();
|
|
15788
|
+
},
|
|
15789
|
+
onEnd: () => {
|
|
15790
|
+
this.#nativeDragging = false;
|
|
15791
|
+
this.toggleAttribute(`data-native-dragging`, false);
|
|
15792
|
+
this.removeAttribute(`aria-label`);
|
|
15793
|
+
for (const el of this.querySelectorAll(`li`)) el.removeAttribute(`data-drag-origin`);
|
|
15794
|
+
this.#startPostDragSuppressTimer();
|
|
15795
|
+
},
|
|
15796
|
+
syncLightDomDraggable: () => this._syncNativeDraggable()
|
|
14885
15797
|
});
|
|
14886
15798
|
this.#dragSelect = new ListDragSelectController(this, {
|
|
14887
15799
|
getSurface: () => this.renderRoot.querySelector(`.container`),
|
|
@@ -14978,7 +15890,7 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
14978
15890
|
}
|
|
14979
15891
|
};
|
|
14980
15892
|
this._onClick = (e) => {
|
|
14981
|
-
if (this.#dragSelect.isDragging) return;
|
|
15893
|
+
if (this.#dragSelect.isDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
14982
15894
|
const item = this._findListItem(e.composedPath());
|
|
14983
15895
|
if (!item) return;
|
|
14984
15896
|
this.focus();
|
|
@@ -15005,6 +15917,42 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
15005
15917
|
#builtFromProvider;
|
|
15006
15918
|
#providerBuilt;
|
|
15007
15919
|
#data;
|
|
15920
|
+
#nativeDragging;
|
|
15921
|
+
#postDragSuppressTimer;
|
|
15922
|
+
#nativeDrag;
|
|
15923
|
+
#prepareNativeDrag(originKey) {
|
|
15924
|
+
const visible = this._getVisibleItems();
|
|
15925
|
+
const originEl = visible.find((el) => keyForElement(el) === originKey);
|
|
15926
|
+
if (!originEl || !this._isCheckable(originEl)) return void 0;
|
|
15927
|
+
if (!this.selection.selected.has(originEl)) this.selection.replace(originEl);
|
|
15928
|
+
const selected = [];
|
|
15929
|
+
visible.forEach((el, index) => {
|
|
15930
|
+
if (!this.selection.selected.has(el)) return;
|
|
15931
|
+
const key = keyForElement(el) ?? originKey;
|
|
15932
|
+
selected.push({
|
|
15933
|
+
key,
|
|
15934
|
+
index,
|
|
15935
|
+
item: this.#itemData.get(el) ?? el,
|
|
15936
|
+
element: el
|
|
15937
|
+
});
|
|
15938
|
+
});
|
|
15939
|
+
const origin = selected.find((entry) => entry.key === originKey);
|
|
15940
|
+
if (!origin) return void 0;
|
|
15941
|
+
return {
|
|
15942
|
+
origin,
|
|
15943
|
+
selected
|
|
15944
|
+
};
|
|
15945
|
+
}
|
|
15946
|
+
_syncNativeDraggable() {
|
|
15947
|
+
if (!this.isConnected) return;
|
|
15948
|
+
for (const el of this.querySelectorAll(`li`)) if (el instanceof HTMLElement) el.draggable = this.itemsDraggable && this._isCheckable(el);
|
|
15949
|
+
}
|
|
15950
|
+
#startPostDragSuppressTimer() {
|
|
15951
|
+
if (this.#postDragSuppressTimer) clearTimeout(this.#postDragSuppressTimer);
|
|
15952
|
+
this.#postDragSuppressTimer = window.setTimeout(() => {
|
|
15953
|
+
this.#postDragSuppressTimer = 0;
|
|
15954
|
+
}, 0);
|
|
15955
|
+
}
|
|
15008
15956
|
/** Live drag-select preview rect (surface-relative); the covered items carry `data-marquee`. */
|
|
15009
15957
|
#marqueeRect;
|
|
15010
15958
|
#dragSelect;
|
|
@@ -15107,11 +16055,16 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
15107
16055
|
this.#unregisterSearchCommands?.();
|
|
15108
16056
|
this.#unregisterSearchCommands = void 0;
|
|
15109
16057
|
this.#searchRegistry = void 0;
|
|
16058
|
+
if (this.#postDragSuppressTimer) {
|
|
16059
|
+
clearTimeout(this.#postDragSuppressTimer);
|
|
16060
|
+
this.#postDragSuppressTimer = 0;
|
|
16061
|
+
}
|
|
15110
16062
|
}
|
|
15111
16063
|
firstUpdated() {
|
|
15112
16064
|
this.#processChildren();
|
|
15113
16065
|
if (this.filterPredicate) this.#applyFilterPredicate();
|
|
15114
16066
|
this.#recomputeGeometry();
|
|
16067
|
+
this._syncNativeDraggable();
|
|
15115
16068
|
}
|
|
15116
16069
|
updated(changed) {
|
|
15117
16070
|
super.updated(changed);
|
|
@@ -15135,7 +16088,12 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
15135
16088
|
if (changed.has(`interactionMode`)) {
|
|
15136
16089
|
this.selection.clearAnchor();
|
|
15137
16090
|
this._syncItemStates();
|
|
16091
|
+
this._syncNativeDraggable();
|
|
15138
16092
|
} else if (changed.has(`checkboxRenderer`) && this.interactionMode === `checked`) this._syncCheckboxes();
|
|
16093
|
+
if (changed.has(`itemsDraggable`)) {
|
|
16094
|
+
this._syncNativeDraggable();
|
|
16095
|
+
this.#nativeDrag.refreshDraggable();
|
|
16096
|
+
}
|
|
15139
16097
|
}
|
|
15140
16098
|
/** The most recently selected item, or `undefined` if nothing is selected. */
|
|
15141
16099
|
get selectedItem() {
|
|
@@ -15700,6 +16658,14 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
15700
16658
|
composed: true
|
|
15701
16659
|
}));
|
|
15702
16660
|
}
|
|
16661
|
+
_dispatchCancelable(name, detail) {
|
|
16662
|
+
return this.dispatchEvent(new CustomEvent(name, {
|
|
16663
|
+
detail,
|
|
16664
|
+
bubbles: true,
|
|
16665
|
+
composed: true,
|
|
16666
|
+
cancelable: true
|
|
16667
|
+
}));
|
|
16668
|
+
}
|
|
15703
16669
|
_activateItem(item) {
|
|
15704
16670
|
if (this.interactionMode !== `manual`) this.selection.replace(item);
|
|
15705
16671
|
this._dispatch(`list-activate`, { item });
|
|
@@ -15817,6 +16783,10 @@ let DetailListElement = class DetailListElement extends i {
|
|
|
15817
16783
|
color: var(--item-text-selected);
|
|
15818
16784
|
}
|
|
15819
16785
|
|
|
16786
|
+
::slotted([data-drag-origin]) {
|
|
16787
|
+
opacity: 0.6;
|
|
16788
|
+
}
|
|
16789
|
+
|
|
15820
16790
|
/* checked mode: the injected checkbox communicates selection — suppress bg */
|
|
15821
16791
|
:host([interaction-mode="checked"]) ::slotted([data-selected]) {
|
|
15822
16792
|
background: transparent;
|
|
@@ -15906,6 +16876,12 @@ __decorate([property({
|
|
|
15906
16876
|
attribute: `search-modes`,
|
|
15907
16877
|
reflect: true
|
|
15908
16878
|
})], DetailListElement.prototype, "searchModes", void 0);
|
|
16879
|
+
__decorate([property({
|
|
16880
|
+
type: Boolean,
|
|
16881
|
+
attribute: `items-draggable`,
|
|
16882
|
+
reflect: true
|
|
16883
|
+
})], DetailListElement.prototype, "itemsDraggable", void 0);
|
|
16884
|
+
__decorate([property({ attribute: false })], DetailListElement.prototype, "dragPreviewRenderer", void 0);
|
|
15909
16885
|
__decorate([query(`ul`)], DetailListElement.prototype, "_listEl", void 0);
|
|
15910
16886
|
DetailListElement = __decorate([safeCustomElement(`ixfx-detail-list`)], DetailListElement);
|
|
15911
16887
|
//#endregion
|
|
@@ -21944,12 +22920,50 @@ let GridListElement = class GridListElement extends i {
|
|
|
21944
22920
|
},
|
|
21945
22921
|
onStateChange: () => this._syncItemStates(),
|
|
21946
22922
|
itemWrap: this.#itemWrap,
|
|
21947
|
-
hoverDisabled: () => this.disableHoverTickle || this.#dragSelect.isDragging
|
|
22923
|
+
hoverDisabled: () => this.disableHoverTickle || this.#dragSelect.isDragging || this.#nativeDrag.isDragging
|
|
21948
22924
|
});
|
|
21949
22925
|
this.#marqueePreview = /* @__PURE__ */ new Set();
|
|
21950
22926
|
this.#nativeDragging = false;
|
|
21951
22927
|
this.#dragOriginKey = void 0;
|
|
21952
22928
|
this.#postDragSuppressTimer = 0;
|
|
22929
|
+
this.#nativeDrag = new ListNativeDragController(this, {
|
|
22930
|
+
source: `grid-list`,
|
|
22931
|
+
isEnabled: () => this.itemsDraggable && this.selectionMode !== `none` && this.#source.count > 0,
|
|
22932
|
+
resolveEventToKey: (target) => {
|
|
22933
|
+
if (target instanceof Element) {
|
|
22934
|
+
const key = (target.closest?.(`.cell`))?.dataset.key;
|
|
22935
|
+
if (key) return key;
|
|
22936
|
+
const keyed = (target.closest?.(`[data-key]`))?.dataset.key ?? target.dataset?.key ?? keyForElement(target);
|
|
22937
|
+
if (keyed) return keyed;
|
|
22938
|
+
}
|
|
22939
|
+
},
|
|
22940
|
+
prepareSelection: (originKey) => this.#prepareNativeDrag(originKey),
|
|
22941
|
+
getMetrics: () => ({
|
|
22942
|
+
itemSize: this.itemSize,
|
|
22943
|
+
captionStyle: this.captionStyle,
|
|
22944
|
+
captionHeight: this.captionHeight,
|
|
22945
|
+
rowHeight: this.#rowHeight()
|
|
22946
|
+
}),
|
|
22947
|
+
getRenderer: () => this.dragPreviewRenderer,
|
|
22948
|
+
dispatch: (detail) => this._dispatch(`list-native-drag-start`, detail, true),
|
|
22949
|
+
onActiveChange: (active, originKey) => {
|
|
22950
|
+
this.#nativeDragging = active;
|
|
22951
|
+
this.#dragOriginKey = active ? originKey : void 0;
|
|
22952
|
+
this.toggleAttribute(`data-native-dragging`, active);
|
|
22953
|
+
if (active) {
|
|
22954
|
+
const count = [...this.selection.selectedKeys].filter((k) => !isSyntheticKey(k)).length;
|
|
22955
|
+
this.setAttribute(`aria-label`, count <= 1 ? `Dragging 1 item` : `Dragging ${count} items`);
|
|
22956
|
+
} else this.removeAttribute(`aria-label`);
|
|
22957
|
+
this.requestUpdate();
|
|
22958
|
+
},
|
|
22959
|
+
onEnd: () => {
|
|
22960
|
+
this.#clearNativeDragState();
|
|
22961
|
+
this.#startPostDragSuppressTimer();
|
|
22962
|
+
},
|
|
22963
|
+
syncLightDomDraggable: () => {
|
|
22964
|
+
for (const child of this.children) if (child instanceof HTMLElement) child.draggable = this.itemsDraggable;
|
|
22965
|
+
}
|
|
22966
|
+
});
|
|
21953
22967
|
this.#activeCaptionPan = null;
|
|
21954
22968
|
this.#dragSelect = new ListDragSelectController(this, {
|
|
21955
22969
|
getSurface: () => this.#viewportRef.value,
|
|
@@ -21995,23 +23009,6 @@ let GridListElement = class GridListElement extends i {
|
|
|
21995
23009
|
this.#emitViewportChange();
|
|
21996
23010
|
});
|
|
21997
23011
|
};
|
|
21998
|
-
this.#onDragStart = (e, key) => {
|
|
21999
|
-
this.#doDragStart(key, () => e.preventDefault(), e);
|
|
22000
|
-
};
|
|
22001
|
-
this.#onSlottedDragStart = (e) => {
|
|
22002
|
-
if (!this.itemsDraggable) return;
|
|
22003
|
-
let cell = e.composedPath().find((n) => n instanceof Element && n.classList.contains(`cell`));
|
|
22004
|
-
if (!cell && e.target instanceof Element) cell = e.target.closest?.(`.cell`);
|
|
22005
|
-
if (!cell) return;
|
|
22006
|
-
const key = cell.dataset.key;
|
|
22007
|
-
if (!key) return;
|
|
22008
|
-
if (e instanceof DragEvent) this.#doDragStart(key, () => e.preventDefault(), e);
|
|
22009
|
-
else this.#doDragStart(key, () => {});
|
|
22010
|
-
};
|
|
22011
|
-
this.#onDragEnd = () => {
|
|
22012
|
-
this.#clearNativeDragState();
|
|
22013
|
-
this.#startPostDragSuppressTimer();
|
|
22014
|
-
};
|
|
22015
23012
|
this._onKeyDown = (e) => {
|
|
22016
23013
|
if ((e.ctrlKey || e.metaKey) && e.key === `f`) return;
|
|
22017
23014
|
if ((e.ctrlKey || e.metaKey) && e.key === `a`) {
|
|
@@ -22448,6 +23445,35 @@ let GridListElement = class GridListElement extends i {
|
|
|
22448
23445
|
#dragOriginKey;
|
|
22449
23446
|
/** Timer handle for post-drag click suppression. */
|
|
22450
23447
|
#postDragSuppressTimer;
|
|
23448
|
+
#nativeDrag;
|
|
23449
|
+
/** Origin rule + display-ordered entry resolution for native drag-out (both modes). */
|
|
23450
|
+
#prepareNativeDrag(originKey) {
|
|
23451
|
+
const index = this.#source.indexOfKey(originKey);
|
|
23452
|
+
if (index < 0 || !this.#source.isSelectable(index)) return void 0;
|
|
23453
|
+
if (!this.selection.selectedKeys.has(originKey)) this.selection.replace(originKey);
|
|
23454
|
+
const ordered = this.#source.keys().filter((k) => !isSyntheticKey(k) && this.selection.selectedKeys.has(k));
|
|
23455
|
+
const selected = [];
|
|
23456
|
+
for (const key of ordered) {
|
|
23457
|
+
const entryIndex = this.#source.indexOfKey(key);
|
|
23458
|
+
if (entryIndex < 0) continue;
|
|
23459
|
+
const data = this.#source.resolveKeyToData(key);
|
|
23460
|
+
const element = this.#source.resolveKeyToElement(key);
|
|
23461
|
+
const item = data ?? element;
|
|
23462
|
+
if (item === void 0) continue;
|
|
23463
|
+
selected.push({
|
|
23464
|
+
key,
|
|
23465
|
+
index: entryIndex,
|
|
23466
|
+
item,
|
|
23467
|
+
...element ? { element } : {}
|
|
23468
|
+
});
|
|
23469
|
+
}
|
|
23470
|
+
const origin = selected.find((entry) => entry.key === originKey);
|
|
23471
|
+
if (!origin) return void 0;
|
|
23472
|
+
return {
|
|
23473
|
+
origin,
|
|
23474
|
+
selected
|
|
23475
|
+
};
|
|
23476
|
+
}
|
|
22451
23477
|
/**
|
|
22452
23478
|
* The single caption pan-text currently scrolling. At most one caption is
|
|
22453
23479
|
* a pan-text in loop mode at a time — when tickle moves, the old one is
|
|
@@ -22580,7 +23606,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22580
23606
|
clearTimeout(this.#reflowTimer);
|
|
22581
23607
|
this.#reflowTimer = 0;
|
|
22582
23608
|
}
|
|
22583
|
-
if (this.#nativeDragging) this.#clearNativeDragState();
|
|
23609
|
+
if (this.#nativeDragging || this.#nativeDrag.isDragging) this.#clearNativeDragState();
|
|
22584
23610
|
}
|
|
22585
23611
|
#onChildrenChanged(records) {
|
|
22586
23612
|
const previousLength = this.#items.length;
|
|
@@ -22661,7 +23687,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22661
23687
|
this.#measureViewport(false);
|
|
22662
23688
|
this.#syncItems();
|
|
22663
23689
|
this.requestUpdate();
|
|
22664
|
-
this.#
|
|
23690
|
+
this.#nativeDrag.refreshDraggable();
|
|
22665
23691
|
}
|
|
22666
23692
|
/** (Re)construct {@link #source} for the current mode and re-apply the filters. */
|
|
22667
23693
|
#rebuildSource() {
|
|
@@ -22751,7 +23777,7 @@ let GridListElement = class GridListElement extends i {
|
|
|
22751
23777
|
this.selection.clearAnchor();
|
|
22752
23778
|
this.#syncAriaMultiselectable();
|
|
22753
23779
|
}
|
|
22754
|
-
if (changed.has(`itemsDraggable`)) this.#
|
|
23780
|
+
if (changed.has(`itemsDraggable`)) this.#nativeDrag.refreshDraggable();
|
|
22755
23781
|
if (changed.has(`orientation`)) {
|
|
22756
23782
|
const vp = this.#viewportRef.value;
|
|
22757
23783
|
if (vp) {
|
|
@@ -23170,8 +24196,6 @@ let GridListElement = class GridListElement extends i {
|
|
|
23170
24196
|
@click=${(e) => this.#onCellClick(e, key)}
|
|
23171
24197
|
@dblclick=${() => this.#onCellActivate(key)}
|
|
23172
24198
|
@pointerenter=${() => this.tickled.handlePointerEnter(key)}
|
|
23173
|
-
@dragstart=${(e) => this.#onDragStart(e, key)}
|
|
23174
|
-
@dragend=${() => this.#onDragEnd()}
|
|
23175
24199
|
>
|
|
23176
24200
|
<div class="content" part="content">${this.#source.renderCellContent(index)}</div>
|
|
23177
24201
|
${showCaption ? this.#renderCaption(caption, captionCss, tickled) : ``}
|
|
@@ -23256,8 +24280,6 @@ let GridListElement = class GridListElement extends i {
|
|
|
23256
24280
|
@click=${(e) => this.#onCellClick(e, key)}
|
|
23257
24281
|
@dblclick=${() => this.#onCellActivate(key)}
|
|
23258
24282
|
@pointerenter=${() => this.tickled.handlePointerEnter(key)}
|
|
23259
|
-
@dragstart=${(e) => this.#onDragStart(e, key)}
|
|
23260
|
-
@dragend=${() => this.#onDragEnd()}
|
|
23261
24283
|
>
|
|
23262
24284
|
<div class="thumb" part="thumb" style=${thumbStyle}>
|
|
23263
24285
|
${this.#source.renderCellContent(index)}
|
|
@@ -23274,145 +24296,10 @@ let GridListElement = class GridListElement extends i {
|
|
|
23274
24296
|
}
|
|
23275
24297
|
}
|
|
23276
24298
|
#onCellClick(e, key) {
|
|
23277
|
-
if (this.#dragSelect.isDragging || this.#nativeDragging || this.#postDragSuppressTimer !== 0) return;
|
|
24299
|
+
if (this.#dragSelect.isDragging || this.#nativeDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
23278
24300
|
this.selection.handleClick(key, e);
|
|
23279
24301
|
this.#emitItemEvent(`list-item-click`, key);
|
|
23280
24302
|
}
|
|
23281
|
-
#doDragStart(key, cancelled, dragEvent) {
|
|
23282
|
-
if (!this.itemsDraggable) return false;
|
|
23283
|
-
const index = this.#source.indexOfKey(key);
|
|
23284
|
-
if (index < 0 || !this.#source.isSelectable(index)) return false;
|
|
23285
|
-
if (!this.selection.selectedKeys.has(key)) this.selection.replace(key);
|
|
23286
|
-
const selectedKeys = this.#source.keys().filter((k) => !isSyntheticKey(k)).filter((k) => this.selection.selectedKeys.has(k));
|
|
23287
|
-
const detail = {
|
|
23288
|
-
key,
|
|
23289
|
-
index: this.#source.indexOfKey(key),
|
|
23290
|
-
item: this.#source.resolveKeyToData(key) ?? this.#source.resolveKeyToElement(key),
|
|
23291
|
-
selectedKeys
|
|
23292
|
-
};
|
|
23293
|
-
if (!this._dispatch(`grid-list-native-drag-start`, detail, true)) {
|
|
23294
|
-
cancelled();
|
|
23295
|
-
return false;
|
|
23296
|
-
}
|
|
23297
|
-
this.#nativeDragging = true;
|
|
23298
|
-
this.#dragOriginKey = key;
|
|
23299
|
-
this.toggleAttribute(`data-native-dragging`, true);
|
|
23300
|
-
const count = selectedKeys.length;
|
|
23301
|
-
this.setAttribute(`aria-label`, count === 1 ? `Dragging 1 item` : `Dragging ${count} items`);
|
|
23302
|
-
if (dragEvent && count > 1) this.#setMultiItemDragImage(dragEvent, selectedKeys);
|
|
23303
|
-
return true;
|
|
23304
|
-
}
|
|
23305
|
-
#setMultiItemDragImage(e, selectedKeys) {
|
|
23306
|
-
const preview = this.#createMultiItemPreview(selectedKeys);
|
|
23307
|
-
document.body.appendChild(preview);
|
|
23308
|
-
const rect = preview.getBoundingClientRect();
|
|
23309
|
-
e.dataTransfer?.setDragImage(preview, rect.width / 2, rect.height / 2);
|
|
23310
|
-
requestAnimationFrame(() => preview.remove());
|
|
23311
|
-
}
|
|
23312
|
-
#createMultiItemPreview(selectedKeys) {
|
|
23313
|
-
const preview = document.createElement(`div`);
|
|
23314
|
-
preview.style.cssText = `
|
|
23315
|
-
position: fixed;
|
|
23316
|
-
top: -9999px;
|
|
23317
|
-
left: -9999px;
|
|
23318
|
-
display: flex;
|
|
23319
|
-
flex-direction: column;
|
|
23320
|
-
gap: 4px;
|
|
23321
|
-
padding: 8px;
|
|
23322
|
-
background: var(--surface-4, #333);
|
|
23323
|
-
border: 1px solid var(--border, #555);
|
|
23324
|
-
border-radius: 8px;
|
|
23325
|
-
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
|
|
23326
|
-
font-family: system-ui, sans-serif;
|
|
23327
|
-
font-size: 12px;
|
|
23328
|
-
color: var(--surface-text, #fff);
|
|
23329
|
-
max-width: 200px;
|
|
23330
|
-
z-index: 999999;
|
|
23331
|
-
`;
|
|
23332
|
-
const header = document.createElement(`div`);
|
|
23333
|
-
header.style.cssText = `
|
|
23334
|
-
font-weight: 600;
|
|
23335
|
-
padding-bottom: 4px;
|
|
23336
|
-
border-bottom: 1px solid var(--border, #555);
|
|
23337
|
-
margin-bottom: 4px;
|
|
23338
|
-
`;
|
|
23339
|
-
header.textContent = `${selectedKeys.length} items`;
|
|
23340
|
-
preview.appendChild(header);
|
|
23341
|
-
for (const key of selectedKeys.slice(0, 5)) {
|
|
23342
|
-
const row = this.#createPreviewRow(key);
|
|
23343
|
-
if (row) preview.appendChild(row);
|
|
23344
|
-
}
|
|
23345
|
-
if (selectedKeys.length > 5) {
|
|
23346
|
-
const more = document.createElement(`div`);
|
|
23347
|
-
more.style.cssText = `opacity: 0.6; text-align: center;`;
|
|
23348
|
-
more.textContent = `+${selectedKeys.length - 5} more`;
|
|
23349
|
-
preview.appendChild(more);
|
|
23350
|
-
}
|
|
23351
|
-
return preview;
|
|
23352
|
-
}
|
|
23353
|
-
#createPreviewRow(key) {
|
|
23354
|
-
const el = this.#source.resolveKeyToElement(key);
|
|
23355
|
-
if (!el) return null;
|
|
23356
|
-
const row = document.createElement(`div`);
|
|
23357
|
-
row.style.cssText = `
|
|
23358
|
-
display: flex;
|
|
23359
|
-
align-items: center;
|
|
23360
|
-
gap: 6px;
|
|
23361
|
-
`;
|
|
23362
|
-
const thumb = document.createElement(`div`);
|
|
23363
|
-
thumb.style.cssText = `
|
|
23364
|
-
width: 32px;
|
|
23365
|
-
height: 32px;
|
|
23366
|
-
border-radius: 4px;
|
|
23367
|
-
overflow: hidden;
|
|
23368
|
-
background: var(--surface-5, #444);
|
|
23369
|
-
flex-shrink: 0;
|
|
23370
|
-
display: flex;
|
|
23371
|
-
align-items: center;
|
|
23372
|
-
justify-content: center;
|
|
23373
|
-
`;
|
|
23374
|
-
const slottedImg = el.querySelector(`img`);
|
|
23375
|
-
const slottedSvg = el.querySelector(`svg`);
|
|
23376
|
-
const slottedPlaceholder = el.querySelector(`.placeholder`);
|
|
23377
|
-
if (slottedImg) {
|
|
23378
|
-
const img = slottedImg.cloneNode(true);
|
|
23379
|
-
img.style.cssText = `width: 100%; height: 100%; object-fit: cover;`;
|
|
23380
|
-
thumb.appendChild(img);
|
|
23381
|
-
} else if (slottedSvg) {
|
|
23382
|
-
const svg = slottedSvg.cloneNode(true);
|
|
23383
|
-
svg.style.cssText = `width: 70%; height: 70%; opacity: 0.8;`;
|
|
23384
|
-
thumb.appendChild(svg);
|
|
23385
|
-
} else if (slottedPlaceholder) thumb.textContent = slottedPlaceholder.textContent || `?`;
|
|
23386
|
-
const label = document.createElement(`span`);
|
|
23387
|
-
label.style.cssText = `
|
|
23388
|
-
flex: 1;
|
|
23389
|
-
overflow: hidden;
|
|
23390
|
-
text-overflow: ellipsis;
|
|
23391
|
-
white-space: nowrap;
|
|
23392
|
-
`;
|
|
23393
|
-
label.textContent = el.getAttribute(`data-label`) || key;
|
|
23394
|
-
row.appendChild(thumb);
|
|
23395
|
-
row.appendChild(label);
|
|
23396
|
-
return row;
|
|
23397
|
-
}
|
|
23398
|
-
#onDragStart;
|
|
23399
|
-
#onSlottedDragStart;
|
|
23400
|
-
#initSlottedDragInterceptor() {
|
|
23401
|
-
this.renderRoot.addEventListener(`dragstart`, this.#onSlottedDragStart, { capture: true });
|
|
23402
|
-
const observer = new MutationObserver(() => this.#syncSlottedDraggable());
|
|
23403
|
-
observer.observe(this, {
|
|
23404
|
-
childList: true,
|
|
23405
|
-
subtree: true
|
|
23406
|
-
});
|
|
23407
|
-
this.#slottedDragObserver = observer;
|
|
23408
|
-
this.#syncSlottedDraggable();
|
|
23409
|
-
}
|
|
23410
|
-
#slottedDragObserver;
|
|
23411
|
-
#syncSlottedDraggable() {
|
|
23412
|
-
const draggable = this.itemsDraggable;
|
|
23413
|
-
for (const child of this.children) if (child instanceof HTMLElement) child.draggable = draggable;
|
|
23414
|
-
}
|
|
23415
|
-
#onDragEnd;
|
|
23416
24303
|
#startPostDragSuppressTimer() {
|
|
23417
24304
|
if (this.#postDragSuppressTimer) clearTimeout(this.#postDragSuppressTimer);
|
|
23418
24305
|
this.#postDragSuppressTimer = window.setTimeout(() => {
|
|
@@ -23487,6 +24374,7 @@ __decorate([property({
|
|
|
23487
24374
|
attribute: `items-draggable`,
|
|
23488
24375
|
reflect: true
|
|
23489
24376
|
})], GridListElement.prototype, "itemsDraggable", void 0);
|
|
24377
|
+
__decorate([property({ attribute: false })], GridListElement.prototype, "dragPreviewRenderer", void 0);
|
|
23490
24378
|
__decorate([property({
|
|
23491
24379
|
type: String,
|
|
23492
24380
|
attribute: `search-modes`,
|
|
@@ -23881,6 +24769,360 @@ __decorate([property({
|
|
|
23881
24769
|
})], GroupedItemListerElement.prototype, "crossGroupSelection", void 0);
|
|
23882
24770
|
GroupedItemListerElement = __decorate([safeCustomElement(`ixfx-grouped-item-lister`)], GroupedItemListerElement);
|
|
23883
24771
|
//#endregion
|
|
24772
|
+
//#region src/tree/tree-drag-registry.ts
|
|
24773
|
+
const TREE_DRAG_MIME = `application/x-ixfx-tree`;
|
|
24774
|
+
const registry = /* @__PURE__ */ new Map();
|
|
24775
|
+
const weakRefs = /* @__PURE__ */ new Map();
|
|
24776
|
+
/**
|
|
24777
|
+
* The source id of the drag currently in flight, if any. There is only ever one
|
|
24778
|
+
* native drag at a time, so a drop target can resolve the dragged nodes during
|
|
24779
|
+
* `dragover` — when `DataTransfer.getData()` is unreadable (protected mode) — by
|
|
24780
|
+
* looking this up in the registry.
|
|
24781
|
+
*/
|
|
24782
|
+
let currentSourceId;
|
|
24783
|
+
let sourceIdCounter = 0;
|
|
24784
|
+
function treeDragGenerateSourceId() {
|
|
24785
|
+
return `tree-drag-${++sourceIdCounter}-${Date.now()}`;
|
|
24786
|
+
}
|
|
24787
|
+
function treeDragRegister(sourceId, element, nodes, keys) {
|
|
24788
|
+
registry.set(sourceId, {
|
|
24789
|
+
sourceId,
|
|
24790
|
+
nodes,
|
|
24791
|
+
keys
|
|
24792
|
+
});
|
|
24793
|
+
weakRefs.set(sourceId, new WeakRef(element));
|
|
24794
|
+
currentSourceId = sourceId;
|
|
24795
|
+
}
|
|
24796
|
+
function treeDragUnregister(sourceId) {
|
|
24797
|
+
registry.delete(sourceId);
|
|
24798
|
+
weakRefs.delete(sourceId);
|
|
24799
|
+
if (currentSourceId === sourceId) currentSourceId = void 0;
|
|
24800
|
+
}
|
|
24801
|
+
/** The in-flight drag's `{ keys, nodes, element }`, or `undefined` when nothing is dragging. */
|
|
24802
|
+
function treeDragCurrent() {
|
|
24803
|
+
if (currentSourceId === void 0) return void 0;
|
|
24804
|
+
const entry = registry.get(currentSourceId);
|
|
24805
|
+
if (!entry) return void 0;
|
|
24806
|
+
return {
|
|
24807
|
+
sourceId: currentSourceId,
|
|
24808
|
+
keys: entry.keys,
|
|
24809
|
+
nodes: entry.nodes,
|
|
24810
|
+
element: weakRefs.get(currentSourceId)?.deref()
|
|
24811
|
+
};
|
|
24812
|
+
}
|
|
24813
|
+
//#endregion
|
|
24814
|
+
//#region src/tree/tree-drop-controller.ts
|
|
24815
|
+
const EDGE_ZONE_PX$1 = 24;
|
|
24816
|
+
const MAX_SCROLL_SPEED = 16;
|
|
24817
|
+
function clamp$4(value, min, max) {
|
|
24818
|
+
return Math.max(min, Math.min(max, value));
|
|
24819
|
+
}
|
|
24820
|
+
var TreeDropController = class {
|
|
24821
|
+
#host;
|
|
24822
|
+
#config;
|
|
24823
|
+
#active = false;
|
|
24824
|
+
#current;
|
|
24825
|
+
#source = `internal`;
|
|
24826
|
+
#dragKeys = [];
|
|
24827
|
+
#dragNodes = [];
|
|
24828
|
+
#expandTimer;
|
|
24829
|
+
#expandPendingKey;
|
|
24830
|
+
#scrollRaf = 0;
|
|
24831
|
+
#pointerX = 0;
|
|
24832
|
+
#pointerY = 0;
|
|
24833
|
+
#boundContainer;
|
|
24834
|
+
constructor(host, config) {
|
|
24835
|
+
this.#host = host;
|
|
24836
|
+
this.#config = config;
|
|
24837
|
+
host.addController(this);
|
|
24838
|
+
}
|
|
24839
|
+
/** A drag is currently over this tree. */
|
|
24840
|
+
get isDragging() {
|
|
24841
|
+
return this.#active;
|
|
24842
|
+
}
|
|
24843
|
+
/** A drag is over this tree but the current position is not a valid drop. */
|
|
24844
|
+
get isRejected() {
|
|
24845
|
+
return this.#active && this.#current === void 0;
|
|
24846
|
+
}
|
|
24847
|
+
get dropState() {
|
|
24848
|
+
return this.#current;
|
|
24849
|
+
}
|
|
24850
|
+
hostConnected() {
|
|
24851
|
+
this.#bind();
|
|
24852
|
+
}
|
|
24853
|
+
/** Bind once the shadow `#container` exists (it does not yet at `hostConnected`). */
|
|
24854
|
+
hostUpdated() {
|
|
24855
|
+
this.#bind();
|
|
24856
|
+
}
|
|
24857
|
+
#bind() {
|
|
24858
|
+
const container = this.#config.getScrollContainer();
|
|
24859
|
+
if (!container || container === this.#boundContainer) return;
|
|
24860
|
+
this.#unbind();
|
|
24861
|
+
this.#boundContainer = container;
|
|
24862
|
+
container.addEventListener(`dragenter`, this.#onDragEnter);
|
|
24863
|
+
container.addEventListener(`dragover`, this.#onDragOver);
|
|
24864
|
+
container.addEventListener(`dragleave`, this.#onDragLeave);
|
|
24865
|
+
container.addEventListener(`drop`, this.#onDrop);
|
|
24866
|
+
}
|
|
24867
|
+
#unbind() {
|
|
24868
|
+
const c = this.#boundContainer;
|
|
24869
|
+
if (!c) return;
|
|
24870
|
+
c.removeEventListener(`dragenter`, this.#onDragEnter);
|
|
24871
|
+
c.removeEventListener(`dragover`, this.#onDragOver);
|
|
24872
|
+
c.removeEventListener(`dragleave`, this.#onDragLeave);
|
|
24873
|
+
c.removeEventListener(`drop`, this.#onDrop);
|
|
24874
|
+
this.#boundContainer = void 0;
|
|
24875
|
+
}
|
|
24876
|
+
hostDisconnected() {
|
|
24877
|
+
this.#unbind();
|
|
24878
|
+
this.#clearExpand();
|
|
24879
|
+
this.#stopScroll();
|
|
24880
|
+
this.#active = false;
|
|
24881
|
+
this.#current = void 0;
|
|
24882
|
+
}
|
|
24883
|
+
#onDragEnter = (event) => {
|
|
24884
|
+
if (this.#config.getDndMode() === `none` || !event.dataTransfer) return;
|
|
24885
|
+
if (this.#config.resolveDrag(event.dataTransfer, `hover`) === void 0) return;
|
|
24886
|
+
event.preventDefault();
|
|
24887
|
+
if (!this.#active) {
|
|
24888
|
+
this.#active = true;
|
|
24889
|
+
this.#config.onActiveChange(true);
|
|
24890
|
+
}
|
|
24891
|
+
};
|
|
24892
|
+
#onDragOver = (event) => {
|
|
24893
|
+
if (this.#config.getDndMode() === `none` || !event.dataTransfer) return;
|
|
24894
|
+
this.#pointerX = event.clientX;
|
|
24895
|
+
this.#pointerY = event.clientY;
|
|
24896
|
+
const drag = this.#config.resolveDrag(event.dataTransfer, `hover`);
|
|
24897
|
+
if (!drag) {
|
|
24898
|
+
this.#reject(event);
|
|
24899
|
+
return;
|
|
24900
|
+
}
|
|
24901
|
+
if (!this.#active) {
|
|
24902
|
+
this.#active = true;
|
|
24903
|
+
this.#config.onActiveChange(true);
|
|
24904
|
+
}
|
|
24905
|
+
this.#source = drag.source;
|
|
24906
|
+
this.#dragKeys = drag.keys;
|
|
24907
|
+
this.#dragNodes = drag.nodes;
|
|
24908
|
+
const rows = this.#config.getVisibleRows();
|
|
24909
|
+
this.#handleExpandHover(this.#rowAtPointer(rows, event.clientY));
|
|
24910
|
+
this.#kickScroll();
|
|
24911
|
+
const target = this.#resolveIntent(event, rows, drag.source);
|
|
24912
|
+
if (!target) {
|
|
24913
|
+
this.#reject(event, false);
|
|
24914
|
+
return;
|
|
24915
|
+
}
|
|
24916
|
+
const ctx = {
|
|
24917
|
+
source: drag.source,
|
|
24918
|
+
dragged: drag.nodes.length > 0 ? drag.nodes : void 0,
|
|
24919
|
+
draggedKeys: drag.keys,
|
|
24920
|
+
target,
|
|
24921
|
+
dataTransfer: event.dataTransfer
|
|
24922
|
+
};
|
|
24923
|
+
if (!this.#config.vet(ctx)) {
|
|
24924
|
+
this.#reject(event, false);
|
|
24925
|
+
return;
|
|
24926
|
+
}
|
|
24927
|
+
event.preventDefault();
|
|
24928
|
+
event.dataTransfer.dropEffect = drag.source === `internal` ? `move` : `copy`;
|
|
24929
|
+
this.#setDropState(target);
|
|
24930
|
+
};
|
|
24931
|
+
/** Not a valid drop here: keep the drag active for feedback but accept nothing. */
|
|
24932
|
+
#reject(event, clearHover = true) {
|
|
24933
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = `none`;
|
|
24934
|
+
this.#setDropState(void 0);
|
|
24935
|
+
if (clearHover) this.#clearExpand();
|
|
24936
|
+
}
|
|
24937
|
+
#onDragLeave = (event) => {
|
|
24938
|
+
const container = this.#config.getScrollContainer();
|
|
24939
|
+
const related = event.relatedTarget;
|
|
24940
|
+
if (container && related && container.contains(related)) return;
|
|
24941
|
+
this.#endHover();
|
|
24942
|
+
};
|
|
24943
|
+
#onDrop = (event) => {
|
|
24944
|
+
if (!event.dataTransfer) {
|
|
24945
|
+
this.#endHover();
|
|
24946
|
+
return;
|
|
24947
|
+
}
|
|
24948
|
+
event.preventDefault();
|
|
24949
|
+
this.#stopScroll();
|
|
24950
|
+
this.#clearExpand();
|
|
24951
|
+
const finish = (dropped) => {
|
|
24952
|
+
this.#current = void 0;
|
|
24953
|
+
this.#active = false;
|
|
24954
|
+
this.#config.onDropStateChange(void 0);
|
|
24955
|
+
this.#config.onActiveChange(false);
|
|
24956
|
+
this.#config.onDragEnd(dropped);
|
|
24957
|
+
};
|
|
24958
|
+
if (this.#config.getDndMode() === `none`) {
|
|
24959
|
+
finish(false);
|
|
24960
|
+
return;
|
|
24961
|
+
}
|
|
24962
|
+
const drag = this.#config.resolveDrag(event.dataTransfer, `drop`);
|
|
24963
|
+
if (!drag) {
|
|
24964
|
+
finish(false);
|
|
24965
|
+
return;
|
|
24966
|
+
}
|
|
24967
|
+
this.#dragKeys = drag.keys;
|
|
24968
|
+
this.#dragNodes = drag.nodes;
|
|
24969
|
+
const target = this.#resolveIntent(event, this.#config.getVisibleRows(), drag.source);
|
|
24970
|
+
if (!target) {
|
|
24971
|
+
finish(false);
|
|
24972
|
+
return;
|
|
24973
|
+
}
|
|
24974
|
+
const ctx = {
|
|
24975
|
+
source: drag.source,
|
|
24976
|
+
dragged: drag.nodes.length > 0 ? drag.nodes : void 0,
|
|
24977
|
+
draggedKeys: drag.keys,
|
|
24978
|
+
target,
|
|
24979
|
+
dataTransfer: event.dataTransfer
|
|
24980
|
+
};
|
|
24981
|
+
if (!this.#config.vet(ctx)) {
|
|
24982
|
+
finish(false);
|
|
24983
|
+
return;
|
|
24984
|
+
}
|
|
24985
|
+
const detail = {
|
|
24986
|
+
...ctx,
|
|
24987
|
+
external: drag.source === `external` ? drag.nodes : void 0
|
|
24988
|
+
};
|
|
24989
|
+
finish(this.#config.commitDrop(detail));
|
|
24990
|
+
};
|
|
24991
|
+
#endHover() {
|
|
24992
|
+
this.#clearExpand();
|
|
24993
|
+
this.#stopScroll();
|
|
24994
|
+
if (this.#current !== void 0) {
|
|
24995
|
+
this.#current = void 0;
|
|
24996
|
+
this.#config.onDropStateChange(void 0);
|
|
24997
|
+
}
|
|
24998
|
+
if (this.#active) {
|
|
24999
|
+
this.#active = false;
|
|
25000
|
+
this.#config.onActiveChange(false);
|
|
25001
|
+
}
|
|
25002
|
+
}
|
|
25003
|
+
#rowAtPointer(rows, clientY) {
|
|
25004
|
+
if (rows.length === 0) return void 0;
|
|
25005
|
+
if (clientY < rows[0].rect.top) return rows[0];
|
|
25006
|
+
if (clientY > rows[rows.length - 1].rect.bottom) return rows[rows.length - 1];
|
|
25007
|
+
return rows.find((r) => clientY >= r.rect.top && clientY <= r.rect.bottom) ?? rows[rows.length - 1];
|
|
25008
|
+
}
|
|
25009
|
+
#parentRow(rows, index) {
|
|
25010
|
+
const target = rows[index];
|
|
25011
|
+
for (let i = index - 1; i >= 0; i--) if (rows[i].depth === target.depth - 1) return rows[i];
|
|
25012
|
+
}
|
|
25013
|
+
#resolveIntent(event, rows, source) {
|
|
25014
|
+
if (rows.length === 0) return void 0;
|
|
25015
|
+
const row = this.#rowAtPointer(rows, event.clientY);
|
|
25016
|
+
if (!row) return void 0;
|
|
25017
|
+
const rowIndex = rows.indexOf(row);
|
|
25018
|
+
const f = clamp$4((event.clientY - row.rect.top) / row.rect.height, 0, 1);
|
|
25019
|
+
let position = f < .25 ? `before` : f > .75 ? `after` : `inside`;
|
|
25020
|
+
const isLeaf = row.node.item.isLeaf === true;
|
|
25021
|
+
if (position === `inside` && isLeaf) position = `after`;
|
|
25022
|
+
let insideFromExpandedAfter = false;
|
|
25023
|
+
if (position === `after` && !isLeaf && this.#config.isExpanded(row.key)) {
|
|
25024
|
+
position = `inside`;
|
|
25025
|
+
insideFromExpandedAfter = true;
|
|
25026
|
+
}
|
|
25027
|
+
let parentKey;
|
|
25028
|
+
let referenceKey;
|
|
25029
|
+
let depth;
|
|
25030
|
+
let index;
|
|
25031
|
+
if (position === `inside`) {
|
|
25032
|
+
parentKey = row.key;
|
|
25033
|
+
referenceKey = row.key;
|
|
25034
|
+
depth = row.depth + 1;
|
|
25035
|
+
index = insideFromExpandedAfter ? 0 : row.node.children?.length ?? 0;
|
|
25036
|
+
} else {
|
|
25037
|
+
const indent = this.#config.getIndentPx() || 1;
|
|
25038
|
+
const treeLeft = rows[0].rect.left;
|
|
25039
|
+
const effDepth = clamp$4(Math.round((event.clientX - treeLeft) / indent), 0, row.depth);
|
|
25040
|
+
let anchorIndex = rowIndex;
|
|
25041
|
+
for (let up = row.depth - effDepth; up > 0; up--) {
|
|
25042
|
+
const parent = this.#parentRow(rows, anchorIndex);
|
|
25043
|
+
if (!parent) break;
|
|
25044
|
+
anchorIndex = rows.indexOf(parent);
|
|
25045
|
+
}
|
|
25046
|
+
const anchor = rows[anchorIndex];
|
|
25047
|
+
referenceKey = anchor.key;
|
|
25048
|
+
depth = anchor.depth;
|
|
25049
|
+
const parent = this.#parentRow(rows, anchorIndex);
|
|
25050
|
+
parentKey = parent?.key;
|
|
25051
|
+
const refIdx = (parent ? parent.node.children ?? [] : rows.filter((r) => r.depth === 0).map((r) => r.node)).findIndex((n) => n.item.key === anchor.key);
|
|
25052
|
+
index = (refIdx < 0 ? 0 : refIdx) + (position === `after` ? 1 : 0);
|
|
25053
|
+
}
|
|
25054
|
+
if (source === `internal`) {
|
|
25055
|
+
for (const key of this.#dragKeys) {
|
|
25056
|
+
if (key === parentKey || key === referenceKey) return void 0;
|
|
25057
|
+
if (parentKey !== void 0 && this.#config.isSelfOrDescendant(key, parentKey)) return void 0;
|
|
25058
|
+
if (position !== `inside` && this.#config.isSelfOrDescendant(key, referenceKey)) return void 0;
|
|
25059
|
+
}
|
|
25060
|
+
if (this.#dragKeys.length > 0 && !this.#config.isReorderAllowed()) {
|
|
25061
|
+
if (!this.#dragKeys.some((k) => this.#config.getParentKey(k) !== parentKey)) return void 0;
|
|
25062
|
+
}
|
|
25063
|
+
}
|
|
25064
|
+
return {
|
|
25065
|
+
parentKey,
|
|
25066
|
+
index,
|
|
25067
|
+
referenceKey,
|
|
25068
|
+
position,
|
|
25069
|
+
depth
|
|
25070
|
+
};
|
|
25071
|
+
}
|
|
25072
|
+
#handleExpandHover(row) {
|
|
25073
|
+
if (!row || row.node.item.isLeaf === true || this.#config.isExpanded(row.key)) {
|
|
25074
|
+
this.#clearExpand();
|
|
25075
|
+
return;
|
|
25076
|
+
}
|
|
25077
|
+
if (row.key === this.#expandPendingKey) return;
|
|
25078
|
+
this.#clearExpand();
|
|
25079
|
+
const key = this.#expandPendingKey = row.key;
|
|
25080
|
+
this.#expandTimer = setTimeout(() => {
|
|
25081
|
+
this.#expandTimer = void 0;
|
|
25082
|
+
if (this.#expandPendingKey === key) {
|
|
25083
|
+
this.#expandPendingKey = void 0;
|
|
25084
|
+
this.#config.expandKey(key);
|
|
25085
|
+
}
|
|
25086
|
+
}, Math.max(0, this.#config.getExpandHoverMs()));
|
|
25087
|
+
}
|
|
25088
|
+
#clearExpand() {
|
|
25089
|
+
if (this.#expandTimer !== void 0) {
|
|
25090
|
+
clearTimeout(this.#expandTimer);
|
|
25091
|
+
this.#expandTimer = void 0;
|
|
25092
|
+
}
|
|
25093
|
+
this.#expandPendingKey = void 0;
|
|
25094
|
+
}
|
|
25095
|
+
#kickScroll() {
|
|
25096
|
+
if (this.#scrollRaf === 0) this.#scrollRaf = requestAnimationFrame(this.#scrollTick);
|
|
25097
|
+
}
|
|
25098
|
+
#scrollTick = () => {
|
|
25099
|
+
this.#scrollRaf = 0;
|
|
25100
|
+
if (!this.#active) return;
|
|
25101
|
+
const container = this.#config.getScrollContainer();
|
|
25102
|
+
if (!container) return;
|
|
25103
|
+
const rect = container.getBoundingClientRect();
|
|
25104
|
+
const y = this.#pointerY - rect.top;
|
|
25105
|
+
let dy = 0;
|
|
25106
|
+
if (y < EDGE_ZONE_PX$1) dy = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, y) / EDGE_ZONE_PX$1));
|
|
25107
|
+
else if (y > rect.height - EDGE_ZONE_PX$1) dy = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, rect.height - y) / EDGE_ZONE_PX$1));
|
|
25108
|
+
if (dy !== 0 && this.#pointerX >= rect.left && this.#pointerX <= rect.right) {
|
|
25109
|
+
container.scrollTop += dy;
|
|
25110
|
+
this.#kickScroll();
|
|
25111
|
+
}
|
|
25112
|
+
};
|
|
25113
|
+
#stopScroll() {
|
|
25114
|
+
if (this.#scrollRaf !== 0) {
|
|
25115
|
+
cancelAnimationFrame(this.#scrollRaf);
|
|
25116
|
+
this.#scrollRaf = 0;
|
|
25117
|
+
}
|
|
25118
|
+
}
|
|
25119
|
+
#setDropState(state) {
|
|
25120
|
+
const unchanged = state === void 0 ? this.#current === void 0 : state.referenceKey === this.#current?.referenceKey && state.position === this.#current?.position && state.depth === this.#current?.depth && state.index === this.#current?.index;
|
|
25121
|
+
this.#current = state;
|
|
25122
|
+
if (!unchanged || this.#active) this.#config.onDropStateChange(state);
|
|
25123
|
+
}
|
|
25124
|
+
};
|
|
25125
|
+
//#endregion
|
|
23884
25126
|
//#region src/tree/tree-base.ts
|
|
23885
25127
|
/** Above this many rows entering / leaving at once, skip the animation entirely. */
|
|
23886
25128
|
const MAX_ANIMATED_ROWS = 50;
|
|
@@ -23893,6 +25135,10 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
23893
25135
|
this._selectedNodes = /* @__PURE__ */ new Set();
|
|
23894
25136
|
this.disableKeyboardNavigation = false;
|
|
23895
25137
|
this.registry = void 0;
|
|
25138
|
+
this.itemDnd = `none`;
|
|
25139
|
+
this.dndExpandHoverMs = 500;
|
|
25140
|
+
this.reorderable = true;
|
|
25141
|
+
this.applyInternalDrop = true;
|
|
23896
25142
|
this._expandedKeys = /* @__PURE__ */ new Set();
|
|
23897
25143
|
this.tickled = new TickledController(this, {
|
|
23898
25144
|
getItems: () => {
|
|
@@ -23901,6 +25147,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
23901
25147
|
enabled: true
|
|
23902
25148
|
}));
|
|
23903
25149
|
},
|
|
25150
|
+
hoverDisabled: () => this.#drop?.isDragging === true || this.#nativeDrag?.isDragging === true,
|
|
23904
25151
|
onStateChange: () => {
|
|
23905
25152
|
this.setAttribute(`data-input-mode`, this.tickled.inputMode);
|
|
23906
25153
|
}
|
|
@@ -23915,8 +25162,14 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
23915
25162
|
this.#lastNodeByKey = /* @__PURE__ */ new Map();
|
|
23916
25163
|
this.#enteringKeys = /* @__PURE__ */ new Set();
|
|
23917
25164
|
this.#leaving = /* @__PURE__ */ new Map();
|
|
23918
|
-
this.#
|
|
25165
|
+
this.#leavingAnimations = /* @__PURE__ */ new Map();
|
|
23919
25166
|
this.#treeAnimReady = false;
|
|
25167
|
+
this.#dragSourceId = ``;
|
|
25168
|
+
this.#nativeDragKeys = /* @__PURE__ */ new Set();
|
|
25169
|
+
this.#internalDropHandled = false;
|
|
25170
|
+
this.#onContainerScroll = () => {
|
|
25171
|
+
this.#rowsCache = void 0;
|
|
25172
|
+
};
|
|
23920
25173
|
this.#onKeyDown = (event) => {
|
|
23921
25174
|
if (this.search.isOpen) return;
|
|
23922
25175
|
const nodes = this.#getAllNodes();
|
|
@@ -24068,8 +25321,40 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24068
25321
|
#lastNodeByKey;
|
|
24069
25322
|
#enteringKeys;
|
|
24070
25323
|
#leaving;
|
|
24071
|
-
#
|
|
25324
|
+
#leavingAnimations;
|
|
24072
25325
|
#treeAnimReady;
|
|
25326
|
+
#dragSourceId;
|
|
25327
|
+
#postDragSuppressTimer;
|
|
25328
|
+
#dropState;
|
|
25329
|
+
#drop;
|
|
25330
|
+
#nativeDrag;
|
|
25331
|
+
/** Keys of the nodes currently being dragged out (for `.dragging` styling). */
|
|
25332
|
+
#nativeDragKeys;
|
|
25333
|
+
/** Set by `commitDrop` for a same-tree internal drop, read by the native `onEnd` to avoid a duplicate `tree-drag-end`. */
|
|
25334
|
+
#internalDropHandled;
|
|
25335
|
+
/** Per-drag cache of measured rows; invalidated on scroll / update. */
|
|
25336
|
+
#rowsCache;
|
|
25337
|
+
#onContainerScroll;
|
|
25338
|
+
get nativeDrag() {
|
|
25339
|
+
return this.#nativeDrag;
|
|
25340
|
+
}
|
|
25341
|
+
get dropState() {
|
|
25342
|
+
return this.#dropState;
|
|
25343
|
+
}
|
|
25344
|
+
/** Keys of the nodes currently being dragged out of this tree. */
|
|
25345
|
+
get nativeDragKeys() {
|
|
25346
|
+
return this.#nativeDragKeys;
|
|
25347
|
+
}
|
|
25348
|
+
#cancelLeavingAnimation(key) {
|
|
25349
|
+
this.#leavingAnimations.get(key)?.cancel();
|
|
25350
|
+
this.#leavingAnimations.delete(key);
|
|
25351
|
+
}
|
|
25352
|
+
#cancelAllLeavingAnimations() {
|
|
25353
|
+
for (const animation of this.#leavingAnimations.values()) try {
|
|
25354
|
+
animation.cancel();
|
|
25355
|
+
} catch {}
|
|
25356
|
+
this.#leavingAnimations.clear();
|
|
25357
|
+
}
|
|
24073
25358
|
willUpdate(changedProps) {
|
|
24074
25359
|
super.willUpdate(changedProps);
|
|
24075
25360
|
this.#diffVisibleNodes();
|
|
@@ -24088,12 +25373,12 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24088
25373
|
}
|
|
24089
25374
|
}
|
|
24090
25375
|
for (const key of [...this.#leaving.keys()]) if (nowKeys.has(key)) {
|
|
25376
|
+
this.#cancelLeavingAnimation(key);
|
|
24091
25377
|
this.#leaving.delete(key);
|
|
24092
|
-
this.#leavingAnimating.delete(key);
|
|
24093
25378
|
}
|
|
24094
25379
|
if (this.#leaving.size > MAX_ANIMATED_ROWS) {
|
|
25380
|
+
this.#cancelAllLeavingAnimations();
|
|
24095
25381
|
this.#leaving.clear();
|
|
24096
|
-
this.#leavingAnimating.clear();
|
|
24097
25382
|
}
|
|
24098
25383
|
}
|
|
24099
25384
|
/** True while `node` is a fading ghost row (removed / collapsed, still animating out). */
|
|
@@ -24130,18 +25415,38 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24130
25415
|
if (this.#enteringKeys.size > 0) {
|
|
24131
25416
|
for (const el of this.renderRoot.querySelectorAll(`.item`)) {
|
|
24132
25417
|
const key = el.dataset.key;
|
|
24133
|
-
if (key
|
|
25418
|
+
if (key === void 0 || !this.#enteringKeys.has(key)) continue;
|
|
25419
|
+
if (this.#leavingAnimations.has(key)) this.#cancelLeavingAnimation(key);
|
|
25420
|
+
else for (const animation of el.getAnimations()) animation.cancel();
|
|
25421
|
+
animateListItemIn(el);
|
|
24134
25422
|
}
|
|
24135
25423
|
this.#enteringKeys.clear();
|
|
24136
25424
|
}
|
|
24137
25425
|
if (this.#leaving.size > 0) for (const el of this.renderRoot.querySelectorAll(`.item.leaving`)) {
|
|
24138
25426
|
const key = el.dataset.key;
|
|
24139
|
-
if (key === void 0 || this.#
|
|
24140
|
-
|
|
24141
|
-
|
|
25427
|
+
if (key === void 0 || this.#leavingAnimations.has(key)) continue;
|
|
25428
|
+
const result = animateListItemOut(el);
|
|
25429
|
+
const animation = result.animation;
|
|
25430
|
+
if (!animation) {
|
|
25431
|
+
result.then(() => {
|
|
25432
|
+
if (!this.#leaving.has(key)) return;
|
|
25433
|
+
this.#leaving.delete(key);
|
|
25434
|
+
this.requestUpdate();
|
|
25435
|
+
});
|
|
25436
|
+
continue;
|
|
25437
|
+
}
|
|
25438
|
+
this.#cancelLeavingAnimation(key);
|
|
25439
|
+
this.#leavingAnimations.set(key, animation);
|
|
25440
|
+
result.then(() => {
|
|
25441
|
+
if (this.#leavingAnimations.get(key) !== animation) return;
|
|
25442
|
+
this.#leavingAnimations.delete(key);
|
|
24142
25443
|
this.#leaving.delete(key);
|
|
24143
|
-
this.#leavingAnimating.delete(key);
|
|
24144
25444
|
this.requestUpdate();
|
|
25445
|
+
this.updateComplete.then(() => {
|
|
25446
|
+
try {
|
|
25447
|
+
animation.cancel();
|
|
25448
|
+
} catch {}
|
|
25449
|
+
});
|
|
24145
25450
|
});
|
|
24146
25451
|
}
|
|
24147
25452
|
const visible = this.root ? this.#getAllNodes() : [];
|
|
@@ -24151,12 +25456,16 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24151
25456
|
this.#treeAnimReady = true;
|
|
24152
25457
|
}
|
|
24153
25458
|
updated(changedProps) {
|
|
25459
|
+
this.#rowsCache = void 0;
|
|
24154
25460
|
if (changedProps.has(`root`) && this.root) {
|
|
24155
25461
|
this.#abortPending();
|
|
24156
25462
|
this._expandedKeys.clear();
|
|
24157
25463
|
this.#clearSelectionInternal();
|
|
24158
25464
|
this.tickled.clearTickled();
|
|
24159
25465
|
this._focusedDepth = 0;
|
|
25466
|
+
this.#cancelAllLeavingAnimations();
|
|
25467
|
+
this.#leaving.clear();
|
|
25468
|
+
this.#enteringKeys.clear();
|
|
24160
25469
|
}
|
|
24161
25470
|
if (changedProps.has(`model`)) {
|
|
24162
25471
|
this.#modelUnsubscribe?.();
|
|
@@ -24204,13 +25513,307 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24204
25513
|
});
|
|
24205
25514
|
this.registry = registry;
|
|
24206
25515
|
this.#syncSearchCommands();
|
|
25516
|
+
this.#initDnd();
|
|
25517
|
+
}
|
|
25518
|
+
#initDnd() {
|
|
25519
|
+
this.#dragSourceId = treeDragGenerateSourceId();
|
|
25520
|
+
this.#nativeDrag = new ListNativeDragController(this, {
|
|
25521
|
+
source: `tree-list`,
|
|
25522
|
+
isEnabled: () => this.itemDnd !== `none` && this.#anyRowDraggable(),
|
|
25523
|
+
resolveEventToKey: (target) => {
|
|
25524
|
+
if (!(target instanceof Element)) return void 0;
|
|
25525
|
+
return target.closest(`li[data-key]`)?.getAttribute(`data-key`) ?? void 0;
|
|
25526
|
+
},
|
|
25527
|
+
prepareSelection: (originKey) => {
|
|
25528
|
+
const allNodes = this.#getAllNodes();
|
|
25529
|
+
const originEntry = allNodes.find((n) => n.node.item.key === originKey);
|
|
25530
|
+
if (!originEntry) return void 0;
|
|
25531
|
+
const selectedNodes = new Set(this._selectedNodes);
|
|
25532
|
+
if (!selectedNodes.has(originEntry.node)) selectedNodes.clear();
|
|
25533
|
+
selectedNodes.add(originEntry.node);
|
|
25534
|
+
const orderedKeys = allNodes.filter((n) => selectedNodes.has(n.node)).map((n) => n.node.item.key);
|
|
25535
|
+
const topKeys = new Set(this.root ? pruneDraggedDescendants(this.root, orderedKeys) : orderedKeys);
|
|
25536
|
+
const selected = allNodes.filter((n) => topKeys.has(n.node.item.key)).map((n, i) => ({
|
|
25537
|
+
key: n.node.item.key,
|
|
25538
|
+
index: i,
|
|
25539
|
+
item: n.node,
|
|
25540
|
+
element: this.shadowRoot?.querySelector(`li[data-key="${CSS.escape(n.node.item.key)}"]`) ?? void 0
|
|
25541
|
+
}));
|
|
25542
|
+
const origin = selected.find((e) => e.key === originKey) ?? {
|
|
25543
|
+
key: originKey,
|
|
25544
|
+
index: 0,
|
|
25545
|
+
item: originEntry.node,
|
|
25546
|
+
element: void 0
|
|
25547
|
+
};
|
|
25548
|
+
if (!selected.some((e) => e.key === origin.key)) selected.unshift(origin);
|
|
25549
|
+
return {
|
|
25550
|
+
origin,
|
|
25551
|
+
selected
|
|
25552
|
+
};
|
|
25553
|
+
},
|
|
25554
|
+
getMetrics: () => ({ rowHeight: this.#getItemHeight() }),
|
|
25555
|
+
getRenderer: () => this.dragPreviewRenderer,
|
|
25556
|
+
dispatch: (detail) => {
|
|
25557
|
+
const keys = detail.selected.map((e) => e.key);
|
|
25558
|
+
const nodes = detail.selected.map((e) => e.item);
|
|
25559
|
+
const evt = new CustomEvent(`list-native-drag-start`, {
|
|
25560
|
+
detail,
|
|
25561
|
+
bubbles: true,
|
|
25562
|
+
composed: true,
|
|
25563
|
+
cancelable: true
|
|
25564
|
+
});
|
|
25565
|
+
const notCancelled = this.dispatchEvent(evt);
|
|
25566
|
+
if (notCancelled) {
|
|
25567
|
+
this.#nativeDragKeys = new Set(keys);
|
|
25568
|
+
this.#internalDropHandled = false;
|
|
25569
|
+
if (this.itemDnd === `internal` || this.itemDnd === `both`) treeDragRegister(this.#dragSourceId, this, nodes, keys);
|
|
25570
|
+
this.dispatchEvent(new CustomEvent(`tree-drag-start`, {
|
|
25571
|
+
detail: {
|
|
25572
|
+
nodes,
|
|
25573
|
+
keys
|
|
25574
|
+
},
|
|
25575
|
+
bubbles: true,
|
|
25576
|
+
composed: true
|
|
25577
|
+
}));
|
|
25578
|
+
}
|
|
25579
|
+
return notCancelled;
|
|
25580
|
+
},
|
|
25581
|
+
writeDataTransfer: (dataTransfer, detail) => {
|
|
25582
|
+
if (this.itemDnd !== `internal` && this.itemDnd !== `both`) return;
|
|
25583
|
+
const keys = detail.selected.map((e) => e.key);
|
|
25584
|
+
const nodes = detail.selected.map((e) => e.item);
|
|
25585
|
+
try {
|
|
25586
|
+
dataTransfer.setData(TREE_DRAG_MIME, JSON.stringify({
|
|
25587
|
+
sourceId: this.#dragSourceId,
|
|
25588
|
+
keys,
|
|
25589
|
+
nodes
|
|
25590
|
+
}));
|
|
25591
|
+
dataTransfer.setData(`text/plain`, nodes.map((n) => n.item.label).join(`\n`));
|
|
25592
|
+
} catch {}
|
|
25593
|
+
},
|
|
25594
|
+
onActiveChange: (active) => {
|
|
25595
|
+
this.toggleAttribute(`data-native-dragging`, active);
|
|
25596
|
+
if (!active) this.#nativeDragKeys = /* @__PURE__ */ new Set();
|
|
25597
|
+
this.requestUpdate();
|
|
25598
|
+
},
|
|
25599
|
+
onEnd: () => {
|
|
25600
|
+
treeDragUnregister(this.#dragSourceId);
|
|
25601
|
+
this.#nativeDragKeys = /* @__PURE__ */ new Set();
|
|
25602
|
+
this.#postDragSuppressTimer = setTimeout(() => {
|
|
25603
|
+
this.#postDragSuppressTimer = void 0;
|
|
25604
|
+
}, 150);
|
|
25605
|
+
if (!this.#internalDropHandled) this.dispatchEvent(new CustomEvent(`tree-drag-end`, {
|
|
25606
|
+
detail: { dropped: false },
|
|
25607
|
+
bubbles: true,
|
|
25608
|
+
composed: true
|
|
25609
|
+
}));
|
|
25610
|
+
this.#internalDropHandled = false;
|
|
25611
|
+
}
|
|
25612
|
+
});
|
|
25613
|
+
this.#drop = new TreeDropController(this, {
|
|
25614
|
+
getDndMode: () => this.itemDnd,
|
|
25615
|
+
getExpandHoverMs: () => this.dndExpandHoverMs,
|
|
25616
|
+
getVisibleRows: () => this.#getVisibleRows(),
|
|
25617
|
+
getIndentPx: () => this.#getIndentPx(),
|
|
25618
|
+
getScrollContainer: () => this.#container(),
|
|
25619
|
+
isSelfOrDescendant: (ancestorKey, key) => this.#isSelfOrDescendant(ancestorKey, key),
|
|
25620
|
+
isExpanded: (key) => this._expandedKeys.has(key),
|
|
25621
|
+
isReorderAllowed: () => this.reorderable,
|
|
25622
|
+
getParentKey: (key) => this.#findParentByKey(key)?.item.key,
|
|
25623
|
+
resolveDrag: (dataTransfer, phase) => this.#resolveDrag(dataTransfer, phase),
|
|
25624
|
+
vet: (ctx) => {
|
|
25625
|
+
if (this.canDrop && !this.canDrop(ctx)) return false;
|
|
25626
|
+
const evt = new CustomEvent(`tree-drag-over`, {
|
|
25627
|
+
detail: ctx,
|
|
25628
|
+
bubbles: true,
|
|
25629
|
+
composed: true,
|
|
25630
|
+
cancelable: true
|
|
25631
|
+
});
|
|
25632
|
+
return this.dispatchEvent(evt);
|
|
25633
|
+
},
|
|
25634
|
+
expandKey: (key) => this.#springLoadExpand(key),
|
|
25635
|
+
onDropStateChange: (state) => {
|
|
25636
|
+
this.#dropState = state;
|
|
25637
|
+
this.toggleAttribute(`data-drop-rejected`, this.#drop.isDragging && state === void 0);
|
|
25638
|
+
this.requestUpdate();
|
|
25639
|
+
},
|
|
25640
|
+
onActiveChange: (active) => {
|
|
25641
|
+
if (active) {
|
|
25642
|
+
this.#rowsCache = void 0;
|
|
25643
|
+
this.#container()?.addEventListener(`scroll`, this.#onContainerScroll, { passive: true });
|
|
25644
|
+
} else {
|
|
25645
|
+
this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);
|
|
25646
|
+
this.#rowsCache = void 0;
|
|
25647
|
+
this.toggleAttribute(`data-drop-rejected`, false);
|
|
25648
|
+
}
|
|
25649
|
+
this.requestUpdate();
|
|
25650
|
+
},
|
|
25651
|
+
commitDrop: (detail) => {
|
|
25652
|
+
if (!this.dispatchEvent(new CustomEvent(`tree-drop`, {
|
|
25653
|
+
detail,
|
|
25654
|
+
bubbles: true,
|
|
25655
|
+
composed: true,
|
|
25656
|
+
cancelable: true
|
|
25657
|
+
}))) return false;
|
|
25658
|
+
if (this.applyInternalDrop && detail.source === `internal` && this.model) this.model.applyDrop({
|
|
25659
|
+
source: `internal`,
|
|
25660
|
+
draggedKeys: detail.draggedKeys,
|
|
25661
|
+
target: detail.target
|
|
25662
|
+
});
|
|
25663
|
+
this.#internalDropHandled = true;
|
|
25664
|
+
return true;
|
|
25665
|
+
},
|
|
25666
|
+
onDragEnd: (dropped) => {
|
|
25667
|
+
this.#dropState = void 0;
|
|
25668
|
+
this.toggleAttribute(`data-drop-rejected`, false);
|
|
25669
|
+
this.requestUpdate();
|
|
25670
|
+
this.dispatchEvent(new CustomEvent(`tree-drag-end`, {
|
|
25671
|
+
detail: { dropped },
|
|
25672
|
+
bubbles: true,
|
|
25673
|
+
composed: true
|
|
25674
|
+
}));
|
|
25675
|
+
}
|
|
25676
|
+
});
|
|
25677
|
+
}
|
|
25678
|
+
#container() {
|
|
25679
|
+
return this.shadowRoot?.querySelector(`#container`) ?? void 0;
|
|
25680
|
+
}
|
|
25681
|
+
#getIndentPx() {
|
|
25682
|
+
const parsed = Number.parseInt(getComputedStyle(this).getPropertyValue(`--tree-indent`), 10);
|
|
25683
|
+
return Number.isNaN(parsed) ? 20 : parsed;
|
|
25684
|
+
}
|
|
25685
|
+
#getItemHeight() {
|
|
25686
|
+
const parsed = Number.parseInt(getComputedStyle(this).getPropertyValue(`--tree-item-height`), 10);
|
|
25687
|
+
return Number.isNaN(parsed) ? 30 : parsed;
|
|
25688
|
+
}
|
|
25689
|
+
/** Measured rows, cached for the duration of a drag and invalidated on scroll / update. */
|
|
25690
|
+
#getVisibleRows() {
|
|
25691
|
+
if (this.#rowsCache) return this.#rowsCache;
|
|
25692
|
+
const rows = [];
|
|
25693
|
+
for (const { node, depth } of this.#getAllNodes()) {
|
|
25694
|
+
const li = this.shadowRoot?.querySelector(`li[data-key="${CSS.escape(node.item.key)}"]`);
|
|
25695
|
+
if (li) rows.push({
|
|
25696
|
+
key: node.item.key,
|
|
25697
|
+
node,
|
|
25698
|
+
depth,
|
|
25699
|
+
rect: li.getBoundingClientRect()
|
|
25700
|
+
});
|
|
25701
|
+
}
|
|
25702
|
+
this.#rowsCache = rows;
|
|
25703
|
+
return rows;
|
|
25704
|
+
}
|
|
25705
|
+
/** Route spring-load through the real expand path so lazy children load and `expand` fires with the right depth. */
|
|
25706
|
+
#springLoadExpand(key) {
|
|
25707
|
+
if (this._expandedKeys.has(key)) return;
|
|
25708
|
+
const entry = this.#getAllNodes().find((n) => n.node.item.key === key);
|
|
25709
|
+
if (!entry || entry.node.item.isLeaf === true) return;
|
|
25710
|
+
this.#toggleExpand(entry.node, entry.depth);
|
|
25711
|
+
this.#rowsCache = void 0;
|
|
25712
|
+
this.requestUpdate();
|
|
25713
|
+
}
|
|
25714
|
+
#isSelfOrDescendant(ancestorKey, key) {
|
|
25715
|
+
if (ancestorKey === key) return true;
|
|
25716
|
+
let node = this.#getAllNodes().find((n) => n.node.item.key === key)?.node;
|
|
25717
|
+
let parent = node ? this.#findParentByKey(node.item.key) : void 0;
|
|
25718
|
+
while (parent) {
|
|
25719
|
+
if (parent.item.key === ancestorKey) return true;
|
|
25720
|
+
node = parent;
|
|
25721
|
+
parent = this.#findParentByKey(node.item.key);
|
|
25722
|
+
}
|
|
25723
|
+
return false;
|
|
25724
|
+
}
|
|
25725
|
+
#findParentByKey(key) {
|
|
25726
|
+
for (const { node } of this.#getAllNodes()) if (node.children?.some((c) => c.item.key === key)) return node;
|
|
25727
|
+
}
|
|
25728
|
+
/**
|
|
25729
|
+
* Decide whether a DataTransfer is acceptable and resolve the dragged set.
|
|
25730
|
+
* During `hover` the DataTransfer is read-protected, so an internal drag is
|
|
25731
|
+
* recovered from the module-level drag registry (there is only one at a time).
|
|
25732
|
+
*/
|
|
25733
|
+
#resolveDrag(dataTransfer, phase) {
|
|
25734
|
+
const mode = this.itemDnd;
|
|
25735
|
+
if (mode === `none`) return void 0;
|
|
25736
|
+
const canInternal = mode === `internal` || mode === `both`;
|
|
25737
|
+
const canExternal = mode === `external` || mode === `both`;
|
|
25738
|
+
let types = [];
|
|
25739
|
+
try {
|
|
25740
|
+
types = Array.from(dataTransfer.types);
|
|
25741
|
+
} catch {}
|
|
25742
|
+
const current = treeDragCurrent();
|
|
25743
|
+
const looksInternal = types.includes(TREE_DRAG_MIME) || current !== void 0;
|
|
25744
|
+
if (canInternal && looksInternal) {
|
|
25745
|
+
if (current && current.keys.length > 0) {
|
|
25746
|
+
const keys = this.root ? pruneDraggedDescendants(this.root, current.keys) : current.keys;
|
|
25747
|
+
return {
|
|
25748
|
+
source: `internal`,
|
|
25749
|
+
keys,
|
|
25750
|
+
nodes: keys.map((k) => this.#getAllNodes().find((n) => n.node.item.key === k)?.node).filter((n) => n !== void 0)
|
|
25751
|
+
};
|
|
25752
|
+
}
|
|
25753
|
+
if (phase === `drop`) try {
|
|
25754
|
+
const raw = dataTransfer.getData(TREE_DRAG_MIME);
|
|
25755
|
+
if (raw) {
|
|
25756
|
+
const payload = JSON.parse(raw);
|
|
25757
|
+
return {
|
|
25758
|
+
source: `internal`,
|
|
25759
|
+
keys: payload.keys ?? [],
|
|
25760
|
+
nodes: payload.nodes ?? []
|
|
25761
|
+
};
|
|
25762
|
+
}
|
|
25763
|
+
} catch {}
|
|
25764
|
+
return {
|
|
25765
|
+
source: `internal`,
|
|
25766
|
+
keys: [],
|
|
25767
|
+
nodes: []
|
|
25768
|
+
};
|
|
25769
|
+
}
|
|
25770
|
+
if (canExternal && !looksInternal) {
|
|
25771
|
+
if (this.acceptDropTypes !== void 0) {
|
|
25772
|
+
const accepted = this.acceptDropTypes.trim().split(/\s+/).filter(Boolean);
|
|
25773
|
+
const present = Array.from(dataTransfer.types);
|
|
25774
|
+
if (accepted.length > 0 && !accepted.some((t) => present.includes(t))) return void 0;
|
|
25775
|
+
}
|
|
25776
|
+
if (phase === `drop`) {
|
|
25777
|
+
const nodes = this.parseExternalDrop?.(dataTransfer);
|
|
25778
|
+
if (!nodes || nodes.length === 0) return void 0;
|
|
25779
|
+
return {
|
|
25780
|
+
source: `external`,
|
|
25781
|
+
keys: nodes.map((n) => n.item.key),
|
|
25782
|
+
nodes
|
|
25783
|
+
};
|
|
25784
|
+
}
|
|
25785
|
+
return this.parseExternalDrop ? {
|
|
25786
|
+
source: `external`,
|
|
25787
|
+
keys: [],
|
|
25788
|
+
nodes: []
|
|
25789
|
+
} : void 0;
|
|
25790
|
+
}
|
|
25791
|
+
}
|
|
25792
|
+
#anyRowDraggable() {
|
|
25793
|
+
if (this.itemDnd === `none`) return false;
|
|
25794
|
+
const allNodes = this.#getAllNodes();
|
|
25795
|
+
if (allNodes.length === 0) return false;
|
|
25796
|
+
if (!this.canDrag) return true;
|
|
25797
|
+
return allNodes.some(({ node }) => this.canDrag({
|
|
25798
|
+
nodes: [node],
|
|
25799
|
+
keys: [node.item.key]
|
|
25800
|
+
}));
|
|
24207
25801
|
}
|
|
24208
25802
|
disconnectedCallback() {
|
|
24209
25803
|
super.disconnectedCallback();
|
|
25804
|
+
this.#cancelAllLeavingAnimations();
|
|
25805
|
+
this.#leaving.clear();
|
|
25806
|
+
this.#enteringKeys.clear();
|
|
24210
25807
|
this.#modelUnsubscribe?.();
|
|
24211
25808
|
this.#modelUnsubscribe = void 0;
|
|
24212
25809
|
this.#unregisterSearchCommands?.();
|
|
24213
25810
|
this.#unregisterSearchCommands = void 0;
|
|
25811
|
+
if (this.#postDragSuppressTimer !== void 0) {
|
|
25812
|
+
clearTimeout(this.#postDragSuppressTimer);
|
|
25813
|
+
this.#postDragSuppressTimer = void 0;
|
|
25814
|
+
}
|
|
25815
|
+
this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);
|
|
25816
|
+
treeDragUnregister(this.#dragSourceId);
|
|
24214
25817
|
if (this.#ownedRegistry) {
|
|
24215
25818
|
this.#ownedRegistry.unregister(`select-all`);
|
|
24216
25819
|
this.#ownedRegistry.unregister(`deselect-all`);
|
|
@@ -24385,6 +25988,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24385
25988
|
`;
|
|
24386
25989
|
}
|
|
24387
25990
|
_handleItemClick(node, depth, event) {
|
|
25991
|
+
if (this.#drop?.isDragging || this.#nativeDrag?.isDragging || this.#postDragSuppressTimer !== void 0) return;
|
|
24388
25992
|
if (event && event.detail >= 2) return;
|
|
24389
25993
|
if (this.#pendingNode && this._expandedKeys.has(this.#pendingNode.item.key)) this.#abortPending();
|
|
24390
25994
|
this.tickled.handlePointerEnter(node.item.key);
|
|
@@ -24819,6 +26423,23 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24819
26423
|
</ul>
|
|
24820
26424
|
`;
|
|
24821
26425
|
}
|
|
26426
|
+
/** Shared drag-and-drop render state for a row, used by every `_renderNode` variant. */
|
|
26427
|
+
_dndRowState(node) {
|
|
26428
|
+
const draggable = this.itemDnd !== `none` && (this.root?.children?.length ?? 0) > 0 && (this.itemDnd === `internal` || this.itemDnd === `both` || this.itemDnd === `external`) && (this.canDrag?.({
|
|
26429
|
+
nodes: [node],
|
|
26430
|
+
keys: [node.item.key]
|
|
26431
|
+
}) ?? true);
|
|
26432
|
+
const dragging = this.#nativeDragKeys.has(node.item.key);
|
|
26433
|
+
const state = this.#dropState;
|
|
26434
|
+
const dropTarget = state !== void 0 && state.referenceKey === node.item.key;
|
|
26435
|
+
return {
|
|
26436
|
+
draggable,
|
|
26437
|
+
dragging,
|
|
26438
|
+
dropTarget,
|
|
26439
|
+
dropPosition: dropTarget ? state.position : void 0,
|
|
26440
|
+
dropDepth: dropTarget ? state.depth : void 0
|
|
26441
|
+
};
|
|
26442
|
+
}
|
|
24822
26443
|
_renderNode(node, depth) {
|
|
24823
26444
|
const selected = this._isSelected(node);
|
|
24824
26445
|
const tickled = this._isFocused(node);
|
|
@@ -24827,9 +26448,10 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24827
26448
|
const isPending = this.#pendingNode === node;
|
|
24828
26449
|
const isFiltered = this._isFilteredOut(node, depth);
|
|
24829
26450
|
const isLeaving = this._isLeaving(node);
|
|
26451
|
+
const dnd = this._dndRowState(node);
|
|
24830
26452
|
return b`
|
|
24831
26453
|
<li
|
|
24832
|
-
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${isFiltered ? `filtered` : ``} ${isLeaving ? `leaving` : ``}"
|
|
26454
|
+
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${isFiltered ? `filtered` : ``} ${isLeaving ? `leaving` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}"
|
|
24833
26455
|
role="treeitem"
|
|
24834
26456
|
aria-selected=${selected}
|
|
24835
26457
|
aria-expanded=${isBranch ? isExpanded : A}
|
|
@@ -24837,6 +26459,8 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24837
26459
|
aria-level=${depth + 1}
|
|
24838
26460
|
data-key=${node.item.key}
|
|
24839
26461
|
style=${`--depth: ${depth}`}
|
|
26462
|
+
draggable=${dnd.draggable ? `true` : A}
|
|
26463
|
+
part=${dnd.dropTarget ? `drop-target` : A}
|
|
24840
26464
|
@click=${(e) => this._handleItemClick(node, depth, e)}
|
|
24841
26465
|
@pointerenter=${() => {
|
|
24842
26466
|
this.tickled.handlePointerEnter(node.item.key);
|
|
@@ -24850,6 +26474,11 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24850
26474
|
}));
|
|
24851
26475
|
}}
|
|
24852
26476
|
>
|
|
26477
|
+
${dnd.dropTarget && (dnd.dropPosition === `before` || dnd.dropPosition === `after`) ? b`<div
|
|
26478
|
+
class="drop-line drop-line-${dnd.dropPosition}"
|
|
26479
|
+
style="--drop-depth: ${dnd.dropDepth ?? depth}"
|
|
26480
|
+
part="drop-indicator"
|
|
26481
|
+
></div>` : A}
|
|
24853
26482
|
${this.renderNodeContent(node, depth)}
|
|
24854
26483
|
${isPending ? this.renderLoadingIndicator() : A}
|
|
24855
26484
|
</li>
|
|
@@ -24867,9 +26496,13 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24867
26496
|
--tree-text: var(--surface-3-text);
|
|
24868
26497
|
--tree-muted-text: var(--surface-muted-text);
|
|
24869
26498
|
--tree-indent: 1ch;
|
|
24870
|
-
--tree-item-height:
|
|
26499
|
+
--tree-item-height: 30px;
|
|
24871
26500
|
--tree-caret-size: 30px;
|
|
24872
26501
|
--tree-radius: var(--radius-s);
|
|
26502
|
+
--tree-drop-line: var(--accent);
|
|
26503
|
+
--tree-drop-nub-size: 5px;
|
|
26504
|
+
--tree-drop-into-outline: 2px solid var(--accent);
|
|
26505
|
+
--tree-drop-into-bg: color-mix(in srgb, var(--accent) 14%, transparent);
|
|
24873
26506
|
|
|
24874
26507
|
position: relative;
|
|
24875
26508
|
display: block;
|
|
@@ -24897,10 +26530,11 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24897
26530
|
}
|
|
24898
26531
|
|
|
24899
26532
|
.item {
|
|
26533
|
+
position: relative; /* anchor for the .drop-line before/after indicator */
|
|
24900
26534
|
display: flex;
|
|
24901
26535
|
align-items: center;
|
|
24902
26536
|
height: var(--tree-item-height);
|
|
24903
|
-
padding-left: calc(var(--tree-indent) * var(--depth, 0)
|
|
26537
|
+
padding-left: calc(var(--tree-indent) * var(--depth, 0));
|
|
24904
26538
|
cursor: pointer;
|
|
24905
26539
|
user-select: none;
|
|
24906
26540
|
font-family: var(--font-family);
|
|
@@ -24972,11 +26606,49 @@ let TreeBaseElement = class TreeBaseElement extends i {
|
|
|
24972
26606
|
overflow: hidden;
|
|
24973
26607
|
}
|
|
24974
26608
|
|
|
24975
|
-
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
26609
|
+
/* Drag and drop styles */
|
|
26610
|
+
.item.dragging {
|
|
26611
|
+
opacity: 0.4;
|
|
26612
|
+
}
|
|
26613
|
+
|
|
26614
|
+
.item.drop-into {
|
|
26615
|
+
outline: var(--tree-drop-into-outline);
|
|
26616
|
+
outline-offset: -2px;
|
|
26617
|
+
background: var(--tree-drop-into-bg);
|
|
26618
|
+
}
|
|
26619
|
+
|
|
26620
|
+
.drop-line {
|
|
26621
|
+
position: absolute;
|
|
26622
|
+
left: calc(var(--tree-indent) * var(--drop-depth, 0) + var(--space-xs));
|
|
26623
|
+
right: var(--space-xs);
|
|
26624
|
+
height: 2px;
|
|
26625
|
+
background: var(--tree-drop-line);
|
|
26626
|
+
pointer-events: none;
|
|
26627
|
+
z-index: 10;
|
|
26628
|
+
}
|
|
26629
|
+
|
|
26630
|
+
/* Nub at the left end of the insertion line (VS Code style). */
|
|
26631
|
+
.drop-line::before {
|
|
26632
|
+
content: "";
|
|
26633
|
+
position: absolute;
|
|
26634
|
+
left: calc(-1 * var(--tree-drop-nub-size) / 2);
|
|
26635
|
+
top: calc(50% - var(--tree-drop-nub-size) / 2);
|
|
26636
|
+
width: var(--tree-drop-nub-size);
|
|
26637
|
+
height: var(--tree-drop-nub-size);
|
|
26638
|
+
border-radius: 50%;
|
|
26639
|
+
background: var(--tree-drop-line);
|
|
26640
|
+
}
|
|
26641
|
+
|
|
26642
|
+
.drop-line-before {
|
|
26643
|
+
top: -1px;
|
|
26644
|
+
}
|
|
26645
|
+
|
|
26646
|
+
.drop-line-after {
|
|
26647
|
+
bottom: -1px;
|
|
26648
|
+
}
|
|
26649
|
+
|
|
26650
|
+
:host([data-drop-rejected]) {
|
|
26651
|
+
cursor: not-allowed;
|
|
24980
26652
|
}
|
|
24981
26653
|
`
|
|
24982
26654
|
];
|
|
@@ -25010,6 +26682,31 @@ __decorate([property({
|
|
|
25010
26682
|
attribute: `search-modes`,
|
|
25011
26683
|
reflect: true
|
|
25012
26684
|
})], TreeBaseElement.prototype, "searchModes", void 0);
|
|
26685
|
+
__decorate([property({
|
|
26686
|
+
reflect: true,
|
|
26687
|
+
attribute: `item-dnd`
|
|
26688
|
+
})], TreeBaseElement.prototype, "itemDnd", void 0);
|
|
26689
|
+
__decorate([property({
|
|
26690
|
+
type: String,
|
|
26691
|
+
attribute: `accept-drop-types`
|
|
26692
|
+
})], TreeBaseElement.prototype, "acceptDropTypes", void 0);
|
|
26693
|
+
__decorate([property({
|
|
26694
|
+
type: Number,
|
|
26695
|
+
attribute: `dnd-expand-hover-ms`
|
|
26696
|
+
})], TreeBaseElement.prototype, "dndExpandHoverMs", void 0);
|
|
26697
|
+
__decorate([property({
|
|
26698
|
+
reflect: true,
|
|
26699
|
+
attribute: `reorderable`,
|
|
26700
|
+
converter: {
|
|
26701
|
+
fromAttribute: (value) => value !== `false`,
|
|
26702
|
+
toAttribute: (value) => value ? null : `false`
|
|
26703
|
+
}
|
|
26704
|
+
})], TreeBaseElement.prototype, "reorderable", void 0);
|
|
26705
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "dragPreviewRenderer", void 0);
|
|
26706
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "canDrag", void 0);
|
|
26707
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "canDrop", void 0);
|
|
26708
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "parseExternalDrop", void 0);
|
|
26709
|
+
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "applyInternalDrop", void 0);
|
|
25013
26710
|
__decorate([state()], TreeBaseElement.prototype, "_expandedKeys", void 0);
|
|
25014
26711
|
__decorate([state()], TreeBaseElement.prototype, "_focusedDepth", void 0);
|
|
25015
26712
|
TreeBaseElement = __decorate([safeCustomElement(`ixfx-tree-base`)], TreeBaseElement);
|
|
@@ -25091,9 +26788,10 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
|
|
|
25091
26788
|
const hasIconAtDepth = this.#depthsWithIcons.has(depth);
|
|
25092
26789
|
const isLeaving = this._isLeaving(node);
|
|
25093
26790
|
const isFiltered = this._isFilteredOut(node, depth);
|
|
26791
|
+
const dnd = this._dndRowState(node);
|
|
25094
26792
|
return b`
|
|
25095
26793
|
<li
|
|
25096
|
-
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${isFiltered ? `filtered` : ``}"
|
|
26794
|
+
class="item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${isFiltered ? `filtered` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}"
|
|
25097
26795
|
data-key=${node.item.key}
|
|
25098
26796
|
role="treeitem"
|
|
25099
26797
|
aria-selected=${selected}
|
|
@@ -25101,9 +26799,16 @@ let TreeListElement = class TreeListElement extends TreeBaseElement {
|
|
|
25101
26799
|
aria-hidden=${isLeaving ? `true` : A}
|
|
25102
26800
|
aria-level=${depth + 1}
|
|
25103
26801
|
style=${`--depth: ${depth}`}
|
|
26802
|
+
draggable=${dnd.draggable ? `true` : A}
|
|
26803
|
+
part=${dnd.dropTarget ? `drop-target` : A}
|
|
25104
26804
|
@click=${(e) => this._handleItemClick(node, depth, e)}
|
|
25105
26805
|
@pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}
|
|
25106
26806
|
>
|
|
26807
|
+
${dnd.dropTarget && (dnd.dropPosition === `before` || dnd.dropPosition === `after`) ? b`<div
|
|
26808
|
+
class="drop-line drop-line-${dnd.dropPosition}"
|
|
26809
|
+
style="--drop-depth: ${dnd.dropDepth ?? depth}"
|
|
26810
|
+
part="drop-indicator"
|
|
26811
|
+
></div>` : A}
|
|
25107
26812
|
${this.renderNodeContent(node, depth)}
|
|
25108
26813
|
${isPending ? this.renderLoadingIndicator() : A}
|
|
25109
26814
|
</li>
|
|
@@ -25371,6 +27076,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25371
27076
|
this.selectionMode = `single`;
|
|
25372
27077
|
this.interactionMode = `standard`;
|
|
25373
27078
|
this.itemWrap = `stop`;
|
|
27079
|
+
this.itemsDraggable = false;
|
|
25374
27080
|
this.#customWrappers = /* @__PURE__ */ new Map();
|
|
25375
27081
|
this.#wrappedElements = /* @__PURE__ */ new Set();
|
|
25376
27082
|
this.#animatedItems = /* @__PURE__ */ new WeakSet();
|
|
@@ -25401,7 +27107,41 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25401
27107
|
},
|
|
25402
27108
|
onStateChange: () => this._syncItemStates(),
|
|
25403
27109
|
itemWrap: this.itemWrap,
|
|
25404
|
-
hoverDisabled: () => this.#dragSelect.isDragging
|
|
27110
|
+
hoverDisabled: () => this.#dragSelect.isDragging || this.#nativeDrag.isDragging
|
|
27111
|
+
});
|
|
27112
|
+
this.#nativeDragging = false;
|
|
27113
|
+
this.#postDragSuppressTimer = 0;
|
|
27114
|
+
this.#nativeDrag = new ListNativeDragController(this, {
|
|
27115
|
+
source: `vertical-list`,
|
|
27116
|
+
isEnabled: () => this.itemsDraggable && this.selectionMode !== `none` && this._getVisibleItems().length > 0,
|
|
27117
|
+
resolveEventToKey: (target) => {
|
|
27118
|
+
if (!(target instanceof Element)) return void 0;
|
|
27119
|
+
const item = target.closest?.(ITEM_SELECTOR);
|
|
27120
|
+
if (!item || !this.contains(item) || this.#wrappedElements.has(item)) return void 0;
|
|
27121
|
+
return keyForElement(item);
|
|
27122
|
+
},
|
|
27123
|
+
prepareSelection: (originKey) => this.#prepareNativeDrag(originKey),
|
|
27124
|
+
getMetrics: () => ({}),
|
|
27125
|
+
getRenderer: () => this.dragPreviewRenderer,
|
|
27126
|
+
dispatch: (detail) => this._dispatchCancelable(`list-native-drag-start`, detail),
|
|
27127
|
+
onActiveChange: (active, originKey) => {
|
|
27128
|
+
this.#nativeDragging = active;
|
|
27129
|
+
this.toggleAttribute(`data-native-dragging`, active);
|
|
27130
|
+
for (const el of this._getVisibleItems()) el.toggleAttribute(`data-drag-origin`, active && originKey !== void 0 && keyForElement(el) === originKey);
|
|
27131
|
+
if (active) {
|
|
27132
|
+
const count = this.selection.selected.size;
|
|
27133
|
+
this.setAttribute(`aria-label`, count <= 1 ? `Dragging 1 item` : `Dragging ${count} items`);
|
|
27134
|
+
} else this.removeAttribute(`aria-label`);
|
|
27135
|
+
this.requestUpdate();
|
|
27136
|
+
},
|
|
27137
|
+
onEnd: () => {
|
|
27138
|
+
this.#nativeDragging = false;
|
|
27139
|
+
this.toggleAttribute(`data-native-dragging`, false);
|
|
27140
|
+
this.removeAttribute(`aria-label`);
|
|
27141
|
+
for (const el of this._getVisibleItems()) el.removeAttribute(`data-drag-origin`);
|
|
27142
|
+
this.#startPostDragSuppressTimer();
|
|
27143
|
+
},
|
|
27144
|
+
syncLightDomDraggable: () => this._syncNativeDraggable()
|
|
25405
27145
|
});
|
|
25406
27146
|
this.#dragSelect = new ListDragSelectController(this, {
|
|
25407
27147
|
getSurface: () => this.renderRoot.querySelector(`.container`),
|
|
@@ -25483,7 +27223,7 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25483
27223
|
}
|
|
25484
27224
|
};
|
|
25485
27225
|
this._onClick = (e) => {
|
|
25486
|
-
if (this.#dragSelect.isDragging) return;
|
|
27226
|
+
if (this.#dragSelect.isDragging || this.#nativeDrag.isDragging || this.#postDragSuppressTimer !== 0) return;
|
|
25487
27227
|
const item = this._findListItem(e.composedPath());
|
|
25488
27228
|
if (!item) return;
|
|
25489
27229
|
this._dispatch(`list-item-click`, { item });
|
|
@@ -25500,6 +27240,44 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25500
27240
|
#itemObserver;
|
|
25501
27241
|
/** Items that have already played (or been skipped for) their enter animation. */
|
|
25502
27242
|
#animatedItems;
|
|
27243
|
+
#nativeDragging;
|
|
27244
|
+
#postDragSuppressTimer;
|
|
27245
|
+
#nativeDrag;
|
|
27246
|
+
#prepareNativeDrag(originKey) {
|
|
27247
|
+
const visible = this._getVisibleItems();
|
|
27248
|
+
const originEl = visible.find((el) => keyForElement(el) === originKey);
|
|
27249
|
+
if (!originEl || !this._isCheckable(originEl)) return void 0;
|
|
27250
|
+
if (!this.selection.selected.has(originEl)) this.selection.replace(originEl);
|
|
27251
|
+
const selected = [];
|
|
27252
|
+
visible.forEach((el, index) => {
|
|
27253
|
+
if (!this.selection.selected.has(el)) return;
|
|
27254
|
+
selected.push({
|
|
27255
|
+
key: keyForElement(el) ?? originKey,
|
|
27256
|
+
index,
|
|
27257
|
+
item: el,
|
|
27258
|
+
element: el
|
|
27259
|
+
});
|
|
27260
|
+
});
|
|
27261
|
+
const origin = selected.find((entry) => entry.key === originKey);
|
|
27262
|
+
if (!origin) return void 0;
|
|
27263
|
+
return {
|
|
27264
|
+
origin,
|
|
27265
|
+
selected
|
|
27266
|
+
};
|
|
27267
|
+
}
|
|
27268
|
+
_syncNativeDraggable() {
|
|
27269
|
+
if (!this.isConnected) return;
|
|
27270
|
+
for (const el of this.querySelectorAll(ITEM_SELECTOR)) {
|
|
27271
|
+
if (this.#wrappedElements.has(el)) continue;
|
|
27272
|
+
if (el instanceof HTMLElement) el.draggable = this.itemsDraggable && this._isCheckable(el);
|
|
27273
|
+
}
|
|
27274
|
+
}
|
|
27275
|
+
#startPostDragSuppressTimer() {
|
|
27276
|
+
if (this.#postDragSuppressTimer) clearTimeout(this.#postDragSuppressTimer);
|
|
27277
|
+
this.#postDragSuppressTimer = window.setTimeout(() => {
|
|
27278
|
+
this.#postDragSuppressTimer = 0;
|
|
27279
|
+
}, 0);
|
|
27280
|
+
}
|
|
25503
27281
|
/** Live drag-select preview rect (surface-relative); the covered items carry `data-marquee`. */
|
|
25504
27282
|
#marqueeRect;
|
|
25505
27283
|
#dragSelect;
|
|
@@ -25567,6 +27345,10 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25567
27345
|
this.#unregisterSearchCommands?.();
|
|
25568
27346
|
this.#unregisterSearchCommands = void 0;
|
|
25569
27347
|
this.#searchRegistry = void 0;
|
|
27348
|
+
if (this.#postDragSuppressTimer) {
|
|
27349
|
+
clearTimeout(this.#postDragSuppressTimer);
|
|
27350
|
+
this.#postDragSuppressTimer = 0;
|
|
27351
|
+
}
|
|
25570
27352
|
}
|
|
25571
27353
|
/**
|
|
25572
27354
|
* Animate in items appended to the light DOM (however they got there —
|
|
@@ -25606,6 +27388,10 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25606
27388
|
}
|
|
25607
27389
|
this._syncItemStates();
|
|
25608
27390
|
} else if (changed.has(`checkboxRenderer`) && this.interactionMode === `checked`) this._syncCheckboxes();
|
|
27391
|
+
if (changed.has(`itemsDraggable`) || changed.has(`interactionMode`)) {
|
|
27392
|
+
this._syncNativeDraggable();
|
|
27393
|
+
this.#nativeDrag.refreshDraggable();
|
|
27394
|
+
}
|
|
25609
27395
|
}
|
|
25610
27396
|
/** The most recently selected item, or `undefined` if nothing is selected. */
|
|
25611
27397
|
get selectedItem() {
|
|
@@ -25875,6 +27661,14 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
25875
27661
|
composed: true
|
|
25876
27662
|
}));
|
|
25877
27663
|
}
|
|
27664
|
+
_dispatchCancelable(name, detail) {
|
|
27665
|
+
return this.dispatchEvent(new CustomEvent(name, {
|
|
27666
|
+
detail,
|
|
27667
|
+
bubbles: true,
|
|
27668
|
+
composed: true,
|
|
27669
|
+
cancelable: true
|
|
27670
|
+
}));
|
|
27671
|
+
}
|
|
25878
27672
|
_activateItem(item) {
|
|
25879
27673
|
if (this.interactionMode !== `manual`) this.selection.replace(item);
|
|
25880
27674
|
this._dispatch(`list-activate`, { item });
|
|
@@ -26010,6 +27804,10 @@ let VerticalListElement = class VerticalListElement extends i {
|
|
|
26010
27804
|
color: var(--item-text-selected);
|
|
26011
27805
|
}
|
|
26012
27806
|
|
|
27807
|
+
::slotted([data-drag-origin]) {
|
|
27808
|
+
opacity: 0.6;
|
|
27809
|
+
}
|
|
27810
|
+
|
|
26013
27811
|
/* checked mode: checkbox (injected into li) communicates selection — suppress bg highlight */
|
|
26014
27812
|
:host([interaction-mode="checked"]) ::slotted([data-selected]) {
|
|
26015
27813
|
background: transparent;
|
|
@@ -26056,6 +27854,12 @@ __decorate([property({
|
|
|
26056
27854
|
attribute: `search-modes`,
|
|
26057
27855
|
reflect: true
|
|
26058
27856
|
})], VerticalListElement.prototype, "searchModes", void 0);
|
|
27857
|
+
__decorate([property({
|
|
27858
|
+
type: Boolean,
|
|
27859
|
+
attribute: `items-draggable`,
|
|
27860
|
+
reflect: true
|
|
27861
|
+
})], VerticalListElement.prototype, "itemsDraggable", void 0);
|
|
27862
|
+
__decorate([property({ attribute: false })], VerticalListElement.prototype, "dragPreviewRenderer", void 0);
|
|
26059
27863
|
VerticalListElement = __decorate([safeCustomElement(`ixfx-vertical-list`)], VerticalListElement);
|
|
26060
27864
|
//#endregion
|
|
26061
27865
|
//#region src/grouped-item-lister/vertical-list-adapter.ts
|
|
@@ -28542,6 +30346,77 @@ function valueToRelative(value, min, max) {
|
|
|
28542
30346
|
const HANDLE_HIT_RADIUS = .06;
|
|
28543
30347
|
const DEFAULT_VALUE_MIN_FRACTION = .01;
|
|
28544
30348
|
const CHANGE_DEBOUNCE_MS = 150;
|
|
30349
|
+
/**
|
|
30350
|
+
* Evaluate a simple arithmetic expression (decimal numbers, `+ - * /` and
|
|
30351
|
+
* parentheses). Returns `undefined` when the string contains anything else.
|
|
30352
|
+
* Used for CSS `calc()`-derived values — a safe substitute for `new Function`.
|
|
30353
|
+
*/
|
|
30354
|
+
function evaluateArithmetic(source) {
|
|
30355
|
+
let pos = 0;
|
|
30356
|
+
const skipSpaces = () => {
|
|
30357
|
+
while (pos < source.length) {
|
|
30358
|
+
const c = source[pos];
|
|
30359
|
+
if (c !== ` ` && c !== `\t` && c !== `\n` && c !== `\r`) break;
|
|
30360
|
+
pos++;
|
|
30361
|
+
}
|
|
30362
|
+
};
|
|
30363
|
+
function parseNumber() {
|
|
30364
|
+
skipSpaces();
|
|
30365
|
+
const match = /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?/i.exec(source.slice(pos));
|
|
30366
|
+
if (!match) return void 0;
|
|
30367
|
+
pos += match[0].length;
|
|
30368
|
+
return Number.parseFloat(match[0]);
|
|
30369
|
+
}
|
|
30370
|
+
function parseFactor() {
|
|
30371
|
+
skipSpaces();
|
|
30372
|
+
const c = source[pos];
|
|
30373
|
+
if (c === `+` || c === `-`) {
|
|
30374
|
+
pos++;
|
|
30375
|
+
const value = parseFactor();
|
|
30376
|
+
return value === void 0 ? void 0 : c === `-` ? -value : value;
|
|
30377
|
+
}
|
|
30378
|
+
if (c === `(`) {
|
|
30379
|
+
pos++;
|
|
30380
|
+
const value = parseSum();
|
|
30381
|
+
if (value === void 0) return void 0;
|
|
30382
|
+
skipSpaces();
|
|
30383
|
+
if (source[pos] !== `)`) return void 0;
|
|
30384
|
+
pos++;
|
|
30385
|
+
return value;
|
|
30386
|
+
}
|
|
30387
|
+
return parseNumber();
|
|
30388
|
+
}
|
|
30389
|
+
function parseProduct() {
|
|
30390
|
+
let value = parseFactor();
|
|
30391
|
+
if (value === void 0) return void 0;
|
|
30392
|
+
while (true) {
|
|
30393
|
+
skipSpaces();
|
|
30394
|
+
const op = source[pos];
|
|
30395
|
+
if (op !== `*` && op !== `/`) return value;
|
|
30396
|
+
pos++;
|
|
30397
|
+
const rhs = parseFactor();
|
|
30398
|
+
if (rhs === void 0) return void 0;
|
|
30399
|
+
value = op === `*` ? value * rhs : value / rhs;
|
|
30400
|
+
}
|
|
30401
|
+
}
|
|
30402
|
+
function parseSum() {
|
|
30403
|
+
let value = parseProduct();
|
|
30404
|
+
if (value === void 0) return void 0;
|
|
30405
|
+
while (true) {
|
|
30406
|
+
skipSpaces();
|
|
30407
|
+
const op = source[pos];
|
|
30408
|
+
if (op !== `+` && op !== `-`) return value;
|
|
30409
|
+
pos++;
|
|
30410
|
+
const rhs = parseProduct();
|
|
30411
|
+
if (rhs === void 0) return void 0;
|
|
30412
|
+
value = op === `+` ? value + rhs : value - rhs;
|
|
30413
|
+
}
|
|
30414
|
+
}
|
|
30415
|
+
const value = parseSum();
|
|
30416
|
+
if (value === void 0) return void 0;
|
|
30417
|
+
skipSpaces();
|
|
30418
|
+
return pos === source.length ? value : void 0;
|
|
30419
|
+
}
|
|
28545
30420
|
let SliderInputElement = class SliderInputElement extends WheelNudgeMixin(i) {
|
|
28546
30421
|
#lanes;
|
|
28547
30422
|
/** Raw pole values: independent of which is "low" or "high". */
|
|
@@ -29455,14 +31330,10 @@ let SliderInputElement = class SliderInputElement extends WheelNudgeMixin(i) {
|
|
|
29455
31330
|
const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));
|
|
29456
31331
|
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
29457
31332
|
}
|
|
29458
|
-
const
|
|
29459
|
-
|
|
29460
|
-
|
|
29461
|
-
|
|
29462
|
-
} catch {
|
|
29463
|
-
const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));
|
|
29464
|
-
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
29465
|
-
}
|
|
31333
|
+
const result = evaluateArithmetic(val.replace(/var\(--value-relative\)/g, valueRelative).replace(/calc\s*\(([^)]+)\)/g, `$1`));
|
|
31334
|
+
if (result !== void 0) return Number.isNaN(result) ? defaultValue : result;
|
|
31335
|
+
const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));
|
|
31336
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
29466
31337
|
}
|
|
29467
31338
|
const parsed = Number.parseFloat(val);
|
|
29468
31339
|
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
@@ -29539,10 +31410,10 @@ let SliderInputElement = class SliderInputElement extends WheelNudgeMixin(i) {
|
|
|
29539
31410
|
proposedHigh = clamp$1(proposedHigh, this.min, this.max);
|
|
29540
31411
|
}
|
|
29541
31412
|
const lowKey = this.#lengthDragLowKey ?? this.#lowKey();
|
|
29542
|
-
this.#lengthDragHighKey ?? this.#highKey();
|
|
31413
|
+
const highKey = this.#lengthDragHighKey ?? this.#highKey();
|
|
29543
31414
|
const previous = this.#poles();
|
|
29544
31415
|
const newPoleA = lowKey === `a` ? proposedLow : proposedHigh;
|
|
29545
|
-
const newPoleB =
|
|
31416
|
+
const newPoleB = highKey === `b` ? proposedHigh : proposedLow;
|
|
29546
31417
|
this.#poleA = newPoleA;
|
|
29547
31418
|
this.#poleB = newPoleB;
|
|
29548
31419
|
if (this.valueMode === `triple` && this.#poleC !== void 0) {
|
|
@@ -33161,7 +35032,7 @@ function getScaleSteps(palette) {
|
|
|
33161
35032
|
function resolveCssVariable(el, prop) {
|
|
33162
35033
|
const style = getComputedStyle(el);
|
|
33163
35034
|
let value = style.getPropertyValue(prop).trim();
|
|
33164
|
-
const varRegex = /var\((--[\w-]+)(
|
|
35035
|
+
const varRegex = /var\((--[\w-]+)(?:,(.*))?\)/g;
|
|
33165
35036
|
for (let i = 0; i < 5 && value.includes(`var(`); i++) value = value.replace(varRegex, (_, varName, fallback) => {
|
|
33166
35037
|
const resolved = style.getPropertyValue(varName).trim();
|
|
33167
35038
|
if (resolved) return resolved;
|
|
@@ -42587,6 +44458,6 @@ function init() {
|
|
|
42587
44458
|
console.log(`Init`);
|
|
42588
44459
|
}
|
|
42589
44460
|
//#endregion
|
|
42590
|
-
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeKeyboardNavController, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createDataListSearchAdapter, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
44461
|
+
export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeKeyboardNavController, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, dropTargetFor, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
42591
44462
|
|
|
42592
44463
|
//# sourceMappingURL=index.js.map
|