@ixfx/components 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +259 -44
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +828 -125
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +1 -1
- package/dist/ac-text.js +1 -1
- package/dist/{ac-token-BAa6ke09.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
- package/dist/{ac-token-BAa6ke09.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
- package/dist/ac-token.d.ts +1 -1
- package/dist/ac-token.js +1 -1
- package/dist/{button-Dat2yHAU.js → button-DsFbV4XD.js} +3 -3
- package/dist/{button-Dat2yHAU.js.map → button-DsFbV4XD.js.map} +1 -1
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +1 -1
- package/dist/{colour-picker-BSDBL-QL.js → colour-picker-Ddsk-7E_.js} +2 -2
- package/dist/{colour-picker-BSDBL-QL.js.map → colour-picker-Ddsk-7E_.js.map} +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/crumbs.js +1 -1
- package/dist/{data-grid-C8qIo1-u.d.ts → data-grid-Bh4YrQGK.d.ts} +2 -2
- package/dist/{data-grid-C8qIo1-u.d.ts.map → data-grid-Bh4YrQGK.d.ts.map} +1 -1
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +1 -1
- package/dist/{defaults-BkWCPJFL.js → defaults-BJwDsMH4.js} +26 -2
- package/dist/defaults-BJwDsMH4.js.map +1 -0
- package/dist/{hex-editor-Bk6rxhfg.js → hex-editor-BiRfwTz1.js} +2 -2
- package/dist/{hex-editor-Bk6rxhfg.js.map → hex-editor-BiRfwTz1.js.map} +1 -1
- package/dist/hex.js +1 -1
- package/dist/{icon-DpA9x2Ve.d.ts → icon-CDGprSdE.d.ts} +1 -12
- package/dist/icon-CDGprSdE.d.ts.map +1 -0
- package/dist/{icon-CvnPanhA.js → icon-DcEEGQa_.js} +37 -8
- package/dist/icon-DcEEGQa_.js.map +1 -0
- package/dist/icons.d.ts +3 -3
- package/dist/icons.js +4 -4
- package/dist/icons.js.map +1 -1
- package/dist/{index-CKtLhgYj.d.ts → index-9AhaHIT2.d.ts} +3 -3
- package/dist/{index-CKtLhgYj.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
- package/dist/{index-BtGFYfaK.d.ts → index-CS9yM8L-.d.ts} +14 -4
- package/dist/index-CS9yM8L-.d.ts.map +1 -0
- package/dist/{index-CG2vIgPv.d.ts → index-UvnoZUAo.d.ts} +4 -4
- package/dist/{index-CG2vIgPv.d.ts.map → index-UvnoZUAo.d.ts.map} +1 -1
- package/dist/index.d.ts +231 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +701 -110
- package/dist/index.js.map +1 -1
- package/dist/labelled-radial-input.d.ts +1 -1
- package/dist/labelled-radial-input.js +1 -1
- package/dist/{labelled-slider-input-DzigjMwP.js → labelled-slider-input-BInB5GKL.js} +3 -3
- package/dist/{labelled-slider-input-DzigjMwP.js.map → labelled-slider-input-BInB5GKL.js.map} +1 -1
- package/dist/labelled-slider-input.d.ts +1 -1
- package/dist/labelled-slider-input.js +1 -1
- package/dist/{menu-BjRvlgPy.js → menu-CXDFJxNm.js} +3 -3
- package/dist/{menu-BjRvlgPy.js.map → menu-CXDFJxNm.js.map} +1 -1
- package/dist/{menu-item-Bs2MYyHq.d.ts → menu-item-CZi9vy5O.d.ts} +4 -2
- package/dist/menu-item-CZi9vy5O.d.ts.map +1 -0
- package/dist/{menu-item-B-zYrTTi.js → menu-item-D2S4i8u1.js} +16 -4
- package/dist/menu-item-D2S4i8u1.js.map +1 -0
- package/dist/menu.d.ts +2 -2
- package/dist/menu.js +2 -2
- package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -1
- package/dist/notifier.js +2 -2
- package/dist/notifier.js.map +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/plots.js +1 -1
- package/dist/polar-pad.d.ts +2 -2
- package/dist/polar-pad.js +1 -1
- package/dist/{radial-input-Dp5qz0ly.js → radial-input-BfA3GO0H.js} +2 -2
- package/dist/{radial-input-Dp5qz0ly.js.map → radial-input-BfA3GO0H.js.map} +1 -1
- package/dist/{radial-input-DXMN55Nz.d.ts → radial-input-DU6t2hYO.d.ts} +3 -3
- package/dist/{radial-input-DXMN55Nz.d.ts.map → radial-input-DU6t2hYO.d.ts.map} +1 -1
- package/dist/radial-input.d.ts +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.d.ts +2 -2
- package/dist/range-input.js +1 -1
- package/dist/range.d.ts +2 -2
- package/dist/range.js +1 -1
- package/dist/registry-BEtb8_wB.js +46 -0
- package/dist/registry-BEtb8_wB.js.map +1 -0
- package/dist/select-horiz.d.ts +2 -2
- package/dist/select-horiz.js +1 -1
- package/dist/{slider-input-De4eoT11.js → slider-input-Bl1hFE89.js} +2 -2
- package/dist/{slider-input-De4eoT11.js.map → slider-input-Bl1hFE89.js.map} +1 -1
- package/dist/{slider-input-BfRUW2ZB.d.ts → slider-input-BxURAAmD.d.ts} +3 -3
- package/dist/{slider-input-BfRUW2ZB.d.ts.map → slider-input-BxURAAmD.d.ts.map} +1 -1
- package/dist/slider-input.d.ts +1 -1
- package/dist/slider-input.js +1 -1
- package/dist/swipe.d.ts +2 -2
- package/dist/swipe.js +1 -1
- package/dist/{tab-list-MPwq_1Jj.d.ts → tab-list-CGyPt07Z.d.ts} +9 -2
- package/dist/tab-list-CGyPt07Z.d.ts.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +32 -13
- package/dist/tabs.js.map +1 -1
- package/dist/{titlebar-DaCfpliv.d.ts → titlebar-Bj5pfdw_.d.ts} +2 -2
- package/dist/{titlebar-DaCfpliv.d.ts.map → titlebar-Bj5pfdw_.d.ts.map} +1 -1
- package/dist/titlebar.d.ts +1 -1
- package/dist/titlebar.js +1 -1
- package/dist/tooltip-BlvBUQxx.d.ts.map +1 -1
- package/dist/wheel-nudge-By5s_ioH.d.ts +31 -0
- package/dist/wheel-nudge-By5s_ioH.d.ts.map +1 -0
- package/dist/{wheel-nudge-BlSCe_hD.js → wheel-nudge-D5rmht3v.js} +6 -1
- package/dist/wheel-nudge-D5rmht3v.js.map +1 -0
- package/dist/{xy-axis-CxHC8z5E.js → xy-axis-DWizs0bt.js} +3 -3
- package/dist/xy-axis-DWizs0bt.js.map +1 -0
- package/dist/xy-pad.d.ts +2 -2
- package/dist/xy-pad.js +1 -1
- package/docs-user/dock.md +166 -15
- package/docs-user/icons.md +4 -0
- package/docs-user/index.json +2 -2
- package/docs-user/tabs.md +20 -0
- package/docs-user/user-theming.md +109 -0
- package/package.json +1 -1
- package/dist/defaults-BkWCPJFL.js.map +0 -1
- package/dist/icon-CvnPanhA.js.map +0 -1
- package/dist/icon-DpA9x2Ve.d.ts.map +0 -1
- package/dist/index-BtGFYfaK.d.ts.map +0 -1
- package/dist/menu-item-B-zYrTTi.js.map +0 -1
- package/dist/menu-item-Bs2MYyHq.d.ts.map +0 -1
- package/dist/registry-CkW7q09Q.js +0 -21
- package/dist/registry-CkW7q09Q.js.map +0 -1
- package/dist/tab-list-MPwq_1Jj.d.ts.map +0 -1
- package/dist/wheel-nudge-BlSCe_hD.js.map +0 -1
- package/dist/wheel-nudge-DGrNzWuE.d.ts +0 -29
- package/dist/wheel-nudge-DGrNzWuE.d.ts.map +0 -1
- package/dist/xy-axis-CxHC8z5E.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,21 +3,21 @@ import { t as TickledController } from "./tickled-controller-h9GmJ_bU.js";
|
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-DNI9xt0F.js";
|
|
4
4
|
import { t as popupSurfaceStyles } from "./popup-D80sj2QC.js";
|
|
5
5
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
6
|
-
import { a as
|
|
7
|
-
import { t as IxfxIconElement } from "./icon-
|
|
6
|
+
import { a as iconBus, c as setIconFont, i as hasIcon, l as svgToDataUri, n as getIconEntry, o as registerFontIcon, r as getIconFont, s as registerIcon, t as getIcon } from "./registry-BEtb8_wB.js";
|
|
7
|
+
import { t as IxfxIconElement } from "./icon-DcEEGQa_.js";
|
|
8
8
|
import { AcTextElement } from "./ac-text.js";
|
|
9
9
|
import { t as DataController } from "./data-controller-DOlmqNKb.js";
|
|
10
10
|
import { n as createIncrSearch, r as createFuzzySearch, t as createElementIncrSearch } from "./element-search-Y8SRfPGM.js";
|
|
11
11
|
import { n as createAcCompletionProvider, t as IncrSearchTreeController } from "./incr-search-vCzuao-2.js";
|
|
12
12
|
import { AcTokenElement } from "./ac-token.js";
|
|
13
|
-
import { i as ICON_CLOSE, n as ICON_CHECK, r as ICON_CHEVRON_DOWN, t as ICON_CARET_RIGHT } from "./defaults-
|
|
13
|
+
import { i as ICON_CLOSE, n as ICON_CHECK, r as ICON_CHEVRON_DOWN, t as ICON_CARET_RIGHT } from "./defaults-BJwDsMH4.js";
|
|
14
14
|
import "./icons.js";
|
|
15
15
|
import { t as prominenceStyles } from "./prominence-DlFShic3.js";
|
|
16
|
-
import { n as buttonStyles, t as ButtonElement } from "./button-
|
|
16
|
+
import { n as buttonStyles, t as ButtonElement } from "./button-DsFbV4XD.js";
|
|
17
17
|
import { n as ListSelectionController, t as VerticalListElement } from "./vertical-list-ClnqTkF3.js";
|
|
18
|
-
import "./menu-item-
|
|
18
|
+
import "./menu-item-D2S4i8u1.js";
|
|
19
19
|
import { Checkbox } from "./checkbox.js";
|
|
20
|
-
import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-
|
|
20
|
+
import { n as ColourPicker, t as ColourPickerPopup } from "./colour-picker-Ddsk-7E_.js";
|
|
21
21
|
import { LabelledRangeInput } from "./labelled-range-input.js";
|
|
22
22
|
import { t as collectDataResult } from "./data-provider-35TyWclX.js";
|
|
23
23
|
import { i as TreeDataModel, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-Ch4W8qXQ.js";
|
|
@@ -26,24 +26,24 @@ import { NarrowedTextElement } from "./narrowed-text.js";
|
|
|
26
26
|
import { CrumbNavigationElement } from "./crumbs.js";
|
|
27
27
|
import { DataDisplayComponent } from "./data-display.js";
|
|
28
28
|
import { t as createDragGhost } from "./drag-ghost-DtSDvjri.js";
|
|
29
|
-
import { t as menu_exports } from "./menu-
|
|
29
|
+
import { t as menu_exports } from "./menu-CXDFJxNm.js";
|
|
30
30
|
import { DataGridElement } from "./data-grid.js";
|
|
31
31
|
import { a as distribute, c as toSnapshot, i as buildModel, l as walk, n as SplitPanelElement, o as normalise, r as applySnapshot, s as resolveTracks, t as SplitLayoutElement } from "./split-layout-BFSbUZQv.js";
|
|
32
32
|
import { TabListElement } from "./tabs.js";
|
|
33
33
|
import { TitlebarElement } from "./titlebar.js";
|
|
34
34
|
import { EditableLabel } from "./editable-label.js";
|
|
35
|
-
import { n as EditableNumber, t as LabelledSliderInput } from "./labelled-slider-input-
|
|
35
|
+
import { n as EditableNumber, t as LabelledSliderInput } from "./labelled-slider-input-BInB5GKL.js";
|
|
36
36
|
import { t as FormElement } from "./form-CsXJX15p.js";
|
|
37
37
|
import { PanelElement } from "./panel.js";
|
|
38
38
|
import { GroupedItemListerElement } from "./grouped-item-lister.js";
|
|
39
|
-
import { t as IxfxHexEditorElement } from "./hex-editor-
|
|
40
|
-
import { t as RadialInputElement } from "./radial-input-
|
|
39
|
+
import { t as IxfxHexEditorElement } from "./hex-editor-BiRfwTz1.js";
|
|
40
|
+
import { t as RadialInputElement } from "./radial-input-BfA3GO0H.js";
|
|
41
41
|
import { LabelledRadialInput } from "./labelled-radial-input.js";
|
|
42
|
-
import { t as SliderInputElement } from "./slider-input-
|
|
42
|
+
import { t as SliderInputElement } from "./slider-input-Bl1hFE89.js";
|
|
43
43
|
import { LedElement } from "./led.js";
|
|
44
44
|
import { MillerBaseElement, MillerListElement, MillerTreeController } from "./miller.js";
|
|
45
45
|
import { NotificationPillElement } from "./notifier.js";
|
|
46
|
-
import { a as TooltipElement, c as computeColour, i as PlotMultiAxis, l as parseColourScaleAttr, n as PlotSingleAxis, o as PlotDataSeries, r as PlotHistogram, s as applyAgeModification, t as PlotXyAxis, u as readBaseColour } from "./xy-axis-
|
|
46
|
+
import { a as TooltipElement, c as computeColour, i as PlotMultiAxis, l as parseColourScaleAttr, n as PlotSingleAxis, o as PlotDataSeries, r as PlotHistogram, s as applyAgeModification, t as PlotXyAxis, u as readBaseColour } from "./xy-axis-DWizs0bt.js";
|
|
47
47
|
import { PolarPad } from "./polar-pad.js";
|
|
48
48
|
import { t as tooltipValueStyles } from "./tooltip-CJt3WLmN.js";
|
|
49
49
|
import { RangeInput } from "./range-input.js";
|
|
@@ -2526,10 +2526,11 @@ function unregisterDockHost(host) {
|
|
|
2526
2526
|
* Begin a dock-panel drag. Called by hosts in response to their own
|
|
2527
2527
|
* `dock-panel-drag-start` events (titlebar or tab-item handles).
|
|
2528
2528
|
*/
|
|
2529
|
-
function startDrag(panelId, sourceHost, pointerId, clientX, clientY) {
|
|
2529
|
+
function startDrag(panelId, sourceHost, pointerId, clientX, clientY, kind) {
|
|
2530
2530
|
if (activeDrag !== null);
|
|
2531
2531
|
activeDrag = {
|
|
2532
2532
|
panelId,
|
|
2533
|
+
kind,
|
|
2533
2534
|
sourceHost,
|
|
2534
2535
|
pointerId,
|
|
2535
2536
|
ghost: createGhostForPanel(sourceHost, panelId),
|
|
@@ -2601,8 +2602,10 @@ function onKeyDown(event) {
|
|
|
2601
2602
|
endDrag();
|
|
2602
2603
|
}
|
|
2603
2604
|
function findDropZone(drag, clientX, clientY) {
|
|
2605
|
+
const sourceIsolated = drag.sourceHost.isolated;
|
|
2604
2606
|
for (const host of dragHosts) {
|
|
2605
|
-
|
|
2607
|
+
if (sourceIsolated && host !== drag.sourceHost) continue;
|
|
2608
|
+
const zone = host.computeDropZone(clientX, clientY, drag.panelId, drag.kind);
|
|
2606
2609
|
if (zone !== null) return zone;
|
|
2607
2610
|
}
|
|
2608
2611
|
return null;
|
|
@@ -2690,12 +2693,15 @@ function createEmptyLayout() {
|
|
|
2690
2693
|
root: createEmptyStack()
|
|
2691
2694
|
};
|
|
2692
2695
|
}
|
|
2693
|
-
function createStack(panels, active) {
|
|
2694
|
-
|
|
2696
|
+
function createStack(panels, active, name) {
|
|
2697
|
+
const stack = {
|
|
2695
2698
|
kind: `stack`,
|
|
2696
2699
|
panels: [...panels],
|
|
2697
2700
|
active: active ?? panels[0] ?? ``
|
|
2698
2701
|
};
|
|
2702
|
+
const trimmed = name?.trim();
|
|
2703
|
+
if (trimmed) stack.name = trimmed;
|
|
2704
|
+
return stack;
|
|
2699
2705
|
}
|
|
2700
2706
|
function createSplit(direction, children, sizes) {
|
|
2701
2707
|
const mean = children.length > 0 ? 1 / children.length : 1;
|
|
@@ -2709,7 +2715,8 @@ function createSplit(direction, children, sizes) {
|
|
|
2709
2715
|
/**
|
|
2710
2716
|
* Runs after every mutation:
|
|
2711
2717
|
* - stack `active` fixed to a member of `panels` (or `''` when empty)
|
|
2712
|
-
* - empty stacks removed from their parent split (and their
|
|
2718
|
+
* - empty *unnamed* stacks removed from their parent split (and their
|
|
2719
|
+
* `sizes` entry); named empty stacks are kept so the name stays addressable
|
|
2713
2720
|
* - splits with ≤1 child replaced by that child (spliced into the parent)
|
|
2714
2721
|
* - a child split whose direction equals its parent's is flattened into it,
|
|
2715
2722
|
* spreading its sizes across the slot it vacated
|
|
@@ -2718,13 +2725,14 @@ function createSplit(direction, children, sizes) {
|
|
|
2718
2725
|
*/
|
|
2719
2726
|
function normalize(root) {
|
|
2720
2727
|
if (isStack(root)) {
|
|
2728
|
+
sanitizeStackName(root);
|
|
2721
2729
|
if (!root.panels.includes(root.active)) root.active = root.panels[0] ?? ``;
|
|
2722
2730
|
return root;
|
|
2723
2731
|
}
|
|
2724
2732
|
for (let i = root.children.length - 1; i >= 0; i--) {
|
|
2725
2733
|
normalize(root.children[i]);
|
|
2726
2734
|
const child = root.children[i];
|
|
2727
|
-
if (isStack(child) && child.panels.length === 0) {
|
|
2735
|
+
if (isStack(child) && child.panels.length === 0 && !child.name) {
|
|
2728
2736
|
root.children.splice(i, 1);
|
|
2729
2737
|
root.sizes.splice(i, 1);
|
|
2730
2738
|
continue;
|
|
@@ -2758,17 +2766,36 @@ function replaceNodeContents(target, source) {
|
|
|
2758
2766
|
const t = target;
|
|
2759
2767
|
t.panels = source.panels;
|
|
2760
2768
|
t.active = source.active;
|
|
2769
|
+
if (source.name !== void 0) t.name = source.name;
|
|
2770
|
+
else delete t.name;
|
|
2771
|
+
if (source.hideLabels !== void 0) t.hideLabels = source.hideLabels;
|
|
2772
|
+
else delete t.hideLabels;
|
|
2761
2773
|
delete t.collapsed;
|
|
2762
2774
|
delete t.preCollapseSize;
|
|
2775
|
+
if (source.collapsed !== void 0) t.collapsed = source.collapsed;
|
|
2776
|
+
if (source.preCollapseSize !== void 0) t.preCollapseSize = source.preCollapseSize;
|
|
2763
2777
|
} else {
|
|
2764
2778
|
target.kind = `split`;
|
|
2765
2779
|
const t = target;
|
|
2766
2780
|
t.direction = source.direction;
|
|
2767
2781
|
t.children = source.children;
|
|
2768
2782
|
t.sizes = source.sizes;
|
|
2783
|
+
const stale = t;
|
|
2784
|
+
delete stale.panels;
|
|
2785
|
+
delete stale.active;
|
|
2786
|
+
delete stale.name;
|
|
2787
|
+
delete stale.collapsed;
|
|
2788
|
+
delete stale.preCollapseSize;
|
|
2769
2789
|
}
|
|
2770
2790
|
return target;
|
|
2771
2791
|
}
|
|
2792
|
+
/** Trim `name`; drop it when empty / non-string so lookups stay predictable. */
|
|
2793
|
+
function sanitizeStackName(stack) {
|
|
2794
|
+
if (stack.name === void 0) return;
|
|
2795
|
+
const trimmed = typeof stack.name === `string` ? stack.name.trim() : ``;
|
|
2796
|
+
if (trimmed) stack.name = trimmed;
|
|
2797
|
+
else delete stack.name;
|
|
2798
|
+
}
|
|
2772
2799
|
function findNode(root, path) {
|
|
2773
2800
|
let current = root;
|
|
2774
2801
|
for (const index of path) {
|
|
@@ -2802,6 +2829,36 @@ function collectPanelIds(root) {
|
|
|
2802
2829
|
return root.children.flatMap(collectPanelIds);
|
|
2803
2830
|
}
|
|
2804
2831
|
/**
|
|
2832
|
+
* Path of the first stack (tree order) whose `name` matches, or null.
|
|
2833
|
+
* Names are expected to be unique per layout; duplicates resolve first-wins.
|
|
2834
|
+
*/
|
|
2835
|
+
function findStackPathByName(root, name) {
|
|
2836
|
+
const wanted = name.trim();
|
|
2837
|
+
if (!wanted) return null;
|
|
2838
|
+
return findStackPathByNameInner(root, wanted, []);
|
|
2839
|
+
}
|
|
2840
|
+
function findStackPathByNameInner(node, name, path) {
|
|
2841
|
+
if (isStack(node)) return node.name === name ? path : null;
|
|
2842
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2843
|
+
const found = findStackPathByNameInner(node.children[i], name, [...path, i]);
|
|
2844
|
+
if (found !== null) return found;
|
|
2845
|
+
}
|
|
2846
|
+
return null;
|
|
2847
|
+
}
|
|
2848
|
+
/** Names of every named stack leaf, in tree order. */
|
|
2849
|
+
function collectContainerNames(root) {
|
|
2850
|
+
const out = [];
|
|
2851
|
+
const visit = (node) => {
|
|
2852
|
+
if (isStack(node)) {
|
|
2853
|
+
if (node.name) out.push(node.name);
|
|
2854
|
+
return;
|
|
2855
|
+
}
|
|
2856
|
+
node.children.forEach(visit);
|
|
2857
|
+
};
|
|
2858
|
+
visit(root);
|
|
2859
|
+
return out;
|
|
2860
|
+
}
|
|
2861
|
+
/**
|
|
2805
2862
|
* Paths of every stack leaf, in tree order. `[]` is the root itself when it
|
|
2806
2863
|
* is a stack.
|
|
2807
2864
|
*/
|
|
@@ -2883,11 +2940,27 @@ function insertBeside(root, targetPath, direction, newNode, side) {
|
|
|
2883
2940
|
* the caller's reference stays valid. Returns true on success.
|
|
2884
2941
|
*/
|
|
2885
2942
|
function wrapRoot(root, direction, newNode, side) {
|
|
2886
|
-
|
|
2943
|
+
const inner = cloneNodeShallow(root);
|
|
2944
|
+
replaceNodeContents(root, createSplit(direction, side === `before` ? [newNode, inner] : [inner, newNode]));
|
|
2887
2945
|
normalize(root);
|
|
2888
2946
|
return true;
|
|
2889
2947
|
}
|
|
2890
2948
|
/**
|
|
2949
|
+
* Detached copy of `node` (own arrays copied) so it can become a child of a
|
|
2950
|
+
* wrapper that then replaces `node` in place.
|
|
2951
|
+
*/
|
|
2952
|
+
function cloneNodeShallow(node) {
|
|
2953
|
+
if (isStack(node)) return {
|
|
2954
|
+
...node,
|
|
2955
|
+
panels: [...node.panels]
|
|
2956
|
+
};
|
|
2957
|
+
return {
|
|
2958
|
+
...node,
|
|
2959
|
+
children: [...node.children],
|
|
2960
|
+
sizes: [...node.sizes]
|
|
2961
|
+
};
|
|
2962
|
+
}
|
|
2963
|
+
/**
|
|
2891
2964
|
* Remove the stack at `stackPath` from the tree. Its panels are moved into
|
|
2892
2965
|
* `fallbackStack` (if given and still attached) so they are not silently
|
|
2893
2966
|
* lost; otherwise they are dropped from the model (elements return to the
|
|
@@ -2916,6 +2989,251 @@ function extractStack(root, stackPath, fallbackStack) {
|
|
|
2916
2989
|
normalize(root);
|
|
2917
2990
|
return stack;
|
|
2918
2991
|
}
|
|
2992
|
+
/** Tolerance for edge-touch comparisons in unit-square geometry. */
|
|
2993
|
+
const GEOM_EPS = 1e-9;
|
|
2994
|
+
function pathsEqual(a, b) {
|
|
2995
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
2996
|
+
}
|
|
2997
|
+
/**
|
|
2998
|
+
* Resolve a {@link DockLeafRef} to a stack path. Strings match container
|
|
2999
|
+
* `name` first-wins; arrays must index an existing stack leaf. Returns null
|
|
3000
|
+
* when unresolvable.
|
|
3001
|
+
*/
|
|
3002
|
+
function resolveLeafPath(root, ref) {
|
|
3003
|
+
if (typeof ref === `string`) return findStackPathByName(root, ref);
|
|
3004
|
+
if (!Array.isArray(ref)) return null;
|
|
3005
|
+
let current = root;
|
|
3006
|
+
for (const index of ref) {
|
|
3007
|
+
if (!Number.isInteger(index) || index < 0) return null;
|
|
3008
|
+
if (!isSplit(current)) return null;
|
|
3009
|
+
const next = current.children[index];
|
|
3010
|
+
if (!next) return null;
|
|
3011
|
+
current = next;
|
|
3012
|
+
}
|
|
3013
|
+
return isStack(current) ? [...ref] : null;
|
|
3014
|
+
}
|
|
3015
|
+
/** Absolute (unit-square) rect of every stack leaf, in tree order. */
|
|
3016
|
+
function computeLeafGeoms(root) {
|
|
3017
|
+
const out = [];
|
|
3018
|
+
const visit = (node, path, rect) => {
|
|
3019
|
+
if (isStack(node)) {
|
|
3020
|
+
out.push({
|
|
3021
|
+
path,
|
|
3022
|
+
name: node.name ?? null,
|
|
3023
|
+
rect
|
|
3024
|
+
});
|
|
3025
|
+
return;
|
|
3026
|
+
}
|
|
3027
|
+
const total = node.sizes.reduce((sum, w) => sum + w, 0);
|
|
3028
|
+
const safe = total > 0 ? total : node.children.length || 1;
|
|
3029
|
+
let offset = 0;
|
|
3030
|
+
node.children.forEach((child, i) => {
|
|
3031
|
+
const frac = (node.sizes[i] ?? safe / node.children.length) / safe;
|
|
3032
|
+
if (node.direction === `row`) {
|
|
3033
|
+
const w = rect.w * frac;
|
|
3034
|
+
visit(child, [...path, i], {
|
|
3035
|
+
x: rect.x + offset,
|
|
3036
|
+
y: rect.y,
|
|
3037
|
+
w,
|
|
3038
|
+
h: rect.h
|
|
3039
|
+
});
|
|
3040
|
+
offset += w;
|
|
3041
|
+
} else {
|
|
3042
|
+
const h = rect.h * frac;
|
|
3043
|
+
visit(child, [...path, i], {
|
|
3044
|
+
x: rect.x,
|
|
3045
|
+
y: rect.y + offset,
|
|
3046
|
+
w: rect.w,
|
|
3047
|
+
h
|
|
3048
|
+
});
|
|
3049
|
+
offset += h;
|
|
3050
|
+
}
|
|
3051
|
+
});
|
|
3052
|
+
};
|
|
3053
|
+
visit(root, [], {
|
|
3054
|
+
x: 0,
|
|
3055
|
+
y: 0,
|
|
3056
|
+
w: 1,
|
|
3057
|
+
h: 1
|
|
3058
|
+
});
|
|
3059
|
+
return out;
|
|
3060
|
+
}
|
|
3061
|
+
function intervalOverlap(a0, a1, b0, b1) {
|
|
3062
|
+
return Math.min(a1, b1) - Math.max(a0, b0);
|
|
3063
|
+
}
|
|
3064
|
+
/**
|
|
3065
|
+
* Geometric neighbours of a leaf — what the user sees above / below / left /
|
|
3066
|
+
* right of it. Each list holds `{ name, path }` (name is null for unnamed
|
|
3067
|
+
* leaves), ordered most-overlapping first. Returns null when `ref` is
|
|
3068
|
+
* unresolvable.
|
|
3069
|
+
*/
|
|
3070
|
+
function getLeafNeighbours(root, ref) {
|
|
3071
|
+
const path = resolveLeafPath(root, ref);
|
|
3072
|
+
if (path === null) return null;
|
|
3073
|
+
const geoms = computeLeafGeoms(root);
|
|
3074
|
+
const self = geoms.find((g) => pathsEqual(g.path, path));
|
|
3075
|
+
if (!self) return null;
|
|
3076
|
+
const s = self.rect;
|
|
3077
|
+
const above = [];
|
|
3078
|
+
const below = [];
|
|
3079
|
+
const left = [];
|
|
3080
|
+
const right = [];
|
|
3081
|
+
geoms.forEach((g, order) => {
|
|
3082
|
+
if (g === self) return;
|
|
3083
|
+
const r = g.rect;
|
|
3084
|
+
const info = {
|
|
3085
|
+
name: g.name,
|
|
3086
|
+
path: [...g.path]
|
|
3087
|
+
};
|
|
3088
|
+
if (Math.abs(r.y + r.h - s.y) < GEOM_EPS) {
|
|
3089
|
+
const o = intervalOverlap(r.x, r.x + r.w, s.x, s.x + s.w);
|
|
3090
|
+
if (o > GEOM_EPS) above.push({
|
|
3091
|
+
info,
|
|
3092
|
+
overlap: o,
|
|
3093
|
+
order
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
if (Math.abs(s.y + s.h - r.y) < GEOM_EPS) {
|
|
3097
|
+
const o = intervalOverlap(r.x, r.x + r.w, s.x, s.x + s.w);
|
|
3098
|
+
if (o > GEOM_EPS) below.push({
|
|
3099
|
+
info,
|
|
3100
|
+
overlap: o,
|
|
3101
|
+
order
|
|
3102
|
+
});
|
|
3103
|
+
}
|
|
3104
|
+
if (Math.abs(r.x + r.w - s.x) < GEOM_EPS) {
|
|
3105
|
+
const o = intervalOverlap(r.y, r.y + r.h, s.y, s.y + s.h);
|
|
3106
|
+
if (o > GEOM_EPS) left.push({
|
|
3107
|
+
info,
|
|
3108
|
+
overlap: o,
|
|
3109
|
+
order
|
|
3110
|
+
});
|
|
3111
|
+
}
|
|
3112
|
+
if (Math.abs(s.x + s.w - r.x) < GEOM_EPS) {
|
|
3113
|
+
const o = intervalOverlap(r.y, r.y + r.h, s.y, s.y + s.h);
|
|
3114
|
+
if (o > GEOM_EPS) right.push({
|
|
3115
|
+
info,
|
|
3116
|
+
overlap: o,
|
|
3117
|
+
order
|
|
3118
|
+
});
|
|
3119
|
+
}
|
|
3120
|
+
});
|
|
3121
|
+
const rank = (hits) => hits.sort((a, b) => b.overlap - a.overlap || a.order - b.order).map((h) => h.info);
|
|
3122
|
+
return {
|
|
3123
|
+
above: rank(above),
|
|
3124
|
+
below: rank(below),
|
|
3125
|
+
left: rank(left),
|
|
3126
|
+
right: rank(right)
|
|
3127
|
+
};
|
|
3128
|
+
}
|
|
3129
|
+
/**
|
|
3130
|
+
* Exchange two leaves' positions in the tree, each carrying its size slot so
|
|
3131
|
+
* the remaining structure and proportions are untouched. Returns false when
|
|
3132
|
+
* either path is not a stack leaf.
|
|
3133
|
+
*/
|
|
3134
|
+
function swapLeaves(root, pathA, pathB) {
|
|
3135
|
+
if (pathsEqual(pathA, pathB)) return false;
|
|
3136
|
+
const nodeA = findNode(root, pathA);
|
|
3137
|
+
const nodeB = findNode(root, pathB);
|
|
3138
|
+
if (nodeA === null || nodeB === null || !isStack(nodeA) || !isStack(nodeB)) return false;
|
|
3139
|
+
const parentA = findParentOf(root, pathA);
|
|
3140
|
+
const parentB = findParentOf(root, pathB);
|
|
3141
|
+
if (parentA === null || parentB === null) return false;
|
|
3142
|
+
const indexA = pathA[pathA.length - 1];
|
|
3143
|
+
const indexB = pathB[pathB.length - 1];
|
|
3144
|
+
if (parentA === parentB) {
|
|
3145
|
+
const p = parentA;
|
|
3146
|
+
[p.children[indexA], p.children[indexB]] = [p.children[indexB], p.children[indexA]];
|
|
3147
|
+
[p.sizes[indexA], p.sizes[indexB]] = [p.sizes[indexB] ?? 1, p.sizes[indexA] ?? 1];
|
|
3148
|
+
return true;
|
|
3149
|
+
}
|
|
3150
|
+
const carriedNode = parentA.children[indexA];
|
|
3151
|
+
const carriedSize = parentA.sizes[indexA] ?? 1;
|
|
3152
|
+
parentA.children[indexA] = parentB.children[indexB];
|
|
3153
|
+
parentA.sizes[indexA] = parentB.sizes[indexB] ?? 1;
|
|
3154
|
+
parentB.children[indexB] = carriedNode;
|
|
3155
|
+
parentB.sizes[indexB] = carriedSize;
|
|
3156
|
+
return true;
|
|
3157
|
+
}
|
|
3158
|
+
/**
|
|
3159
|
+
* Move a leaf one position in `direction`, swapping with the neighbour it
|
|
3160
|
+
* shares the longest edge with. Returns false when `ref` is unresolvable or
|
|
3161
|
+
* nothing adjoins in that direction. Run `normalize()` afterwards.
|
|
3162
|
+
*/
|
|
3163
|
+
function moveLeafStep(root, ref, direction) {
|
|
3164
|
+
const path = resolveLeafPath(root, ref);
|
|
3165
|
+
if (path === null) return false;
|
|
3166
|
+
const neighbours = getLeafNeighbours(root, ref);
|
|
3167
|
+
if (neighbours === null) return false;
|
|
3168
|
+
const list = direction === `up` ? neighbours.above : direction === `down` ? neighbours.below : direction === `left` ? neighbours.left : neighbours.right;
|
|
3169
|
+
if (list.length === 0) return false;
|
|
3170
|
+
return swapLeaves(root, path, list[0].path);
|
|
3171
|
+
}
|
|
3172
|
+
/**
|
|
3173
|
+
* Move a leaf to an edge of the overall layout, keeping the rest of the
|
|
3174
|
+
* tree intact as a single subtree and preserving the leaf's absolute size
|
|
3175
|
+
* along the target axis. Returns false when `ref` is unresolvable or the
|
|
3176
|
+
* layout holds a single leaf. Run `normalize()` afterwards (also safe to
|
|
3177
|
+
* call it twice — the host's commit does).
|
|
3178
|
+
*/
|
|
3179
|
+
function moveLeafNodeToEdge(root, ref, edge) {
|
|
3180
|
+
const path = resolveLeafPath(root, ref);
|
|
3181
|
+
if (path === null || path.length === 0) return false;
|
|
3182
|
+
const self = computeLeafGeoms(root).find((g) => pathsEqual(g.path, path));
|
|
3183
|
+
if (!self) return false;
|
|
3184
|
+
const horizontal = edge === `left` || edge === `right`;
|
|
3185
|
+
const frac = Math.min(Math.max(horizontal ? self.rect.w : self.rect.h, .05), .95);
|
|
3186
|
+
if (!(frac > 0) || frac >= 1) return false;
|
|
3187
|
+
const parent = findParentOf(root, path);
|
|
3188
|
+
if (parent === null) return false;
|
|
3189
|
+
const [node] = parent.children.splice(path[path.length - 1], 1);
|
|
3190
|
+
parent.sizes.splice(path[path.length - 1], 1);
|
|
3191
|
+
if (!node) return false;
|
|
3192
|
+
normalize(root);
|
|
3193
|
+
const atStart = edge === `left` || edge === `top`;
|
|
3194
|
+
const direction = horizontal ? `row` : `column`;
|
|
3195
|
+
if (isStack(root)) {
|
|
3196
|
+
const rest = root;
|
|
3197
|
+
const remaining = {
|
|
3198
|
+
kind: `stack`,
|
|
3199
|
+
panels: [...rest.panels],
|
|
3200
|
+
active: rest.active
|
|
3201
|
+
};
|
|
3202
|
+
if (rest.name !== void 0) remaining.name = rest.name;
|
|
3203
|
+
if (rest.collapsed !== void 0) remaining.collapsed = rest.collapsed;
|
|
3204
|
+
if (rest.preCollapseSize !== void 0) remaining.preCollapseSize = rest.preCollapseSize;
|
|
3205
|
+
replaceNodeContents(root, {
|
|
3206
|
+
kind: `split`,
|
|
3207
|
+
direction,
|
|
3208
|
+
children: atStart ? [node, remaining] : [remaining, node],
|
|
3209
|
+
sizes: atStart ? [frac, 1 - frac] : [1 - frac, frac]
|
|
3210
|
+
});
|
|
3211
|
+
return true;
|
|
3212
|
+
}
|
|
3213
|
+
if (isSplit(root) && root.direction === direction) {
|
|
3214
|
+
const size = frac * (root.sizes.reduce((total, w) => total + w, 0) || root.children.length || 1) / (1 - frac);
|
|
3215
|
+
const at = atStart ? 0 : root.children.length;
|
|
3216
|
+
root.children.splice(at, 0, node);
|
|
3217
|
+
root.sizes.splice(at, 0, size);
|
|
3218
|
+
return true;
|
|
3219
|
+
}
|
|
3220
|
+
if (isSplit(root)) {
|
|
3221
|
+
const inner = {
|
|
3222
|
+
kind: `split`,
|
|
3223
|
+
direction: root.direction,
|
|
3224
|
+
children: root.children,
|
|
3225
|
+
sizes: root.sizes
|
|
3226
|
+
};
|
|
3227
|
+
replaceNodeContents(root, {
|
|
3228
|
+
kind: `split`,
|
|
3229
|
+
direction,
|
|
3230
|
+
children: atStart ? [node, inner] : [inner, node],
|
|
3231
|
+
sizes: atStart ? [frac, 1 - frac] : [1 - frac, frac]
|
|
3232
|
+
});
|
|
3233
|
+
return true;
|
|
3234
|
+
}
|
|
3235
|
+
return false;
|
|
3236
|
+
}
|
|
2919
3237
|
function serializeLayout(root) {
|
|
2920
3238
|
return {
|
|
2921
3239
|
version: 1,
|
|
@@ -2929,6 +3247,8 @@ function serializeNode(node) {
|
|
|
2929
3247
|
panels: [...node.panels],
|
|
2930
3248
|
active: node.active
|
|
2931
3249
|
};
|
|
3250
|
+
if (node.name !== void 0) out.name = node.name;
|
|
3251
|
+
if (node.hideLabels !== void 0) out.hideLabels = node.hideLabels;
|
|
2932
3252
|
if (node.collapsed !== void 0) out.collapsed = node.collapsed;
|
|
2933
3253
|
if (node.preCollapseSize !== void 0) out.preCollapseSize = node.preCollapseSize;
|
|
2934
3254
|
return out;
|
|
@@ -2971,9 +3291,13 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
2971
3291
|
this.registry = void 0;
|
|
2972
3292
|
this._compact = false;
|
|
2973
3293
|
this._hasToolbarContent = false;
|
|
3294
|
+
this._labelObserver = null;
|
|
2974
3295
|
this._onToolbarSlotChange = () => {
|
|
2975
3296
|
this._updateToolbarContent();
|
|
2976
3297
|
};
|
|
3298
|
+
this._onLabelSlotChange = () => {
|
|
3299
|
+
this._syncLabelSizer();
|
|
3300
|
+
};
|
|
2977
3301
|
}
|
|
2978
3302
|
connectedCallback() {
|
|
2979
3303
|
super.connectedCallback();
|
|
@@ -2982,6 +3306,13 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
2982
3306
|
});
|
|
2983
3307
|
this._resizeObserver.observe(this);
|
|
2984
3308
|
(this.shadowRoot?.querySelector(`slot[name="toolbar"]`))?.addEventListener(`slotchange`, this._onToolbarSlotChange);
|
|
3309
|
+
(this.shadowRoot?.querySelector(`slot:not([name])`))?.addEventListener(`slotchange`, this._onLabelSlotChange);
|
|
3310
|
+
this._labelObserver = new MutationObserver(() => this._syncLabelSizer());
|
|
3311
|
+
this._labelObserver.observe(this, {
|
|
3312
|
+
childList: true,
|
|
3313
|
+
characterData: true,
|
|
3314
|
+
subtree: true
|
|
3315
|
+
});
|
|
2985
3316
|
}
|
|
2986
3317
|
disconnectedCallback() {
|
|
2987
3318
|
super.disconnectedCallback();
|
|
@@ -2989,7 +3320,10 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
2989
3320
|
this._resizeObserver = void 0;
|
|
2990
3321
|
this._commandCleanup?.();
|
|
2991
3322
|
this._commandCleanup = void 0;
|
|
3323
|
+
this._labelObserver?.disconnect();
|
|
3324
|
+
this._labelObserver = null;
|
|
2992
3325
|
(this.shadowRoot?.querySelector(`slot[name="toolbar"]`))?.removeEventListener(`slotchange`, this._onToolbarSlotChange);
|
|
3326
|
+
(this.shadowRoot?.querySelector(`slot:not([name])`))?.removeEventListener(`slotchange`, this._onLabelSlotChange);
|
|
2993
3327
|
}
|
|
2994
3328
|
updated(changed) {
|
|
2995
3329
|
super.updated(changed);
|
|
@@ -3012,12 +3346,25 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
3012
3346
|
if (id === this.commandActive) this.click();
|
|
3013
3347
|
});
|
|
3014
3348
|
}
|
|
3349
|
+
/**
|
|
3350
|
+
* Mirror the default-slot text into `.label[data-label]` for the `::after`
|
|
3351
|
+
* width sizer. Slotted toolbar content is excluded.
|
|
3352
|
+
*/
|
|
3353
|
+
_syncLabelSizer() {
|
|
3354
|
+
const slot = this.shadowRoot?.querySelector(`slot:not([name])`);
|
|
3355
|
+
const label = this.shadowRoot?.querySelector(`.label`);
|
|
3356
|
+
if (slot === null || slot === void 0 || label === null || label === void 0) return;
|
|
3357
|
+
const text = slot.assignedNodes().filter((node) => !(node instanceof HTMLElement && node.hasAttribute(`slot`))).map((node) => node.textContent ?? ``).join(``);
|
|
3358
|
+
if (text) label.setAttribute(`data-label`, text);
|
|
3359
|
+
else label.removeAttribute(`data-label`);
|
|
3360
|
+
}
|
|
3015
3361
|
_updateToolbarContent() {
|
|
3016
3362
|
const slot = this.shadowRoot?.querySelector(`slot[name="toolbar"]`);
|
|
3017
3363
|
this._hasToolbarContent = (slot?.assignedElements().length ?? 0) > 0;
|
|
3018
3364
|
}
|
|
3019
3365
|
firstUpdated() {
|
|
3020
3366
|
this._updateToolbarContent();
|
|
3367
|
+
this._syncLabelSizer();
|
|
3021
3368
|
}
|
|
3022
3369
|
render() {
|
|
3023
3370
|
const showLabel = !this.hideLabels || !this.iconName;
|
|
@@ -3059,15 +3406,21 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
3059
3406
|
css`
|
|
3060
3407
|
:host {
|
|
3061
3408
|
--selected-tab-color: var(--ixfx-selected-tab-color, var(--surface-2-text));
|
|
3409
|
+
--selected-tab-icon-color: var(--ixfx-selected-tab-icon-color, var(--accent));
|
|
3062
3410
|
--selected-tab-border-width: var(--ixfx-selected-tab-border-width, 1px);
|
|
3063
3411
|
--selected-tab-weight: var(--ixfx-selected-tab-weight, bold);
|
|
3412
|
+
--selected-tab-text-decoration: var(--ixfx-selected-tab-text-decoration, none);
|
|
3413
|
+
--selected-tab-text-decoration-color: var(--ixfx-selected-tab-text-decoration-color, var(--accent));
|
|
3414
|
+
--selected-tab-text-decoration-thickness: var(--ixfx-selected-tab-text-decoration-thickness, 0px);
|
|
3415
|
+
--selected-tab-text-decoration-offset: var(--ixfx-selected-tab-text-decoration-offset, 2px);
|
|
3064
3416
|
--selected-background: var(--ixfx-tab-selected-background, var(--surface-5));
|
|
3065
3417
|
--tab-padding: var(--ixfx-tab-padding, var(--space-s));
|
|
3066
3418
|
display: inline-flex;
|
|
3067
3419
|
min-width: 0;
|
|
3068
3420
|
user-select: none;
|
|
3069
3421
|
box-sizing: border-box;
|
|
3070
|
-
font-size: var(--text-
|
|
3422
|
+
font-size: var(--text-m);
|
|
3423
|
+
color: inherit;
|
|
3071
3424
|
/* No explicit height: items stretch (align-self: stretch via the
|
|
3072
3425
|
list's flex container) so every tab in a strip shares one height
|
|
3073
3426
|
even when toolbars give some items taller content. */
|
|
@@ -3082,7 +3435,18 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
3082
3435
|
font-weight: 500;
|
|
3083
3436
|
border: var(--selected-tab-border-width) solid transparent;
|
|
3084
3437
|
gap: var(--space-s);
|
|
3438
|
+
transition: background var(--transition, 0.15s);
|
|
3439
|
+
}
|
|
3085
3440
|
|
|
3441
|
+
/* Hover ("tickle") background. When --ixfx-tab-hover-background is
|
|
3442
|
+
unset each state keeps its resting background, so existing
|
|
3443
|
+
consumers see no change. */
|
|
3444
|
+
:host(:hover:not([selected])) > div {
|
|
3445
|
+
background: var(--ixfx-tab-hover-background, transparent);
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
:host([selected]:hover) > div {
|
|
3449
|
+
background: var(--ixfx-tab-hover-background, var(--selected-background));
|
|
3086
3450
|
}
|
|
3087
3451
|
|
|
3088
3452
|
:host([selected]) > div {
|
|
@@ -3096,6 +3460,13 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
3096
3460
|
border-radius:var(--radius-m);
|
|
3097
3461
|
}
|
|
3098
3462
|
|
|
3463
|
+
:host([selected]) .label {
|
|
3464
|
+
text-decoration: var(--selected-tab-text-decoration);
|
|
3465
|
+
text-decoration-color: var(--selected-tab-text-decoration-color);
|
|
3466
|
+
text-decoration-thickness: var(--selected-tab-text-decoration-thickness);
|
|
3467
|
+
text-decoration-offset: var(--selected-tab-text-decoration-offset);
|
|
3468
|
+
}
|
|
3469
|
+
|
|
3099
3470
|
.label {
|
|
3100
3471
|
overflow: var(--allow-overflow, hidden);
|
|
3101
3472
|
text-overflow: ellipsis;
|
|
@@ -3104,10 +3475,29 @@ let TabListItemElement = class TabListItemElement extends LitElement {
|
|
|
3104
3475
|
flex: 1 1 auto;
|
|
3105
3476
|
}
|
|
3106
3477
|
|
|
3478
|
+
/* Width sizer: an invisible copy of the label, always set at the
|
|
3479
|
+
selected weight, so activating a tab (bold) never shifts the strip.
|
|
3480
|
+
Text is mirrored from the default slot via the data-label attribute
|
|
3481
|
+
(see _syncLabelSizer). */
|
|
3482
|
+
.label::after {
|
|
3483
|
+
content: attr(data-label);
|
|
3484
|
+
display: block;
|
|
3485
|
+
height: 0;
|
|
3486
|
+
overflow: hidden;
|
|
3487
|
+
visibility: hidden;
|
|
3488
|
+
font-weight: var(--selected-tab-weight);
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3107
3491
|
ixfx-icon {
|
|
3108
3492
|
flex-shrink: 0;
|
|
3109
3493
|
}
|
|
3110
3494
|
|
|
3495
|
+
/* Leading icon (direct child — not close/toolbar icons) picks up the
|
|
3496
|
+
accent when selected, so icon-only tabs read as active. */
|
|
3497
|
+
:host([selected]) > div > ixfx-icon {
|
|
3498
|
+
color: var(--selected-tab-icon-color);
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3111
3501
|
.actions {
|
|
3112
3502
|
display: flex;
|
|
3113
3503
|
align-items: center;
|
|
@@ -3203,6 +3593,7 @@ let DockPanelElement = class DockPanelElement extends LitElement {
|
|
|
3203
3593
|
this.iconName = ``;
|
|
3204
3594
|
this.closable = false;
|
|
3205
3595
|
this.collapsible = false;
|
|
3596
|
+
this.kind = `any`;
|
|
3206
3597
|
this.accepts = ``;
|
|
3207
3598
|
this.presentation = `solo`;
|
|
3208
3599
|
this._collapsed = false;
|
|
@@ -3256,6 +3647,10 @@ let DockPanelElement = class DockPanelElement extends LitElement {
|
|
|
3256
3647
|
}
|
|
3257
3648
|
connectedCallback() {
|
|
3258
3649
|
super.connectedCallback();
|
|
3650
|
+
if (this.hasAttribute(`title`)) {
|
|
3651
|
+
if (!this.hasAttribute(`label`)) this.title = this.getAttribute(`title`) ?? ``;
|
|
3652
|
+
this.removeAttribute(`title`);
|
|
3653
|
+
}
|
|
3259
3654
|
this.addEventListener(`pointerdown`, this._onPointerDown);
|
|
3260
3655
|
}
|
|
3261
3656
|
disconnectedCallback() {
|
|
@@ -3347,13 +3742,20 @@ __decorate([property({
|
|
|
3347
3742
|
attribute: `panel-id`,
|
|
3348
3743
|
reflect: true
|
|
3349
3744
|
})], DockPanelElement.prototype, "panelId", void 0);
|
|
3350
|
-
__decorate([property({
|
|
3745
|
+
__decorate([property({
|
|
3746
|
+
type: String,
|
|
3747
|
+
attribute: `label`
|
|
3748
|
+
})], DockPanelElement.prototype, "title", void 0);
|
|
3351
3749
|
__decorate([property({
|
|
3352
3750
|
type: String,
|
|
3353
3751
|
attribute: `icon-name`
|
|
3354
3752
|
})], DockPanelElement.prototype, "iconName", void 0);
|
|
3355
3753
|
__decorate([property({ type: Boolean })], DockPanelElement.prototype, "closable", void 0);
|
|
3356
3754
|
__decorate([property({ type: Boolean })], DockPanelElement.prototype, "collapsible", void 0);
|
|
3755
|
+
__decorate([property({
|
|
3756
|
+
type: String,
|
|
3757
|
+
reflect: true
|
|
3758
|
+
})], DockPanelElement.prototype, "kind", void 0);
|
|
3357
3759
|
__decorate([property({
|
|
3358
3760
|
type: String,
|
|
3359
3761
|
attribute: `accepts`
|
|
@@ -3379,19 +3781,23 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3379
3781
|
super(..._args);
|
|
3380
3782
|
this.layout = null;
|
|
3381
3783
|
this.accepts = `tabs horizontal vertical`;
|
|
3784
|
+
this.isolated = false;
|
|
3382
3785
|
this._model = createStack([]);
|
|
3383
3786
|
this._pool = [];
|
|
3384
3787
|
this._dropZone = null;
|
|
3385
3788
|
this._dragActive = false;
|
|
3386
3789
|
this._junctions = [];
|
|
3387
3790
|
this._toolbarsOut = /* @__PURE__ */ new Map();
|
|
3791
|
+
this._leafContentRules = /* @__PURE__ */ new Map();
|
|
3388
3792
|
this._tabDragPending = null;
|
|
3389
3793
|
this._junctionsKey = ``;
|
|
3390
3794
|
this._junctionsRaf = null;
|
|
3391
3795
|
this._hostResizeObserver = null;
|
|
3796
|
+
this._toolbarSlots = /* @__PURE__ */ new Set();
|
|
3797
|
+
this._toolbarObserver = null;
|
|
3392
3798
|
this._onDragStart = (event) => {
|
|
3393
3799
|
const { panelId, pointerId, clientX, clientY } = event.detail;
|
|
3394
|
-
startDrag(panelId, this, pointerId, clientX, clientY);
|
|
3800
|
+
startDrag(panelId, this, pointerId, clientX, clientY, this._findPanelEl(panelId)?.kind);
|
|
3395
3801
|
};
|
|
3396
3802
|
this._onPoolSlotChange = () => {
|
|
3397
3803
|
this._syncPool();
|
|
@@ -3438,11 +3844,12 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3438
3844
|
const pathStr = this.shadowRoot?.getElementById(detail.id)?.getAttribute(`data-dock-path`);
|
|
3439
3845
|
if (pathStr === null || pathStr === void 0) return;
|
|
3440
3846
|
const path = parsePath(pathStr);
|
|
3441
|
-
const
|
|
3442
|
-
|
|
3443
|
-
const
|
|
3847
|
+
const closing = findNode(this._model, path);
|
|
3848
|
+
if (closing === null || !isStack(closing)) return;
|
|
3849
|
+
const moving = [...closing.panels];
|
|
3444
3850
|
this._returnAllToolbars();
|
|
3445
|
-
extractStack(this._model, path
|
|
3851
|
+
extractStack(this._model, path);
|
|
3852
|
+
for (const panelId of moving) addPanelToStack(this._firstStackAllowing(this._panelKind(panelId)), panelId);
|
|
3446
3853
|
this._commit();
|
|
3447
3854
|
};
|
|
3448
3855
|
this._onTabChange = (event, path) => {
|
|
@@ -3507,11 +3914,21 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3507
3914
|
this.addEventListener(`dock-panel-drag-start`, this._onDragStart);
|
|
3508
3915
|
this._hostResizeObserver = new ResizeObserver(() => this._scheduleJunctions());
|
|
3509
3916
|
this._hostResizeObserver.observe(this);
|
|
3917
|
+
this._scanToolbarSlots();
|
|
3918
|
+
this._toolbarObserver = new MutationObserver(() => this._scanToolbarSlots());
|
|
3919
|
+
this._toolbarObserver.observe(this, {
|
|
3920
|
+
childList: true,
|
|
3921
|
+
subtree: true,
|
|
3922
|
+
attributes: true,
|
|
3923
|
+
attributeFilter: [`slot`]
|
|
3924
|
+
});
|
|
3510
3925
|
}
|
|
3511
3926
|
disconnectedCallback() {
|
|
3512
3927
|
super.disconnectedCallback();
|
|
3513
3928
|
unregisterDockHost(this);
|
|
3514
3929
|
this.removeEventListener(`dock-panel-drag-start`, this._onDragStart);
|
|
3930
|
+
this._toolbarObserver?.disconnect();
|
|
3931
|
+
this._toolbarObserver = null;
|
|
3515
3932
|
this._hostResizeObserver?.disconnect();
|
|
3516
3933
|
this._hostResizeObserver = null;
|
|
3517
3934
|
if (this._junctionsRaf !== null) {
|
|
@@ -3564,6 +3981,19 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3564
3981
|
_scanPanels() {
|
|
3565
3982
|
return Array.from(this.children).filter((el) => el instanceof HTMLElement && el.tagName === `IXFX-DOCK-PANEL` && Boolean(el.panelId));
|
|
3566
3983
|
}
|
|
3984
|
+
/** Refresh the set of provided `toolbar-<name>` slots; re-render on change. */
|
|
3985
|
+
_scanToolbarSlots() {
|
|
3986
|
+
const found = /* @__PURE__ */ new Set();
|
|
3987
|
+
for (const child of this.children) {
|
|
3988
|
+
if (!(child instanceof HTMLElement)) continue;
|
|
3989
|
+
const slot = child.getAttribute(`slot`) ?? ``;
|
|
3990
|
+
if (slot.startsWith(`toolbar-`) && slot.length > `toolbar-`.length) found.add(slot);
|
|
3991
|
+
}
|
|
3992
|
+
if (found.size !== this._toolbarSlots.size || [...found].some((s) => !this._toolbarSlots.has(s))) {
|
|
3993
|
+
this._toolbarSlots = found;
|
|
3994
|
+
this.requestUpdate();
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3567
3997
|
_findPanelEl(panelId) {
|
|
3568
3998
|
return this._pool.find((p) => p.panelId === panelId) ?? this._scanPanels().find((p) => p.panelId === panelId);
|
|
3569
3999
|
}
|
|
@@ -3577,7 +4007,33 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3577
4007
|
return fresh;
|
|
3578
4008
|
}
|
|
3579
4009
|
_appendPanelToFirstStack(panelId) {
|
|
3580
|
-
|
|
4010
|
+
const kind = this._panelKind(panelId);
|
|
4011
|
+
if (this._model.kind === `stack` && this._stackAllowsKind(this._model, kind)) {
|
|
4012
|
+
addPanelToStack(this._model, panelId);
|
|
4013
|
+
return;
|
|
4014
|
+
}
|
|
4015
|
+
addPanelToStack(this._firstStackAllowing(kind), panelId);
|
|
4016
|
+
}
|
|
4017
|
+
/** Normalized content kind of a panel (`'any'` when unknown/unset). */
|
|
4018
|
+
_panelKind(panelId) {
|
|
4019
|
+
return normalizeKind(this._findPanelEl(panelId)?.kind);
|
|
4020
|
+
}
|
|
4021
|
+
/** Whether `kind` may live in `stack` under the current leaf rules. */
|
|
4022
|
+
_stackAllowsKind(stack, kind) {
|
|
4023
|
+
if (stack.name === void 0) return true;
|
|
4024
|
+
const rules = this._leafContentRules.get(stack.name);
|
|
4025
|
+
if (rules === void 0) return true;
|
|
4026
|
+
if (rules.deny.has(kind)) return false;
|
|
4027
|
+
return rules.allow === null || rules.allow.has(kind);
|
|
4028
|
+
}
|
|
4029
|
+
/** First stack (tree order) whose rules admit `kind`, else the first stack. */
|
|
4030
|
+
_firstStackAllowing(kind) {
|
|
4031
|
+
for (const path of collectStackPaths(this._model)) {
|
|
4032
|
+
const node = findNode(this._model, path);
|
|
4033
|
+
if (node !== null && isStack(node) && this._stackAllowsKind(node, kind)) return node;
|
|
4034
|
+
}
|
|
4035
|
+
console.warn(`[ixfx-dock-host] no leaf admits kind "${kind}", using first stack`);
|
|
4036
|
+
return this._firstStack();
|
|
3581
4037
|
}
|
|
3582
4038
|
_syncPool() {
|
|
3583
4039
|
const current = this._scanPanels();
|
|
@@ -3619,7 +4075,34 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3619
4075
|
this.requestUpdate();
|
|
3620
4076
|
this._emitChange();
|
|
3621
4077
|
}
|
|
4078
|
+
/**
|
|
4079
|
+
* Dock a panel. Returns false (without touching the DOM) when the
|
|
4080
|
+
* explicitly targeted container denies the panel's `kind`.
|
|
4081
|
+
*/
|
|
3622
4082
|
addPanel(panel, target) {
|
|
4083
|
+
const kind = panel instanceof HTMLElement ? normalizeKind(panel.kind) : normalizeKind(panel.kind);
|
|
4084
|
+
const op = target?.op ?? `tabs`;
|
|
4085
|
+
let stackPath = null;
|
|
4086
|
+
let splitTarget = null;
|
|
4087
|
+
if (target?.container !== void 0) {
|
|
4088
|
+
const namedPath = findStackPathByName(this._model, target.container);
|
|
4089
|
+
if (namedPath === null) console.warn(`[ixfx-dock-host] addPanel: unknown container "${target.container}", appending to first admitting stack`);
|
|
4090
|
+
else if (op === `tabs` && !this._stackAllowsKindAt(namedPath, kind)) {
|
|
4091
|
+
console.warn(`[ixfx-dock-host] addPanel: container "${target.container}" does not admit kind "${kind}"`);
|
|
4092
|
+
return false;
|
|
4093
|
+
} else stackPath = namedPath;
|
|
4094
|
+
} else if (target?.stack) {
|
|
4095
|
+
const found = findStackOf(this._model, target.stack);
|
|
4096
|
+
if (found === null) console.warn(`[ixfx-dock-host] addPanel: unknown stack panel "${target.stack}", appending to first admitting stack`);
|
|
4097
|
+
else if (op === `tabs` && !this._stackAllowsKindAt(found, kind)) {
|
|
4098
|
+
console.warn(`[ixfx-dock-host] addPanel: target stack does not admit kind "${kind}"`);
|
|
4099
|
+
return false;
|
|
4100
|
+
} else stackPath = found;
|
|
4101
|
+
}
|
|
4102
|
+
if (stackPath !== null && op !== `tabs`) {
|
|
4103
|
+
splitTarget = stackPath;
|
|
4104
|
+
stackPath = null;
|
|
4105
|
+
}
|
|
3623
4106
|
let el;
|
|
3624
4107
|
if (panel instanceof HTMLElement) el = panel;
|
|
3625
4108
|
else {
|
|
@@ -3629,19 +4112,16 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3629
4112
|
if (panel.iconName !== void 0) el.iconName = panel.iconName;
|
|
3630
4113
|
if (panel.closable !== void 0) el.closable = panel.closable;
|
|
3631
4114
|
if (panel.collapsible !== void 0) el.collapsible = panel.collapsible;
|
|
4115
|
+
if (panel.kind !== void 0) el.kind = panel.kind;
|
|
3632
4116
|
}
|
|
3633
4117
|
if (el.parentElement !== this) this.appendChild(el);
|
|
3634
4118
|
if (!this._pool.some((p) => p.panelId === el.panelId)) this._pool = [...this._pool, el];
|
|
3635
4119
|
this._returnAllToolbars();
|
|
3636
|
-
|
|
3637
|
-
if (
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
const stack = findNode(this._model, stackPath);
|
|
3642
|
-
if (stack !== null && isStack(stack)) addPanelToStack(stack, el.panelId, target.index);
|
|
3643
|
-
} else insertBeside(this._model, stackPath, opToDirection(op), createStack([el.panelId]), `after`);
|
|
3644
|
-
}
|
|
4120
|
+
if (collectPanelIds(this._model).includes(el.panelId)) this._removeFromModel(el.panelId);
|
|
4121
|
+
if (splitTarget !== null) insertBeside(this._model, splitTarget, opToDirection(op), createStack([el.panelId]), `after`);
|
|
4122
|
+
else if (stackPath !== null) {
|
|
4123
|
+
const stack = findNode(this._model, stackPath);
|
|
4124
|
+
if (stack !== null && isStack(stack)) addPanelToStack(stack, el.panelId, target?.index);
|
|
3645
4125
|
} else this._appendPanelToFirstStack(el.panelId);
|
|
3646
4126
|
normalize(this._model);
|
|
3647
4127
|
this.requestUpdate();
|
|
@@ -3651,6 +4131,12 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3651
4131
|
composed: true
|
|
3652
4132
|
}));
|
|
3653
4133
|
this._emitChange();
|
|
4134
|
+
return true;
|
|
4135
|
+
}
|
|
4136
|
+
/** Whether the stack at `stackPath` admits `kind` under the leaf rules. */
|
|
4137
|
+
_stackAllowsKindAt(stackPath, kind) {
|
|
4138
|
+
const stack = findNode(this._model, stackPath);
|
|
4139
|
+
return stack !== null && isStack(stack) && this._stackAllowsKind(stack, kind);
|
|
3654
4140
|
}
|
|
3655
4141
|
removePanel(panelId) {
|
|
3656
4142
|
if (!collectPanelIds(this._model).includes(panelId)) return false;
|
|
@@ -3686,6 +4172,123 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3686
4172
|
getPanelIds() {
|
|
3687
4173
|
return collectPanelIds(this._model);
|
|
3688
4174
|
}
|
|
4175
|
+
/** Names of every named stack leaf, in tree order. */
|
|
4176
|
+
getContainerNames() {
|
|
4177
|
+
return collectContainerNames(this._model);
|
|
4178
|
+
}
|
|
4179
|
+
/**
|
|
4180
|
+
* Snapshot of a named container (`{ name, panels, active }`), or null when
|
|
4181
|
+
* no stack carries that name. First match wins when duplicated.
|
|
4182
|
+
*/
|
|
4183
|
+
getContainer(name) {
|
|
4184
|
+
const path = findStackPathByName(this._model, name);
|
|
4185
|
+
if (path === null) return null;
|
|
4186
|
+
const node = findNode(this._model, path);
|
|
4187
|
+
if (node === null || !isStack(node) || node.name === void 0) return null;
|
|
4188
|
+
return {
|
|
4189
|
+
name: node.name,
|
|
4190
|
+
panels: [...node.panels],
|
|
4191
|
+
active: node.active
|
|
4192
|
+
};
|
|
4193
|
+
}
|
|
4194
|
+
/** Panel-ids in a named container, in tab order (`[]` when unknown/empty). */
|
|
4195
|
+
getContainerPanels(name) {
|
|
4196
|
+
return this.getContainer(name)?.panels ?? [];
|
|
4197
|
+
}
|
|
4198
|
+
/** Panel elements in a named container, in tab order — for iterating children. */
|
|
4199
|
+
getContainerElements(name) {
|
|
4200
|
+
return this.getContainerPanels(name).map((id) => this._findPanelEl(id)).filter((el) => el !== void 0);
|
|
4201
|
+
}
|
|
4202
|
+
/**
|
|
4203
|
+
* Restrict a named container to only the given panel kinds — e.g.
|
|
4204
|
+
* `setLeafExclusiveContents('editor', ['document'])`. `tabs` drops,
|
|
4205
|
+
* `addPanel`, and re-homing into the leaf then refuse other kinds, while
|
|
4206
|
+
* edge splits beside the leaf stay allowed (they create a new leaf).
|
|
4207
|
+
* Pass `[]` to seal the leaf (nothing admitted). Warns when no stack
|
|
4208
|
+
* currently carries `name`, but the rule is still stored and applies once
|
|
4209
|
+
* one appears. Rules are host policy: kept across `loadLayout()`, never
|
|
4210
|
+
* serialized.
|
|
4211
|
+
*/
|
|
4212
|
+
setLeafExclusiveContents(name, kinds) {
|
|
4213
|
+
const key = name.trim();
|
|
4214
|
+
if (!key) {
|
|
4215
|
+
console.warn(`[ixfx-dock-host] setLeafExclusiveContents: empty container name`);
|
|
4216
|
+
return;
|
|
4217
|
+
}
|
|
4218
|
+
const allow = new Set(kinds.map((k) => k.trim()).filter((k) => k.length > 0));
|
|
4219
|
+
const entry = this._leafContentRules.get(key) ?? {
|
|
4220
|
+
allow: null,
|
|
4221
|
+
deny: /* @__PURE__ */ new Set()
|
|
4222
|
+
};
|
|
4223
|
+
entry.allow = allow;
|
|
4224
|
+
this._leafContentRules.set(key, entry);
|
|
4225
|
+
if (findStackPathByName(this._model, key) === null) console.warn(`[ixfx-dock-host] setLeafExclusiveContents: no container named "${key}" yet; rule stored`);
|
|
4226
|
+
}
|
|
4227
|
+
/**
|
|
4228
|
+
* Forbid the given panel kinds in a named container — e.g.
|
|
4229
|
+
* `setLeafDenyContents('footer', ['files', 'document'])`. Everything else
|
|
4230
|
+
* stays admitted. Pass `[]` to lift the denial. See
|
|
4231
|
+
* {@link setLeafExclusiveContents} for scope/ordering notes.
|
|
4232
|
+
*/
|
|
4233
|
+
setLeafDenyContents(name, kinds) {
|
|
4234
|
+
const key = name.trim();
|
|
4235
|
+
if (!key) {
|
|
4236
|
+
console.warn(`[ixfx-dock-host] setLeafDenyContents: empty container name`);
|
|
4237
|
+
return;
|
|
4238
|
+
}
|
|
4239
|
+
const deny = new Set(kinds.map((k) => k.trim()).filter((k) => k.length > 0));
|
|
4240
|
+
const entry = this._leafContentRules.get(key) ?? {
|
|
4241
|
+
allow: null,
|
|
4242
|
+
deny: /* @__PURE__ */ new Set()
|
|
4243
|
+
};
|
|
4244
|
+
entry.deny = deny;
|
|
4245
|
+
if (entry.allow === null && entry.deny.size === 0) this._leafContentRules.delete(key);
|
|
4246
|
+
else this._leafContentRules.set(key, entry);
|
|
4247
|
+
if (findStackPathByName(this._model, key) === null) console.warn(`[ixfx-dock-host] setLeafDenyContents: no container named "${key}" yet; rule stored`);
|
|
4248
|
+
}
|
|
4249
|
+
/** Remove every content rule for a named container. */
|
|
4250
|
+
clearLeafContentRestrictions(name) {
|
|
4251
|
+
this._leafContentRules.delete(name.trim());
|
|
4252
|
+
}
|
|
4253
|
+
/** Copy of a container's rules, or null when unrestricted. */
|
|
4254
|
+
getLeafContentRestrictions(name) {
|
|
4255
|
+
const rules = this._leafContentRules.get(name.trim());
|
|
4256
|
+
if (rules === void 0) return null;
|
|
4257
|
+
return {
|
|
4258
|
+
allow: rules.allow === null ? null : [...rules.allow],
|
|
4259
|
+
deny: [...rules.deny]
|
|
4260
|
+
};
|
|
4261
|
+
}
|
|
4262
|
+
/**
|
|
4263
|
+
* Geometric neighbours of a leaf (`name` or numeric `path`) — what sits
|
|
4264
|
+
* above / below / left / right of it on screen. Each entry is
|
|
4265
|
+
* `{ name, path }` (`name` is null for unnamed leaves), ordered
|
|
4266
|
+
* most-overlapping first. Returns null when the leaf is unknown.
|
|
4267
|
+
*/
|
|
4268
|
+
getNeighbours(leaf) {
|
|
4269
|
+
return getLeafNeighbours(this._model, leaf);
|
|
4270
|
+
}
|
|
4271
|
+
/**
|
|
4272
|
+
* Move a leaf one position in `direction`, swapping with the neighbour it
|
|
4273
|
+
* shares the longest edge with (both keep the remaining structure intact).
|
|
4274
|
+
* Returns false when the leaf is unknown or nothing adjoins that way.
|
|
4275
|
+
*/
|
|
4276
|
+
moveLeaf(leaf, direction) {
|
|
4277
|
+
if (!moveLeafStep(this._model, leaf, direction)) return false;
|
|
4278
|
+
this._commit();
|
|
4279
|
+
return true;
|
|
4280
|
+
}
|
|
4281
|
+
/**
|
|
4282
|
+
* Move a leaf to an edge of the overall layout (e.g. toggle a sidebar from
|
|
4283
|
+
* `left` to `right`). The rest of the layout stays intact as a single
|
|
4284
|
+
* subtree and the leaf keeps its absolute size along the target axis.
|
|
4285
|
+
* Returns false when the leaf is unknown or the layout holds one leaf.
|
|
4286
|
+
*/
|
|
4287
|
+
moveLeafToEdge(leaf, edge) {
|
|
4288
|
+
if (!moveLeafNodeToEdge(this._model, leaf, edge)) return false;
|
|
4289
|
+
this._commit();
|
|
4290
|
+
return true;
|
|
4291
|
+
}
|
|
3689
4292
|
/**
|
|
3690
4293
|
* Capture a structured-clone-safe {@link DockPanelSnapshot} of a panel
|
|
3691
4294
|
* (identity, chrome attributes, and a best-effort `innerHTML`). Returns
|
|
@@ -3700,6 +4303,7 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3700
4303
|
iconName: el.iconName,
|
|
3701
4304
|
closable: el.closable,
|
|
3702
4305
|
collapsible: el.collapsible,
|
|
4306
|
+
kind: normalizeKind(el.kind),
|
|
3703
4307
|
accepts: el.accepts,
|
|
3704
4308
|
contentHTML: el.innerHTML
|
|
3705
4309
|
};
|
|
@@ -3723,10 +4327,11 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3723
4327
|
* `accepts` / `canAccept`. Pure query: no model mutation, no overlay.
|
|
3724
4328
|
*
|
|
3725
4329
|
* `panelId` is passed to `canAccept`; use any stable id for an external
|
|
3726
|
-
* panel (defaults to `"__external__"`).
|
|
4330
|
+
* panel (defaults to `"__external__"`). `kind` covers leaf content rules
|
|
4331
|
+
* for panels unknown to this host (defaults to `'any'`).
|
|
3727
4332
|
*/
|
|
3728
|
-
queryDropTarget(clientX, clientY, panelId = `__external__
|
|
3729
|
-
const zone = this.computeDropZone(clientX, clientY, panelId);
|
|
4333
|
+
queryDropTarget(clientX, clientY, panelId = `__external__`, kind) {
|
|
4334
|
+
const zone = this.computeDropZone(clientX, clientY, panelId, kind);
|
|
3730
4335
|
return zone === null ? null : zoneToTarget(zone);
|
|
3731
4336
|
}
|
|
3732
4337
|
/**
|
|
@@ -3735,9 +4340,9 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3735
4340
|
* one. Call on every pointer update from the outer coordinator, then
|
|
3736
4341
|
* {@link endExternalDrop} when the drag leaves or ends.
|
|
3737
4342
|
*/
|
|
3738
|
-
previewExternalDrop(clientX, clientY, panelId = `__external__
|
|
4343
|
+
previewExternalDrop(clientX, clientY, panelId = `__external__`, kind) {
|
|
3739
4344
|
this.setDragActive(true);
|
|
3740
|
-
const zone = this.computeDropZone(clientX, clientY, panelId);
|
|
4345
|
+
const zone = this.computeDropZone(clientX, clientY, panelId, kind);
|
|
3741
4346
|
this.setDropZone(zone);
|
|
3742
4347
|
return zone === null ? null : zoneToTarget(zone);
|
|
3743
4348
|
}
|
|
@@ -3750,8 +4355,9 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3750
4355
|
* Recreate a panel from a {@link DockPanelSnapshot} (or a bare
|
|
3751
4356
|
* {@link DockPanelInit}) and dock it. With `at` viewport coordinates the
|
|
3752
4357
|
* panel lands where a drop there would put it (respecting `accepts` /
|
|
3753
|
-
* `canAccept`); without them, or when the point
|
|
3754
|
-
*
|
|
4358
|
+
* `canAccept` and leaf content rules); without them, or when the point
|
|
4359
|
+
* misses the host, it goes into the first stack admitting its kind.
|
|
4360
|
+
* Returns the created element, or null when a panel
|
|
3755
4361
|
* with that id is already docked here.
|
|
3756
4362
|
*/
|
|
3757
4363
|
acceptExternalPanel(snapshot, at) {
|
|
@@ -3762,6 +4368,7 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3762
4368
|
if (snapshot.iconName !== void 0) el.iconName = snapshot.iconName;
|
|
3763
4369
|
if (snapshot.closable !== void 0) el.closable = snapshot.closable;
|
|
3764
4370
|
if (snapshot.collapsible !== void 0) el.collapsible = snapshot.collapsible;
|
|
4371
|
+
if (`kind` in snapshot && snapshot.kind !== void 0) el.kind = snapshot.kind;
|
|
3765
4372
|
if (`accepts` in snapshot && snapshot.accepts) el.setAttribute(`accepts`, snapshot.accepts);
|
|
3766
4373
|
if (`contentHTML` in snapshot && snapshot.contentHTML) el.innerHTML = snapshot.contentHTML;
|
|
3767
4374
|
this._returnAllToolbars();
|
|
@@ -3787,9 +4394,10 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3787
4394
|
* a zone with rects relative to the host, or null when the pointer is
|
|
3788
4395
|
* outside the host or the candidate zone is disallowed.
|
|
3789
4396
|
*/
|
|
3790
|
-
computeDropZone(clientX, clientY, panelId) {
|
|
4397
|
+
computeDropZone(clientX, clientY, panelId, kind) {
|
|
3791
4398
|
const hostRect = this.getBoundingClientRect();
|
|
3792
4399
|
if (clientX < hostRect.left || clientX > hostRect.right || clientY < hostRect.top || clientY > hostRect.bottom) return null;
|
|
4400
|
+
const resolvedKind = kind?.trim() ? kind.trim() : this._panelKind(panelId);
|
|
3793
4401
|
const rel = (r) => ({
|
|
3794
4402
|
x: r.left - hostRect.left,
|
|
3795
4403
|
y: r.top - hostRect.top,
|
|
@@ -3817,7 +4425,7 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3817
4425
|
rect: rel(leafRect),
|
|
3818
4426
|
caretRect: this._stripCaretRect(strip, gapIndex, hostRect)
|
|
3819
4427
|
};
|
|
3820
|
-
return this._zoneAllowed(panelId, zone) ? zone : null;
|
|
4428
|
+
return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;
|
|
3821
4429
|
}
|
|
3822
4430
|
}
|
|
3823
4431
|
const relX = (clientX - leafRect.left) / Math.max(leafRect.width, 1);
|
|
@@ -3831,7 +4439,7 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3831
4439
|
gapIndex: stack.panels.length,
|
|
3832
4440
|
rect: rel(leafRect)
|
|
3833
4441
|
};
|
|
3834
|
-
return this._zoneAllowed(panelId, zone) ? zone : null;
|
|
4442
|
+
return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;
|
|
3835
4443
|
}
|
|
3836
4444
|
const r = rel(leafRect);
|
|
3837
4445
|
let operation;
|
|
@@ -3877,7 +4485,7 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3877
4485
|
side,
|
|
3878
4486
|
rect: zoneRect
|
|
3879
4487
|
};
|
|
3880
|
-
return this._zoneAllowed(panelId, zone) ? zone : null;
|
|
4488
|
+
return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;
|
|
3881
4489
|
}
|
|
3882
4490
|
const fromLeft = clientX - hostRect.left;
|
|
3883
4491
|
const fromRight = hostRect.right - clientX;
|
|
@@ -3933,15 +4541,18 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3933
4541
|
side,
|
|
3934
4542
|
rect: zoneRect
|
|
3935
4543
|
};
|
|
3936
|
-
return this._zoneAllowed(panelId, zone) ? zone : null;
|
|
4544
|
+
return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;
|
|
3937
4545
|
}
|
|
3938
|
-
_zoneAllowed(panelId, zone) {
|
|
4546
|
+
_zoneAllowed(panelId, zone, kind) {
|
|
3939
4547
|
if (!tokenAllows(this.accepts, operationToToken(zone.operation))) return false;
|
|
3940
4548
|
const stack = findNode(this._model, zone.targetPath);
|
|
3941
4549
|
if (stack !== null && isStack(stack) && stack.panels.length === 1) {
|
|
3942
4550
|
const target = this._findPanelEl(stack.panels[0]);
|
|
3943
4551
|
if (target && !panelAllows(target.accepts, operationToToken(zone.operation))) return false;
|
|
3944
4552
|
}
|
|
4553
|
+
if (zone.operation === `tabs` && stack !== null && isStack(stack)) {
|
|
4554
|
+
if (!this._stackAllowsKind(stack, kind?.trim() ? kind.trim() : this._panelKind(panelId))) return false;
|
|
4555
|
+
}
|
|
3945
4556
|
if (this.canAccept && !this.canAccept(panelId, zone.operation)) return false;
|
|
3946
4557
|
return true;
|
|
3947
4558
|
}
|
|
@@ -3956,22 +4567,32 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
3956
4567
|
this._appendPanelToFirstStack(panelId);
|
|
3957
4568
|
normalize(this._model);
|
|
3958
4569
|
}
|
|
3959
|
-
this._applyZone(panelId, zone);
|
|
4570
|
+
this._applyZone(panelId, zone, sourceHost === void 0 || sourceHost === this);
|
|
3960
4571
|
this._commit();
|
|
3961
4572
|
}
|
|
3962
4573
|
/**
|
|
3963
4574
|
* Move `panelId` (already present somewhere in the model) to the position
|
|
3964
4575
|
* described by `zone`. Shared by in-page drops and external panel adoption.
|
|
3965
4576
|
*/
|
|
3966
|
-
_applyZone(panelId, zone) {
|
|
4577
|
+
_applyZone(panelId, zone, transferName = false) {
|
|
3967
4578
|
const sourcePath = findStackOf(this._model, panelId);
|
|
4579
|
+
let vacated = null;
|
|
3968
4580
|
if (sourcePath !== null) {
|
|
3969
4581
|
const source = findNode(this._model, sourcePath);
|
|
3970
|
-
if (source !== null && isStack(source))
|
|
4582
|
+
if (source !== null && isStack(source)) {
|
|
4583
|
+
removePanelFromStack(source, panelId);
|
|
4584
|
+
if (source.panels.length === 0) vacated = source;
|
|
4585
|
+
}
|
|
3971
4586
|
}
|
|
3972
4587
|
if (zone.operation === `tabs`) {
|
|
3973
4588
|
const target = findNode(this._model, zone.targetPath);
|
|
3974
|
-
if (target !== null && isStack(target))
|
|
4589
|
+
if (target !== null && isStack(target)) {
|
|
4590
|
+
addPanelToStack(target, panelId, zone.gapIndex);
|
|
4591
|
+
if (transferName && vacated !== null && vacated !== target && vacated.name !== void 0 && target.name === void 0) {
|
|
4592
|
+
target.name = vacated.name;
|
|
4593
|
+
delete vacated.name;
|
|
4594
|
+
}
|
|
4595
|
+
}
|
|
3975
4596
|
} else insertBeside(this._model, zone.targetPath, opToDirection(zone.operation), createStack([panelId]), zone.side);
|
|
3976
4597
|
}
|
|
3977
4598
|
/**
|
|
@@ -4107,16 +4728,6 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
4107
4728
|
};
|
|
4108
4729
|
window.addEventListener(`click`, swallow, true);
|
|
4109
4730
|
}
|
|
4110
|
-
_splitStack(path, op) {
|
|
4111
|
-
const stack = findNode(this._model, path);
|
|
4112
|
-
if (stack === null || !isStack(stack) || stack.panels.length === 0) return;
|
|
4113
|
-
const activeId = stack.active;
|
|
4114
|
-
this._returnAllToolbars();
|
|
4115
|
-
removePanelFromStack(stack, activeId);
|
|
4116
|
-
normalize(this._model);
|
|
4117
|
-
insertBeside(this._model, path, opToDirection(op), createStack([activeId]), `after`);
|
|
4118
|
-
this._commit();
|
|
4119
|
-
}
|
|
4120
4731
|
_removeFromModel(panelId) {
|
|
4121
4732
|
const stackPath = findStackOf(this._model, panelId);
|
|
4122
4733
|
if (stackPath === null) return;
|
|
@@ -4247,6 +4858,7 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
4247
4858
|
id=${`dock-leaf-${pathStr}`}
|
|
4248
4859
|
class="leaf"
|
|
4249
4860
|
data-dock-path=${pathStr}
|
|
4861
|
+
data-dock-name=${stack.name ?? nothing}
|
|
4250
4862
|
size=${size === void 0 ? nothing : String(size)}
|
|
4251
4863
|
min=${collapsible ? `1px` : nothing}
|
|
4252
4864
|
when-small=${collapsible ? `collapse` : nothing}
|
|
@@ -4258,26 +4870,19 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
4258
4870
|
<slot name="empty"><span>Drop panels here</span></slot>
|
|
4259
4871
|
</div>
|
|
4260
4872
|
`);
|
|
4873
|
+
const toolbarSlot = stack.name !== void 0 && this._toolbarSlots.has(`toolbar-${stack.name}`) ? html`<slot name="toolbar-${stack.name}" slot="toolbar"></slot>` : nothing;
|
|
4261
4874
|
return leafAttrs(html`
|
|
4262
4875
|
<ixfx-tab-list
|
|
4263
4876
|
class="strip"
|
|
4264
4877
|
orientation="horizontal"
|
|
4878
|
+
scrollable
|
|
4879
|
+
shrink
|
|
4880
|
+
?hide-labels=${stack.hideLabels === true}
|
|
4265
4881
|
@change=${(e) => this._onTabChange(e, path)}
|
|
4266
4882
|
@pointerdown=${this._onStripPointerDown}
|
|
4267
4883
|
>
|
|
4268
4884
|
${repeat(stack.panels, (id) => id, (id) => this._renderTabItem(stack, id))}
|
|
4269
|
-
|
|
4270
|
-
<button
|
|
4271
|
-
class="chrome-btn"
|
|
4272
|
-
title="Split horizontally (top/bottom)"
|
|
4273
|
-
@click=${() => this._splitStack(path, `split-horizontal`)}
|
|
4274
|
-
>↕</button>
|
|
4275
|
-
<button
|
|
4276
|
-
class="chrome-btn"
|
|
4277
|
-
title="Split vertically (left/right)"
|
|
4278
|
-
@click=${() => this._splitStack(path, `split-vertical`)}
|
|
4279
|
-
>↔</button>
|
|
4280
|
-
</div>
|
|
4885
|
+
${toolbarSlot}
|
|
4281
4886
|
</ixfx-tab-list>
|
|
4282
4887
|
<div class="leaf-body">
|
|
4283
4888
|
<slot name="dock-panel-${stack.active}"></slot>
|
|
@@ -4357,9 +4962,14 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
4357
4962
|
.strip {
|
|
4358
4963
|
flex-shrink: 0;
|
|
4359
4964
|
border: 0;
|
|
4360
|
-
/* The leaf background shows through selected tabs;
|
|
4361
|
-
|
|
4965
|
+
/* The leaf background shows through selected tabs; a text underline
|
|
4966
|
+
(not the border indicator) carries the selection. */
|
|
4362
4967
|
--ixfx-tab-selected-background: transparent;
|
|
4968
|
+
--ixfx-selected-tab-border-width: 0;
|
|
4969
|
+
--ixfx-selected-tab-text-decoration: underline;
|
|
4970
|
+
--ixfx-selected-tab-text-decoration-thickness: 2px;
|
|
4971
|
+
--ixfx-selected-tab-text-decoration-offset: 4px;
|
|
4972
|
+
--ixfx-tab-hover-background: var(--surface-4);
|
|
4363
4973
|
}
|
|
4364
4974
|
|
|
4365
4975
|
/* Uniform tab height: a panel toolbar button would otherwise inflate
|
|
@@ -4368,6 +4978,11 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
4368
4978
|
height: var(--dock-tab-height, 30px);
|
|
4369
4979
|
}
|
|
4370
4980
|
|
|
4981
|
+
/* Breathing room between strip toolbars and the leaf edge. */
|
|
4982
|
+
.strip::part(list-toolbar) {
|
|
4983
|
+
padding-right: var(--space-xs);
|
|
4984
|
+
}
|
|
4985
|
+
|
|
4371
4986
|
.leaf-body {
|
|
4372
4987
|
flex: 1;
|
|
4373
4988
|
min-height: 0;
|
|
@@ -4389,38 +5004,6 @@ let DockHostElement = class DockHostElement extends LitElement {
|
|
|
4389
5004
|
margin: var(--space-s);
|
|
4390
5005
|
}
|
|
4391
5006
|
|
|
4392
|
-
.group-toolbar {
|
|
4393
|
-
display: flex;
|
|
4394
|
-
gap: 2px;
|
|
4395
|
-
padding: 0 var(--space-xs);
|
|
4396
|
-
}
|
|
4397
|
-
|
|
4398
|
-
.chrome-btn {
|
|
4399
|
-
display: inline-flex;
|
|
4400
|
-
align-items: center;
|
|
4401
|
-
justify-content: center;
|
|
4402
|
-
width: 1.6em;
|
|
4403
|
-
height: 1.6em;
|
|
4404
|
-
padding: 0;
|
|
4405
|
-
background: none;
|
|
4406
|
-
border: none;
|
|
4407
|
-
border-radius: var(--radius-s);
|
|
4408
|
-
color: inherit;
|
|
4409
|
-
cursor: pointer;
|
|
4410
|
-
opacity: var(--prominence-idle-opacity);
|
|
4411
|
-
transition: background var(--transition), opacity var(--transition);
|
|
4412
|
-
}
|
|
4413
|
-
|
|
4414
|
-
.chrome-btn:hover {
|
|
4415
|
-
background: var(--surface-5);
|
|
4416
|
-
opacity: var(--prominence-tickled-opacity);
|
|
4417
|
-
}
|
|
4418
|
-
|
|
4419
|
-
.chrome-btn:focus-visible {
|
|
4420
|
-
outline: 2px solid var(--accent);
|
|
4421
|
-
outline-offset: 1px;
|
|
4422
|
-
}
|
|
4423
|
-
|
|
4424
5007
|
.overlay {
|
|
4425
5008
|
position: absolute;
|
|
4426
5009
|
inset: 0;
|
|
@@ -4490,6 +5073,10 @@ __decorate([property({
|
|
|
4490
5073
|
type: String,
|
|
4491
5074
|
attribute: `accepts`
|
|
4492
5075
|
})], DockHostElement.prototype, "accepts", void 0);
|
|
5076
|
+
__decorate([property({
|
|
5077
|
+
type: Boolean,
|
|
5078
|
+
attribute: `isolated`
|
|
5079
|
+
})], DockHostElement.prototype, "isolated", void 0);
|
|
4493
5080
|
__decorate([property({ attribute: false })], DockHostElement.prototype, "canAccept", void 0);
|
|
4494
5081
|
__decorate([state()], DockHostElement.prototype, "_model", void 0);
|
|
4495
5082
|
__decorate([state()], DockHostElement.prototype, "_pool", void 0);
|
|
@@ -4537,6 +5124,10 @@ function zoneToTarget(zone) {
|
|
|
4537
5124
|
function cloneNode(node) {
|
|
4538
5125
|
return JSON.parse(JSON.stringify(node));
|
|
4539
5126
|
}
|
|
5127
|
+
/** Panel content kind, normalized (`'any'` when unset/blank). */
|
|
5128
|
+
function normalizeKind(kind) {
|
|
5129
|
+
return (kind?.trim() ?? ``) || `any`;
|
|
5130
|
+
}
|
|
4540
5131
|
function parsePath(pathStr) {
|
|
4541
5132
|
return pathStr.length === 0 ? [] : pathStr.split(`-`).filter((s) => s.length > 0).map(Number);
|
|
4542
5133
|
}
|
|
@@ -7900,6 +8491,6 @@ function init() {
|
|
|
7900
8491
|
console.log(`Init`);
|
|
7901
8492
|
}
|
|
7902
8493
|
//#endregion
|
|
7903
|
-
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, 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, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, applyAgeModification, applyHighlights, applySnapshot, attachTimelineInteractions, buildHighlightTargets, buildModel, clearHighlights, collectDataResult, collectPanelIds, collectStackPaths, computeColour, createAcCompletionProvider, createElementIncrSearch, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createVerticalListAdapter, distribute, extractStack, findNode, findParentOf, findStackOf, getActiveDragPanelId, getIcon, hasIcon, iconBus, init, insertBeside, isDragging, isSplit, isStack, monitorIndeterminate, normalise, normalize, parseColourScaleAttr, parseLayout, pointerOverAnyHost, readBaseColour, registerIcon, removePanelFromStack, resolveCssVars, resolveGrid, resolveTracks, serializeLayout, setActive, svgToDataUri, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
8494
|
+
export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, 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, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, applyAgeModification, applyHighlights, applySnapshot, attachTimelineInteractions, buildHighlightTargets, buildModel, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeLeafGeoms, createAcCompletionProvider, createElementIncrSearch, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createVerticalListAdapter, distribute, extractStack, findNode, findParentOf, findStackOf, findStackPathByName, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isSplit, isStack, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normalize, parseColourScaleAttr, parseLayout, pointerOverAnyHost, readBaseColour, registerFontIcon, registerIcon, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, svgToDataUri, swapLeaves, timelineStyles, toSnapshot, walk, wrapRoot };
|
|
7904
8495
|
|
|
7905
8496
|
//# sourceMappingURL=index.js.map
|