@nvidia-elements/core 2.23.5 → 2.23.6
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/CHANGELOG.md +6 -0
- package/dist/accordion/accordion2.js +4 -4
- package/dist/alert/alert-group2.js +1 -1
- package/dist/alert/alert2.js +1 -1
- package/dist/avatar/avatar-group2.js +1 -1
- package/dist/avatar/avatar2.js +1 -1
- package/dist/badge/badge2.js +1 -1
- package/dist/breadcrumb/breadcrumb2.js +1 -1
- package/dist/bundles/index.js +7 -7
- package/dist/button/button2.js +1 -1
- package/dist/button-group/button-group2.js +1 -1
- package/dist/card/card2.js +4 -4
- package/dist/chat-message/chat-message2.js +1 -1
- package/dist/checkbox/checkbox-group2.js +1 -1
- package/dist/checkbox/checkbox2.js +1 -1
- package/dist/color/color2.js +1 -1
- package/dist/combobox/combobox2.js +1 -1
- package/dist/copy-button/copy-button2.js +1 -1
- package/dist/custom-elements.json +1000 -229
- package/dist/date/date2.js +1 -1
- package/dist/datetime/datetime2.js +1 -1
- package/dist/dialog/dialog-footer2.js +1 -1
- package/dist/dialog/dialog-header2.js +1 -1
- package/dist/dialog/dialog2.js +1 -1
- package/dist/divider/divider2.js +1 -1
- package/dist/dot/dot2.js +1 -1
- package/dist/drag-handle/drag-handle2.js +1 -1
- package/dist/drawer/drawer-content2.js +1 -1
- package/dist/drawer/drawer-footer2.js +1 -1
- package/dist/drawer/drawer-header2.js +1 -1
- package/dist/drawer/drawer2.js +1 -1
- package/dist/dropdown/dropdown-footer2.js +1 -1
- package/dist/dropdown/dropdown-header2.js +1 -1
- package/dist/dropdown/dropdown2.js +1 -1
- package/dist/dropdown-group/dropdown-group.js +1 -1
- package/dist/dropzone/dropzone2.js +1 -1
- package/dist/file/file2.js +1 -1
- package/dist/format-bytes/format-bytes2.js +1 -1
- package/dist/format-datetime/format-datetime2.js +1 -1
- package/dist/format-number/format-number2.js +1 -1
- package/dist/format-relative-time/format-relative-time2.js +1 -1
- package/dist/format-truncate/format-truncate2.js +1 -1
- package/dist/forms/control/control2.js +1 -1
- package/dist/forms/control-group/control-group2.js +1 -1
- package/dist/forms/control-message/control-message2.js +1 -1
- package/dist/gauge/gauge2.js +1 -1
- package/dist/ghost/ghost2.js +1 -1
- package/dist/grid/cell/cell2.js +1 -1
- package/dist/grid/column/column2.js +1 -1
- package/dist/grid/footer/footer2.js +1 -1
- package/dist/grid/grid2.js +1 -1
- package/dist/grid/header/header2.js +1 -1
- package/dist/grid/placeholder/placeholder2.js +1 -1
- package/dist/grid/row/row2.js +1 -1
- package/dist/icon/icon2.js +1 -1
- package/dist/icon-button/icon-button2.js +1 -1
- package/dist/iframe/iframe2.js +1 -1
- package/dist/index.js +1 -1
- package/dist/input/input-group2.js +1 -1
- package/dist/input/input2.js +1 -1
- package/dist/joystick/joystick2.js +1 -1
- package/dist/logo/logo2.js +1 -1
- package/dist/menu/menu-group2.js +1 -1
- package/dist/menu/menu-item2.js +1 -1
- package/dist/menu/menu2.js +1 -1
- package/dist/month/month2.js +1 -1
- package/dist/notification/notification-group2.js +1 -1
- package/dist/notification/notification2.js +1 -1
- package/dist/page/page-panel/page-panel-content2.js +1 -1
- package/dist/page/page-panel/page-panel-footer2.js +1 -1
- package/dist/page/page-panel/page-panel-header2.js +1 -1
- package/dist/page/page-panel/page-panel2.js +1 -1
- package/dist/page/page2.js +1 -1
- package/dist/page-header/page-header2.js +1 -1
- package/dist/page-loader/page-loader2.js +1 -1
- package/dist/pagination/pagination2.js +1 -1
- package/dist/panel/panel2.js +4 -4
- package/dist/password/password2.js +1 -1
- package/dist/preferences-input/preferences-input2.js +1 -1
- package/dist/progress-bar/progress-bar2.js +1 -1
- package/dist/progress-dot/progress-dot2.js +1 -1
- package/dist/progress-ring/progress-ring2.js +1 -1
- package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
- package/dist/pulse/pulse2.js +1 -1
- package/dist/radio/radio-group2.js +1 -1
- package/dist/radio/radio2.js +1 -1
- package/dist/range/range2.js +1 -1
- package/dist/resize-handle/resize-handle2.js +1 -1
- package/dist/search/search2.js +1 -1
- package/dist/select/select2.js +1 -1
- package/dist/skeleton/skeleton2.js +1 -1
- package/dist/sort-button/sort-button2.js +1 -1
- package/dist/sparkline/sparkline2.js +1 -1
- package/dist/star-rating/star-rating2.js +1 -1
- package/dist/steps/steps2.js +2 -2
- package/dist/switch/switch-group2.js +1 -1
- package/dist/switch/switch2.js +1 -1
- package/dist/tabs/tabs-group2.js +1 -1
- package/dist/tabs/tabs-item-group2.js +1 -1
- package/dist/tabs/tabs2.js +2 -2
- package/dist/tag/tag2.js +1 -1
- package/dist/textarea/textarea2.js +1 -1
- package/dist/time/time2.js +1 -1
- package/dist/toast/toast2.js +1 -1
- package/dist/toggletip/toggletip-footer2.js +1 -1
- package/dist/toggletip/toggletip-header2.js +1 -1
- package/dist/toggletip/toggletip2.js +1 -1
- package/dist/toolbar/toolbar2.js +1 -1
- package/dist/tooltip/tooltip2.js +1 -1
- package/dist/tree/tree-node2.js +1 -1
- package/dist/tree/tree2.js +1 -1
- package/dist/week/week2.js +1 -1
- package/dist/workspace/controllers/workspace-composition.controller.d.ts +4 -1
- package/dist/workspace/controllers/workspace-composition.controller.js +69 -39
- package/dist/workspace/controllers/workspace-composition.controller.js.map +1 -1
- package/dist/workspace/controllers/workspace-rearrange.controller.js +27 -27
- package/dist/workspace/controllers/workspace-rearrange.controller.js.map +1 -1
- package/dist/workspace/controllers/workspace-restoration.controller.js +2 -2
- package/dist/workspace/controllers/workspace-restoration.controller.js.map +1 -1
- package/dist/workspace/panel/panel2.js +2 -2
- package/dist/workspace/panel/panel2.js.map +1 -1
- package/dist/workspace/panel-content/panel-content2.js +1 -1
- package/dist/workspace/panel-footer/panel-footer2.js +1 -1
- package/dist/workspace/panel-header/panel-header2.js +1 -1
- package/dist/workspace/utils/comparison.utils.d.ts +3 -0
- package/dist/workspace/utils/comparison.utils.js +13 -0
- package/dist/workspace/utils/comparison.utils.js.map +1 -0
- package/dist/workspace/utils/evaluation.utils.d.ts +65 -6
- package/dist/workspace/utils/evaluation.utils.js +334 -99
- package/dist/workspace/utils/evaluation.utils.js.map +1 -1
- package/dist/workspace/utils/geometry/allocation.utils.js +15 -13
- package/dist/workspace/utils/geometry/allocation.utils.js.map +1 -1
- package/dist/workspace/utils/geometry/sizing.utils.d.ts +2 -0
- package/dist/workspace/utils/geometry/sizing.utils.js +37 -17
- package/dist/workspace/utils/geometry/sizing.utils.js.map +1 -1
- package/dist/workspace/utils/interaction/boundary.utils.d.ts +2 -2
- package/dist/workspace/utils/interaction/boundary.utils.js +2 -2
- package/dist/workspace/utils/interaction/boundary.utils.js.map +1 -1
- package/dist/workspace/utils/interaction/drag-preview.utils.d.ts +3 -3
- package/dist/workspace/utils/interaction/drag-preview.utils.js.map +1 -1
- package/dist/workspace/utils/interaction/insertion-offers.utils.d.ts +11 -9
- package/dist/workspace/utils/interaction/insertion-offers.utils.js +37 -43
- package/dist/workspace/utils/interaction/insertion-offers.utils.js.map +1 -1
- package/dist/workspace/utils/interaction/placement-decision.utils.d.ts +6 -1
- package/dist/workspace/utils/interaction/placement-decision.utils.js +94 -87
- package/dist/workspace/utils/interaction/placement-decision.utils.js.map +1 -1
- package/dist/workspace/utils/model/layout.utils.d.ts +2 -1
- package/dist/workspace/utils/model/layout.utils.js +12 -10
- package/dist/workspace/utils/model/layout.utils.js.map +1 -1
- package/dist/workspace/utils/model/membership.utils.d.ts +4 -0
- package/dist/workspace/utils/model/membership.utils.js +13 -4
- package/dist/workspace/utils/model/membership.utils.js.map +1 -1
- package/dist/workspace/utils/model/operations.utils.d.ts +1 -0
- package/dist/workspace/utils/model/operations.utils.js +51 -46
- package/dist/workspace/utils/model/operations.utils.js.map +1 -1
- package/dist/workspace/utils/model/projection.utils.d.ts +4 -2
- package/dist/workspace/utils/model/projection.utils.js +49 -40
- package/dist/workspace/utils/model/projection.utils.js.map +1 -1
- package/dist/workspace/utils/model/value.utils.d.ts +4 -3
- package/dist/workspace/utils/model/value.utils.js +15 -50
- package/dist/workspace/utils/model/value.utils.js.map +1 -1
- package/dist/workspace/utils/placement/acquisition-sizing.utils.d.ts +2 -0
- package/dist/workspace/utils/placement/acquisition-sizing.utils.js +30 -22
- package/dist/workspace/utils/placement/acquisition-sizing.utils.js.map +1 -1
- package/dist/workspace/utils/placement/group-insertion.utils.d.ts +19 -13
- package/dist/workspace/utils/placement/group-insertion.utils.js +50 -47
- package/dist/workspace/utils/placement/group-insertion.utils.js.map +1 -1
- package/dist/workspace/utils/placement/planner.utils.d.ts +13 -2
- package/dist/workspace/utils/placement/planner.utils.js +79 -73
- package/dist/workspace/utils/placement/planner.utils.js.map +1 -1
- package/dist/workspace/utils/placement/preparation.utils.d.ts +5 -2
- package/dist/workspace/utils/placement/preparation.utils.js +45 -41
- package/dist/workspace/utils/placement/preparation.utils.js.map +1 -1
- package/dist/workspace/utils/placement/region.utils.js +32 -32
- package/dist/workspace/utils/placement/region.utils.js.map +1 -1
- package/dist/workspace/utils/placement/scope.utils.d.ts +34 -0
- package/dist/workspace/utils/placement/scope.utils.js +155 -0
- package/dist/workspace/utils/placement/scope.utils.js.map +1 -0
- package/dist/workspace/utils/placement/session.utils.d.ts +11 -0
- package/dist/workspace/utils/placement/session.utils.js +78 -0
- package/dist/workspace/utils/placement/session.utils.js.map +1 -0
- package/dist/workspace/utils/placement/split-sizing.utils.d.ts +2 -2
- package/dist/workspace/utils/placement/split-sizing.utils.js +19 -19
- package/dist/workspace/utils/placement/split-sizing.utils.js.map +1 -1
- package/dist/workspace/utils/presentation/composition.utils.d.ts +1 -1
- package/dist/workspace/utils/presentation/composition.utils.js +4 -2
- package/dist/workspace/utils/presentation/composition.utils.js.map +1 -1
- package/dist/workspace/utils/presentation/groups.utils.d.ts +3 -3
- package/dist/workspace/utils/presentation/groups.utils.js +40 -30
- package/dist/workspace/utils/presentation/groups.utils.js.map +1 -1
- package/dist/workspace/utils/presentation/measurements.utils.d.ts +1 -0
- package/dist/workspace/utils/presentation/measurements.utils.js +6 -14
- package/dist/workspace/utils/presentation/measurements.utils.js.map +1 -1
- package/dist/workspace/utils/presentation/offers.utils.d.ts +1 -1
- package/dist/workspace/utils/presentation/offers.utils.js +3 -3
- package/dist/workspace/utils/presentation/offers.utils.js.map +1 -1
- package/dist/workspace/utils/presentation/preview.utils.d.ts +6 -0
- package/dist/workspace/utils/presentation/preview.utils.js +14 -3
- package/dist/workspace/utils/presentation/preview.utils.js.map +1 -1
- package/dist/workspace/workspace.examples.js.map +1 -1
- package/dist/workspace/workspace.examples.json +4 -4
- package/dist/workspace/workspace.js +1 -1
- package/dist/workspace/workspace.js.map +1 -1
- package/dist/workspace/workspace2.js +206 -212
- package/dist/workspace/workspace2.js.map +1 -1
- package/package.json +1 -1
- package/dist/workspace/utils/placement/context.utils.d.ts +0 -36
- package/dist/workspace/utils/placement/context.utils.js +0 -135
- package/dist/workspace/utils/placement/context.utils.js.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { getPanelIds as e, getSplitSide as t } from "../model/layout.utils.js";
|
|
2
2
|
import { findGroup as n, projectLayout as r } from "../model/operations.utils.js";
|
|
3
3
|
import { clipCue as i, matchesPlacementIntent as a } from "./drag-preview.utils.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
4
|
+
import { getTabInsertionIndex as o, preservesGroupMembership as s } from "../model/membership.utils.js";
|
|
5
|
+
import { createScopeRectResolver as c } from "../placement/scope.utils.js";
|
|
6
|
+
import { findWorkspaceRegion as l } from "../placement/region.utils.js";
|
|
7
|
+
import { getGroupInsertion as u } from "../placement/group-insertion.utils.js";
|
|
8
|
+
import { resolvePlacementPlan as d } from "../placement/planner.utils.js";
|
|
9
|
+
import { createInsertionOffers as f, findSourcePeerRegionKey as p, getOrderHintRect as m, getPlacementOfferIntent as h, placementOwnsChrome as g } from "./insertion-offers.utils.js";
|
|
10
|
+
import { getBoundaryPlacementOffers as _ } from "./boundary.utils.js";
|
|
11
11
|
// src/workspace/utils/interaction/placement-decision.utils.ts
|
|
12
12
|
var v = (e, t) => t.x >= e.x && t.x < e.x + e.width && t.y >= e.y && t.y < e.y + e.height;
|
|
13
13
|
function y(e) {
|
|
14
|
-
let { placement: t, point: n } = e, r = !!t.headerTarget, i =
|
|
14
|
+
let { placement: t, point: n } = e, r = !!t.headerTarget, i = S(e, t.headerTarget ?? (v(t.bounds, n) ? t.targets.find((e) => v(e.rect, n)) : void 0), r);
|
|
15
15
|
return b({
|
|
16
16
|
...t,
|
|
17
17
|
source: e.source,
|
|
@@ -22,25 +22,23 @@ function y(e) {
|
|
|
22
22
|
gap: e.gap,
|
|
23
23
|
available: e.available,
|
|
24
24
|
projectLayout: e.projectLayout,
|
|
25
|
-
planPlacement: e.planPlacement
|
|
25
|
+
planPlacement: e.planPlacement,
|
|
26
|
+
placementSession: e.placementSession
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
29
|
function b(e) {
|
|
29
|
-
let t =
|
|
30
|
+
let t = D({
|
|
30
31
|
...e,
|
|
31
|
-
|
|
32
|
-
}), n =
|
|
33
|
-
offer: t,
|
|
34
|
-
distance: k(t, e.point)
|
|
35
|
-
})).sort((e, t) => e.distance - t.distance)[0], s = v(e.bounds, e.point) ? t.offers.find((t) => v(t.hitRect ?? t.rect, e.point) && (!e.header || m(t))) : void 0, c = t.hit ?? s;
|
|
32
|
+
resolveScopeRect: e.resolveScopeRect ?? c()
|
|
33
|
+
}), n = k(t.offers, e), r = w(e), i = t.offers.filter((t) => T(t, r, e.bounds)), a = x(i, n, e.point), o = v(e.bounds, e.point) ? t.offers.find((t) => v(t.hitRect ?? t.rect, e.point) && (!e.header || g(t))) : void 0, s = t.hit ?? o;
|
|
36
34
|
return {
|
|
37
|
-
acquisition:
|
|
38
|
-
plan:
|
|
39
|
-
rect:
|
|
35
|
+
acquisition: s ? {
|
|
36
|
+
plan: s.plan,
|
|
37
|
+
rect: s.hitRect ?? s.rect
|
|
40
38
|
} : void 0,
|
|
41
|
-
intent:
|
|
42
|
-
hint:
|
|
43
|
-
hit:
|
|
39
|
+
intent: O(e, s),
|
|
40
|
+
hint: E({
|
|
41
|
+
hit: s && i.includes(s) ? s : void 0,
|
|
44
42
|
selectedKey: n,
|
|
45
43
|
boundary: t.hit,
|
|
46
44
|
nearest: a
|
|
@@ -48,61 +46,73 @@ function b(e) {
|
|
|
48
46
|
};
|
|
49
47
|
}
|
|
50
48
|
function x(e, t, n) {
|
|
49
|
+
let r, i = Infinity;
|
|
50
|
+
for (let a of e) {
|
|
51
|
+
if (a.insertion.key === t) continue;
|
|
52
|
+
let e = A(a, n);
|
|
53
|
+
(!r || e < i) && (r = a, i = e);
|
|
54
|
+
}
|
|
55
|
+
return r && {
|
|
56
|
+
offer: r,
|
|
57
|
+
distance: i
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function S(e, t, n) {
|
|
51
61
|
let { reservationHit: r } = e.placement, i = !n && r, a = n && r === "tab" && e.heldIntent.kind === "tab";
|
|
52
62
|
if (i || a) return e.heldIntent;
|
|
53
63
|
if (!t) return;
|
|
54
64
|
let o = t.panels[0];
|
|
55
|
-
return o ? n ?
|
|
65
|
+
return o ? n ? C(e, t, o) : {
|
|
56
66
|
kind: "split",
|
|
57
67
|
destination: {
|
|
58
68
|
target: o,
|
|
59
|
-
position:
|
|
69
|
+
position: L(e.point, {
|
|
60
70
|
rect: t.rect,
|
|
61
71
|
headerHeight: t.headerHeight
|
|
62
72
|
})
|
|
63
73
|
}
|
|
64
74
|
} : { kind: "invalid" };
|
|
65
75
|
}
|
|
66
|
-
function
|
|
67
|
-
let i = t.tabs.find((t) => e.point.x < t.rect.x + t.rect.width / 2), a = n(e.canonicalRoot, r)?.panels ?? [],
|
|
76
|
+
function C(e, t, r) {
|
|
77
|
+
let i = t.tabs.find((t) => e.point.x < t.rect.x + t.rect.width / 2), a = n(e.canonicalRoot, r)?.panels ?? [], c = {
|
|
68
78
|
kind: "tab",
|
|
69
79
|
destination: {
|
|
70
80
|
target: r,
|
|
71
81
|
position: "tab",
|
|
72
|
-
index:
|
|
82
|
+
index: o(a, i?.id)
|
|
73
83
|
}
|
|
74
84
|
};
|
|
75
|
-
return e.groupable ||
|
|
85
|
+
return e.groupable || s({
|
|
76
86
|
root: e.canonicalRoot,
|
|
77
87
|
source: e.source,
|
|
78
|
-
intent:
|
|
79
|
-
}) ?
|
|
88
|
+
intent: c
|
|
89
|
+
}) ? c : void 0;
|
|
80
90
|
}
|
|
81
|
-
function
|
|
91
|
+
function w(e) {
|
|
82
92
|
let t = e.preview;
|
|
83
|
-
if (e.
|
|
93
|
+
if (e.sourceReservation && t?.phase === "detached" && !t.blocked && t.allocation === "reserved" && t.cue.kind === "group") return i(e.sourceReservation, e.bounds);
|
|
84
94
|
}
|
|
85
|
-
function
|
|
95
|
+
function T(e, t, n) {
|
|
86
96
|
if (!t) return !0;
|
|
87
97
|
let r = i(e.rect, n), a = e.destination.position === "left" || e.destination.position === "right", o = a ? "x" : "y", s = a ? "width" : "height", c = a ? "y" : "x", l = a ? "height" : "width";
|
|
88
98
|
return r[o] > t[o] && r[o] + r[s] < t[o] + t[s] ? !(r[c] >= t[c] && r[c] + r[l] <= t[c] + t[l]) : !0;
|
|
89
99
|
}
|
|
90
|
-
function
|
|
91
|
-
if (e && e.
|
|
100
|
+
function E({ hit: e, selectedKey: t, boundary: n, nearest: r }) {
|
|
101
|
+
if (e && e.insertion.key !== t) return e;
|
|
92
102
|
if (!n && r && r.distance <= 24) return r.offer;
|
|
93
103
|
}
|
|
94
|
-
function
|
|
95
|
-
let t = (e.projectLayout ?? r)(e.currentLayout, e.available).root, n = e.orderingRegions ?? e.regions, i =
|
|
104
|
+
function D(e) {
|
|
105
|
+
let t = (e.projectLayout ?? r)(e.currentLayout, e.available).root, n = e.orderingRegions ?? e.regions, i = f({
|
|
96
106
|
...e,
|
|
97
107
|
root: t,
|
|
98
108
|
regions: n,
|
|
99
109
|
explorationRegions: e.regions,
|
|
100
|
-
existing:
|
|
110
|
+
existing: M({
|
|
101
111
|
...e,
|
|
102
112
|
root: t
|
|
103
113
|
})
|
|
104
114
|
});
|
|
105
|
-
return
|
|
115
|
+
return _({
|
|
106
116
|
offers: i,
|
|
107
117
|
bounds: e.bounds,
|
|
108
118
|
point: e.point,
|
|
@@ -112,52 +122,54 @@ function E(e) {
|
|
|
112
122
|
regions: n,
|
|
113
123
|
source: e.source,
|
|
114
124
|
gap: e.gap,
|
|
115
|
-
|
|
125
|
+
resolveScopeRect: e.resolveScopeRect
|
|
116
126
|
}
|
|
117
127
|
});
|
|
118
128
|
}
|
|
119
|
-
function D(e, t) {
|
|
120
|
-
if (t) return p(t);
|
|
121
|
-
if (v(e.bounds, e.point)) return e.sourceSlot && v(e.sourceSlot, e.point) ? e.preview?.intent ?? e.local : e.local;
|
|
122
|
-
}
|
|
123
129
|
function O(e, t) {
|
|
130
|
+
if (t) return h(t);
|
|
131
|
+
if (v(e.bounds, e.point)) return e.sourceReservation && v(e.sourceReservation, e.point) ? e.preview?.intent ?? e.local : e.local;
|
|
132
|
+
}
|
|
133
|
+
function k(e, t) {
|
|
124
134
|
let n = t.preview;
|
|
125
|
-
if (n && n.phase === "detached") return "layout" in n ?
|
|
135
|
+
if (n && n.phase === "detached") return "layout" in n ? u({
|
|
126
136
|
plan: n,
|
|
127
137
|
source: t.source,
|
|
128
138
|
available: t.available,
|
|
129
|
-
projectLayout: t.projectLayout
|
|
130
|
-
|
|
139
|
+
projectLayout: t.projectLayout,
|
|
140
|
+
placementSession: t.placementSession,
|
|
141
|
+
planPlacement: t.planPlacement
|
|
142
|
+
})?.key : e.find((e) => a(h(e), n.intent))?.insertion.key;
|
|
131
143
|
}
|
|
132
|
-
function
|
|
144
|
+
function A(e, t) {
|
|
133
145
|
let n = e.hitRect ?? e.rect, r = e.destination.position === "left" || e.destination.position === "right", i = r ? t.y : t.x, a = r ? n.y : n.x, o = r ? n.height : n.width;
|
|
134
146
|
if (!(i >= a && i < a + o)) return Infinity;
|
|
135
147
|
let s = r ? t.x - n.x : t.y - n.y, c = r ? n.width : n.height;
|
|
136
148
|
return Math.abs(s - c / 2);
|
|
137
149
|
}
|
|
138
|
-
function
|
|
139
|
-
let { root: r, source: i } = t, a =
|
|
140
|
-
if (o?.type !== "split" || !
|
|
141
|
-
let
|
|
150
|
+
function j(t) {
|
|
151
|
+
let { root: r, source: i } = t, a = p(r, i) ?? "root", o = l(r, a), s = n(t.currentLayout.root, i[0]);
|
|
152
|
+
if (o?.type !== "split" || !F(s, i)) return;
|
|
153
|
+
let c = (n) => n.find((e) => e.key === a)?.rect ?? t.resolveScopeRect({
|
|
142
154
|
members: e(o).filter((e) => !i.includes(e)),
|
|
143
155
|
allocation: n,
|
|
144
156
|
source: i
|
|
145
|
-
}), u =
|
|
146
|
-
if (!u || !
|
|
147
|
-
let
|
|
148
|
-
if (!(
|
|
157
|
+
}), u = c(t.regions), d = c(t.orderingRegions ?? t.regions);
|
|
158
|
+
if (!u || !d) return;
|
|
159
|
+
let f = o.children.findIndex((e) => e.type === "group" && e.panels.some((e) => i.includes(e)));
|
|
160
|
+
if (!(f < 0)) return {
|
|
149
161
|
key: a,
|
|
150
162
|
owner: o,
|
|
151
163
|
rect: u,
|
|
152
|
-
adjacencyRect:
|
|
153
|
-
peers: o.children.flatMap((e, t) => t ===
|
|
164
|
+
adjacencyRect: d,
|
|
165
|
+
peers: o.children.flatMap((e, t) => t === f ? [] : [{
|
|
154
166
|
node: e,
|
|
155
167
|
index: t
|
|
156
168
|
}])
|
|
157
169
|
};
|
|
158
170
|
}
|
|
159
|
-
function
|
|
160
|
-
let t =
|
|
171
|
+
function M(e) {
|
|
172
|
+
let t = j(e);
|
|
161
173
|
if (!t) return [];
|
|
162
174
|
let n = t.peers.map((e) => ({
|
|
163
175
|
...e,
|
|
@@ -166,74 +178,69 @@ function j(e) {
|
|
|
166
178
|
return r && n.push({
|
|
167
179
|
...r,
|
|
168
180
|
after: !0
|
|
169
|
-
}), n.flatMap((n, r) =>
|
|
181
|
+
}), n.flatMap((n, r) => N({
|
|
170
182
|
input: e,
|
|
171
183
|
owner: t,
|
|
172
184
|
entry: n,
|
|
173
|
-
|
|
185
|
+
insertionIndex: r
|
|
174
186
|
}));
|
|
175
187
|
}
|
|
176
|
-
function
|
|
177
|
-
let o =
|
|
188
|
+
function N({ input: n, owner: r, entry: i, insertionIndex: a }) {
|
|
189
|
+
let o = I({
|
|
178
190
|
input: n,
|
|
179
191
|
owner: r,
|
|
180
192
|
entry: i,
|
|
181
|
-
|
|
193
|
+
insertionIndex: a
|
|
182
194
|
});
|
|
183
195
|
if (!o) return [];
|
|
184
|
-
let { region: s, before:
|
|
196
|
+
let { region: s, before: c } = o, l = {
|
|
185
197
|
target: e(i.node)[0],
|
|
186
198
|
region: s.key,
|
|
187
199
|
position: t(r.owner.axis, i.after ? "after" : "before")
|
|
188
|
-
},
|
|
189
|
-
|
|
200
|
+
}, f = d(n, l, "order");
|
|
201
|
+
if (f?.kind !== "reorder") return [];
|
|
202
|
+
let p = u({
|
|
203
|
+
plan: f,
|
|
190
204
|
source: n.source,
|
|
191
|
-
destination: d,
|
|
192
205
|
available: n.available,
|
|
193
206
|
projectLayout: n.projectLayout,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
let m = c({
|
|
198
|
-
plan: p,
|
|
199
|
-
source: n.source,
|
|
200
|
-
available: n.available,
|
|
201
|
-
projectLayout: n.projectLayout
|
|
202
|
-
}), h = N(i, a), g = h ? r.rect : r.adjacencyRect, _ = f({
|
|
207
|
+
placementSession: n.placementSession,
|
|
208
|
+
planPlacement: n.planPlacement
|
|
209
|
+
}), h = P(i, a), g = h ? r.rect : r.adjacencyRect, _ = m({
|
|
203
210
|
owner: g,
|
|
204
211
|
recipient: s.rect,
|
|
205
|
-
previous:
|
|
212
|
+
previous: c?.rect,
|
|
206
213
|
axis: r.owner.axis,
|
|
207
214
|
after: i.after,
|
|
208
|
-
|
|
215
|
+
sourceReservation: n.sourceReservation,
|
|
209
216
|
boundary: h
|
|
210
217
|
});
|
|
211
|
-
return !_ || !
|
|
212
|
-
destination:
|
|
218
|
+
return !_ || !p ? [] : [{
|
|
219
|
+
destination: l,
|
|
213
220
|
owner: r.key,
|
|
214
221
|
boundary: h,
|
|
215
222
|
rect: _,
|
|
216
223
|
scopeRect: g,
|
|
217
|
-
|
|
218
|
-
plan:
|
|
224
|
+
insertion: p,
|
|
225
|
+
plan: f,
|
|
219
226
|
kind: "order"
|
|
220
227
|
}];
|
|
221
228
|
}
|
|
222
|
-
function
|
|
229
|
+
function P(e, t) {
|
|
223
230
|
if (e.after) return "end";
|
|
224
231
|
if (t === 0) return "start";
|
|
225
232
|
}
|
|
226
|
-
function
|
|
233
|
+
function F(e, t) {
|
|
227
234
|
return !!e && e.panels.length === t.length && e.panels.every((e) => t.includes(e));
|
|
228
235
|
}
|
|
229
|
-
function
|
|
236
|
+
function I({ input: e, owner: t, entry: n, insertionIndex: r }) {
|
|
230
237
|
let i = e.orderingRegions ?? e.regions, a = i.find((e) => e.key === `${t.key}.${n.index}`), o = t.peers[r - 1], s = o && i.find((e) => e.key === `${t.key}.${o.index}`);
|
|
231
238
|
return !a || r > 0 && !n.after && !s ? void 0 : {
|
|
232
239
|
region: a,
|
|
233
240
|
before: s
|
|
234
241
|
};
|
|
235
242
|
}
|
|
236
|
-
function
|
|
243
|
+
function L(e, t) {
|
|
237
244
|
let { rect: n, headerHeight: r } = t, i = n.x + n.width / 2, a = Math.max(1, n.height - r), o = n.y + r + a / 2, s = (e.x - i) / Math.max(1, n.width / 2), c = (e.y - o) / Math.max(1, a / 2);
|
|
238
245
|
return Math.abs(s) > Math.abs(c) ? s < 0 ? "left" : "right" : c < 0 ? "top" : "bottom";
|
|
239
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"placement-decision.utils.js","names":["inside","point","rect","decidePointerPlacement","input","header","placement","local","localPlacementIntent","item","decidePlacement","boundary","placementOffers","createContextRectResolver","selectedKey","selectedScopeKey","sourceSlot","reservedSourceSlot","hints","eligiblePlacementHint","offer","nearest","distance","a","b","candidate","placementOwnsChrome","hit","acquiredIntent","placementHint","overReservedBody","reservationHit","overReservedTab","target","anchor","headerPlacementIntent","contentDirection","tab","preferred","findGroup","intent","getTabInsertionIndex","preservesGroupMembership","preview","clipCue","bounds","vertical","normal","normalSize","tangent","tangentSize","root","projectLayout","regions","offers","createInsertionOffers","orderOffers","getBoundaryPlacementOffers","getPlacementOfferIntent","describePlacementSlot","matchesPlacementIntent","start","extent","normalOffset","normalExtent","orderOwner","key","findSourcePeerRegionKey","source","owner","findWorkspaceRegion","group","wholeSource","ownerRect","region","getPanelIds","id","adjacencyRect","from","node","index","entries","peer","last","orderOffer","neighbors","orderNeighbors","destination","entry","getSplitSide","plan","planWorkspacePlacement","descriptor","orderBoundary","slot","area","getOrderHintRect","before","previous","centerX","contentHeight","headerHeight","centerY","dx","dy"],"sources":["../../../../src/workspace/utils/interaction/placement-decision.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Point, Rect } from '@nvidia-elements/core/internal';\n\nimport { getBoundaryPlacementOffers } from './boundary.utils.js';\nimport { clipCue, matchesPlacementIntent } from './drag-preview.utils.js';\nimport {\n createInsertionOffers,\n findSourcePeerRegionKey,\n getOrderHintRect,\n getPlacementOfferIntent,\n placementOwnsChrome\n} from './insertion-offers.utils.js';\nimport { getPanelIds, getSplitSide } from '../model/layout.utils.js';\nimport { getTabInsertionIndex, preservesGroupMembership } from '../model/membership.utils.js';\nimport { findGroup, projectLayout } from '../model/operations.utils.js';\nimport { createContextRectResolver } from '../placement/context.utils.js';\nimport { describePlacementSlot } from '../placement/group-insertion.utils.js';\nimport { planWorkspacePlacement } from '../placement/planner.utils.js';\nimport { findWorkspaceRegion } from '../placement/region.utils.js';\n\nimport type { WorkspacePlacedRegion } from '../geometry/allocation.utils.js';\nimport type { WorkspaceDragPreview, WorkspaceDropIntent, WorkspacePlacementAcquisition } from './drag-preview.utils.js';\nimport type { WorkspaceInsertionOffer } from './insertion-offers.utils.js';\nimport type { WorkspaceLayout, WorkspaceNode, WorkspaceSplit } from '../model/layout.utils.js';\nimport type { WorkspaceDestination } from '../model/operations.utils.js';\nimport type { WorkspaceLayoutProjector } from '../model/projection.utils.js';\nimport type { WorkspaceContextRectResolver } from '../placement/context.utils.js';\nimport type { WorkspacePlacementPlanner } from '../placement/planner.utils.js';\nimport type { WorkspaceTarget } from '../presentation/groups.utils.js';\nimport type { WorkspacePlacementCatalog } from '../evaluation.utils.js';\n\ninterface WorkspacePlacementQuery {\n gap: number;\n source: string[];\n point: Point;\n regions: WorkspacePlacedRegion[];\n orderingRegions?: WorkspacePlacedRegion[];\n sourceSlot?: Rect;\n headers?: Rect[];\n preview?: WorkspaceDragPreview;\n local?: WorkspaceDropIntent;\n header: boolean;\n bounds: Rect;\n}\n\ntype DecisionInput = WorkspacePlacementQuery & {\n currentLayout: WorkspaceLayout;\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n planPlacement?: WorkspacePlacementPlanner;\n};\n\ntype OfferInput = DecisionInput & { contextRect: WorkspaceContextRectResolver };\n\nexport interface WorkspacePlacementDecision {\n intent: WorkspaceDropIntent | undefined;\n acquisition?: WorkspacePlacementAcquisition;\n}\n\ninterface PointerPlacementInput {\n placement: WorkspacePlacementCatalog;\n canonicalRoot: WorkspaceNode | null;\n currentLayout: WorkspaceLayout;\n source: string[];\n point: Point;\n heldIntent: WorkspaceDropIntent;\n groupable: boolean;\n gap: number;\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n planPlacement?: WorkspacePlacementPlanner;\n}\n\nconst inside = (rect: Rect, point: Point) =>\n point.x >= rect.x && point.x < rect.x + rect.width && point.y >= rect.y && point.y < rect.y + rect.height;\n\nexport function decidePointerPlacement(input: PointerPlacementInput): WorkspacePlacementDecision {\n const { placement, point } = input;\n const header = !!placement.headerTarget;\n const target =\n placement.headerTarget ??\n (inside(placement.bounds, point) ? placement.targets.find(item => inside(item.rect, point)) : undefined);\n const local = localPlacementIntent(input, target, header);\n return decidePlacement({\n ...placement,\n source: input.source,\n point,\n local,\n header,\n currentLayout: input.currentLayout,\n gap: input.gap,\n available: input.available,\n projectLayout: input.projectLayout,\n planPlacement: input.planPlacement\n });\n}\n\n/** Chooses input and availability together from the two operation-specific computed projections. */\nexport function decidePlacement(input: DecisionInput) {\n const boundary = placementOffers({ ...input, contextRect: createContextRectResolver() });\n const selectedKey = selectedScopeKey(boundary.offers, input);\n const sourceSlot = reservedSourceSlot(input);\n const hints = boundary.offers.filter(offer => eligiblePlacementHint(offer, sourceSlot, input.bounds));\n const nearest = hints\n .filter(offer => offer.scope.key !== selectedKey)\n .map(offer => ({ offer, distance: distance(offer, input.point) }))\n .sort((a, b) => a.distance - b.distance)[0];\n const candidate = inside(input.bounds, input.point)\n ? boundary.offers.find(\n offer => inside(offer.hitRect ?? offer.rect, input.point) && (!input.header || placementOwnsChrome(offer))\n )\n : undefined;\n const hit = boundary.hit ?? candidate;\n return {\n acquisition: hit ? { plan: hit.plan, rect: hit.hitRect ?? hit.rect } : undefined,\n intent: acquiredIntent(input, hit),\n hint: placementHint({\n hit: hit && hints.includes(hit) ? hit : undefined,\n selectedKey,\n boundary: boundary.hit,\n nearest\n })\n };\n}\n\nfunction localPlacementIntent(input: PointerPlacementInput, target: WorkspaceTarget | undefined, header: boolean) {\n const { reservationHit } = input.placement;\n const overReservedBody = !header && reservationHit;\n const overReservedTab = header && reservationHit === 'tab' && input.heldIntent.kind === 'tab';\n if (overReservedBody || overReservedTab) {\n return input.heldIntent;\n }\n if (!target) return undefined;\n const anchor = target.panels[0];\n if (!anchor) return { kind: 'invalid' } as const;\n if (header) {\n return headerPlacementIntent(input, target, anchor);\n }\n return {\n kind: 'split',\n destination: {\n target: anchor,\n position: contentDirection(input.point, { rect: target.rect, headerHeight: target.headerHeight })\n }\n } as const;\n}\n\nfunction headerPlacementIntent(input: PointerPlacementInput, target: WorkspaceTarget, anchor: string) {\n const tab = target.tabs.find(item => input.point.x < item.rect.x + item.rect.width / 2);\n const preferred = findGroup(input.canonicalRoot, anchor)?.panels ?? [];\n const index = getTabInsertionIndex(preferred, tab?.id);\n const intent = { kind: 'tab', destination: { target: anchor, position: 'tab', index } } as const;\n const allowed =\n input.groupable || preservesGroupMembership({ root: input.canonicalRoot, source: input.source, intent });\n return allowed ? intent : undefined;\n}\n\nfunction reservedSourceSlot(input: WorkspacePlacementQuery) {\n const preview = input.preview;\n if (\n !input.sourceSlot ||\n preview?.phase !== 'detached' ||\n preview.blocked ||\n preview.allocation !== 'reserved' ||\n preview.cue.kind !== 'group'\n ) {\n return undefined;\n }\n return clipCue(input.sourceSlot, input.bounds);\n}\n\nfunction eligiblePlacementHint(offer: WorkspaceInsertionOffer, sourceSlot: Rect | undefined, bounds: Rect) {\n if (!sourceSlot) return true;\n const rect = clipCue(offer.rect, bounds);\n const vertical = offer.destination.position === 'left' || offer.destination.position === 'right';\n const normal = vertical ? 'x' : 'y';\n const normalSize = vertical ? 'width' : 'height';\n const tangent = vertical ? 'y' : 'x';\n const tangentSize = vertical ? 'height' : 'width';\n const normalInsideSource =\n rect[normal] > sourceSlot[normal] && rect[normal] + rect[normalSize] < sourceSlot[normal] + sourceSlot[normalSize];\n if (!normalInsideSource) return true;\n\n const tangentCoveredBySource =\n rect[tangent] >= sourceSlot[tangent] &&\n rect[tangent] + rect[tangentSize] <= sourceSlot[tangent] + sourceSlot[tangentSize];\n return !tangentCoveredBySource;\n}\n\nfunction placementHint({\n hit,\n selectedKey,\n boundary,\n nearest\n}: {\n hit?: WorkspaceInsertionOffer;\n selectedKey?: string;\n boundary?: WorkspaceInsertionOffer;\n nearest?: { offer: WorkspaceInsertionOffer; distance: number };\n}) {\n if (hit && hit.scope.key !== selectedKey) return hit;\n if (!boundary && nearest && nearest.distance <= 24) return nearest.offer;\n return undefined;\n}\n\nfunction placementOffers(input: OfferInput) {\n const root = (input.projectLayout ?? projectLayout)(input.currentLayout, input.available).root;\n const regions = input.orderingRegions ?? input.regions;\n const offers = createInsertionOffers({\n ...input,\n root,\n regions,\n explorationRegions: input.regions,\n existing: orderOffers({ ...input, root })\n });\n return getBoundaryPlacementOffers({\n offers,\n bounds: input.bounds,\n point: input.point,\n current: input.preview?.intent,\n headers: input.headers ?? [],\n geometry: { regions, source: input.source, gap: input.gap, contextRect: input.contextRect }\n });\n}\n\nfunction acquiredIntent(input: WorkspacePlacementQuery, hit: WorkspaceInsertionOffer | undefined) {\n if (hit) return getPlacementOfferIntent(hit);\n if (!inside(input.bounds, input.point)) return undefined;\n if (input.sourceSlot && inside(input.sourceSlot, input.point)) return input.preview?.intent ?? input.local;\n return input.local;\n}\n\nfunction selectedScopeKey(offers: WorkspaceInsertionOffer[], input: DecisionInput) {\n const preview = input.preview;\n if (!preview || preview.phase !== 'detached') return undefined;\n if ('layout' in preview)\n return describePlacementSlot({\n plan: preview,\n source: input.source,\n available: input.available,\n projectLayout: input.projectLayout\n })?.key;\n return offers.find(offer => matchesPlacementIntent(getPlacementOfferIntent(offer), preview.intent))?.scope.key;\n}\n\nfunction distance(offer: WorkspaceInsertionOffer, point: Point) {\n const rect = offer.hitRect ?? offer.rect;\n const vertical = offer.destination.position === 'left' || offer.destination.position === 'right';\n const tangent = vertical ? point.y : point.x;\n const start = vertical ? rect.y : rect.x;\n const extent = vertical ? rect.height : rect.width;\n const withinTangent = tangent >= start && tangent < start + extent;\n if (!withinTangent) return Infinity;\n\n const normalOffset = vertical ? point.x - rect.x : point.y - rect.y;\n const normalExtent = vertical ? rect.width : rect.height;\n return Math.abs(normalOffset - normalExtent / 2);\n}\n\ninterface OrderOwner {\n key: string;\n owner: WorkspaceSplit;\n rect: Rect;\n adjacencyRect: Rect;\n peers: { node: WorkspaceNode; index: number }[];\n}\n\nfunction orderOwner(input: OfferInput & { root: WorkspaceNode | null }): OrderOwner | undefined {\n const { root, source } = input;\n const key = findSourcePeerRegionKey(root, source) ?? 'root';\n const owner = findWorkspaceRegion(root, key);\n const group = findGroup(input.currentLayout.root, source[0]);\n if (owner?.type !== 'split' || !wholeSource(group, source)) return undefined;\n const ownerRect = (regions: WorkspacePlacedRegion[]) =>\n regions.find(region => region.key === key)?.rect ??\n input.contextRect({ members: getPanelIds(owner).filter(id => !source.includes(id)), allocation: regions, source });\n const rect = ownerRect(input.regions);\n const adjacencyRect = ownerRect(input.orderingRegions ?? input.regions);\n if (!rect || !adjacencyRect) return undefined;\n const from = owner.children.findIndex(node => node.type === 'group' && node.panels.some(id => source.includes(id)));\n if (from < 0) return undefined;\n return {\n key,\n owner,\n rect,\n adjacencyRect,\n peers: owner.children.flatMap((node, index) => (index === from ? [] : [{ node, index }]))\n };\n}\n\nfunction orderOffers(input: OfferInput & { root: WorkspaceNode | null }): WorkspaceInsertionOffer[] {\n const owner = orderOwner(input);\n if (!owner) return [];\n const entries = owner.peers.map(peer => ({ ...peer, after: false }));\n const last = owner.peers.at(-1);\n if (last) {\n entries.push({ ...last, after: true });\n }\n return entries.flatMap((entry, slot) => orderOffer({ input, owner, entry, slot }));\n}\n\ninterface OrderOfferInput {\n input: OfferInput;\n owner: OrderOwner;\n entry: { node: WorkspaceNode; index: number; after: boolean };\n slot: number;\n}\n\nfunction orderOffer({ input, owner, entry, slot }: OrderOfferInput): WorkspaceInsertionOffer[] {\n const neighbors = orderNeighbors({ input, owner, entry, slot });\n if (!neighbors) return [];\n const { region, before } = neighbors;\n const destination = {\n target: getPanelIds(entry.node)[0]!,\n region: region.key,\n position: getSplitSide(owner.owner.axis, entry.after ? 'after' : 'before')\n };\n const plan = (input.planPlacement ?? planWorkspacePlacement)({\n layout: input.currentLayout,\n source: input.source,\n destination,\n available: input.available,\n projectLayout: input.projectLayout,\n operation: 'order'\n });\n if (plan?.kind !== 'reorder') return [];\n const descriptor = describePlacementSlot({\n plan,\n source: input.source,\n available: input.available,\n projectLayout: input.projectLayout\n });\n const boundary = orderBoundary(entry, slot);\n const ownerRect = boundary ? owner.rect : owner.adjacencyRect;\n const area = getOrderHintRect({\n owner: ownerRect,\n recipient: region.rect,\n previous: before?.rect,\n axis: owner.owner.axis,\n after: entry.after,\n sourceSlot: input.sourceSlot,\n boundary\n });\n if (!area || !descriptor) return [];\n return [\n {\n destination,\n owner: owner.key,\n boundary,\n rect: area,\n scopeRect: ownerRect,\n scope: descriptor,\n plan,\n kind: 'order'\n }\n ];\n}\n\nfunction orderBoundary(entry: OrderOfferInput['entry'], slot: number): WorkspaceInsertionOffer['boundary'] {\n if (entry.after) return 'end';\n if (slot === 0) return 'start';\n return undefined;\n}\n\nfunction wholeSource(group: ReturnType<typeof findGroup>, source: string[]) {\n return !!group && group.panels.length === source.length && group.panels.every(id => source.includes(id));\n}\n\nfunction orderNeighbors({ input, owner, entry, slot }: Parameters<typeof orderOffer>[0]) {\n const regions = input.orderingRegions ?? input.regions;\n const region = regions.find(candidate => candidate.key === `${owner.key}.${entry.index}`);\n const previous = owner.peers[slot - 1];\n const before = previous && regions.find(candidate => candidate.key === `${owner.key}.${previous.index}`);\n return !region || (slot > 0 && !entry.after && !before) ? undefined : { region, before };\n}\n\nfunction contentDirection(\n point: Point,\n input: { rect: Rect; headerHeight: number }\n): Exclude<WorkspaceDestination['position'], 'tab'> {\n const { rect, headerHeight } = input;\n const centerX = rect.x + rect.width / 2;\n const contentHeight = Math.max(1, rect.height - headerHeight);\n const centerY = rect.y + headerHeight + contentHeight / 2;\n const dx = (point.x - centerX) / Math.max(1, rect.width / 2);\n const dy = (point.y - centerY) / Math.max(1, contentHeight / 2);\n if (Math.abs(dx) > Math.abs(dy)) return dx < 0 ? 'left' : 'right';\n return dy < 0 ? 'top' : 'bottom';\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"placement-decision.utils.js","names":["inside","point","rect","decidePointerPlacement","input","header","placement","local","localPlacementIntent","item","decidePlacement","boundary","placementOffers","createScopeRectResolver","selectedKey","selectedInsertionKey","sourceReservation","getActiveSourceReservation","hints","eligiblePlacementHint","offer","nearest","nearestPlacementHint","candidate","placementOwnsChrome","hit","acquiredIntent","placementHint","nearestOffer","nearestDistance","offerDistance","distance","overReservedBody","reservationHit","overReservedTab","target","anchor","headerPlacementIntent","contentDirection","tab","preferred","findGroup","intent","getTabInsertionIndex","preservesGroupMembership","preview","clipCue","bounds","vertical","normal","normalSize","tangent","tangentSize","root","projectLayout","regions","offers","createInsertionOffers","orderOffers","getBoundaryPlacementOffers","getPlacementOfferIntent","getGroupInsertion","matchesPlacementIntent","start","extent","normalOffset","normalExtent","orderOwner","key","findSourcePeerRegionKey","source","owner","findWorkspaceRegion","group","wholeSource","ownerRect","region","getPanelIds","id","adjacencyRect","from","node","index","entries","peer","last","orderOffer","neighbors","orderNeighbors","destination","entry","getSplitSide","plan","resolvePlacementPlan","insertion","orderBoundary","insertionIndex","area","getOrderHintRect","before","previous","centerX","contentHeight","headerHeight","centerY","dx","dy"],"sources":["../../../../src/workspace/utils/interaction/placement-decision.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Point, Rect } from '@nvidia-elements/core/internal';\n\nimport { getBoundaryPlacementOffers } from './boundary.utils.js';\nimport { clipCue, matchesPlacementIntent } from './drag-preview.utils.js';\nimport {\n createInsertionOffers,\n findSourcePeerRegionKey,\n getOrderHintRect,\n getPlacementOfferIntent,\n placementOwnsChrome\n} from './insertion-offers.utils.js';\nimport { getPanelIds, getSplitSide } from '../model/layout.utils.js';\nimport { getTabInsertionIndex, preservesGroupMembership } from '../model/membership.utils.js';\nimport { findGroup, projectLayout } from '../model/operations.utils.js';\nimport { getGroupInsertion } from '../placement/group-insertion.utils.js';\nimport { resolvePlacementPlan } from '../placement/planner.utils.js';\nimport { findWorkspaceRegion } from '../placement/region.utils.js';\nimport { createScopeRectResolver } from '../placement/scope.utils.js';\n\nimport type { WorkspacePlacedRegion } from '../geometry/allocation.utils.js';\nimport type { WorkspaceDragPreview, WorkspaceDropIntent, WorkspacePlacementAcquisition } from './drag-preview.utils.js';\nimport type { WorkspaceInsertionOffer } from './insertion-offers.utils.js';\nimport type { WorkspaceLayout, WorkspaceNode, WorkspaceSplit } from '../model/layout.utils.js';\nimport type { WorkspaceDestination } from '../model/operations.utils.js';\nimport type { WorkspaceLayoutProjector } from '../model/projection.utils.js';\nimport type { WorkspacePlacementPlanner } from '../placement/planner.utils.js';\nimport type { WorkspaceScopeRectResolver } from '../placement/scope.utils.js';\nimport type { WorkspacePlacementSession } from '../placement/session.utils.js';\nimport type { WorkspaceTarget } from '../presentation/groups.utils.js';\nimport type { WorkspacePlacementCatalog } from '../evaluation.utils.js';\n\ninterface WorkspacePlacementQuery {\n resolveScopeRect?: WorkspaceScopeRectResolver;\n gap: number;\n source: string[];\n point: Point;\n regions: WorkspacePlacedRegion[];\n orderingRegions?: WorkspacePlacedRegion[];\n sourceReservation?: Rect;\n headers?: Rect[];\n preview?: WorkspaceDragPreview;\n local?: WorkspaceDropIntent;\n header: boolean;\n bounds: Rect;\n}\n\ntype DecisionInput = WorkspacePlacementQuery & {\n currentLayout: WorkspaceLayout;\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n planPlacement?: WorkspacePlacementPlanner;\n placementSession?: WorkspacePlacementSession;\n};\n\ntype OfferInput = DecisionInput & { resolveScopeRect: WorkspaceScopeRectResolver };\n\nexport interface WorkspacePlacementDecision {\n intent: WorkspaceDropIntent | undefined;\n acquisition?: WorkspacePlacementAcquisition;\n}\n\ninterface PointerPlacementInput {\n placement: WorkspacePlacementCatalog;\n canonicalRoot: WorkspaceNode | null;\n currentLayout: WorkspaceLayout;\n source: string[];\n point: Point;\n heldIntent: WorkspaceDropIntent;\n groupable: boolean;\n gap: number;\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n planPlacement?: WorkspacePlacementPlanner;\n placementSession?: WorkspacePlacementSession;\n}\n\nconst inside = (rect: Rect, point: Point) =>\n point.x >= rect.x && point.x < rect.x + rect.width && point.y >= rect.y && point.y < rect.y + rect.height;\n\nexport function decidePointerPlacement(input: PointerPlacementInput): WorkspacePlacementDecision {\n const { placement, point } = input;\n const header = !!placement.headerTarget;\n const target =\n placement.headerTarget ??\n (inside(placement.bounds, point) ? placement.targets.find(item => inside(item.rect, point)) : undefined);\n const local = localPlacementIntent(input, target, header);\n return decidePlacement({\n ...placement,\n source: input.source,\n point,\n local,\n header,\n currentLayout: input.currentLayout,\n gap: input.gap,\n available: input.available,\n projectLayout: input.projectLayout,\n planPlacement: input.planPlacement,\n placementSession: input.placementSession\n });\n}\n\n/** Chooses input and availability together from the two operation-specific computed projections. */\nexport function decidePlacement(input: DecisionInput) {\n const boundary = placementOffers({ ...input, resolveScopeRect: input.resolveScopeRect ?? createScopeRectResolver() });\n const selectedKey = selectedInsertionKey(boundary.offers, input);\n const sourceReservation = getActiveSourceReservation(input);\n const hints = boundary.offers.filter(offer => eligiblePlacementHint(offer, sourceReservation, input.bounds));\n const nearest = nearestPlacementHint(hints, selectedKey, input.point);\n const candidate = inside(input.bounds, input.point)\n ? boundary.offers.find(\n offer => inside(offer.hitRect ?? offer.rect, input.point) && (!input.header || placementOwnsChrome(offer))\n )\n : undefined;\n const hit = boundary.hit ?? candidate;\n return {\n acquisition: hit ? { plan: hit.plan, rect: hit.hitRect ?? hit.rect } : undefined,\n intent: acquiredIntent(input, hit),\n hint: placementHint({\n hit: hit && hints.includes(hit) ? hit : undefined,\n selectedKey,\n boundary: boundary.hit,\n nearest\n })\n };\n}\n\nfunction nearestPlacementHint(hints: WorkspaceInsertionOffer[], selectedKey: string | undefined, point: Point) {\n let nearestOffer: WorkspaceInsertionOffer | undefined;\n let nearestDistance = Infinity;\n for (const offer of hints) {\n if (offer.insertion.key === selectedKey) continue;\n const offerDistance = distance(offer, point);\n if (!nearestOffer || offerDistance < nearestDistance) {\n nearestOffer = offer;\n nearestDistance = offerDistance;\n }\n }\n return nearestOffer && { offer: nearestOffer, distance: nearestDistance };\n}\n\nfunction localPlacementIntent(input: PointerPlacementInput, target: WorkspaceTarget | undefined, header: boolean) {\n const { reservationHit } = input.placement;\n const overReservedBody = !header && reservationHit;\n const overReservedTab = header && reservationHit === 'tab' && input.heldIntent.kind === 'tab';\n if (overReservedBody || overReservedTab) {\n return input.heldIntent;\n }\n if (!target) return undefined;\n const anchor = target.panels[0];\n if (!anchor) return { kind: 'invalid' } as const;\n if (header) {\n return headerPlacementIntent(input, target, anchor);\n }\n return {\n kind: 'split',\n destination: {\n target: anchor,\n position: contentDirection(input.point, { rect: target.rect, headerHeight: target.headerHeight })\n }\n } as const;\n}\n\nfunction headerPlacementIntent(input: PointerPlacementInput, target: WorkspaceTarget, anchor: string) {\n const tab = target.tabs.find(item => input.point.x < item.rect.x + item.rect.width / 2);\n const preferred = findGroup(input.canonicalRoot, anchor)?.panels ?? [];\n const index = getTabInsertionIndex(preferred, tab?.id);\n const intent = { kind: 'tab', destination: { target: anchor, position: 'tab', index } } as const;\n const allowed =\n input.groupable || preservesGroupMembership({ root: input.canonicalRoot, source: input.source, intent });\n return allowed ? intent : undefined;\n}\n\nfunction getActiveSourceReservation(input: WorkspacePlacementQuery) {\n const preview = input.preview;\n if (\n !input.sourceReservation ||\n preview?.phase !== 'detached' ||\n preview.blocked ||\n preview.allocation !== 'reserved' ||\n preview.cue.kind !== 'group'\n ) {\n return undefined;\n }\n return clipCue(input.sourceReservation, input.bounds);\n}\n\nfunction eligiblePlacementHint(offer: WorkspaceInsertionOffer, sourceReservation: Rect | undefined, bounds: Rect) {\n if (!sourceReservation) return true;\n const rect = clipCue(offer.rect, bounds);\n const vertical = offer.destination.position === 'left' || offer.destination.position === 'right';\n const normal = vertical ? 'x' : 'y';\n const normalSize = vertical ? 'width' : 'height';\n const tangent = vertical ? 'y' : 'x';\n const tangentSize = vertical ? 'height' : 'width';\n const normalInsideSource =\n rect[normal] > sourceReservation[normal] &&\n rect[normal] + rect[normalSize] < sourceReservation[normal] + sourceReservation[normalSize];\n if (!normalInsideSource) return true;\n\n const tangentCoveredBySource =\n rect[tangent] >= sourceReservation[tangent] &&\n rect[tangent] + rect[tangentSize] <= sourceReservation[tangent] + sourceReservation[tangentSize];\n return !tangentCoveredBySource;\n}\n\nfunction placementHint({\n hit,\n selectedKey,\n boundary,\n nearest\n}: {\n hit?: WorkspaceInsertionOffer;\n selectedKey?: string;\n boundary?: WorkspaceInsertionOffer;\n nearest?: { offer: WorkspaceInsertionOffer; distance: number };\n}) {\n if (hit && hit.insertion.key !== selectedKey) return hit;\n if (!boundary && nearest && nearest.distance <= 24) return nearest.offer;\n return undefined;\n}\n\nfunction placementOffers(input: OfferInput) {\n const root = (input.projectLayout ?? projectLayout)(input.currentLayout, input.available).root;\n const regions = input.orderingRegions ?? input.regions;\n const offers = createInsertionOffers({\n ...input,\n root,\n regions,\n explorationRegions: input.regions,\n existing: orderOffers({ ...input, root })\n });\n return getBoundaryPlacementOffers({\n offers,\n bounds: input.bounds,\n point: input.point,\n current: input.preview?.intent,\n headers: input.headers ?? [],\n geometry: { regions, source: input.source, gap: input.gap, resolveScopeRect: input.resolveScopeRect }\n });\n}\n\nfunction acquiredIntent(input: WorkspacePlacementQuery, hit: WorkspaceInsertionOffer | undefined) {\n if (hit) return getPlacementOfferIntent(hit);\n if (!inside(input.bounds, input.point)) return undefined;\n if (input.sourceReservation && inside(input.sourceReservation, input.point))\n return input.preview?.intent ?? input.local;\n return input.local;\n}\n\nfunction selectedInsertionKey(offers: WorkspaceInsertionOffer[], input: DecisionInput) {\n const preview = input.preview;\n if (!preview || preview.phase !== 'detached') return undefined;\n if ('layout' in preview)\n return getGroupInsertion({\n plan: preview,\n source: input.source,\n available: input.available,\n projectLayout: input.projectLayout,\n placementSession: input.placementSession,\n planPlacement: input.planPlacement\n })?.key;\n return offers.find(offer => matchesPlacementIntent(getPlacementOfferIntent(offer), preview.intent))?.insertion.key;\n}\n\nfunction distance(offer: WorkspaceInsertionOffer, point: Point) {\n const rect = offer.hitRect ?? offer.rect;\n const vertical = offer.destination.position === 'left' || offer.destination.position === 'right';\n const tangent = vertical ? point.y : point.x;\n const start = vertical ? rect.y : rect.x;\n const extent = vertical ? rect.height : rect.width;\n const withinTangent = tangent >= start && tangent < start + extent;\n if (!withinTangent) return Infinity;\n\n const normalOffset = vertical ? point.x - rect.x : point.y - rect.y;\n const normalExtent = vertical ? rect.width : rect.height;\n return Math.abs(normalOffset - normalExtent / 2);\n}\n\ninterface OrderOwner {\n key: string;\n owner: WorkspaceSplit;\n rect: Rect;\n adjacencyRect: Rect;\n peers: { node: WorkspaceNode; index: number }[];\n}\n\nfunction orderOwner(input: OfferInput & { root: WorkspaceNode | null }): OrderOwner | undefined {\n const { root, source } = input;\n const key = findSourcePeerRegionKey(root, source) ?? 'root';\n const owner = findWorkspaceRegion(root, key);\n const group = findGroup(input.currentLayout.root, source[0]);\n if (owner?.type !== 'split' || !wholeSource(group, source)) return undefined;\n const ownerRect = (regions: WorkspacePlacedRegion[]) =>\n regions.find(region => region.key === key)?.rect ??\n input.resolveScopeRect({\n members: getPanelIds(owner).filter(id => !source.includes(id)),\n allocation: regions,\n source\n });\n const rect = ownerRect(input.regions);\n const adjacencyRect = ownerRect(input.orderingRegions ?? input.regions);\n if (!rect || !adjacencyRect) return undefined;\n const from = owner.children.findIndex(node => node.type === 'group' && node.panels.some(id => source.includes(id)));\n if (from < 0) return undefined;\n return {\n key,\n owner,\n rect,\n adjacencyRect,\n peers: owner.children.flatMap((node, index) => (index === from ? [] : [{ node, index }]))\n };\n}\n\nfunction orderOffers(input: OfferInput & { root: WorkspaceNode | null }): WorkspaceInsertionOffer[] {\n const owner = orderOwner(input);\n if (!owner) return [];\n const entries = owner.peers.map(peer => ({ ...peer, after: false }));\n const last = owner.peers.at(-1);\n if (last) {\n entries.push({ ...last, after: true });\n }\n return entries.flatMap((entry, insertionIndex) => orderOffer({ input, owner, entry, insertionIndex }));\n}\n\ninterface OrderOfferInput {\n input: OfferInput;\n owner: OrderOwner;\n entry: { node: WorkspaceNode; index: number; after: boolean };\n insertionIndex: number;\n}\n\nfunction orderOffer({ input, owner, entry, insertionIndex }: OrderOfferInput): WorkspaceInsertionOffer[] {\n const neighbors = orderNeighbors({ input, owner, entry, insertionIndex });\n if (!neighbors) return [];\n const { region, before } = neighbors;\n const destination = {\n target: getPanelIds(entry.node)[0]!,\n region: region.key,\n position: getSplitSide(owner.owner.axis, entry.after ? 'after' : 'before')\n };\n const plan = resolvePlacementPlan(input, destination, 'order');\n if (plan?.kind !== 'reorder') return [];\n const insertion = getGroupInsertion({\n plan,\n source: input.source,\n available: input.available,\n projectLayout: input.projectLayout,\n placementSession: input.placementSession,\n planPlacement: input.planPlacement\n });\n const boundary = orderBoundary(entry, insertionIndex);\n const ownerRect = boundary ? owner.rect : owner.adjacencyRect;\n const area = getOrderHintRect({\n owner: ownerRect,\n recipient: region.rect,\n previous: before?.rect,\n axis: owner.owner.axis,\n after: entry.after,\n sourceReservation: input.sourceReservation,\n boundary\n });\n if (!area || !insertion) return [];\n return [\n {\n destination,\n owner: owner.key,\n boundary,\n rect: area,\n scopeRect: ownerRect,\n insertion,\n plan,\n kind: 'order'\n }\n ];\n}\n\nfunction orderBoundary(entry: OrderOfferInput['entry'], insertionIndex: number): WorkspaceInsertionOffer['boundary'] {\n if (entry.after) return 'end';\n if (insertionIndex === 0) return 'start';\n return undefined;\n}\n\nfunction wholeSource(group: ReturnType<typeof findGroup>, source: string[]) {\n return !!group && group.panels.length === source.length && group.panels.every(id => source.includes(id));\n}\n\nfunction orderNeighbors({ input, owner, entry, insertionIndex }: Parameters<typeof orderOffer>[0]) {\n const regions = input.orderingRegions ?? input.regions;\n const region = regions.find(candidate => candidate.key === `${owner.key}.${entry.index}`);\n const previous = owner.peers[insertionIndex - 1];\n const before = previous && regions.find(candidate => candidate.key === `${owner.key}.${previous.index}`);\n return !region || (insertionIndex > 0 && !entry.after && !before) ? undefined : { region, before };\n}\n\nfunction contentDirection(\n point: Point,\n input: { rect: Rect; headerHeight: number }\n): Exclude<WorkspaceDestination['position'], 'tab'> {\n const { rect, headerHeight } = input;\n const centerX = rect.x + rect.width / 2;\n const contentHeight = Math.max(1, rect.height - headerHeight);\n const centerY = rect.y + headerHeight + contentHeight / 2;\n const dx = (point.x - centerX) / Math.max(1, rect.width / 2);\n const dy = (point.y - centerY) / Math.max(1, contentHeight / 2);\n if (Math.abs(dx) > Math.abs(dy)) return dx < 0 ? 'left' : 'right';\n return dy < 0 ? 'top' : 'bottom';\n}\n"],"mappings":"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"}
|
|
@@ -19,4 +19,5 @@ export declare function getPanelIds(node: WorkspaceNode | null): string[];
|
|
|
19
19
|
export declare function getSplitSide(axis: WorkspaceSplit['axis'], position: 'before' | 'after'): 'left' | 'right' | 'top' | 'bottom';
|
|
20
20
|
/** Converts consecutive splits on the same axis into siblings. */
|
|
21
21
|
export declare function normalizeLayout(node: WorkspaceNode): WorkspaceNode;
|
|
22
|
-
|
|
22
|
+
/** Reuses unchanged nodes in canonical split graphs produced by mapGroups. */
|
|
23
|
+
export declare function normalizeLayoutWithSharing(node: WorkspaceNode): WorkspaceNode;
|
|
@@ -9,33 +9,35 @@ function n(e) {
|
|
|
9
9
|
return i(e, "copy");
|
|
10
10
|
}
|
|
11
11
|
function r(e) {
|
|
12
|
-
return i(e, "
|
|
12
|
+
return i(e, "share-nodes");
|
|
13
13
|
}
|
|
14
14
|
function i(e, t) {
|
|
15
15
|
if (e.type === "group") return t === "copy" ? {
|
|
16
|
-
|
|
17
|
-
panels: [...e.panels]
|
|
16
|
+
type: "group",
|
|
17
|
+
panels: [...e.panels],
|
|
18
|
+
active: e.active
|
|
18
19
|
} : e;
|
|
19
|
-
let n = e.weights.reduce((e, t) => e + t, 0), r = [], a = t === "copy" ? [] : void 0;
|
|
20
|
+
let n = e.weights.reduce((e, t) => e + t, 0), r = t === "copy" ? [] : void 0, a = t === "copy" ? [] : void 0;
|
|
20
21
|
e.children.forEach((o, s) => {
|
|
21
22
|
let c = i(o, t), l = e.weights[s] / n;
|
|
22
23
|
if (!(l > 0)) throw TypeError("Split proportions exceed the supported range");
|
|
23
24
|
if (c.type === "split" && c.axis === e.axis) {
|
|
24
25
|
let t = a ??= e.weights.slice(0, s), n = c.weights.reduce((e, t) => e + t, 0);
|
|
25
|
-
c.children.forEach((
|
|
26
|
-
r.push(
|
|
26
|
+
c.children.forEach((i, a) => {
|
|
27
|
+
(r ??= e.children.slice(0, s)).push(i), t.push(l * c.weights[a] / n);
|
|
27
28
|
});
|
|
28
|
-
} else !a && l !== e.weights[s] && (a = e.weights.slice(0, s)), r.push(c), a?.push(l);
|
|
29
|
+
} else !a && l !== e.weights[s] && (a = e.weights.slice(0, s)), r ? r.push(c) : c !== o && (r = e.children.slice(0, s), r.push(c)), a?.push(l);
|
|
29
30
|
});
|
|
30
31
|
let o = a ?? e.weights;
|
|
31
32
|
if (!o.every((e) => Number.isFinite(e) && e > 0)) throw TypeError("Split proportions exceed the supported range");
|
|
32
|
-
|
|
33
|
+
let s = r ?? e.children;
|
|
34
|
+
return s === e.children && o === e.weights ? e : {
|
|
33
35
|
type: "split",
|
|
34
36
|
axis: e.axis,
|
|
35
|
-
children:
|
|
37
|
+
children: s,
|
|
36
38
|
weights: o
|
|
37
39
|
};
|
|
38
40
|
}
|
|
39
|
-
export { e as getPanelIds, t as getSplitSide, n as normalizeLayout, r as
|
|
41
|
+
export { e as getPanelIds, t as getSplitSide, n as normalizeLayout, r as normalizeLayoutWithSharing };
|
|
40
42
|
|
|
41
43
|
//# sourceMappingURL=layout.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.utils.js","names":["getPanelIds","node","getSplitSide","axis","position","normalizeLayout","normalizeNode","
|
|
1
|
+
{"version":3,"file":"layout.utils.js","names":["getPanelIds","node","getSplitSide","axis","position","normalizeLayout","normalizeNode","normalizeLayoutWithSharing","mode","total","a","b","children","weights","normalized","child","share","index","shares","sum","nested","i","normalizedWeights","weight","normalizedChildren"],"sources":["../../../../src/workspace/utils/model/layout.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nexport type WorkspaceNode = WorkspaceGroup | WorkspaceSplit;\n\nexport interface WorkspaceGroup {\n type: 'group';\n panels: string[];\n active: string;\n}\n\nexport interface WorkspaceSplit {\n type: 'split';\n axis: 'horizontal' | 'vertical';\n weights: number[];\n children: WorkspaceNode[];\n}\n\nexport interface WorkspaceLayout {\n version: 1;\n root: WorkspaceNode | null;\n closed: string[];\n}\n\nexport function getPanelIds(node: WorkspaceNode | null): string[] {\n if (!node) return [];\n return node.type === 'group' ? node.panels : node.children.flatMap(getPanelIds);\n}\n\nexport function getSplitSide(\n axis: WorkspaceSplit['axis'],\n position: 'before' | 'after'\n): 'left' | 'right' | 'top' | 'bottom' {\n if (axis === 'horizontal') return position === 'before' ? 'left' : 'right';\n return position === 'before' ? 'top' : 'bottom';\n}\n\n/** Converts consecutive splits on the same axis into siblings. */\nexport function normalizeLayout(node: WorkspaceNode): WorkspaceNode {\n return normalizeNode(node, 'copy');\n}\n\n/** Reuses unchanged nodes in canonical split graphs produced by mapGroups. */\nexport function normalizeLayoutWithSharing(node: WorkspaceNode): WorkspaceNode {\n return normalizeNode(node, 'share-nodes');\n}\n\nfunction normalizeNode(node: WorkspaceNode, mode: 'copy' | 'share-nodes'): WorkspaceNode {\n if (node.type === 'group')\n return mode === 'copy' ? { type: 'group', panels: [...node.panels], active: node.active } : node;\n const total = node.weights.reduce((a, b) => a + b, 0);\n let children: WorkspaceNode[] | undefined = mode === 'copy' ? [] : undefined;\n let weights: number[] | undefined = mode === 'copy' ? [] : undefined;\n node.children.forEach((child, index) => {\n const normalized = normalizeNode(child, mode);\n const share = node.weights[index]! / total;\n if (!(share > 0)) throw new TypeError('Split proportions exceed the supported range');\n if (normalized.type === 'split' && normalized.axis === node.axis) {\n const shares = (weights ??= node.weights.slice(0, index));\n const sum = normalized.weights.reduce((a, b) => a + b, 0);\n normalized.children.forEach((nested, i) => {\n (children ??= node.children.slice(0, index)).push(nested);\n shares.push((share * normalized.weights[i]!) / sum);\n });\n } else {\n if (!weights && share !== node.weights[index]) {\n weights = node.weights.slice(0, index);\n }\n if (children) {\n children.push(normalized);\n } else if (normalized !== child) {\n children = node.children.slice(0, index);\n children.push(normalized);\n }\n weights?.push(share);\n }\n });\n const normalizedWeights = weights ?? node.weights;\n if (!normalizedWeights.every(weight => Number.isFinite(weight) && weight > 0))\n throw new TypeError('Split proportions exceed the supported range');\n const normalizedChildren = children ?? node.children;\n if (normalizedChildren === node.children && normalizedWeights === node.weights) return node;\n return { type: 'split', axis: node.axis, children: normalizedChildren, weights: normalizedWeights };\n}\n"],"mappings":";AAwBA,SAAgBA,EAAY,GAAsC;CAEhE,OADKC,IACEA,EAAK,SAAS,UAAUA,EAAK,SAASA,EAAK,SAAS,QAAQD,CAAW,IAD5D,CAAC;AAErB;AAEA,SAAgBE,EACd,GACA,GACqC;CAErC,OADIC,MAAS,eAAqBC,MAAa,WAAW,SAAS,UAC5DA,MAAa,WAAW,QAAQ;AACzC;AAGA,SAAgBC,EAAgB,GAAoC;CAClE,OAAOC,EAAcL,GAAM,MAAM;AACnC;AAGA,SAAgBM,EAA2B,GAAoC;CAC7E,OAAOD,EAAcL,GAAM,aAAa;AAC1C;AAEA,SAASK,EAAc,GAAqB,GAA6C;CACvF,IAAIL,EAAK,SAAS,SAChB,OAAOO,MAAS,SAAS;EAAE,MAAM;EAAS,QAAQ,CAAC,GAAGP,EAAK,MAAM;EAAG,QAAQA,EAAK;CAAO,IAAIA;CAC9F,IAAMQ,IAAQR,EAAK,QAAQ,QAAQ,GAAG,MAAMS,IAAIC,GAAG,CAAC,GAChDC,IAAwCJ,MAAS,SAAS,CAAC,IAAI,KAAA,GAC/DK,IAAgCL,MAAS,SAAS,CAAC,IAAI,KAAA;CAC3D,EAAK,SAAS,SAAS,GAAO,MAAU;EACtC,IAAMM,IAAaR,EAAcS,GAAOP,CAAI,GACtCQ,IAAQf,EAAK,QAAQgB,KAAUR;EACrC,IAAI,EAAEO,IAAQ,IAAI,MAAU,UAAU,8CAA8C;EACpF,IAAIF,EAAW,SAAS,WAAWA,EAAW,SAASb,EAAK,MAAM;GAChE,IAAMiB,IAAU,MAAYjB,EAAK,QAAQ,MAAM,GAAGgB,CAAK,GACjDE,IAAML,EAAW,QAAQ,QAAQ,GAAG,MAAMJ,IAAIC,GAAG,CAAC;GACxD,EAAW,SAAS,SAAS,GAAQ,MAAM;IAEzC,CADC,MAAaV,EAAK,SAAS,MAAM,GAAGgB,CAAK,EAAA,CAAG,KAAKG,CAAM,GACxDF,EAAO,KAAMF,IAAQF,EAAW,QAAQO,KAAOF,CAAG;GACpD,CAAC;EACH,OAUE,AATI,CAACN,KAAWG,MAAUf,EAAK,QAAQgB,OACrC,IAAUhB,EAAK,QAAQ,MAAM,GAAGgB,CAAK,IAEnCL,IACFA,EAAS,KAAKE,CAAU,IACfA,MAAeC,MACxB,IAAWd,EAAK,SAAS,MAAM,GAAGgB,CAAK,GACvCL,EAAS,KAAKE,CAAU,IAE1BD,GAAS,KAAKG,CAAK;CAEvB,CAAC;CACD,IAAMM,IAAoBT,KAAWZ,EAAK;CAC1C,IAAI,CAACqB,EAAkB,OAAM,MAAU,OAAO,SAASC,CAAM,KAAKA,IAAS,CAAC,GAC1E,MAAU,UAAU,8CAA8C;CACpE,IAAMC,IAAqBZ,KAAYX,EAAK;CAE5C,OADIuB,MAAuBvB,EAAK,YAAYqB,MAAsBrB,EAAK,UAAgBA,IAChF;EAAE,MAAM;EAAS,MAAMA,EAAK;EAAM,UAAUuB;EAAoB,SAASF;CAAkB;AACpG"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { WorkspacePlacementIntent } from '../interaction/command.utils.js';
|
|
2
2
|
import type { WorkspaceLayout, WorkspaceNode } from './layout.utils.js';
|
|
3
|
+
/** Identifies panel membership independently of its order. */
|
|
4
|
+
export declare function getPanelMembershipKey(members: readonly string[]): string;
|
|
5
|
+
/** Compares unique panel IDs independently of their order. */
|
|
6
|
+
export declare function samePanelMembership(left: readonly string[], right: readonly string[]): boolean;
|
|
3
7
|
export declare function preservesGroupMembership(input: {
|
|
4
8
|
root: WorkspaceNode | null;
|
|
5
9
|
source: string[];
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { findGroup as e } from "./operations.utils.js";
|
|
2
2
|
// src/workspace/utils/model/membership.utils.ts
|
|
3
|
-
function t(
|
|
3
|
+
function t(e) {
|
|
4
|
+
return JSON.stringify([...e].sort());
|
|
5
|
+
}
|
|
6
|
+
function n(e, t) {
|
|
7
|
+
if (e === t) return !0;
|
|
8
|
+
if (e.length !== t.length) return !1;
|
|
9
|
+
for (let n of e) if (!t.includes(n)) return !1;
|
|
10
|
+
return !0;
|
|
11
|
+
}
|
|
12
|
+
function r(t) {
|
|
4
13
|
let n = e(t.root, t.source[0]);
|
|
5
14
|
return !n || !t.source.length ? !1 : t.intent.kind === "tab" ? e(t.root, t.intent.destination.target) === n : n.panels.every((e) => t.source.includes(e));
|
|
6
15
|
}
|
|
7
|
-
function
|
|
16
|
+
function i(t) {
|
|
8
17
|
let n = e(t.layout?.root ?? null, t.anchor);
|
|
9
18
|
return n && n.panels.filter((e) => !t.layout?.closed.includes(e) && t.available.includes(e)).length === 1 ? [...n.panels] : [t.anchor];
|
|
10
19
|
}
|
|
11
|
-
function
|
|
20
|
+
function a(e, t) {
|
|
12
21
|
let n = t === void 0 ? e.length : e.indexOf(t);
|
|
13
22
|
return n < 0 ? e.length : n;
|
|
14
23
|
}
|
|
15
|
-
export {
|
|
24
|
+
export { t as getPanelMembershipKey, a as getTabInsertionIndex, i as getWorkspacePanelSource, r as preservesGroupMembership, n as samePanelMembership };
|
|
16
25
|
|
|
17
26
|
//# sourceMappingURL=membership.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"membership.utils.js","names":["preservesGroupMembership","origin","findGroup","input","
|
|
1
|
+
{"version":3,"file":"membership.utils.js","names":["getPanelMembershipKey","members","samePanelMembership","left","right","id","preservesGroupMembership","origin","findGroup","input","getWorkspacePanelSource","group","getTabInsertionIndex","index","before","preferred"],"sources":["../../../../src/workspace/utils/model/membership.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { findGroup } from './operations.utils.js';\n\nimport type { WorkspacePlacementIntent } from '../interaction/command.utils.js';\nimport type { WorkspaceLayout, WorkspaceNode } from './layout.utils.js';\n\n/** Identifies panel membership independently of its order. */\nexport function getPanelMembershipKey(members: readonly string[]): string {\n return JSON.stringify([...members].sort());\n}\n\n/** Compares unique panel IDs independently of their order. */\nexport function samePanelMembership(left: readonly string[], right: readonly string[]): boolean {\n if (left === right) return true;\n if (left.length !== right.length) return false;\n for (const id of left) {\n if (!right.includes(id)) return false;\n }\n return true;\n}\n\nexport function preservesGroupMembership(input: {\n root: WorkspaceNode | null;\n source: string[];\n intent: WorkspacePlacementIntent;\n}): boolean {\n const origin = findGroup(input.root, input.source[0]);\n if (!origin || !input.source.length) return false;\n if (input.intent.kind === 'tab') return findGroup(input.root, input.intent.destination.target) === origin;\n return origin.panels.every(id => input.source.includes(id));\n}\n\nexport function getWorkspacePanelSource(input: {\n layout?: WorkspaceLayout;\n anchor: string;\n available: string[];\n}): string[] {\n const group = findGroup(input.layout?.root ?? null, input.anchor);\n return group &&\n group.panels.filter(id => !input.layout?.closed.includes(id) && input.available.includes(id)).length === 1\n ? [...group.panels]\n : [input.anchor];\n}\n\n/** Maps a visible insertion neighbor to its original order, retaining dormant members. */\nexport function getTabInsertionIndex(preferred: string[], before: string | undefined): number {\n const index = before === undefined ? preferred.length : preferred.indexOf(before);\n return index < 0 ? preferred.length : index;\n}\n"],"mappings":";;AASA,SAAgBA,EAAsB,GAAoC;CACxE,OAAO,KAAK,UAAU,CAAC,GAAGC,CAAO,CAAC,CAAC,KAAK,CAAC;AAC3C;AAGA,SAAgBC,EAAoB,GAAyB,GAAmC;CAC9F,IAAIC,MAASC,GAAO,OAAO;CAC3B,IAAID,EAAK,WAAWC,EAAM,QAAQ,OAAO;CACzC,KAAK,IAAMC,KAAMF,GACf,IAAI,CAACC,EAAM,SAASC,CAAE,GAAG,OAAO;CAElC,OAAO;AACT;AAEA,SAAgBC,EAAyB,GAI7B;CACV,IAAMC,IAASC,EAAUC,EAAM,MAAMA,EAAM,OAAO,EAAE;CAGpD,OAFI,CAACF,KAAU,CAACE,EAAM,OAAO,SAAe,KACxCA,EAAM,OAAO,SAAS,QAAcD,EAAUC,EAAM,MAAMA,EAAM,OAAO,YAAY,MAAM,MAAMF,IAC5FA,EAAO,OAAO,OAAM,MAAME,EAAM,OAAO,SAASJ,CAAE,CAAC;AAC5D;AAEA,SAAgBK,EAAwB,GAI3B;CACX,IAAMC,IAAQH,EAAUC,EAAM,QAAQ,QAAQ,MAAMA,EAAM,MAAM;CAChE,OAAOE,KACLA,EAAM,OAAO,QAAO,MAAM,CAACF,EAAM,QAAQ,OAAO,SAASJ,CAAE,KAAKI,EAAM,UAAU,SAASJ,CAAE,CAAC,CAAC,CAAC,WAAW,IACvG,CAAC,GAAGM,EAAM,MAAM,IAChB,CAACF,EAAM,MAAM;AACnB;AAGA,SAAgBG,EAAqB,GAAqB,GAAoC;CAC5F,IAAMC,IAAQC,MAAW,KAAA,IAAYC,EAAU,SAASA,EAAU,QAAQD,CAAM;CAChF,OAAOD,IAAQ,IAAIE,EAAU,SAASF;AACxC"}
|
|
@@ -6,6 +6,7 @@ export interface WorkspaceDestination {
|
|
|
6
6
|
position: 'tab' | 'left' | 'right' | 'top' | 'bottom';
|
|
7
7
|
index?: number;
|
|
8
8
|
}
|
|
9
|
+
export declare function sameDestination(left: WorkspaceDestination, right: WorkspaceDestination): boolean;
|
|
9
10
|
export declare function findGroup(node: WorkspaceNode | null, id?: string): WorkspaceGroup | undefined;
|
|
10
11
|
export declare function isValidInsertionIndex(index: number | undefined): boolean;
|
|
11
12
|
/** Removes carried panels from the arrangement and closed list without changing the saved layout. */
|