@nvidia-elements/core 2.22.4 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/accordion/accordion2.js +4 -4
  3. package/dist/alert/alert-group2.js +1 -1
  4. package/dist/alert/alert2.js +1 -1
  5. package/dist/avatar/avatar-group2.js +1 -1
  6. package/dist/avatar/avatar2.js +1 -1
  7. package/dist/badge/badge2.js +1 -1
  8. package/dist/breadcrumb/breadcrumb2.js +1 -1
  9. package/dist/bundle.d.ts +4 -0
  10. package/dist/bundles/index.d.ts +336 -0
  11. package/dist/bundles/index.js +14 -14
  12. package/dist/button/button2.js +1 -1
  13. package/dist/button-group/button-group2.js +1 -1
  14. package/dist/card/card2.js +4 -4
  15. package/dist/chat-message/chat-message2.js +1 -1
  16. package/dist/checkbox/checkbox-group2.js +1 -1
  17. package/dist/checkbox/checkbox2.js +1 -1
  18. package/dist/color/color2.js +6 -6
  19. package/dist/combobox/combobox2.js +1 -1
  20. package/dist/copy-button/copy-button2.js +1 -1
  21. package/dist/custom-elements-jsx.d.ts +189 -0
  22. package/dist/custom-elements-vue.d.ts +189 -0
  23. package/dist/custom-elements.json +6555 -0
  24. package/dist/data.html.json +133 -0
  25. package/dist/data.snippets.json +27 -27
  26. package/dist/date/date2.js +6 -6
  27. package/dist/datetime/datetime2.js +6 -6
  28. package/dist/dialog/dialog-footer2.js +1 -1
  29. package/dist/dialog/dialog-header2.js +1 -1
  30. package/dist/dialog/dialog2.js +1 -1
  31. package/dist/divider/divider2.js +1 -1
  32. package/dist/dot/dot2.js +1 -1
  33. package/dist/drag-handle/drag-handle2.js +1 -1
  34. package/dist/drawer/drawer-content2.js +1 -1
  35. package/dist/drawer/drawer-footer2.js +1 -1
  36. package/dist/drawer/drawer-header2.js +1 -1
  37. package/dist/drawer/drawer2.js +1 -1
  38. package/dist/dropdown/dropdown-footer2.js +1 -1
  39. package/dist/dropdown/dropdown-header2.js +1 -1
  40. package/dist/dropdown/dropdown2.js +1 -1
  41. package/dist/dropdown-group/dropdown-group.js +1 -1
  42. package/dist/dropzone/dropzone2.js +1 -1
  43. package/dist/file/file2.js +1 -1
  44. package/dist/format-bytes/format-bytes2.js +1 -1
  45. package/dist/format-datetime/format-datetime2.js +1 -1
  46. package/dist/format-number/format-number2.js +1 -1
  47. package/dist/format-relative-time/format-relative-time2.js +1 -1
  48. package/dist/format-truncate/format-truncate2.js +1 -1
  49. package/dist/forms/control/control2.js +1 -1
  50. package/dist/forms/control-group/control-group2.js +1 -1
  51. package/dist/forms/control-message/control-message2.js +1 -1
  52. package/dist/gauge/gauge2.js +1 -1
  53. package/dist/ghost/define.d.ts +6 -0
  54. package/dist/ghost/define.js +6 -0
  55. package/dist/ghost/define.js.map +1 -0
  56. package/dist/ghost/ghost.d.ts +27 -0
  57. package/dist/ghost/ghost.examples.js +5 -0
  58. package/dist/ghost/ghost.examples.js.map +1 -0
  59. package/dist/ghost/ghost.examples.json +37 -0
  60. package/dist/ghost/ghost.js +5 -0
  61. package/dist/ghost/ghost.js.map +1 -0
  62. package/dist/ghost/ghost2.js +28 -0
  63. package/dist/ghost/ghost2.js.map +1 -0
  64. package/dist/ghost/index.d.ts +1 -0
  65. package/dist/ghost/index.js +1 -0
  66. package/dist/grid/cell/cell2.js +1 -1
  67. package/dist/grid/column/column2.js +1 -1
  68. package/dist/grid/footer/footer2.js +1 -1
  69. package/dist/grid/grid2.js +1 -1
  70. package/dist/grid/header/header2.js +1 -1
  71. package/dist/grid/placeholder/placeholder2.js +1 -1
  72. package/dist/grid/row/row2.js +1 -1
  73. package/dist/icon/icon2.js +2 -2
  74. package/dist/icon-button/icon-button2.js +1 -1
  75. package/dist/iframe/iframe2.js +1 -1
  76. package/dist/index.js +1 -1
  77. package/dist/input/input-group2.js +1 -1
  78. package/dist/input/input2.js +1 -1
  79. package/dist/internal/utils/a11y.js.map +1 -1
  80. package/dist/joystick/joystick2.js +5 -5
  81. package/dist/logo/logo2.js +1 -1
  82. package/dist/menu/menu-group2.js +1 -1
  83. package/dist/menu/menu-item2.js +1 -1
  84. package/dist/menu/menu2.js +1 -1
  85. package/dist/month/month2.js +6 -6
  86. package/dist/notification/notification-group2.js +1 -1
  87. package/dist/notification/notification2.js +1 -1
  88. package/dist/page/page-panel/page-panel-content2.js +1 -1
  89. package/dist/page/page-panel/page-panel-footer2.js +1 -1
  90. package/dist/page/page-panel/page-panel-header2.js +1 -1
  91. package/dist/page/page-panel/page-panel2.js +1 -1
  92. package/dist/page/page2.js +1 -1
  93. package/dist/page-header/page-header2.js +1 -1
  94. package/dist/page-loader/page-loader2.js +1 -1
  95. package/dist/pagination/pagination2.js +1 -1
  96. package/dist/panel/panel2.js +4 -4
  97. package/dist/password/password2.js +6 -6
  98. package/dist/polyfills/index.d.ts +4 -7
  99. package/dist/polyfills/index.js +0 -8
  100. package/dist/preferences-input/preferences-input2.js +5 -5
  101. package/dist/progress-bar/progress-bar2.js +1 -1
  102. package/dist/progress-dot/progress-dot2.js +1 -1
  103. package/dist/progress-ring/progress-ring2.js +1 -1
  104. package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
  105. package/dist/pulse/pulse2.js +1 -1
  106. package/dist/radio/radio-group2.js +1 -1
  107. package/dist/radio/radio2.js +1 -1
  108. package/dist/range/range2.js +1 -1
  109. package/dist/resize-handle/resize-handle2.js +5 -5
  110. package/dist/search/search2.js +6 -6
  111. package/dist/select/select2.js +1 -1
  112. package/dist/select/select2.js.map +1 -1
  113. package/dist/skeleton/skeleton2.js +1 -1
  114. package/dist/sort-button/sort-button2.js +1 -1
  115. package/dist/sparkline/sparkline2.js +1 -1
  116. package/dist/star-rating/star-rating2.js +1 -1
  117. package/dist/steps/steps2.js +6 -6
  118. package/dist/switch/switch-group2.js +1 -1
  119. package/dist/switch/switch2.js +1 -1
  120. package/dist/tabs/tabs-group2.js +1 -1
  121. package/dist/tabs/tabs-item-group2.js +1 -1
  122. package/dist/tabs/tabs2.js +2 -2
  123. package/dist/tag/tag2.js +5 -5
  124. package/dist/textarea/textarea2.js +1 -1
  125. package/dist/time/time2.js +6 -6
  126. package/dist/toast/toast2.js +1 -1
  127. package/dist/toast/toast2.js.map +1 -1
  128. package/dist/toggletip/toggletip-footer2.js +1 -1
  129. package/dist/toggletip/toggletip-header2.js +1 -1
  130. package/dist/toggletip/toggletip2.js +1 -1
  131. package/dist/toolbar/toolbar2.js +1 -1
  132. package/dist/tooltip/tooltip2.js +1 -1
  133. package/dist/tree/tree-node2.js +1 -1
  134. package/dist/tree/tree2.js +1 -1
  135. package/dist/week/week2.js +6 -6
  136. package/dist/workspace/controllers/workspace-command.controller.d.ts +34 -0
  137. package/dist/workspace/controllers/workspace-command.controller.js +87 -0
  138. package/dist/workspace/controllers/workspace-command.controller.js.map +1 -0
  139. package/dist/workspace/controllers/workspace-composition.controller.d.ts +54 -0
  140. package/dist/workspace/controllers/workspace-composition.controller.js +169 -0
  141. package/dist/workspace/controllers/workspace-composition.controller.js.map +1 -0
  142. package/dist/workspace/controllers/workspace-fullscreen.controller.d.ts +25 -0
  143. package/dist/workspace/controllers/workspace-fullscreen.controller.js +84 -0
  144. package/dist/workspace/controllers/workspace-fullscreen.controller.js.map +1 -0
  145. package/dist/workspace/controllers/workspace-measurement.controller.d.ts +19 -0
  146. package/dist/workspace/controllers/workspace-measurement.controller.js +188 -0
  147. package/dist/workspace/controllers/workspace-measurement.controller.js.map +1 -0
  148. package/dist/workspace/controllers/workspace-rearrange.controller.d.ts +40 -0
  149. package/dist/workspace/controllers/workspace-rearrange.controller.js +385 -0
  150. package/dist/workspace/controllers/workspace-rearrange.controller.js.map +1 -0
  151. package/dist/workspace/controllers/workspace-resize.controller.d.ts +43 -0
  152. package/dist/workspace/controllers/workspace-resize.controller.js +168 -0
  153. package/dist/workspace/controllers/workspace-resize.controller.js.map +1 -0
  154. package/dist/workspace/controllers/workspace-restoration.controller.d.ts +24 -0
  155. package/dist/workspace/controllers/workspace-restoration.controller.js +193 -0
  156. package/dist/workspace/controllers/workspace-restoration.controller.js.map +1 -0
  157. package/dist/workspace/define.d.ts +10 -0
  158. package/dist/workspace/define.js +9 -0
  159. package/dist/workspace/define.js.map +1 -0
  160. package/dist/workspace/index.d.ts +8 -0
  161. package/dist/workspace/index.js +6 -0
  162. package/dist/workspace/panel/panel.d.ts +48 -0
  163. package/dist/workspace/panel/panel.js +5 -0
  164. package/dist/workspace/panel/panel.js.map +1 -0
  165. package/dist/workspace/panel/panel2.js +53 -0
  166. package/dist/workspace/panel/panel2.js.map +1 -0
  167. package/dist/workspace/panel-content/panel-content.d.ts +20 -0
  168. package/dist/workspace/panel-content/panel-content.js +5 -0
  169. package/dist/workspace/panel-content/panel-content.js.map +1 -0
  170. package/dist/workspace/panel-content/panel-content2.js +22 -0
  171. package/dist/workspace/panel-content/panel-content2.js.map +1 -0
  172. package/dist/workspace/panel-footer/panel-footer.d.ts +24 -0
  173. package/dist/workspace/panel-footer/panel-footer.js +5 -0
  174. package/dist/workspace/panel-footer/panel-footer.js.map +1 -0
  175. package/dist/workspace/panel-footer/panel-footer2.js +28 -0
  176. package/dist/workspace/panel-footer/panel-footer2.js.map +1 -0
  177. package/dist/workspace/panel-header/panel-header.d.ts +61 -0
  178. package/dist/workspace/panel-header/panel-header.js +5 -0
  179. package/dist/workspace/panel-header/panel-header.js.map +1 -0
  180. package/dist/workspace/panel-header/panel-header2.js +102 -0
  181. package/dist/workspace/panel-header/panel-header2.js.map +1 -0
  182. package/dist/workspace/utils/evaluation.utils.d.ts +83 -0
  183. package/dist/workspace/utils/evaluation.utils.js +294 -0
  184. package/dist/workspace/utils/evaluation.utils.js.map +1 -0
  185. package/dist/workspace/utils/geometry/allocation.utils.d.ts +40 -0
  186. package/dist/workspace/utils/geometry/allocation.utils.js +73 -0
  187. package/dist/workspace/utils/geometry/allocation.utils.js.map +1 -0
  188. package/dist/workspace/utils/geometry/partition.utils.d.ts +10 -0
  189. package/dist/workspace/utils/geometry/partition.utils.js +40 -0
  190. package/dist/workspace/utils/geometry/partition.utils.js.map +1 -0
  191. package/dist/workspace/utils/geometry/sizing.utils.d.ts +35 -0
  192. package/dist/workspace/utils/geometry/sizing.utils.js +42 -0
  193. package/dist/workspace/utils/geometry/sizing.utils.js.map +1 -0
  194. package/dist/workspace/utils/interaction/boundary.utils.d.ts +40 -0
  195. package/dist/workspace/utils/interaction/boundary.utils.js +91 -0
  196. package/dist/workspace/utils/interaction/boundary.utils.js.map +1 -0
  197. package/dist/workspace/utils/interaction/command.utils.d.ts +74 -0
  198. package/dist/workspace/utils/interaction/command.utils.js +189 -0
  199. package/dist/workspace/utils/interaction/command.utils.js.map +1 -0
  200. package/dist/workspace/utils/interaction/drag-preview.utils.d.ts +79 -0
  201. package/dist/workspace/utils/interaction/drag-preview.utils.js +16 -0
  202. package/dist/workspace/utils/interaction/drag-preview.utils.js.map +1 -0
  203. package/dist/workspace/utils/interaction/insertion-offers.utils.d.ts +58 -0
  204. package/dist/workspace/utils/interaction/insertion-offers.utils.js +259 -0
  205. package/dist/workspace/utils/interaction/insertion-offers.utils.js.map +1 -0
  206. package/dist/workspace/utils/interaction/placement-decision.utils.d.ts +55 -0
  207. package/dist/workspace/utils/interaction/placement-decision.utils.js +242 -0
  208. package/dist/workspace/utils/interaction/placement-decision.utils.js.map +1 -0
  209. package/dist/workspace/utils/interaction/resize-input.utils.d.ts +1 -0
  210. package/dist/workspace/utils/interaction/resize-input.utils.js +17 -0
  211. package/dist/workspace/utils/interaction/resize-input.utils.js.map +1 -0
  212. package/dist/workspace/utils/model/layout.utils.d.ts +22 -0
  213. package/dist/workspace/utils/model/layout.utils.js +41 -0
  214. package/dist/workspace/utils/model/layout.utils.js.map +1 -0
  215. package/dist/workspace/utils/model/membership.utils.d.ts +14 -0
  216. package/dist/workspace/utils/model/membership.utils.js +17 -0
  217. package/dist/workspace/utils/model/membership.utils.js.map +1 -0
  218. package/dist/workspace/utils/model/operations.utils.d.ts +31 -0
  219. package/dist/workspace/utils/model/operations.utils.js +178 -0
  220. package/dist/workspace/utils/model/operations.utils.js.map +1 -0
  221. package/dist/workspace/utils/model/projection.utils.d.ts +7 -0
  222. package/dist/workspace/utils/model/projection.utils.js +87 -0
  223. package/dist/workspace/utils/model/projection.utils.js.map +1 -0
  224. package/dist/workspace/utils/model/value.utils.d.ts +5 -0
  225. package/dist/workspace/utils/model/value.utils.js +68 -0
  226. package/dist/workspace/utils/model/value.utils.js.map +1 -0
  227. package/dist/workspace/utils/placement/acquisition-sizing.utils.d.ts +32 -0
  228. package/dist/workspace/utils/placement/acquisition-sizing.utils.js +152 -0
  229. package/dist/workspace/utils/placement/acquisition-sizing.utils.js.map +1 -0
  230. package/dist/workspace/utils/placement/context.utils.d.ts +36 -0
  231. package/dist/workspace/utils/placement/context.utils.js +135 -0
  232. package/dist/workspace/utils/placement/context.utils.js.map +1 -0
  233. package/dist/workspace/utils/placement/group-insertion.utils.d.ts +26 -0
  234. package/dist/workspace/utils/placement/group-insertion.utils.js +171 -0
  235. package/dist/workspace/utils/placement/group-insertion.utils.js.map +1 -0
  236. package/dist/workspace/utils/placement/origin.utils.d.ts +13 -0
  237. package/dist/workspace/utils/placement/origin.utils.js +49 -0
  238. package/dist/workspace/utils/placement/origin.utils.js.map +1 -0
  239. package/dist/workspace/utils/placement/planner.utils.d.ts +22 -0
  240. package/dist/workspace/utils/placement/planner.utils.js +184 -0
  241. package/dist/workspace/utils/placement/planner.utils.js.map +1 -0
  242. package/dist/workspace/utils/placement/preparation.utils.d.ts +28 -0
  243. package/dist/workspace/utils/placement/preparation.utils.js +140 -0
  244. package/dist/workspace/utils/placement/preparation.utils.js.map +1 -0
  245. package/dist/workspace/utils/placement/region.utils.d.ts +15 -0
  246. package/dist/workspace/utils/placement/region.utils.js +111 -0
  247. package/dist/workspace/utils/placement/region.utils.js.map +1 -0
  248. package/dist/workspace/utils/placement/split-sizing.utils.d.ts +18 -0
  249. package/dist/workspace/utils/placement/split-sizing.utils.js +108 -0
  250. package/dist/workspace/utils/placement/split-sizing.utils.js.map +1 -0
  251. package/dist/workspace/utils/presentation/composition.utils.d.ts +17 -0
  252. package/dist/workspace/utils/presentation/composition.utils.js +95 -0
  253. package/dist/workspace/utils/presentation/composition.utils.js.map +1 -0
  254. package/dist/workspace/utils/presentation/groups.utils.d.ts +91 -0
  255. package/dist/workspace/utils/presentation/groups.utils.js +169 -0
  256. package/dist/workspace/utils/presentation/groups.utils.js.map +1 -0
  257. package/dist/workspace/utils/presentation/header-configuration.utils.d.ts +11 -0
  258. package/dist/workspace/utils/presentation/header-configuration.utils.js +7 -0
  259. package/dist/workspace/utils/presentation/header-configuration.utils.js.map +1 -0
  260. package/dist/workspace/utils/presentation/measurements.utils.d.ts +21 -0
  261. package/dist/workspace/utils/presentation/measurements.utils.js +28 -0
  262. package/dist/workspace/utils/presentation/measurements.utils.js.map +1 -0
  263. package/dist/workspace/utils/presentation/offers.utils.d.ts +43 -0
  264. package/dist/workspace/utils/presentation/offers.utils.js +137 -0
  265. package/dist/workspace/utils/presentation/offers.utils.js.map +1 -0
  266. package/dist/workspace/utils/presentation/preview.utils.d.ts +6 -0
  267. package/dist/workspace/utils/presentation/preview.utils.js +36 -0
  268. package/dist/workspace/utils/presentation/preview.utils.js.map +1 -0
  269. package/dist/workspace/workspace.d.ts +103 -0
  270. package/dist/workspace/workspace.examples.js +5 -0
  271. package/dist/workspace/workspace.examples.js.map +1 -0
  272. package/dist/workspace/workspace.examples.json +133 -0
  273. package/dist/workspace/workspace.js +5 -0
  274. package/dist/workspace/workspace.js.map +1 -0
  275. package/dist/workspace/workspace.types.d.ts +3 -0
  276. package/dist/workspace/workspace2.js +518 -0
  277. package/dist/workspace/workspace2.js.map +1 -0
  278. package/package.json +26 -3
  279. package/dist/polyfills/index.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ import type { Point, Rect } from '@nvidia-elements/core/internal';
2
+ import { getCurrentInsertionSeam } from './insertion-offers.utils.js';
3
+ import type { WorkspaceDropIntent } from './drag-preview.utils.js';
4
+ import type { WorkspaceInsertionOffer } from './insertion-offers.utils.js';
5
+ type Side = 'left' | 'right' | 'top' | 'bottom';
6
+ interface BoundaryInput {
7
+ offers: WorkspaceInsertionOffer[];
8
+ bounds: Rect;
9
+ point: Point;
10
+ current?: WorkspaceDropIntent;
11
+ headers: Rect[];
12
+ geometry?: Parameters<typeof getCurrentInsertionSeam>[1];
13
+ }
14
+ /** Separates a mathematical boundary selection from its clipped, inward-only cue. */
15
+ export declare function getBoundaryPlacementOffers(input: BoundaryInput): {
16
+ offers: {
17
+ kind: 'order' | 'insert';
18
+ owner: string;
19
+ boundary?: 'start' | 'end';
20
+ scope: NonNullable<ReturnType<typeof import("../placement/group-insertion.utils.js").describePlacementSlot>>;
21
+ plan: import("../placement/planner.utils.js").WorkspacePlacementPlan;
22
+ hitRect?: Rect;
23
+ scopeRect: Rect;
24
+ destination: import("../model/operations.utils.js").WorkspaceDestination;
25
+ rect: Rect;
26
+ }[];
27
+ hit: {
28
+ kind: 'order' | 'insert';
29
+ owner: string;
30
+ boundary?: 'start' | 'end';
31
+ scope: NonNullable<ReturnType<typeof import("../placement/group-insertion.utils.js").describePlacementSlot>>;
32
+ plan: import("../placement/planner.utils.js").WorkspacePlacementPlan;
33
+ hitRect?: Rect;
34
+ scopeRect: Rect;
35
+ destination: import("../model/operations.utils.js").WorkspaceDestination;
36
+ rect: Rect;
37
+ } | undefined;
38
+ };
39
+ export declare function getBoundarySide(bounds: Rect, point: Point, current?: Side): Side;
40
+ export {};
@@ -0,0 +1,91 @@
1
+ import { getCurrentInsertionSeam as e, partitionPlacementOffers as t, placementOwnsChrome as n } from "./insertion-offers.utils.js";
2
+ // src/workspace/utils/interaction/boundary.utils.ts
3
+ var r = [
4
+ "left",
5
+ "right",
6
+ "top",
7
+ "bottom"
8
+ ];
9
+ function i(e) {
10
+ let { offers: n, bounds: r, point: i, current: l } = e, u = n.filter((e) => e.owner === "root" && e.boundary), d = s(r, i, l && l.kind !== "invalid" && l.kind !== "tab" ? l.destination.position : void 0), f = u.find((e) => e.destination.position === d), p = f && c(r, i)[d] <= 6 ? f : void 0, m = t(n.filter((e) => !u.includes(e))).flatMap((t) => o({
11
+ input: e,
12
+ roots: u,
13
+ offer: t
14
+ })), h = u.filter((e) => e.destination.position === d).flatMap((e) => {
15
+ let t = a(r, d);
16
+ return t.width && t.height ? [{
17
+ ...e,
18
+ rect: t
19
+ }] : [];
20
+ });
21
+ return {
22
+ offers: [...h, ...m],
23
+ hit: p ? h.find((e) => e.scope.key === p.scope.key) : void 0
24
+ };
25
+ }
26
+ function a(e, t) {
27
+ return t === "left" || t === "right" ? {
28
+ x: t === "left" ? e.x : e.x + e.width - 6,
29
+ y: e.y,
30
+ width: 6,
31
+ height: e.height
32
+ } : {
33
+ x: e.x,
34
+ y: t === "top" ? e.y : e.y + e.height - 6,
35
+ width: e.width,
36
+ height: 6
37
+ };
38
+ }
39
+ function o({ input: t, roots: r, offer: i }) {
40
+ let a = t.offers.find((e) => e.scope.key === i.scope.key), o = t.geometry ? e(a, t.geometry) ?? a.rect : a.rect, s = i.destination.position, c = s === "left" || s === "right", d = { ...i.rect };
41
+ return r.some((e) => e.destination.position === s) && l(d, t.bounds, s) && (c ? d.x += s === "left" ? 6 : -6 : d.y += s === "top" ? 6 : -6), n(i) ? [{
42
+ ...i,
43
+ rect: a.rect,
44
+ hitRect: d
45
+ }] : u(d, t.headers, c).map((e) => ({
46
+ ...i,
47
+ rect: o,
48
+ hitRect: e
49
+ }));
50
+ }
51
+ function s(e, t, n) {
52
+ let i = c(e, t), a = Math.min(...Object.values(i)), o = r.filter((e) => i[e] === a);
53
+ return n && o.includes(n) ? n : o[0];
54
+ }
55
+ function c(e, t) {
56
+ return {
57
+ left: t.x - e.x,
58
+ right: e.x + e.width - t.x,
59
+ top: t.y - e.y,
60
+ bottom: e.y + e.height - t.y
61
+ };
62
+ }
63
+ function l(e, t, n) {
64
+ switch (n) {
65
+ case "left": return Math.abs(e.x - t.x) < 1;
66
+ case "right": return Math.abs(e.x + e.width - t.x - t.width) < 1;
67
+ case "top": return Math.abs(e.y - t.y) < 1;
68
+ case "bottom":
69
+ case "tab": return Math.abs(e.y + e.height - t.y - t.height) < 1;
70
+ }
71
+ }
72
+ function u(e, t, n = e.width === 12) {
73
+ let r = [e];
74
+ for (let e of t) r = r.flatMap((t) => d(t, e, n));
75
+ return r;
76
+ }
77
+ function d(e, t, n) {
78
+ if (e.x >= t.x + t.width || e.x + e.width <= t.x || e.y >= t.y + t.height || e.y + e.height <= t.y) return [e];
79
+ let r = n ? "y" : "x", i = n ? "height" : "width", a = t[r] - e[r], o = e[r] + e[i] - t[r] - t[i], s = [];
80
+ return a > 0 && s.push({
81
+ ...e,
82
+ [i]: a
83
+ }), o > 0 && s.push({
84
+ ...e,
85
+ [r]: t[r] + t[i],
86
+ [i]: o
87
+ }), s;
88
+ }
89
+ export { i as getBoundaryPlacementOffers, s as getBoundarySide };
90
+
91
+ //# sourceMappingURL=boundary.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.utils.js","names":["sides","getBoundaryPlacementOffers","input","roots","offers","offer","side","getBoundarySide","bounds","point","current","root","hit","edgeDistances","local","partitionPlacementOffers","localGeometry","painted","rect","boundaryPaint","paint","original","paintRect","getCurrentInsertionSeam","position","vertical","touches","placementOwnsChrome","protectChrome","distances","minimum","tied","fragments","header","headers","subtractHeaderFromFragment","fragment","start","extent","before","after"],"sources":["../../../../src/workspace/utils/interaction/boundary.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 { getCurrentInsertionSeam, partitionPlacementOffers, placementOwnsChrome } from './insertion-offers.utils.js';\n\nimport type { WorkspaceDropIntent } from './drag-preview.utils.js';\nimport type { WorkspaceInsertionOffer } from './insertion-offers.utils.js';\n\ntype Side = 'left' | 'right' | 'top' | 'bottom';\n\nconst sides: Side[] = ['left', 'right', 'top', 'bottom'];\n\ninterface BoundaryInput {\n offers: WorkspaceInsertionOffer[];\n bounds: Rect;\n point: Point;\n current?: WorkspaceDropIntent;\n headers: Rect[];\n geometry?: Parameters<typeof getCurrentInsertionSeam>[1];\n}\n\n/** Separates a mathematical boundary selection from its clipped, inward-only cue. */\nexport function getBoundaryPlacementOffers(input: BoundaryInput) {\n const { offers, bounds, point, current } = input;\n const roots = offers.filter(offer => offer.owner === 'root' && offer.boundary);\n const side = getBoundarySide(\n bounds,\n point,\n current && current.kind !== 'invalid' && current.kind !== 'tab' ? current.destination.position : undefined\n );\n const root = roots.find(offer => offer.destination.position === side);\n const hit = root && edgeDistances(bounds, point)[side] <= 6 ? root : undefined;\n const local = partitionPlacementOffers(offers.filter(offer => !roots.includes(offer))).flatMap(offer =>\n localGeometry({ input, roots, offer })\n );\n const painted = roots\n .filter(offer => offer.destination.position === side)\n .flatMap(offer => {\n const rect = boundaryPaint(bounds, side);\n return rect.width && rect.height ? [{ ...offer, rect }] : [];\n });\n return {\n offers: [...painted, ...local],\n hit: hit ? painted.find(offer => offer.scope.key === hit.scope.key) : undefined\n };\n}\n\nfunction boundaryPaint(bounds: Rect, side: Side): Rect {\n if (side === 'left' || side === 'right') {\n const x = side === 'left' ? bounds.x : bounds.x + bounds.width - 6;\n return { x, y: bounds.y, width: 6, height: bounds.height };\n }\n\n const x = bounds.x;\n const y = side === 'top' ? bounds.y : bounds.y + bounds.height - 6;\n return { x, y, width: bounds.width, height: 6 };\n}\n\nfunction localGeometry({\n input,\n roots,\n offer\n}: {\n input: BoundaryInput;\n roots: WorkspaceInsertionOffer[];\n offer: WorkspaceInsertionOffer;\n}) {\n const paint = input.offers.find(original => original.scope.key === offer.scope.key)!;\n const paintRect = input.geometry ? (getCurrentInsertionSeam(paint, input.geometry) ?? paint.rect) : paint.rect;\n const position = offer.destination.position;\n const vertical = position === 'left' || position === 'right';\n const rect = { ...offer.rect };\n if (roots.some(root => root.destination.position === position) && touches(rect, input.bounds, position)) {\n if (vertical) {\n rect.x += position === 'left' ? 6 : -6;\n } else {\n rect.y += position === 'top' ? 6 : -6;\n }\n }\n if (placementOwnsChrome(offer)) return [{ ...offer, rect: paint.rect, hitRect: rect }];\n return protectChrome(rect, input.headers, vertical).map(hitRect => ({\n ...offer,\n rect: paintRect,\n hitRect\n }));\n}\n\nexport function getBoundarySide(bounds: Rect, point: Point, current?: Side): Side {\n const distances = edgeDistances(bounds, point);\n const minimum = Math.min(...Object.values(distances));\n const tied = sides.filter(side => distances[side] === minimum);\n return current && tied.includes(current) ? current : tied[0]!;\n}\n\nfunction edgeDistances(bounds: Rect, point: Point) {\n return {\n left: point.x - bounds.x,\n right: bounds.x + bounds.width - point.x,\n top: point.y - bounds.y,\n bottom: bounds.y + bounds.height - point.y\n };\n}\n\nfunction touches(rect: Rect, bounds: Rect, side: WorkspaceInsertionOffer['destination']['position']) {\n switch (side) {\n case 'left':\n return Math.abs(rect.x - bounds.x) < 1;\n case 'right':\n return Math.abs(rect.x + rect.width - bounds.x - bounds.width) < 1;\n case 'top':\n return Math.abs(rect.y - bounds.y) < 1;\n case 'bottom':\n case 'tab':\n return Math.abs(rect.y + rect.height - bounds.y - bounds.height) < 1;\n }\n}\n\nfunction protectChrome(rect: Rect, headers: Rect[], vertical = rect.width === 12): Rect[] {\n let fragments = [rect];\n for (const header of headers) {\n fragments = fragments.flatMap(fragment => subtractHeaderFromFragment(fragment, header, vertical));\n }\n return fragments;\n}\n\nfunction subtractHeaderFromFragment(fragment: Rect, header: Rect, vertical: boolean): Rect[] {\n if (\n fragment.x >= header.x + header.width ||\n fragment.x + fragment.width <= header.x ||\n fragment.y >= header.y + header.height ||\n fragment.y + fragment.height <= header.y\n ) {\n return [fragment];\n }\n const start = vertical ? 'y' : 'x';\n const extent = vertical ? 'height' : 'width';\n const before = header[start] - fragment[start];\n const after = fragment[start] + fragment[extent] - header[start] - header[extent];\n const fragments: Rect[] = [];\n if (before > 0) {\n fragments.push({ ...fragment, [extent]: before });\n }\n if (after > 0) {\n fragments.push({ ...fragment, [start]: header[start] + header[extent], [extent]: after });\n }\n return fragments;\n}\n"],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import type { WorkspaceDropIntent } from './drag-preview.utils.js';
2
+ import type { WorkspaceLayout } from '../model/layout.utils.js';
3
+ import type { WorkspacePanel } from '../../panel/panel.js';
4
+ export type WorkspaceSide = 'left' | 'right' | 'top' | 'bottom';
5
+ /** A placement supplied on the invoker's `placement` property for `--place`.
6
+ * Source defaults to one panel; `group` carries its entire current group, including closed members.
7
+ * An arrangement target identifies the enclosing split of the target panel, before source removal.
8
+ */
9
+ export type WorkspacePlacement = {
10
+ source?: 'panel' | 'group';
11
+ } & ({
12
+ operation: 'split';
13
+ target: string;
14
+ position: WorkspaceSide;
15
+ } | {
16
+ operation: 'join';
17
+ target: string;
18
+ index?: number;
19
+ } | {
20
+ operation: 'reorder';
21
+ target: string;
22
+ position: 'before' | 'after';
23
+ } | {
24
+ operation: 'insert';
25
+ scope: 'arrangement';
26
+ target: string;
27
+ position: WorkspaceSide;
28
+ } | {
29
+ operation: 'insert';
30
+ scope: 'workspace';
31
+ position: WorkspaceSide;
32
+ });
33
+ export type WorkspacePlacementIntent = Exclude<WorkspaceDropIntent, {
34
+ kind: 'invalid';
35
+ }>;
36
+ /** Identifies a supplied panel and optional placement without requiring an invoker element. */
37
+ export interface WorkspaceCommandContext {
38
+ value?: string | null;
39
+ placement?: WorkspacePlacement;
40
+ }
41
+ export interface WorkspaceCommandSource extends HTMLElement, WorkspaceCommandContext {
42
+ disabled?: boolean;
43
+ readOnly?: boolean;
44
+ }
45
+ export type WorkspaceCommandEvent = Event & {
46
+ command?: string;
47
+ source?: WorkspaceCommandSource | null;
48
+ };
49
+ interface WorkspaceCommandAvailability {
50
+ command: string;
51
+ context: WorkspaceCommandContext;
52
+ layout?: WorkspaceLayout;
53
+ available: string[];
54
+ closable: boolean;
55
+ rearrangeable: boolean;
56
+ placementAvailable(source: string[], intent: WorkspacePlacementIntent): boolean;
57
+ canEnterFullscreen(anchor: string): boolean;
58
+ canExitFullscreen(): boolean;
59
+ isFullscreenGroup(anchor: string): boolean;
60
+ }
61
+ export declare function findWorkspaceCommandPanel(host: HTMLElement, panels: WorkspacePanel[], event: WorkspaceCommandEvent): WorkspacePanel | undefined;
62
+ export declare function isWorkspaceCommandAvailable(input: WorkspaceCommandAvailability): boolean;
63
+ export declare function isWorkspacePlacement(value: unknown): value is WorkspacePlacement;
64
+ /** Resolves panel IDs to placement operations without exposing region paths. */
65
+ export declare function resolveWorkspacePlacement(input: {
66
+ layout: WorkspaceLayout;
67
+ available: string[];
68
+ anchor: string;
69
+ placement: WorkspacePlacement;
70
+ }): {
71
+ source: string[];
72
+ intent: WorkspacePlacementIntent;
73
+ } | undefined;
74
+ export {};
@@ -0,0 +1,189 @@
1
+ import { getSplitSide as e } from "../model/layout.utils.js";
2
+ import { findGroup as t, projectLayout as n } from "../model/operations.utils.js";
3
+ // src/workspace/utils/interaction/command.utils.ts
4
+ function r(e, t, n) {
5
+ return n.target === e ? t.find((e) => e.id === n.source?.value) : t.find((e) => e === n.target);
6
+ }
7
+ function i(e) {
8
+ let t = o(e);
9
+ if (!t) return !1;
10
+ let { id: n } = t;
11
+ switch (e.command) {
12
+ case "--enter-fullscreen": return e.canEnterFullscreen(n);
13
+ case "--exit-fullscreen": return e.canExitFullscreen();
14
+ case "--toggle-fullscreen": return e.isFullscreenGroup(n) ? e.canExitFullscreen() : e.canEnterFullscreen(n);
15
+ default: return a(e, t);
16
+ }
17
+ }
18
+ function a(e, t) {
19
+ let { id: n, group: r, closed: i } = t;
20
+ switch (e.command) {
21
+ case "--open": return i || r.active !== n;
22
+ case "--select": return !i && r.active !== n;
23
+ case "--close": return e.closable && !i;
24
+ case "--place": return s(e, n);
25
+ default: return !1;
26
+ }
27
+ }
28
+ function o(e) {
29
+ let n = e.context.value;
30
+ if (!n || !e.layout || !e.available.includes(n)) return;
31
+ let r = t(e.layout.root, n);
32
+ return r ? {
33
+ id: n,
34
+ group: r,
35
+ closed: e.layout.closed.includes(n)
36
+ } : void 0;
37
+ }
38
+ function s(e, t) {
39
+ let n = e.context.placement;
40
+ if (!e.rearrangeable || !c(n) || !e.layout) return !1;
41
+ let r = g({
42
+ layout: e.layout,
43
+ available: e.available,
44
+ anchor: t,
45
+ placement: n
46
+ });
47
+ return !!r && e.placementAvailable(r.source, r.intent);
48
+ }
49
+ function c(e) {
50
+ if (!p(e) || !l(e.source)) return !1;
51
+ switch (e.operation) {
52
+ case "split": return e.scope === void 0 && m(e.target) && h(e.position);
53
+ case "join": return u(e);
54
+ case "reorder": return d(e);
55
+ case "insert": return f(e);
56
+ default: return !1;
57
+ }
58
+ }
59
+ function l(e) {
60
+ return e === void 0 || e === "panel" || e === "group";
61
+ }
62
+ function u(e) {
63
+ let t = e.index;
64
+ return e.scope === void 0 && m(e.target) && (t === void 0 || typeof t == "number" && Number.isInteger(t) && t >= 0);
65
+ }
66
+ function d(e) {
67
+ return e.scope === void 0 && m(e.target) && (e.position === "before" || e.position === "after");
68
+ }
69
+ function f(e) {
70
+ return h(e.position) && (e.scope === "workspace" && e.target === void 0 || e.scope === "arrangement" && m(e.target));
71
+ }
72
+ function p(e) {
73
+ return typeof e == "object" && !!e && !Array.isArray(e);
74
+ }
75
+ function m(e) {
76
+ return typeof e == "string" && e.length > 0;
77
+ }
78
+ function h(e) {
79
+ return e === "left" || e === "right" || e === "top" || e === "bottom";
80
+ }
81
+ function g(e) {
82
+ let { layout: r, available: i, anchor: a, placement: o } = e, s = i.filter((e) => !r.closed.includes(e));
83
+ if (!s.includes(a)) return;
84
+ let c = t(r.root, a);
85
+ if (!c) return;
86
+ let l = o.source === "group" ? [...c.panels] : [a], u = n(r, i).root;
87
+ if (o.operation === "insert" && o.scope === "workspace") {
88
+ let e = b(u, l);
89
+ return e ? {
90
+ source: l,
91
+ intent: {
92
+ kind: "insert",
93
+ destination: {
94
+ target: e,
95
+ region: "root",
96
+ position: o.position
97
+ }
98
+ }
99
+ } : void 0;
100
+ }
101
+ if (!s.includes(o.target) || !t(u, o.target)) return;
102
+ let d = _({
103
+ root: u,
104
+ source: l,
105
+ placement: o
106
+ });
107
+ return d ? {
108
+ source: l,
109
+ intent: d
110
+ } : void 0;
111
+ }
112
+ function _({ root: e, source: t, placement: n }) {
113
+ let r = n.target;
114
+ switch (n.operation) {
115
+ case "join": return {
116
+ kind: "tab",
117
+ destination: {
118
+ target: r,
119
+ position: "tab",
120
+ index: n.index
121
+ }
122
+ };
123
+ case "split": return t.includes(r) ? void 0 : {
124
+ kind: "split",
125
+ destination: {
126
+ target: r,
127
+ position: n.position
128
+ }
129
+ };
130
+ case "reorder": return v({
131
+ root: e,
132
+ source: t,
133
+ target: r,
134
+ position: n.position
135
+ });
136
+ case "insert": {
137
+ let t = y(e, r)?.owner;
138
+ return t ? {
139
+ kind: "insert",
140
+ destination: {
141
+ target: r,
142
+ region: t.key,
143
+ position: n.position
144
+ }
145
+ } : void 0;
146
+ }
147
+ }
148
+ }
149
+ function v(n) {
150
+ let r = y(n.root, n.source[0]), i = r?.owner;
151
+ if (!i) return;
152
+ let a = i.node.children.findIndex((e) => !!t(e, n.target));
153
+ if (a < 0 || a === r.index) return;
154
+ let o = e(i.node.axis, n.position);
155
+ return {
156
+ kind: "order",
157
+ destination: {
158
+ target: n.target,
159
+ region: `${i.key}.${a}`,
160
+ position: o
161
+ }
162
+ };
163
+ }
164
+ function y(e, t, n = "root") {
165
+ if (e) {
166
+ if (e.type === "group") return e.panels.includes(t) ? {
167
+ group: e,
168
+ index: 0
169
+ } : void 0;
170
+ for (let [r, i] of e.children.entries()) {
171
+ if (i.type === "group" && i.panels.includes(t)) return {
172
+ group: i,
173
+ index: r,
174
+ owner: {
175
+ node: e,
176
+ key: n
177
+ }
178
+ };
179
+ let a = y(i, t, `${n}.${r}`);
180
+ if (a) return a;
181
+ }
182
+ }
183
+ }
184
+ function b(e, t) {
185
+ if (e) return e.type === "group" ? e.panels.find((e) => !t.includes(e)) : e.children.map((e) => b(e, t)).find(Boolean);
186
+ }
187
+ export { r as findWorkspaceCommandPanel, i as isWorkspaceCommandAvailable, c as isWorkspacePlacement, g as resolveWorkspacePlacement };
188
+
189
+ //# sourceMappingURL=command.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.utils.js","names":["findWorkspaceCommandPanel","event","host","panels","panel","isWorkspaceCommandAvailable","commandPanel","input","id","layoutCommandAvailable","closed","group","placementCommandAvailable","findGroup","placement","isWorkspacePlacement","request","resolveWorkspacePlacement","isRecord","value","isValidSource","isNonemptyString","isWorkspaceSide","hasValidJoinFields","hasValidReorderFields","hasValidInsertionFields","index","visible","available","layout","anchor","source","root","projectLayout","target","firstRemaining","intent","relativePlacement","peerOrder","owner","groupAddress","address","child","position","getSplitSide","node","nested","key"],"sources":["../../../../src/workspace/utils/interaction/command.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { getSplitSide } from '../model/layout.utils.js';\nimport { findGroup, projectLayout } from '../model/operations.utils.js';\n\nimport type { WorkspaceDropIntent } from './drag-preview.utils.js';\nimport type { WorkspaceGroup, WorkspaceLayout, WorkspaceNode, WorkspaceSplit } from '../model/layout.utils.js';\n\nimport type { WorkspacePanel } from '../../panel/panel.js';\n\nexport type WorkspaceSide = 'left' | 'right' | 'top' | 'bottom';\n\n/** A placement supplied on the invoker's `placement` property for `--place`.\n * Source defaults to one panel; `group` carries its entire current group, including closed members.\n * An arrangement target identifies the enclosing split of the target panel, before source removal.\n */\nexport type WorkspacePlacement = { source?: 'panel' | 'group' } & (\n | { operation: 'split'; target: string; position: WorkspaceSide }\n | { operation: 'join'; target: string; index?: number }\n | { operation: 'reorder'; target: string; position: 'before' | 'after' }\n | { operation: 'insert'; scope: 'arrangement'; target: string; position: WorkspaceSide }\n | { operation: 'insert'; scope: 'workspace'; position: WorkspaceSide }\n);\n\nexport type WorkspacePlacementIntent = Exclude<WorkspaceDropIntent, { kind: 'invalid' }>;\n\n/** Identifies a supplied panel and optional placement without requiring an invoker element. */\nexport interface WorkspaceCommandContext {\n value?: string | null;\n placement?: WorkspacePlacement;\n}\n\nexport interface WorkspaceCommandSource extends HTMLElement, WorkspaceCommandContext {\n disabled?: boolean;\n readOnly?: boolean;\n}\n\nexport type WorkspaceCommandEvent = Event & { command?: string; source?: WorkspaceCommandSource | null };\n\ninterface CommandPanelState {\n id: string;\n group: WorkspaceGroup;\n closed: boolean;\n}\n\ninterface WorkspaceCommandAvailability {\n command: string;\n context: WorkspaceCommandContext;\n layout?: WorkspaceLayout;\n available: string[];\n closable: boolean;\n rearrangeable: boolean;\n placementAvailable(source: string[], intent: WorkspacePlacementIntent): boolean;\n canEnterFullscreen(anchor: string): boolean;\n canExitFullscreen(): boolean;\n isFullscreenGroup(anchor: string): boolean;\n}\n\nexport function findWorkspaceCommandPanel(\n host: HTMLElement,\n panels: WorkspacePanel[],\n event: WorkspaceCommandEvent\n): WorkspacePanel | undefined {\n return event.target === host\n ? panels.find(panel => panel.id === event.source?.value)\n : panels.find(panel => panel === event.target);\n}\n\nexport function isWorkspaceCommandAvailable(input: WorkspaceCommandAvailability): boolean {\n const panel = commandPanel(input);\n if (!panel) return false;\n const { id } = panel;\n switch (input.command) {\n case '--enter-fullscreen':\n return input.canEnterFullscreen(id);\n case '--exit-fullscreen':\n return input.canExitFullscreen();\n case '--toggle-fullscreen':\n if (input.isFullscreenGroup(id)) {\n return input.canExitFullscreen();\n }\n return input.canEnterFullscreen(id);\n default:\n return layoutCommandAvailable(input, panel);\n }\n}\n\nfunction layoutCommandAvailable(input: WorkspaceCommandAvailability, panel: CommandPanelState) {\n const { id, group, closed } = panel;\n switch (input.command) {\n case '--open':\n return closed || group.active !== id;\n case '--select':\n return !closed && group.active !== id;\n case '--close':\n return input.closable && !closed;\n case '--place':\n return placementCommandAvailable(input, id);\n default:\n return false;\n }\n}\n\nfunction commandPanel(input: WorkspaceCommandAvailability): CommandPanelState | undefined {\n const id = input.context.value;\n if (!id || !input.layout || !input.available.includes(id)) return undefined;\n const group = findGroup(input.layout.root, id);\n return group ? { id, group, closed: input.layout.closed.includes(id) } : undefined;\n}\n\nfunction placementCommandAvailable(input: WorkspaceCommandAvailability, id: string) {\n const placement = input.context.placement;\n if (!input.rearrangeable || !isWorkspacePlacement(placement) || !input.layout) return false;\n const request = resolveWorkspacePlacement({\n layout: input.layout,\n available: input.available,\n anchor: id,\n placement\n });\n return !!request && input.placementAvailable(request.source, request.intent);\n}\n\nexport function isWorkspacePlacement(value: unknown): value is WorkspacePlacement {\n if (!isRecord(value) || !isValidSource(value.source)) return false;\n switch (value.operation) {\n case 'split':\n return value.scope === undefined && isNonemptyString(value.target) && isWorkspaceSide(value.position);\n case 'join':\n return hasValidJoinFields(value);\n case 'reorder':\n return hasValidReorderFields(value);\n case 'insert':\n return hasValidInsertionFields(value);\n default:\n return false;\n }\n}\n\nfunction isValidSource(value: unknown) {\n return value === undefined || value === 'panel' || value === 'group';\n}\n\nfunction hasValidJoinFields(value: Record<string, unknown>) {\n const index = value.index;\n return (\n value.scope === undefined &&\n isNonemptyString(value.target) &&\n (index === undefined || (typeof index === 'number' && Number.isInteger(index) && index >= 0))\n );\n}\n\nfunction hasValidReorderFields(value: Record<string, unknown>) {\n return (\n value.scope === undefined &&\n isNonemptyString(value.target) &&\n (value.position === 'before' || value.position === 'after')\n );\n}\n\nfunction hasValidInsertionFields(value: Record<string, unknown>) {\n return (\n isWorkspaceSide(value.position) &&\n ((value.scope === 'workspace' && value.target === undefined) ||\n (value.scope === 'arrangement' && isNonemptyString(value.target)))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonemptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\nfunction isWorkspaceSide(value: unknown): value is WorkspaceSide {\n return value === 'left' || value === 'right' || value === 'top' || value === 'bottom';\n}\n\n/** Resolves panel IDs to placement operations without exposing region paths. */\nexport function resolveWorkspacePlacement(input: {\n layout: WorkspaceLayout;\n available: string[];\n anchor: string;\n placement: WorkspacePlacement;\n}): { source: string[]; intent: WorkspacePlacementIntent } | undefined {\n const { layout, available, anchor, placement } = input;\n const visible = available.filter(id => !layout.closed.includes(id));\n if (!visible.includes(anchor)) return undefined;\n const group = findGroup(layout.root, anchor);\n if (!group) return undefined;\n const source = placement.source === 'group' ? [...group.panels] : [anchor];\n const root = projectLayout(layout, available).root;\n if (placement.operation === 'insert' && placement.scope === 'workspace') {\n const target = firstRemaining(root, source);\n if (!target) return undefined;\n\n return {\n source,\n intent: { kind: 'insert', destination: { target, region: 'root', position: placement.position } }\n };\n }\n if (!visible.includes(placement.target) || !findGroup(root, placement.target)) return undefined;\n const intent = relativePlacement({ root, source, placement });\n return intent ? { source, intent } : undefined;\n}\n\nfunction relativePlacement({\n root,\n source,\n placement\n}: {\n root: WorkspaceNode | null;\n source: string[];\n placement: Exclude<WorkspacePlacement, { operation: 'insert'; scope: 'workspace' }>;\n}): WorkspacePlacementIntent | undefined {\n const target = placement.target;\n switch (placement.operation) {\n case 'join':\n return { kind: 'tab', destination: { target, position: 'tab', index: placement.index } };\n case 'split':\n if (source.includes(target)) return undefined;\n\n return { kind: 'split', destination: { target, position: placement.position } };\n case 'reorder':\n return peerOrder({ root, source, target, position: placement.position });\n case 'insert': {\n const owner = groupAddress(root, target)?.owner;\n if (!owner) return undefined;\n\n return { kind: 'insert', destination: { target, region: owner.key, position: placement.position } };\n }\n }\n}\n\nfunction peerOrder(input: {\n root: WorkspaceNode | null;\n source: string[];\n target: string;\n position: 'before' | 'after';\n}): WorkspacePlacementIntent | undefined {\n const address = groupAddress(input.root, input.source[0]!);\n const owner = address?.owner;\n if (!owner) return undefined;\n const index = owner.node.children.findIndex(child => !!findGroup(child, input.target));\n if (index < 0 || index === address.index) return undefined;\n const position = getSplitSide(owner.node.axis, input.position);\n return { kind: 'order', destination: { target: input.target, region: `${owner.key}.${index}`, position } };\n}\n\ninterface GroupAddress {\n group: WorkspaceGroup;\n index: number;\n owner?: { node: WorkspaceSplit; key: string };\n}\n\nfunction groupAddress(node: WorkspaceNode | null, id: string, key = 'root'): GroupAddress | undefined {\n if (!node) return undefined;\n if (node.type === 'group') return node.panels.includes(id) ? { group: node, index: 0 } : undefined;\n for (const [index, child] of node.children.entries()) {\n if (child.type === 'group' && child.panels.includes(id)) return { group: child, index, owner: { node, key } };\n const nested = groupAddress(child, id, `${key}.${index}`);\n if (nested) return nested;\n }\n return undefined;\n}\n\nfunction firstRemaining(node: WorkspaceNode | null, source: string[]): string | undefined {\n if (!node) return undefined;\n return node.type === 'group'\n ? node.panels.find(id => !source.includes(id))\n : node.children.map(child => firstRemaining(child, source)).find(Boolean);\n}\n"],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import type { Point, Rect } from '@nvidia-elements/core/internal';
2
+ import type { WorkspaceLayout } from '../model/layout.utils.js';
3
+ import type { WorkspaceDestination } from '../model/operations.utils.js';
4
+ import type { WorkspacePlacementContext } from '../placement/context.utils.js';
5
+ import type { WorkspacePlacementPlan } from '../placement/planner.utils.js';
6
+ import type { WorkspaceSeamPreview } from '../presentation/offers.utils.js';
7
+ type TabDestination = Omit<WorkspaceDestination, 'position'> & {
8
+ position: 'tab';
9
+ };
10
+ type SplitDestination = Omit<WorkspaceDestination, 'position'> & {
11
+ position: Exclude<WorkspaceDestination['position'], 'tab'>;
12
+ };
13
+ export type WorkspaceDropIntent = {
14
+ kind: 'tab';
15
+ destination: TabDestination;
16
+ } | {
17
+ kind: 'split' | 'order';
18
+ destination: SplitDestination;
19
+ } | {
20
+ kind: 'insert';
21
+ destination: SplitDestination;
22
+ } | {
23
+ kind: 'invalid';
24
+ };
25
+ export interface WorkspaceDragCue {
26
+ rect: Rect;
27
+ kind: 'tab' | 'group';
28
+ }
29
+ interface PreviewPresentation {
30
+ seams?: WorkspaceSeamPreview;
31
+ context?: WorkspacePlacementContext;
32
+ source: string[];
33
+ point?: Point;
34
+ cue: WorkspaceDragCue;
35
+ }
36
+ interface AttachedPreview extends PreviewPresentation {
37
+ phase: 'attached';
38
+ intent: {
39
+ kind: 'invalid';
40
+ };
41
+ blocked: false;
42
+ }
43
+ export type WorkspaceDragAllocation = {
44
+ allocation: 'overlay' | 'committed';
45
+ } | {
46
+ allocation: 'reserved';
47
+ layout: WorkspaceLayout;
48
+ };
49
+ export type WorkspaceDragOffer = {
50
+ cue: WorkspaceDragCue;
51
+ feasible: boolean;
52
+ seams?: WorkspaceSeamPreview;
53
+ context?: WorkspacePlacementContext;
54
+ } & WorkspaceDragAllocation;
55
+ type DetachedPreview = PreviewPresentation & WorkspaceDragAllocation & {
56
+ phase: 'detached';
57
+ intent: WorkspaceDropIntent;
58
+ blocked: boolean;
59
+ };
60
+ export type WorkspaceDragPreview = AttachedPreview | DetachedPreview | (PreviewPresentation & WorkspaceDragAllocation & {
61
+ phase: 'returning-attached' | 'returning-detached';
62
+ intent: {
63
+ kind: 'invalid';
64
+ };
65
+ blocked: false;
66
+ });
67
+ export interface WorkspacePlacementAcquisition {
68
+ plan: WorkspacePlacementPlan;
69
+ rect: Rect;
70
+ }
71
+ export interface WorkspaceOfferContext {
72
+ selected?: WorkspaceDragPreview;
73
+ acquisition?: WorkspacePlacementAcquisition & {
74
+ point: Point;
75
+ };
76
+ }
77
+ export declare function clipCue(rect: Rect, bounds: Rect): Rect;
78
+ export declare function matchesPlacementIntent(a: WorkspaceDropIntent, b: WorkspaceDropIntent): boolean;
79
+ export {};
@@ -0,0 +1,16 @@
1
+ // src/workspace/utils/interaction/drag-preview.utils.ts
2
+ function e(e, t) {
3
+ let n = Math.max(t.x, Math.min(e.x, t.x + t.width)), r = Math.max(t.y, Math.min(e.y, t.y + t.height));
4
+ return {
5
+ x: n,
6
+ y: r,
7
+ width: Math.max(0, Math.min(e.x + e.width, t.x + t.width) - n),
8
+ height: Math.max(0, Math.min(e.y + e.height, t.y + t.height) - r)
9
+ };
10
+ }
11
+ function t(e, t) {
12
+ return e.kind === "invalid" || t.kind === "invalid" || e.kind !== t.kind ? !1 : e.destination.target === t.destination.target && e.destination.region === t.destination.region && e.destination.position === t.destination.position && e.destination.index === t.destination.index;
13
+ }
14
+ export { e as clipCue, t as matchesPlacementIntent };
15
+
16
+ //# sourceMappingURL=drag-preview.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drag-preview.utils.js","names":["clipCue","x","bounds","rect","y","matchesPlacementIntent","a","b"],"sources":["../../../../src/workspace/utils/interaction/drag-preview.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 type { WorkspaceLayout } from '../model/layout.utils.js';\nimport type { WorkspaceDestination } from '../model/operations.utils.js';\nimport type { WorkspacePlacementContext } from '../placement/context.utils.js';\nimport type { WorkspacePlacementPlan } from '../placement/planner.utils.js';\nimport type { WorkspaceSeamPreview } from '../presentation/offers.utils.js';\n\ntype TabDestination = Omit<WorkspaceDestination, 'position'> & { position: 'tab' };\n\ntype SplitDestination = Omit<WorkspaceDestination, 'position'> & {\n position: Exclude<WorkspaceDestination['position'], 'tab'>;\n};\n\nexport type WorkspaceDropIntent =\n | { kind: 'tab'; destination: TabDestination }\n | { kind: 'split' | 'order'; destination: SplitDestination }\n | { kind: 'insert'; destination: SplitDestination }\n | { kind: 'invalid' };\n\nexport interface WorkspaceDragCue {\n rect: Rect;\n kind: 'tab' | 'group';\n}\n\ninterface PreviewPresentation {\n seams?: WorkspaceSeamPreview;\n context?: WorkspacePlacementContext;\n source: string[];\n point?: Point;\n cue: WorkspaceDragCue;\n}\n\ninterface AttachedPreview extends PreviewPresentation {\n phase: 'attached';\n intent: { kind: 'invalid' };\n blocked: false;\n}\n\nexport type WorkspaceDragAllocation =\n | { allocation: 'overlay' | 'committed' }\n | { allocation: 'reserved'; layout: WorkspaceLayout };\n\nexport type WorkspaceDragOffer = {\n cue: WorkspaceDragCue;\n feasible: boolean;\n seams?: WorkspaceSeamPreview;\n context?: WorkspacePlacementContext;\n} & WorkspaceDragAllocation;\n\ntype DetachedPreview = PreviewPresentation &\n WorkspaceDragAllocation & {\n phase: 'detached';\n intent: WorkspaceDropIntent;\n blocked: boolean;\n };\n\nexport type WorkspaceDragPreview =\n | AttachedPreview\n | DetachedPreview\n | (PreviewPresentation &\n WorkspaceDragAllocation & {\n phase: 'returning-attached' | 'returning-detached';\n intent: { kind: 'invalid' };\n blocked: false;\n });\n\nexport interface WorkspacePlacementAcquisition {\n plan: WorkspacePlacementPlan;\n rect: Rect;\n}\n\nexport interface WorkspaceOfferContext {\n selected?: WorkspaceDragPreview;\n acquisition?: WorkspacePlacementAcquisition & { point: Point };\n}\n\nexport function clipCue(rect: Rect, bounds: Rect): Rect {\n const x = Math.max(bounds.x, Math.min(rect.x, bounds.x + bounds.width));\n const y = Math.max(bounds.y, Math.min(rect.y, bounds.y + bounds.height));\n return {\n x,\n y,\n width: Math.max(0, Math.min(rect.x + rect.width, bounds.x + bounds.width) - x),\n height: Math.max(0, Math.min(rect.y + rect.height, bounds.y + bounds.height) - y)\n };\n}\n\nexport function matchesPlacementIntent(a: WorkspaceDropIntent, b: WorkspaceDropIntent) {\n if (a.kind === 'invalid' || b.kind === 'invalid' || a.kind !== b.kind) return false;\n return (\n a.destination.target === b.destination.target &&\n a.destination.region === b.destination.region &&\n a.destination.position === b.destination.position &&\n a.destination.index === b.destination.index\n );\n}\n"],"mappings":";AAgFA,SAAgBA,EAAQ,GAAY,GAAoB;CACtD,IAAMC,IAAI,KAAK,IAAIC,EAAO,GAAG,KAAK,IAAIC,EAAK,GAAGD,EAAO,IAAIA,EAAO,KAAK,CAAC,GAChEE,IAAI,KAAK,IAAIF,EAAO,GAAG,KAAK,IAAIC,EAAK,GAAGD,EAAO,IAAIA,EAAO,MAAM,CAAC;CACvE,OAAO;EACL;EACA;EACA,OAAO,KAAK,IAAI,GAAG,KAAK,IAAIC,EAAK,IAAIA,EAAK,OAAOD,EAAO,IAAIA,EAAO,KAAK,IAAID,CAAC;EAC7E,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAIE,EAAK,IAAIA,EAAK,QAAQD,EAAO,IAAIA,EAAO,MAAM,IAAIE,CAAC;CAClF;AACF;AAEA,SAAgBC,EAAuB,GAAwB,GAAwB;CAErF,OADIC,EAAE,SAAS,aAAaC,EAAE,SAAS,aAAaD,EAAE,SAASC,EAAE,OAAa,KAE5ED,EAAE,YAAY,WAAWC,EAAE,YAAY,UACvCD,EAAE,YAAY,WAAWC,EAAE,YAAY,UACvCD,EAAE,YAAY,aAAaC,EAAE,YAAY,YACzCD,EAAE,YAAY,UAAUC,EAAE,YAAY;AAE1C"}
@@ -0,0 +1,58 @@
1
+ import type { Rect } from '@nvidia-elements/core/internal';
2
+ import { describePlacementSlot } from '../placement/group-insertion.utils.js';
3
+ import type { WorkspacePlacedRegion } from '../geometry/allocation.utils.js';
4
+ import type { WorkspaceDropIntent } from './drag-preview.utils.js';
5
+ import type { WorkspaceLayout, WorkspaceNode } from '../model/layout.utils.js';
6
+ import type { WorkspaceDestination } from '../model/operations.utils.js';
7
+ import type { WorkspaceLayoutProjector } from '../model/projection.utils.js';
8
+ import type { WorkspaceContextRectResolver } from '../placement/context.utils.js';
9
+ import type { WorkspacePlacementPlan, WorkspacePlacementPlanner } from '../placement/planner.utils.js';
10
+ export interface WorkspaceInsertionOffer {
11
+ kind: 'order' | 'insert';
12
+ owner: string;
13
+ boundary?: 'start' | 'end';
14
+ scope: NonNullable<ReturnType<typeof describePlacementSlot>>;
15
+ plan: WorkspacePlacementPlan;
16
+ rect: Rect;
17
+ hitRect?: Rect;
18
+ scopeRect: Rect;
19
+ destination: WorkspaceDestination;
20
+ }
21
+ /** Gives only an explicit peer lane or structural receiving endcap priority over chrome. */
22
+ export declare function placementOwnsChrome(offer: WorkspaceInsertionOffer): boolean;
23
+ export declare function findSourcePeerRegionKey(node: WorkspaceNode | null, source: string[], key?: string): string | undefined;
24
+ /** Aliases of the same planned insertion share one descriptor. */
25
+ export declare function createInsertionOffers(input: {
26
+ currentLayout: WorkspaceLayout;
27
+ root: WorkspaceNode | null;
28
+ source: string[];
29
+ available: string[];
30
+ projectLayout?: WorkspaceLayoutProjector;
31
+ planPlacement?: WorkspacePlacementPlanner;
32
+ contextRect?: WorkspaceContextRectResolver;
33
+ regions: WorkspacePlacedRegion[];
34
+ explorationRegions?: WorkspacePlacedRegion[];
35
+ existing: WorkspaceInsertionOffer[];
36
+ gap: number;
37
+ }): WorkspaceInsertionOffer[];
38
+ /** Shares the painted descriptor's exact operation with input resolution. */
39
+ export declare function getPlacementOfferIntent(offer: WorkspaceInsertionOffer): WorkspaceDropIntent;
40
+ /** Locates ordering availability in the computed exploration geometry, not a prospective landing. */
41
+ export declare function getOrderHintRect(input: {
42
+ owner: Rect;
43
+ recipient: Rect;
44
+ previous?: Rect;
45
+ axis: 'horizontal' | 'vertical';
46
+ after: boolean;
47
+ sourceSlot?: Rect;
48
+ boundary?: 'start' | 'end';
49
+ }): Rect | undefined;
50
+ /** Orders overlapping scope offers into lanes from outermost to innermost. */
51
+ export declare function partitionPlacementOffers(offers: WorkspaceInsertionOffer[]): WorkspaceInsertionOffer[];
52
+ /** Uses current peer geometry for interior insertion cues, before allocating the candidate. */
53
+ export declare function getCurrentInsertionSeam(offer: WorkspaceInsertionOffer, geometry: {
54
+ regions: WorkspacePlacedRegion[];
55
+ source: string[];
56
+ gap: number;
57
+ contextRect?: WorkspaceContextRectResolver;
58
+ }): Rect | undefined;