@ixfx/components 0.15.2 → 0.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/bundle/index.d.ts +167 -13
  2. package/bundle/index.js +266 -228
  3. package/dist/ac-text.d.ts +1 -1
  4. package/dist/{ac-token-qEs3FsQv.d.ts → ac-token-Cq7lsYf-.d.ts} +1 -1
  5. package/dist/ac-token.d.ts +1 -1
  6. package/dist/colour-picker.d.ts +1 -1
  7. package/dist/crumbs.d.ts +2 -2
  8. package/dist/{data-grid-DmkId8bu.d.ts → data-grid-CbiubdG2.d.ts} +4 -4
  9. package/dist/data-grid.d.ts +2 -2
  10. package/dist/{detail-list-CmQqeXvp.d.ts → detail-list-ClkMV0SN.d.ts} +4 -4
  11. package/dist/detail-list.d.ts +3 -3
  12. package/dist/{flat-list-BmQBB3ZC.d.ts → flat-list-0xTZdXzh.d.ts} +3 -3
  13. package/dist/flat-list.d.ts +1 -1
  14. package/dist/{grid-list-BVsUEvgd.d.ts → grid-list-BnWJUIBC.d.ts} +3 -3
  15. package/dist/grid-list.d.ts +2 -2
  16. package/dist/{grouped-item-lister-DETte0Dh.d.ts → grouped-item-lister-Bhyo-dkH.d.ts} +1 -1
  17. package/dist/grouped-item-lister.d.ts +1 -1
  18. package/dist/{icon-CDGprSdE.d.ts → icon-DR_3rSyZ.d.ts} +1 -1
  19. package/dist/icons.d.ts +2 -2
  20. package/dist/incr-search.d.ts +1 -1
  21. package/dist/{index-DuhzWWTr.d.ts → index-BAuqR9El.d.ts} +28 -8
  22. package/dist/{index-BvoXLnBf.d.ts → index-BPTuCRGb.d.ts} +2 -2
  23. package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +1 -1
  24. package/dist/{index-DN2BWctP.d.ts → index-Bz3loIAf.d.ts} +1 -1
  25. package/dist/{index-UvnoZUAo.d.ts → index-CJ5fshD3.d.ts} +1 -1
  26. package/dist/{index-DxyyVqzA.d.ts → index-cnaRPQPp.d.ts} +2 -2
  27. package/dist/{index-CYndvTWH.d.ts → index-garxxqgV.d.ts} +1 -1
  28. package/dist/index.d.ts +152 -27
  29. package/dist/index.js +275 -65
  30. package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +1 -1
  31. package/dist/labelled-radial-input.d.ts +2 -2
  32. package/dist/labelled-range-input.d.ts +1 -1
  33. package/dist/labelled-slider-input.d.ts +1 -1
  34. package/dist/list-group-header.d.ts +1 -1
  35. package/dist/{list-native-drag-controller-NMspr0E1.d.ts → list-native-drag-controller-O2Nruqpi.d.ts} +1 -1
  36. package/dist/{menu-item-bF6narIz.d.ts → menu-item-B0zqw2xp.d.ts} +1 -1
  37. package/dist/menu.d.ts +2 -2
  38. package/dist/miller.d.ts +2 -2
  39. package/dist/panel.d.ts +1 -1
  40. package/dist/{split-layout-JK3xWVX2.d.ts → split-layout-C5SYbDrq.d.ts} +1 -1
  41. package/dist/split-layout.d.ts +1 -1
  42. package/dist/{tab-list-Df371rqw.d.ts → tab-list-wC0xNz1b.d.ts} +1 -1
  43. package/dist/tabs.d.ts +1 -1
  44. package/dist/{titlebar-Tqu-VvMU.d.ts → titlebar-B5zSTZnF.d.ts} +1 -1
  45. package/dist/titlebar.d.ts +1 -1
  46. package/dist/{tree-2_TRrLAV.js → tree-D8VxvR9u.js} +44 -5
  47. package/dist/{tree-component-CDsYTBDi.d.ts → tree-component-C6UHO-w9.d.ts} +12 -3
  48. package/dist/tree.d.ts +3 -3
  49. package/dist/tree.js +1 -1
  50. package/dist/{vertical-list-ztrdFvyT.d.ts → vertical-list-B8FoU-pU.d.ts} +2 -2
  51. package/dist/vertical-list.d.ts +2 -2
  52. package/docs-user/dock.md +62 -1
  53. package/docs-user/index.json +2 -2
  54. package/docs-user/tree.md +39 -0
  55. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import { t as CheckedSelect } from "./checked-select-CBUidG7n.js";
26
26
  import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-DwAa6RDh.js";
27
27
  import { LabelledRangeInput } from "./labelled-range-input.js";
28
28
  import { t as collectDataResult } from "./data-provider-35TyWclX.js";
29
- import { a as TreeDataModel, c as pruneDraggedDescendants, i as TreeDropController, n as TreeListElement, o as applyTreeDrop, r as TreeBaseElement, s as dropTargetFor, t as TreeController } from "./tree-2_TRrLAV.js";
29
+ import { a as TreeDataModel, c as pruneDraggedDescendants, i as TreeDropController, n as TreeListElement, o as applyTreeDrop, r as TreeBaseElement, s as dropTargetFor, t as TreeController } from "./tree-D8VxvR9u.js";
30
30
  import { t as scrollFadeStyles } from "./scroll-fade-Xx28D7mH.js";
31
31
  import { NarrowedTextElement } from "./narrowed-text.js";
32
32
  import { CrumbNavigationElement } from "./crumbs.js";
@@ -75,6 +75,7 @@ import { createCommandRegistry } from "@clinth/ui-commands";
75
75
  import { repeat } from "lit/directives/repeat.js";
76
76
  import { Trees } from "@ixfx/collections";
77
77
  import { clamp, clamper, scaler } from "@ixfx/numbers";
78
+ import { live } from "lit/directives/live.js";
78
79
  //#region src/bottom-drawer/bottom-drawer.ts
79
80
  /** Builds the command id for a named drawer's command, e.g. `inspector.expand`. */
80
81
  function bottomDrawerCommandId(name, command) {
@@ -2722,7 +2723,10 @@ function startDrag(panelId, sourceHost, pointerId, clientX, clientY, kind) {
2722
2723
  ghost: createGhostForPanel(sourceHost, panelId),
2723
2724
  outside: false
2724
2725
  };
2725
- for (const host of dragHosts) host.setDragActive(true);
2726
+ for (const host of dragHosts) host.setDragActive(true, hostsExchange(sourceHost, host) ? {
2727
+ panelId,
2728
+ kind
2729
+ } : void 0);
2726
2730
  activeDrag.ghost?.move(clientX, clientY);
2727
2731
  window.addEventListener(`pointermove`, onPointerMove);
2728
2732
  window.addEventListener(`pointerup`, onPointerUp);
@@ -2787,10 +2791,18 @@ function onKeyDown(event) {
2787
2791
  if (event.key !== `Escape`) return;
2788
2792
  endDrag();
2789
2793
  }
2794
+ /**
2795
+ * Whether `target` may receive panels dragged from `source`: always for the
2796
+ * same host; otherwise only when the source is not `isolated` and both hosts
2797
+ * share a `family`.
2798
+ */
2799
+ function hostsExchange(source, target) {
2800
+ if (source === target) return true;
2801
+ return !source.isolated && source.family === target.family;
2802
+ }
2790
2803
  function findDropZone(drag, clientX, clientY) {
2791
- const sourceIsolated = drag.sourceHost.isolated;
2792
2804
  for (const host of dragHosts) {
2793
- if (sourceIsolated && host !== drag.sourceHost) continue;
2805
+ if (!hostsExchange(drag.sourceHost, host)) continue;
2794
2806
  const zone = host.computeDropZone(clientX, clientY, drag.panelId, drag.kind);
2795
2807
  if (zone !== null) return zone;
2796
2808
  }
@@ -2956,6 +2968,8 @@ function replaceNodeContents(target, source) {
2956
2968
  else delete t.name;
2957
2969
  if (source.hideLabels !== void 0) t.hideLabels = source.hideLabels;
2958
2970
  else delete t.hideLabels;
2971
+ if (source.hideSingleTabStrip !== void 0) t.hideSingleTabStrip = source.hideSingleTabStrip;
2972
+ else delete t.hideSingleTabStrip;
2959
2973
  delete t.collapsed;
2960
2974
  delete t.preCollapseSize;
2961
2975
  if (source.collapsed !== void 0) t.collapsed = source.collapsed;
@@ -2970,6 +2984,8 @@ function replaceNodeContents(target, source) {
2970
2984
  delete stale.panels;
2971
2985
  delete stale.active;
2972
2986
  delete stale.name;
2987
+ delete stale.hideLabels;
2988
+ delete stale.hideSingleTabStrip;
2973
2989
  delete stale.collapsed;
2974
2990
  delete stale.preCollapseSize;
2975
2991
  }
@@ -3386,6 +3402,8 @@ function moveLeafNodeToEdge(root, ref, edge) {
3386
3402
  active: rest.active
3387
3403
  };
3388
3404
  if (rest.name !== void 0) remaining.name = rest.name;
3405
+ if (rest.hideLabels !== void 0) remaining.hideLabels = rest.hideLabels;
3406
+ if (rest.hideSingleTabStrip !== void 0) remaining.hideSingleTabStrip = rest.hideSingleTabStrip;
3389
3407
  if (rest.collapsed !== void 0) remaining.collapsed = rest.collapsed;
3390
3408
  if (rest.preCollapseSize !== void 0) remaining.preCollapseSize = rest.preCollapseSize;
3391
3409
  replaceNodeContents(root, {
@@ -3435,6 +3453,7 @@ function serializeNode(node) {
3435
3453
  };
3436
3454
  if (node.name !== void 0) out.name = node.name;
3437
3455
  if (node.hideLabels !== void 0) out.hideLabels = node.hideLabels;
3456
+ if (node.hideSingleTabStrip !== void 0) out.hideSingleTabStrip = node.hideSingleTabStrip;
3438
3457
  if (node.collapsed !== void 0) out.collapsed = node.collapsed;
3439
3458
  if (node.preCollapseSize !== void 0) out.preCollapseSize = node.preCollapseSize;
3440
3459
  return out;
@@ -3464,6 +3483,36 @@ function parseLayout(json) {
3464
3483
  return null;
3465
3484
  }
3466
3485
  }
3486
+ /** Every stack holding at least one panel, keyed by node identity. */
3487
+ function snapshotNonEmptyStacks(root) {
3488
+ const out = /* @__PURE__ */ new Map();
3489
+ const visit = (node) => {
3490
+ if (isStack(node)) {
3491
+ if (node.panels.length > 0) out.set(node, {
3492
+ name: node.name,
3493
+ key: node.panels.join(`\n`)
3494
+ });
3495
+ return;
3496
+ }
3497
+ node.children.forEach(visit);
3498
+ };
3499
+ visit(root);
3500
+ return out;
3501
+ }
3502
+ /**
3503
+ * Stacks in `before` that no longer hold their panels in `after`. A stack
3504
+ * node that was re-created with the same panels (some leaf moves rebuild
3505
+ * nodes) does not count as emptied.
3506
+ */
3507
+ function findEmptiedStacks(before, after) {
3508
+ const afterKeys = new Set([...after.values()].map((s) => s.key));
3509
+ const emptied = [];
3510
+ for (const [node, snapshot] of before) {
3511
+ if (after.has(node) || afterKeys.has(snapshot.key)) continue;
3512
+ emptied.push(snapshot);
3513
+ }
3514
+ return emptied;
3515
+ }
3467
3516
  //#endregion
3468
3517
  //#region src/tabs/tab-list-item.ts
3469
3518
  const resizeHandlers = /* @__PURE__ */ new WeakMap();
@@ -4077,6 +4126,8 @@ DockPanelElement = __decorate([safeCustomElement(`ixfx-dock-panel`)], DockPanelE
4077
4126
  const BAND = .25;
4078
4127
  /** Pointer movement threshold before a press becomes a dock drag (matches tab-list). */
4079
4128
  const DRAG_THRESHOLD_PX$3 = 5;
4129
+ /** Tab items of a strip, or the stand-in tab of a hidden strip's drop hint. */
4130
+ const STRIP_ITEMS = `ixfx-tab-list-item, .ghost-tab`;
4080
4131
  /** Tolerance (px) when matching a child gutter endpoint to a parent gutter line. */
4081
4132
  const JUNCTION_TOL_PX = 6;
4082
4133
  /** Junction points closer than this merge into one handle (a 4-way cross yields one per side). */
@@ -4087,10 +4138,15 @@ let DockHostElement = class DockHostElement extends LitElement {
4087
4138
  this.layout = null;
4088
4139
  this.accepts = `tabs horizontal vertical`;
4089
4140
  this.isolated = false;
4141
+ this.hideSingleTabStrip = false;
4142
+ this.family = ``;
4143
+ this.acceptsKinds = null;
4090
4144
  this._model = createStack([]);
4091
4145
  this._pool = [];
4092
4146
  this._dropZone = null;
4093
4147
  this._dragActive = false;
4148
+ this._dragPanel = null;
4149
+ this._liveStacks = /* @__PURE__ */ new Map();
4094
4150
  this._junctions = [];
4095
4151
  this._toolbarsOut = /* @__PURE__ */ new Map();
4096
4152
  this._leafContentRules = /* @__PURE__ */ new Map();
@@ -4103,6 +4159,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4103
4159
  this._toolbarObserver = null;
4104
4160
  this._panelObservers = /* @__PURE__ */ new Map();
4105
4161
  this._onDragStart = (event) => {
4162
+ if (event.composedPath().find((n) => n instanceof HTMLElement && n.tagName === `IXFX-DOCK-HOST`) !== this) return;
4106
4163
  const { panelId, pointerId, clientX, clientY } = event.detail;
4107
4164
  startDrag(panelId, this, pointerId, clientX, clientY, this._findPanelEl(panelId)?.kind);
4108
4165
  };
@@ -4178,17 +4235,18 @@ let DockHostElement = class DockHostElement extends LitElement {
4178
4235
  if (!(node instanceof HTMLElement)) continue;
4179
4236
  if (node.classList.contains(`list-toolbar`) || node.classList.contains(`close-btn`)) return;
4180
4237
  }
4181
- const item = path.find((node) => node instanceof HTMLElement && node.tagName === `IXFX-TAB-LIST-ITEM`) ?? null;
4182
- if (item === null || !item.id) return;
4183
- this._tabDragPending = {
4238
+ const item = tabItemIn(path);
4239
+ if (item === null) return;
4240
+ this._armPanelDrag(item.id, event);
4241
+ };
4242
+ this._onStripContextMenu = (event) => {
4243
+ const item = tabItemIn(event.composedPath());
4244
+ if (item === null) return;
4245
+ if (!this._emit(`dock-tab-contextmenu`, {
4184
4246
  panelId: item.id,
4185
- pointerId: event.pointerId,
4186
- startX: event.clientX,
4187
- startY: event.clientY
4188
- };
4189
- window.addEventListener(`pointermove`, this._onTabDragMove);
4190
- window.addEventListener(`pointerup`, this._onTabDragUp);
4191
- window.addEventListener(`pointercancel`, this._onTabDragUp);
4247
+ clientX: event.clientX,
4248
+ clientY: event.clientY
4249
+ }, true)) event.preventDefault();
4192
4250
  };
4193
4251
  this._onTabDragMove = (event) => {
4194
4252
  const pending = this._tabDragPending;
@@ -4217,6 +4275,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4217
4275
  connectedCallback() {
4218
4276
  super.connectedCallback();
4219
4277
  this._buildInitialModel();
4278
+ this._liveStacks = snapshotNonEmptyStacks(this._model);
4220
4279
  registerDockHost(this);
4221
4280
  this.addEventListener(`dock-panel-drag-start`, this._onDragStart);
4222
4281
  this._hostResizeObserver = new ResizeObserver(() => this._scheduleJunctions());
@@ -4255,8 +4314,25 @@ let DockHostElement = class DockHostElement extends LitElement {
4255
4314
  if (parsed) {
4256
4315
  this._model = parsed.root;
4257
4316
  this._mergePoolIntoModel();
4317
+ this._liveStacks = snapshotNonEmptyStacks(this._model);
4258
4318
  }
4259
4319
  }
4320
+ this._returnToolbarsOfHiddenStrips();
4321
+ }
4322
+ /**
4323
+ * A toolbar parked in a tab item would be destroyed with the strip, so
4324
+ * hand it back before a hidden strip stops rendering.
4325
+ */
4326
+ _returnToolbarsOfHiddenStrips() {
4327
+ for (const [panelId, nodes] of [...this._toolbarsOut]) {
4328
+ const path = findStackOf(this._model, panelId);
4329
+ const stack = path === null ? null : findNode(this._model, path);
4330
+ if (stack === null || !isStack(stack) || this._stripHidden(stack)) this._returnToolbar(panelId, nodes);
4331
+ }
4332
+ }
4333
+ /** Whether `stack` currently renders without a tab strip. */
4334
+ _stripHidden(stack) {
4335
+ return stack.panels.length === 1 && (stack.hideSingleTabStrip ?? this.hideSingleTabStrip);
4260
4336
  }
4261
4337
  updated(changed) {
4262
4338
  super.updated(changed);
@@ -4385,11 +4461,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4385
4461
  this._unobservePanel(el);
4386
4462
  this._toolbarsOut.delete(el.panelId);
4387
4463
  this._removeFromModel(el.panelId);
4388
- this.dispatchEvent(new CustomEvent(`dock-panel-removed`, {
4389
- detail: { panelId: el.panelId },
4390
- bubbles: true,
4391
- composed: true
4392
- }));
4464
+ this._emitRemoved(el.panelId);
4393
4465
  structuralChange = true;
4394
4466
  }
4395
4467
  for (const el of current) {
@@ -4397,11 +4469,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4397
4469
  if (!collectPanelIds(this._model).includes(el.panelId)) {
4398
4470
  this._appendPanelToFirstStack(el.panelId);
4399
4471
  normalize(this._model);
4400
- this.dispatchEvent(new CustomEvent(`dock-panel-added`, {
4401
- detail: { panelId: el.panelId },
4402
- bubbles: true,
4403
- composed: true
4404
- }));
4472
+ this._emitAdded(el.panelId);
4405
4473
  structuralChange = true;
4406
4474
  }
4407
4475
  }
@@ -4419,6 +4487,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4419
4487
  this._loadGeneration++;
4420
4488
  this._model = normalize(cloneNode(layout.root));
4421
4489
  this._mergePoolIntoModel();
4490
+ this._liveStacks = snapshotNonEmptyStacks(this._model);
4422
4491
  this.requestUpdate();
4423
4492
  this._emitChange();
4424
4493
  }
@@ -4478,11 +4547,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4478
4547
  } else this._appendPanelToFirstStack(el.panelId);
4479
4548
  normalize(this._model);
4480
4549
  this.requestUpdate();
4481
- this.dispatchEvent(new CustomEvent(`dock-panel-added`, {
4482
- detail: { panelId: el.panelId },
4483
- bubbles: true,
4484
- composed: true
4485
- }));
4550
+ this._emitAdded(el.panelId);
4486
4551
  this._emitChange();
4487
4552
  return true;
4488
4553
  }
@@ -4505,11 +4570,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4505
4570
  this._scanPanels().find((p) => p.panelId === panelId)?.remove();
4506
4571
  normalize(this._model);
4507
4572
  this.requestUpdate();
4508
- this.dispatchEvent(new CustomEvent(`dock-panel-removed`, {
4509
- detail: { panelId },
4510
- bubbles: true,
4511
- composed: true
4512
- }));
4573
+ this._emitRemoved(panelId);
4513
4574
  this._emitChange();
4514
4575
  return true;
4515
4576
  }
@@ -4752,7 +4813,10 @@ let DockHostElement = class DockHostElement extends LitElement {
4752
4813
  * {@link endExternalDrop} when the drag leaves or ends.
4753
4814
  */
4754
4815
  previewExternalDrop(clientX, clientY, panelId = `__external__`, kind) {
4755
- this.setDragActive(true);
4816
+ this.setDragActive(true, {
4817
+ panelId,
4818
+ kind
4819
+ });
4756
4820
  const zone = this.computeDropZone(clientX, clientY, panelId, kind);
4757
4821
  this.setDropZone(zone);
4758
4822
  return zone === null ? null : zoneToTarget(zone);
@@ -4768,11 +4832,12 @@ let DockHostElement = class DockHostElement extends LitElement {
4768
4832
  * panel lands where a drop there would put it (respecting `accepts` /
4769
4833
  * `canAccept` and leaf content rules); without them, or when the point
4770
4834
  * misses the host, it goes into the first stack admitting its kind.
4771
- * Returns the created element, or null when a panel
4772
- * with that id is already docked here.
4835
+ * Returns the created element, or null when a panel with that id is
4836
+ * already docked here or its kind is refused by `acceptsKinds`.
4773
4837
  */
4774
4838
  acceptExternalPanel(snapshot, at) {
4775
4839
  if (collectPanelIds(this._model).includes(snapshot.panelId)) return null;
4840
+ if (this.acceptsKinds !== null && !this.acceptsKinds.includes(normalizeKind(snapshot.kind))) return null;
4776
4841
  const el = document.createElement(`ixfx-dock-panel`);
4777
4842
  el.panelId = snapshot.panelId;
4778
4843
  if (snapshot.title !== void 0) el.title = snapshot.title;
@@ -4783,20 +4848,16 @@ let DockHostElement = class DockHostElement extends LitElement {
4783
4848
  if (`accepts` in snapshot && snapshot.accepts) el.setAttribute(`accepts`, snapshot.accepts);
4784
4849
  if (`contentHTML` in snapshot && snapshot.contentHTML) el.innerHTML = snapshot.contentHTML;
4785
4850
  this._returnAllToolbars();
4786
- this.appendChild(el);
4787
4851
  this._pool = [...this._pool, el];
4788
4852
  this._appendPanelToFirstStack(el.panelId);
4853
+ this.appendChild(el);
4789
4854
  normalize(this._model);
4790
4855
  this.endExternalDrop();
4791
4856
  const zone = at ? this.computeDropZone(at.clientX, at.clientY, el.panelId) : null;
4792
4857
  if (zone !== null) this._applyZone(el.panelId, zone);
4793
4858
  normalize(this._model);
4794
4859
  this.requestUpdate();
4795
- this.dispatchEvent(new CustomEvent(`dock-panel-added`, {
4796
- detail: { panelId: el.panelId },
4797
- bubbles: true,
4798
- composed: true
4799
- }));
4860
+ this._emitAdded(el.panelId);
4800
4861
  this._emitChange();
4801
4862
  return el;
4802
4863
  }
@@ -4815,6 +4876,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4815
4876
  w: r.width,
4816
4877
  h: r.height
4817
4878
  });
4879
+ const splitsAllowed = tokenAllows(this.accepts, `horizontal`) || tokenAllows(this.accepts, `vertical`);
4818
4880
  for (const path of collectStackPaths(this._model)) {
4819
4881
  const leaf = this.shadowRoot?.querySelector(`[data-dock-path="${path.join(`-`)}"]`);
4820
4882
  if (!leaf) continue;
@@ -4822,7 +4884,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4822
4884
  if (clientX < leafRect.left || clientX > leafRect.right || clientY < leafRect.top || clientY > leafRect.bottom) continue;
4823
4885
  const stack = findNode(this._model, path);
4824
4886
  if (stack === null || !isStack(stack)) continue;
4825
- const strip = leaf.querySelector(`ixfx-tab-list`);
4887
+ const strip = leaf.querySelector(`ixfx-tab-list`) ?? leaf.querySelector(`.ghost-strip`);
4826
4888
  if (strip !== null) {
4827
4889
  const stripRect = strip.getBoundingClientRect();
4828
4890
  if (clientX >= stripRect.left && clientX <= stripRect.right && clientY >= stripRect.top && clientY <= stripRect.bottom) {
@@ -4841,7 +4903,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4841
4903
  }
4842
4904
  const relX = (clientX - leafRect.left) / Math.max(leafRect.width, 1);
4843
4905
  const relY = (clientY - leafRect.top) / Math.max(leafRect.height, 1);
4844
- if (relX >= BAND && relX <= .75 && relY >= BAND && relY <= .75) {
4906
+ if (!splitsAllowed || relX >= BAND && relX <= .75 && relY >= BAND && relY <= .75) {
4845
4907
  const zone = {
4846
4908
  host: this,
4847
4909
  operation: `tabs`,
@@ -4955,6 +5017,7 @@ let DockHostElement = class DockHostElement extends LitElement {
4955
5017
  return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;
4956
5018
  }
4957
5019
  _zoneAllowed(panelId, zone, kind) {
5020
+ if (this.acceptsKinds !== null && !collectPanelIds(this._model).includes(panelId) && !this.acceptsKinds.includes(normalizeKind(kind))) return false;
4958
5021
  if (!tokenAllows(this.accepts, operationToToken(zone.operation))) return false;
4959
5022
  const stack = findNode(this._model, zone.targetPath);
4960
5023
  if (stack !== null && isStack(stack) && stack.panels.length === 1) {
@@ -4981,6 +5044,11 @@ let DockHostElement = class DockHostElement extends LitElement {
4981
5044
  }
4982
5045
  this._applyZone(panelId, zone, sourceHost === void 0 || sourceHost === this);
4983
5046
  this._commit();
5047
+ if (sourceHost !== void 0 && sourceHost !== this) this._emit(`dock-panel-moved`, {
5048
+ panelId,
5049
+ sourceHost,
5050
+ targetHost: this
5051
+ });
4984
5052
  }
4985
5053
  /**
4986
5054
  * Move `panelId` (already present somewhere in the model) to the position
@@ -5021,26 +5089,34 @@ let DockHostElement = class DockHostElement extends LitElement {
5021
5089
  }
5022
5090
  normalize(this._model);
5023
5091
  this._pool = this._pool.filter((p) => p !== el);
5024
- if (el !== void 0) target.adoptPanelElement(el);
5092
+ this._toolbarsOut.delete(panelId);
5093
+ this._emitRemoved(panelId, target);
5094
+ if (el !== void 0) target.adoptPanelElement(el, this);
5025
5095
  this.requestUpdate();
5096
+ this._emitChange();
5026
5097
  }
5027
- /** Adopt a panel element from another host (the one sanctioned reparent). */
5028
- adoptPanelElement(el) {
5029
- this.appendChild(el);
5098
+ /**
5099
+ * Adopt a panel element from another host (the one sanctioned reparent).
5100
+ * `sourceHost` is reported in `dock-panel-added`.
5101
+ */
5102
+ adoptPanelElement(el, sourceHost = null) {
5030
5103
  if (!this._pool.some((p) => p.panelId === el.panelId)) this._pool = [...this._pool, el];
5031
- this._appendPanelToFirstStack(el.panelId);
5104
+ if (!collectPanelIds(this._model).includes(el.panelId)) this._appendPanelToFirstStack(el.panelId);
5105
+ this.appendChild(el);
5032
5106
  normalize(this._model);
5033
- this.dispatchEvent(new CustomEvent(`dock-panel-added`, {
5034
- detail: { panelId: el.panelId },
5035
- bubbles: true,
5036
- composed: true
5037
- }));
5107
+ this._emitAdded(el.panelId, sourceHost);
5038
5108
  }
5039
- setDragActive(active) {
5109
+ /**
5110
+ * `drag` names the panel in flight when this host may receive it; it drives
5111
+ * the drop hint over a leaf whose tab strip is hidden.
5112
+ */
5113
+ setDragActive(active, drag) {
5114
+ const next = active && drag !== void 0 ? drag : null;
5040
5115
  if (this._dragActive !== active) {
5041
5116
  this._dragActive = active;
5042
5117
  this.requestUpdate();
5043
5118
  }
5119
+ if (this._dragPanel?.panelId !== next?.panelId || this._dragPanel?.kind !== next?.kind) this._dragPanel = next;
5044
5120
  }
5045
5121
  setDropZone(zone) {
5046
5122
  if (this._dropZone !== zone) {
@@ -5132,6 +5208,29 @@ let DockHostElement = class DockHostElement extends LitElement {
5132
5208
  }
5133
5209
  }
5134
5210
  }
5211
+ /**
5212
+ * Start a panel drag from an app-supplied handle — the way to move a panel
5213
+ * whose tab strip is hidden. Call it from the handle's `pointerdown`. The
5214
+ * drag begins once the pointer moves a few pixels (a plain click is left
5215
+ * alone) and then behaves exactly like a tab-item drag. Returns false when
5216
+ * the panel is not docked here or the press is not a primary-button press.
5217
+ */
5218
+ beginPanelDrag(panelId, event) {
5219
+ if (event.button !== 0 || !collectPanelIds(this._model).includes(panelId)) return false;
5220
+ this._armPanelDrag(panelId, event);
5221
+ return true;
5222
+ }
5223
+ _armPanelDrag(panelId, event) {
5224
+ this._tabDragPending = {
5225
+ panelId,
5226
+ pointerId: event.pointerId,
5227
+ startX: event.clientX,
5228
+ startY: event.clientY
5229
+ };
5230
+ window.addEventListener(`pointermove`, this._onTabDragMove);
5231
+ window.addEventListener(`pointerup`, this._onTabDragUp);
5232
+ window.addEventListener(`pointercancel`, this._onTabDragUp);
5233
+ }
5135
5234
  _teardownTabDragListeners() {
5136
5235
  window.removeEventListener(`pointermove`, this._onTabDragMove);
5137
5236
  window.removeEventListener(`pointerup`, this._onTabDragUp);
@@ -5213,13 +5312,44 @@ let DockHostElement = class DockHostElement extends LitElement {
5213
5312
  _returnAllToolbars() {
5214
5313
  for (const [panelId, nodes] of [...this._toolbarsOut]) this._returnToolbar(panelId, nodes);
5215
5314
  }
5216
- _emitChange() {
5217
- this.dispatchEvent(new CustomEvent(`dock-change`, {
5218
- detail: { layout: this.saveLayout() },
5315
+ /** Dispatch a bubbling, composed event; returns false when a cancelable one was cancelled. */
5316
+ _emit(type, detail, cancelable = false) {
5317
+ return this.dispatchEvent(new CustomEvent(type, {
5318
+ detail,
5219
5319
  bubbles: true,
5220
- composed: true
5320
+ composed: true,
5321
+ cancelable
5221
5322
  }));
5222
5323
  }
5324
+ _emitAdded(panelId, sourceHost = null) {
5325
+ this._emit(`dock-panel-added`, {
5326
+ panelId,
5327
+ sourceHost,
5328
+ targetHost: this
5329
+ });
5330
+ }
5331
+ _emitRemoved(panelId, targetHost = null) {
5332
+ this._emit(`dock-panel-removed`, {
5333
+ panelId,
5334
+ sourceHost: this,
5335
+ targetHost
5336
+ });
5337
+ }
5338
+ /** Announce `dock-stack-empty` for each stack that lost its last panel since the last change. */
5339
+ _announceEmptiedStacks() {
5340
+ const now = snapshotNonEmptyStacks(this._model);
5341
+ const emptied = findEmptiedStacks(this._liveStacks, now);
5342
+ this._liveStacks = now;
5343
+ for (const stack of emptied) this._emit(`dock-stack-empty`, {
5344
+ name: stack.name ?? null,
5345
+ hostEmpty: now.size === 0
5346
+ });
5347
+ }
5348
+ _emitChange() {
5349
+ const layout = this.saveLayout();
5350
+ this._announceEmptiedStacks();
5351
+ this._emit(`dock-change`, { layout });
5352
+ }
5223
5353
  render() {
5224
5354
  return html`
5225
5355
  <div class="root">
@@ -5255,7 +5385,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5255
5385
  <ixfx-split-layout
5256
5386
  class="split"
5257
5387
  direction=${node.direction}
5258
- size=${size === void 0 ? nothing : String(size)}
5388
+ size=${size === void 0 ? nothing : live(String(size))}
5259
5389
  style=${`--split-gutter-size: var(--dock-split-bar-size, 2px); --split-collapsed-size: var(--dock-collapsed-size, 40px)`}
5260
5390
  data-dock-path=${pathStr}
5261
5391
  data-dock-gen=${this._loadGeneration}
@@ -5278,7 +5408,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5278
5408
  class="leaf"
5279
5409
  data-dock-path=${pathStr}
5280
5410
  data-dock-name=${stack.name ?? nothing}
5281
- size=${size === void 0 ? nothing : String(size)}
5411
+ size=${size === void 0 ? nothing : live(String(size))}
5282
5412
  min=${collapsible ? `1px` : nothing}
5283
5413
  when-small=${collapsible ? `collapse` : nothing}
5284
5414
  ?collapsed=${stack.collapsed === true}
@@ -5290,6 +5420,12 @@ let DockHostElement = class DockHostElement extends LitElement {
5290
5420
  </div>
5291
5421
  `);
5292
5422
  const toolbarSlot = stack.name !== void 0 && this._toolbarSlots.has(`toolbar-${stack.name}`) ? html`<slot name="toolbar-${stack.name}" slot="toolbar"></slot>` : nothing;
5423
+ if (this._stripHidden(stack)) return leafAttrs(html`
5424
+ ${this._renderDropHint(stack, path)}
5425
+ <div class="leaf-body">
5426
+ <slot name="dock-panel-${stack.active}"></slot>
5427
+ </div>
5428
+ `);
5293
5429
  return leafAttrs(html`
5294
5430
  <ixfx-tab-list
5295
5431
  class="strip"
@@ -5299,6 +5435,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5299
5435
  ?hide-labels=${stack.hideLabels === true}
5300
5436
  @change=${(e) => this._onTabChange(e, path)}
5301
5437
  @pointerdown=${this._onStripPointerDown}
5438
+ @contextmenu=${this._onStripContextMenu}
5302
5439
  >
5303
5440
  ${repeat(stack.panels, (id) => id, (id) => this._renderTabItem(stack, id))}
5304
5441
  ${toolbarSlot}
@@ -5307,6 +5444,34 @@ let DockHostElement = class DockHostElement extends LitElement {
5307
5444
  <slot name="dock-panel-${stack.active}"></slot>
5308
5445
  </div>
5309
5446
  `);
5447
+ }
5448
+ /**
5449
+ * While a drag that this leaf would accept is in flight, overlay a compact
5450
+ * strip stand-in on the hidden strip's slot: it shows where the dropped tab
5451
+ * will land (the overlay takes no layout space, so nothing jumps).
5452
+ */
5453
+ _renderDropHint(stack, path) {
5454
+ const drag = this._dragPanel;
5455
+ if (!this._dragActive || drag === null || stack.panels[0] === drag.panelId) return nothing;
5456
+ const probe = {
5457
+ host: this,
5458
+ operation: `tabs`,
5459
+ targetPath: path,
5460
+ side: `after`,
5461
+ rect: {
5462
+ x: 0,
5463
+ y: 0,
5464
+ w: 0,
5465
+ h: 0
5466
+ }
5467
+ };
5468
+ if (!this._zoneAllowed(drag.panelId, probe, drag.kind)) return nothing;
5469
+ const id = stack.panels[0];
5470
+ return html`
5471
+ <div class="ghost-strip" part="drop-hint">
5472
+ <span class="ghost-tab">${this._findPanelEl(id)?.title || id}</span>
5473
+ </div>
5474
+ `;
5310
5475
  }
5311
5476
  _renderTabItem(stack, panelId) {
5312
5477
  const el = this._findPanelEl(panelId);
@@ -5321,7 +5486,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5321
5486
  `;
5322
5487
  }
5323
5488
  _stripCaretRect(strip, gapIndex, hostRect) {
5324
- const items = Array.from(strip.querySelectorAll(`ixfx-tab-list-item`));
5489
+ const items = Array.from(strip.querySelectorAll(STRIP_ITEMS));
5325
5490
  if (items.length === 0) return void 0;
5326
5491
  const index = Math.max(0, Math.min(gapIndex ?? items.length, items.length));
5327
5492
  const edge = index < items.length ? items[index].getBoundingClientRect().left : items[items.length - 1].getBoundingClientRect().right;
@@ -5368,6 +5533,7 @@ let DockHostElement = class DockHostElement extends LitElement {
5368
5533
  min-height: 0;
5369
5534
  box-sizing: border-box;
5370
5535
  overflow: hidden;
5536
+ position: relative;
5371
5537
  border: 1px solid var(--surface-4);
5372
5538
  border-radius: var(--radius-m);
5373
5539
  }
@@ -5405,6 +5571,32 @@ let DockHostElement = class DockHostElement extends LitElement {
5405
5571
  padding-right: var(--space-xs);
5406
5572
  }
5407
5573
 
5574
+ /* Drop hint over a hidden strip: overlaid, so it reserves no height. */
5575
+ .ghost-strip {
5576
+ position: absolute;
5577
+ inset: 0 0 auto 0;
5578
+ height: var(--dock-tab-height, 30px);
5579
+ z-index: 1;
5580
+ display: flex;
5581
+ align-items: center;
5582
+ box-sizing: border-box;
5583
+ padding: 0 var(--space-s);
5584
+ background: var(--surface-3);
5585
+ border-bottom: 1px solid var(--surface-4);
5586
+ color: var(--surface-3-text);
5587
+ font-size: var(--text-m);
5588
+ pointer-events: none;
5589
+ }
5590
+
5591
+ .ghost-tab {
5592
+ overflow: hidden;
5593
+ text-overflow: ellipsis;
5594
+ white-space: nowrap;
5595
+ text-decoration: underline;
5596
+ text-decoration-thickness: 2px;
5597
+ text-underline-offset: 4px;
5598
+ }
5599
+
5408
5600
  .leaf-body {
5409
5601
  flex: 1;
5410
5602
  min-height: 0;
@@ -5496,11 +5688,24 @@ __decorate([property({
5496
5688
  type: Boolean,
5497
5689
  attribute: `isolated`
5498
5690
  })], DockHostElement.prototype, "isolated", void 0);
5691
+ __decorate([property({
5692
+ type: Boolean,
5693
+ attribute: `hide-single-tab-strip`
5694
+ })], DockHostElement.prototype, "hideSingleTabStrip", void 0);
5695
+ __decorate([property({
5696
+ type: String,
5697
+ attribute: `family`
5698
+ })], DockHostElement.prototype, "family", void 0);
5699
+ __decorate([property({
5700
+ attribute: `accepts-kinds`,
5701
+ converter: { fromAttribute: (value) => value === null ? null : value.split(/\s+/).filter((k) => k.length > 0) }
5702
+ })], DockHostElement.prototype, "acceptsKinds", void 0);
5499
5703
  __decorate([property({ attribute: false })], DockHostElement.prototype, "canAccept", void 0);
5500
5704
  __decorate([state()], DockHostElement.prototype, "_model", void 0);
5501
5705
  __decorate([state()], DockHostElement.prototype, "_pool", void 0);
5502
5706
  __decorate([state()], DockHostElement.prototype, "_dropZone", void 0);
5503
5707
  __decorate([state()], DockHostElement.prototype, "_dragActive", void 0);
5708
+ __decorate([state()], DockHostElement.prototype, "_dragPanel", void 0);
5504
5709
  __decorate([state()], DockHostElement.prototype, "_junctions", void 0);
5505
5710
  DockHostElement = __decorate([safeCustomElement(`ixfx-dock-host`)], DockHostElement);
5506
5711
  /** `split-horizontal` = horizontal divider = panels stacked vertically. */
@@ -5550,13 +5755,18 @@ function normalizeKind(kind) {
5550
5755
  function parsePath(pathStr) {
5551
5756
  return pathStr.length === 0 ? [] : pathStr.split(`-`).filter((s) => s.length > 0).map(Number);
5552
5757
  }
5758
+ /** The tab item in an event's composed path, if it has a panel id. */
5759
+ function tabItemIn(path) {
5760
+ const item = path.find((node) => node instanceof HTMLElement && node.tagName === `IXFX-TAB-LIST-ITEM`);
5761
+ return item !== void 0 && item.id ? item : null;
5762
+ }
5553
5763
  /** Toolbar-slot light children of a dock panel. */
5554
5764
  function toolbarNodesOf(el) {
5555
5765
  return Array.from(el.children).filter((c) => c instanceof HTMLElement && c.getAttribute(`slot`) === `toolbar`);
5556
5766
  }
5557
5767
  /** Nearest strip gap to the pointer (reuses the tab-list midpoint rule). */
5558
5768
  function computeStripGapIndex(strip, clientX, _clientY) {
5559
- const items = Array.from(strip.querySelectorAll(`ixfx-tab-list-item`));
5769
+ const items = Array.from(strip.querySelectorAll(STRIP_ITEMS));
5560
5770
  if (items.length === 0) return 0;
5561
5771
  for (let i = 0; i < items.length; i++) {
5562
5772
  const r = items[i].getBoundingClientRect();
@@ -16056,4 +16266,4 @@ function init() {
16056
16266
  console.log(`Init`);
16057
16267
  }
16058
16268
  //#endregion
16059
- export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, CheckedSelect, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DEFAULT_SIBLING_SPACING, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EMPTY_GROUP_LABEL, EditableLabel, EditableNumber, FlatListElement, FormElement, FormGroupElement, FormOptionsElement, FormPartElement, FormRowElement, GridListElement, GroupedItemListerElement, HyperbolicTreeListElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IcicleTreeListElement, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListGroupHeaderElement, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, MulticolListElement, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, ShapefillValueElement, 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, TreemapListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applyIsometry, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clampToDisk, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, composeIsometry, computeCanonicalPositions, computeColour, computeHyperbolicLayout, computeIcicleLayout, computeLeafGeoms, computeTreemapLayout, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, decomposeViewIsometry, defaultGroupLabel, distribute, dropTargetFor, euclideanRadiusForHyperbolicDistance, extractStack, findHyperbolicIdOf, findHyperbolicKeyPath, findHyperbolicNode, findHyperbolicPath, findHyperbolicPathById, findIcicleNode, findIciclePath, findNode, findPanelNode, findParentOf, findStackOf, findStackPathByName, findTreemapNode, findTreemapPath, geodesicInterpolate, geodesicPath, geodesicSegment, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, hyperbolicBranchId, hyperbolicChildIds, hyperbolicDistanceForEuclideanRadius, hyperbolicIdDepth, hyperbolicRelativeFrame, iconBus, identityIsometry, init, insertBeside, invertIsometry, isDragging, isHyperbolicDescendantId, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, mobiusAdd, mobiusFromOrigin, mobiusToOrigin, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, norm, normalise, normaliseValue, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, partitionByGroup, poincareDistance, pointerOverAnyHost, prefersReducedMotion, preserveRestoreWeights, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveGroupKey, resolveLeafPath, resolveTracks, rotationIsometry, serializeLayout, setActive, setIconFont, setPanelRestoreWeight, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toGroupKey, toSnapshot, toggleInSet, toolbarGapIndex, translationFromOrigin, viewIsometry, walk, wrapRoot };
16269
+ export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, CheckedSelect, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DEFAULT_SIBLING_SPACING, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EMPTY_GROUP_LABEL, EditableLabel, EditableNumber, FlatListElement, FormElement, FormGroupElement, FormOptionsElement, FormPartElement, FormRowElement, GridListElement, GroupedItemListerElement, HyperbolicTreeListElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IcicleTreeListElement, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListGroupHeaderElement, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, MulticolListElement, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, ShapefillValueElement, 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, TreemapListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applyIsometry, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clampToDisk, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, composeIsometry, computeCanonicalPositions, computeColour, computeHyperbolicLayout, computeIcicleLayout, computeLeafGeoms, computeTreemapLayout, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, decomposeViewIsometry, defaultGroupLabel, distribute, dropTargetFor, euclideanRadiusForHyperbolicDistance, extractStack, findEmptiedStacks, findHyperbolicIdOf, findHyperbolicKeyPath, findHyperbolicNode, findHyperbolicPath, findHyperbolicPathById, findIcicleNode, findIciclePath, findNode, findPanelNode, findParentOf, findStackOf, findStackPathByName, findTreemapNode, findTreemapPath, geodesicInterpolate, geodesicPath, geodesicSegment, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, hyperbolicBranchId, hyperbolicChildIds, hyperbolicDistanceForEuclideanRadius, hyperbolicIdDepth, hyperbolicRelativeFrame, iconBus, identityIsometry, init, insertBeside, invertIsometry, isDragging, isHyperbolicDescendantId, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, mobiusAdd, mobiusFromOrigin, mobiusToOrigin, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, norm, normalise, normaliseValue, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, partitionByGroup, poincareDistance, pointerOverAnyHost, prefersReducedMotion, preserveRestoreWeights, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveGroupKey, resolveLeafPath, resolveTracks, rotationIsometry, serializeLayout, setActive, setIconFont, setPanelRestoreWeight, snapshotNonEmptyStacks, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toGroupKey, toSnapshot, toggleInSet, toolbarGapIndex, translationFromOrigin, viewIsometry, walk, wrapRoot };