@nvidia-elements/core 2.23.5 → 2.24.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.
- package/CHANGELOG.md +19 -0
- package/dist/accordion/accordion-group.js.map +1 -1
- package/dist/accordion/accordion.js.map +1 -1
- 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/bundle.d.ts +2 -0
- package/dist/bundles/index.d.ts +323 -56
- package/dist/bundles/index.js +9 -9
- 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-jsx.d.ts +167 -1
- package/dist/custom-elements-vue.d.ts +161 -1
- package/dist/custom-elements.json +5017 -268
- package/dist/dashboard/controllers/arrangement.controller.d.ts +30 -0
- package/dist/dashboard/controllers/arrangement.controller.js +68 -0
- package/dist/dashboard/controllers/arrangement.controller.js.map +1 -0
- package/dist/dashboard/controllers/command.controller.d.ts +28 -0
- package/dist/dashboard/controllers/command.controller.js +69 -0
- package/dist/dashboard/controllers/command.controller.js.map +1 -0
- package/dist/dashboard/controllers/composition.controller.d.ts +61 -0
- package/dist/dashboard/controllers/composition.controller.js +285 -0
- package/dist/dashboard/controllers/composition.controller.js.map +1 -0
- package/dist/dashboard/controllers/fullscreen.controller.d.ts +23 -0
- package/dist/dashboard/controllers/fullscreen.controller.js +46 -0
- package/dist/dashboard/controllers/fullscreen.controller.js.map +1 -0
- package/dist/dashboard/controllers/interaction.controller.d.ts +53 -0
- package/dist/dashboard/controllers/interaction.controller.js +407 -0
- package/dist/dashboard/controllers/interaction.controller.js.map +1 -0
- package/dist/dashboard/controllers/measurement.controller.d.ts +28 -0
- package/dist/dashboard/controllers/measurement.controller.js +77 -0
- package/dist/dashboard/controllers/measurement.controller.js.map +1 -0
- package/dist/dashboard/dashboard.d.ts +83 -0
- package/dist/dashboard/dashboard.examples.js +5 -0
- package/dist/dashboard/dashboard.examples.js.map +1 -0
- package/dist/dashboard/dashboard.examples.json +138 -0
- package/dist/dashboard/dashboard.js +5 -0
- package/dist/dashboard/dashboard.js.map +1 -0
- package/dist/dashboard/dashboard.types.d.ts +33 -0
- package/dist/dashboard/dashboard2.js +352 -0
- package/dist/dashboard/dashboard2.js.map +1 -0
- package/dist/dashboard/define.d.ts +10 -0
- package/dist/dashboard/define.js +9 -0
- package/dist/dashboard/define.js.map +1 -0
- package/dist/dashboard/index.d.ts +8 -0
- package/dist/dashboard/index.js +6 -0
- package/dist/dashboard/panel/panel.d.ts +88 -0
- package/dist/dashboard/panel/panel.js +5 -0
- package/dist/dashboard/panel/panel.js.map +1 -0
- package/dist/dashboard/panel/panel2.js +110 -0
- package/dist/dashboard/panel/panel2.js.map +1 -0
- package/dist/dashboard/panel-content/panel-content.d.ts +20 -0
- package/dist/dashboard/panel-content/panel-content.js +5 -0
- package/dist/dashboard/panel-content/panel-content.js.map +1 -0
- package/dist/dashboard/panel-content/panel-content2.js +22 -0
- package/dist/dashboard/panel-content/panel-content2.js.map +1 -0
- package/dist/dashboard/panel-footer/panel-footer.d.ts +25 -0
- package/dist/dashboard/panel-footer/panel-footer.js +5 -0
- package/dist/dashboard/panel-footer/panel-footer.js.map +1 -0
- package/dist/dashboard/panel-footer/panel-footer2.js +28 -0
- package/dist/dashboard/panel-footer/panel-footer2.js.map +1 -0
- package/dist/dashboard/panel-header/panel-header.d.ts +27 -0
- package/dist/dashboard/panel-header/panel-header.js +5 -0
- package/dist/dashboard/panel-header/panel-header.js.map +1 -0
- package/dist/dashboard/panel-header/panel-header2.js +28 -0
- package/dist/dashboard/panel-header/panel-header2.js.map +1 -0
- package/dist/dashboard/utils/action.utils.d.ts +17 -0
- package/dist/dashboard/utils/action.utils.js +144 -0
- package/dist/dashboard/utils/action.utils.js.map +1 -0
- package/dist/dashboard/utils/geometry.utils.d.ts +110 -0
- package/dist/dashboard/utils/geometry.utils.js +208 -0
- package/dist/dashboard/utils/geometry.utils.js.map +1 -0
- package/dist/dashboard/utils/intent.types.d.ts +67 -0
- package/dist/dashboard/utils/layout.utils.d.ts +20 -0
- package/dist/dashboard/utils/layout.utils.js +224 -0
- package/dist/dashboard/utils/layout.utils.js.map +1 -0
- package/dist/dashboard/utils/movement.utils.d.ts +7 -0
- package/dist/dashboard/utils/movement.utils.js +15 -0
- package/dist/dashboard/utils/movement.utils.js.map +1 -0
- package/dist/dashboard/utils/mutation.utils.d.ts +2 -0
- package/dist/dashboard/utils/mutation.utils.js +19 -0
- package/dist/dashboard/utils/mutation.utils.js.map +1 -0
- package/dist/dashboard/utils/packing.utils.d.ts +13 -0
- package/dist/dashboard/utils/packing.utils.js +421 -0
- package/dist/dashboard/utils/packing.utils.js.map +1 -0
- package/dist/data.html.json +141 -1
- 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/dropdown.examples.js.map +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/grid.js.map +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/internal/controllers/native-fullscreen.controller.d.ts +13 -0
- package/dist/internal/controllers/native-fullscreen.controller.js +73 -0
- package/dist/internal/controllers/native-fullscreen.controller.js.map +1 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.js +59 -57
- package/dist/internal/index.js.map +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-fullscreen.controller.d.ts +2 -4
- package/dist/workspace/controllers/workspace-fullscreen.controller.js +17 -47
- package/dist/workspace/controllers/workspace-fullscreen.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 +16 -4
- 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value.utils.js","names":["
|
|
1
|
+
{"version":3,"file":"value.utils.js","names":["parseWorkspaceValue","value","data","ids","record","item","node","id","splitShape","child","normalizeLayout","serializeWorkspaceValue","layout","weight","sum","sameWorkspaceLayout","left","right","sameArrayItems","sameWorkspaceNode","index"],"sources":["../../../../src/workspace/utils/model/value.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { normalizeLayout } from './layout.utils.js';\nimport { sameArrayItems } from '../comparison.utils.js';\n\nimport type { WorkspaceLayout, WorkspaceNode, WorkspaceSplit } from './layout.utils.js';\n\nexport function parseWorkspaceValue(value: string): WorkspaceLayout | undefined {\n if (!value) return undefined;\n\n const data: unknown = JSON.parse(value);\n const ids = new Set<string>();\n const record = (item: unknown): item is Record<string, unknown> => typeof item === 'object' && item !== null;\n const node = (item: unknown): item is WorkspaceNode => {\n if (!record(item)) return false;\n if (item.type === 'group') {\n if (\n !Array.isArray(item.panels) ||\n !item.panels.length ||\n typeof item.active !== 'string' ||\n !item.panels.includes(item.active)\n ) {\n return false;\n }\n return item.panels.every(id => {\n if (typeof id !== 'string' || !id || ids.has(id)) return false;\n ids.add(id);\n return true;\n });\n }\n if (!splitShape(item)) return false;\n return item.children.every(child => node(child));\n };\n if (\n !record(data) ||\n data.version !== 1 ||\n !(data.root === null || node(data.root)) ||\n !Array.isArray(data.closed) ||\n !data.closed.every(id => typeof id === 'string' && ids.has(id)) ||\n new Set(data.closed).size !== data.closed.length\n ) {\n throw new TypeError('Invalid workspace arrangement');\n }\n return { version: 1, root: data.root === null ? null : normalizeLayout(data.root), closed: [...data.closed] };\n}\n\nexport function serializeWorkspaceValue(layout: WorkspaceLayout | undefined): string {\n return layout ? JSON.stringify(layout) : '';\n}\n\nfunction splitShape(item: Record<string, unknown>): item is Record<string, unknown> & WorkspaceSplit {\n if (item.type !== 'split' || !['horizontal', 'vertical'].includes(String(item.axis))) return false;\n if (!Array.isArray(item.children) || item.children.length < 2) return false;\n if (!Array.isArray(item.weights) || item.weights.length !== item.children.length) return false;\n if (!item.weights.every(weight => typeof weight === 'number' && Number.isFinite(weight) && weight > 0)) return false;\n return Number.isFinite(item.weights.reduce((sum: number, weight: number) => sum + weight, 0));\n}\n\n/** Compares known arrangement fields; object property insertion order is irrelevant. */\nexport function sameWorkspaceLayout(left: WorkspaceLayout | undefined, right: WorkspaceLayout | undefined): boolean {\n if (left === right) return true;\n if (!left || !right) return false;\n return (\n left.version === right.version &&\n sameArrayItems(left.closed, right.closed) &&\n sameWorkspaceNode(left.root, right.root)\n );\n}\n\n// eslint-disable-next-line complexity -- Compare the owned node fields directly without comparison callbacks.\nexport function sameWorkspaceNode(left: WorkspaceNode | null, right: WorkspaceNode | null): boolean {\n if (left === right) return true;\n if (!left || !right) return false;\n if (left.type === 'group') {\n return right.type === 'group' && left.active === right.active && sameArrayItems(left.panels, right.panels);\n }\n if (\n right.type !== 'split' ||\n left.axis !== right.axis ||\n !sameArrayItems(left.weights, right.weights) ||\n left.children.length !== right.children.length\n )\n return false;\n for (let index = 0; index < left.children.length; index++) {\n if (!sameWorkspaceNode(left.children[index]!, right.children[index]!)) return false;\n }\n return true;\n}\n"],"mappings":";;;AAQA,SAAgBA,EAAoB,GAA4C;CAC9E,IAAI,CAACC,GAAO;CAEZ,IAAMC,IAAgB,KAAK,MAAMD,CAAK,GAChCE,oBAAM,IAAI,IAAY,GACtBC,KAAU,MAAmD,OAAOC,KAAS,cAAYA,GACzFC,KAAQ,MACPF,EAAOC,CAAI,IACZA,EAAK,SAAS,UAEd,CAAC,MAAM,QAAQA,EAAK,MAAM,KAC1B,CAACA,EAAK,OAAO,UACb,OAAOA,EAAK,UAAW,YACvB,CAACA,EAAK,OAAO,SAASA,EAAK,MAAM,IAE1B,KAEFA,EAAK,OAAO,OAAM,MACnB,OAAOE,KAAO,YAAY,CAACA,KAAMJ,EAAI,IAAII,CAAE,IAAU,MACzDJ,EAAI,IAAII,CAAE,GACH,GACR,IAEEC,EAAWH,CAAI,IACbA,EAAK,SAAS,OAAM,MAASC,EAAKG,CAAK,CAAC,IADjB,KAhBJ;CAmB5B,IACE,CAACL,EAAOF,CAAI,KACZA,EAAK,YAAY,KACjB,EAAEA,EAAK,SAAS,QAAQI,EAAKJ,EAAK,IAAI,MACtC,CAAC,MAAM,QAAQA,EAAK,MAAM,KAC1B,CAACA,EAAK,OAAO,OAAM,MAAM,OAAOK,KAAO,YAAYJ,EAAI,IAAII,CAAE,CAAC,KAC9D,IAAI,IAAIL,EAAK,MAAM,CAAC,CAAC,SAASA,EAAK,OAAO,QAE1C,MAAU,UAAU,+BAA+B;CAErD,OAAO;EAAE,SAAS;EAAG,MAAMA,EAAK,SAAS,OAAO,OAAOQ,EAAgBR,EAAK,IAAI;EAAG,QAAQ,CAAC,GAAGA,EAAK,MAAM;CAAE;AAC9G;AAEA,SAAgBS,EAAwB,GAA6C;CACnF,OAAOC,IAAS,KAAK,UAAUA,CAAM,IAAI;AAC3C;AAEA,SAASJ,EAAW,GAAiF;CAKnG,OAJIH,EAAK,SAAS,WAAW,CAAC,CAAC,cAAc,UAAU,CAAC,CAAC,SAAS,OAAOA,EAAK,IAAI,CAAC,KAC/E,CAAC,MAAM,QAAQA,EAAK,QAAQ,KAAKA,EAAK,SAAS,SAAS,KACxD,CAAC,MAAM,QAAQA,EAAK,OAAO,KAAKA,EAAK,QAAQ,WAAWA,EAAK,SAAS,UACtE,CAACA,EAAK,QAAQ,OAAM,MAAU,OAAOQ,KAAW,YAAY,OAAO,SAASA,CAAM,KAAKA,IAAS,CAAC,IAAU,KACxG,OAAO,SAASR,EAAK,QAAQ,QAAQ,GAAa,MAAmBS,IAAMD,GAAQ,CAAC,CAAC;AAC9F;AAGA,SAAgBE,EAAoB,GAAmC,GAA6C;CAGlH,OAFIC,MAASC,IAAc,KACvB,CAACD,KAAQ,CAACC,IAAc,KAE1BD,EAAK,YAAYC,EAAM,WACvBC,EAAeF,EAAK,QAAQC,EAAM,MAAM,KACxCE,EAAkBH,EAAK,MAAMC,EAAM,IAAI;AAE3C;AAGA,SAAgBE,EAAkB,GAA4B,GAAsC;CAClG,IAAIH,MAASC,GAAO,OAAO;CAC3B,IAAI,CAACD,KAAQ,CAACC,GAAO,OAAO;CAC5B,IAAID,EAAK,SAAS,SAChB,OAAOC,EAAM,SAAS,WAAWD,EAAK,WAAWC,EAAM,UAAUC,EAAeF,EAAK,QAAQC,EAAM,MAAM;CAE3G,IACEA,EAAM,SAAS,WACfD,EAAK,SAASC,EAAM,QACpB,CAACC,EAAeF,EAAK,SAASC,EAAM,OAAO,KAC3CD,EAAK,SAAS,WAAWC,EAAM,SAAS,QAExC,OAAO;CACT,KAAK,IAAIG,IAAQ,GAAGA,IAAQJ,EAAK,SAAS,QAAQ,KAChD,IAAI,CAACG,EAAkBH,EAAK,SAASI,IAASH,EAAM,SAASG,EAAO,GAAG,OAAO;CAEhF,OAAO;AACT"}
|
|
@@ -4,7 +4,9 @@ import type { WorkspaceRequirements } from '../geometry/sizing.utils.js';
|
|
|
4
4
|
import type { WorkspaceDragPreview, WorkspaceDropIntent } from '../interaction/drag-preview.utils.js';
|
|
5
5
|
import type { WorkspaceLayout } from '../model/layout.utils.js';
|
|
6
6
|
import type { WorkspacePlacementPlan } from './planner.utils.js';
|
|
7
|
+
import type { WorkspacePlacementSession } from './session.utils.js';
|
|
7
8
|
interface AcquisitionInput {
|
|
9
|
+
placementSession?: WorkspacePlacementSession;
|
|
8
10
|
plan: WorkspacePlacementPlan;
|
|
9
11
|
previous: WorkspaceLayout;
|
|
10
12
|
source: string[];
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getPanelIds as e } from "../model/layout.utils.js";
|
|
2
2
|
import { projectLayout as t } from "../model/operations.utils.js";
|
|
3
3
|
import { matchesPlacementIntent as n } from "../interaction/drag-preview.utils.js";
|
|
4
|
-
import {
|
|
5
|
-
import { rebaseProjectedSplit as
|
|
6
|
-
import {
|
|
4
|
+
import { samePanelMembership as r } from "../model/membership.utils.js";
|
|
5
|
+
import { rebaseProjectedSplit as i } from "../model/projection.utils.js";
|
|
6
|
+
import { getAllocatedScopeRect as a } from "./scope.utils.js";
|
|
7
|
+
import { getGroupInsertion as o } from "./group-insertion.utils.js";
|
|
7
8
|
import { getMinimumWorkspaceDimensions as s } from "../geometry/sizing.utils.js";
|
|
8
9
|
import { fitSizes as c } from "../geometry/partition.utils.js";
|
|
9
10
|
import { allocateWorkspace as l } from "../geometry/allocation.utils.js";
|
|
@@ -24,7 +25,7 @@ function u(e) {
|
|
|
24
25
|
} : void 0;
|
|
25
26
|
}
|
|
26
27
|
function d(e, t) {
|
|
27
|
-
return !!e?.previous && !!e.next && !!t && (e.axis !== t.axis ||
|
|
28
|
+
return !!e?.previous && !!e.next && !!t && (e.axis !== t.axis || !r(e.members, t.members));
|
|
28
29
|
}
|
|
29
30
|
function f(e, t) {
|
|
30
31
|
return !!t && e.covers(t, "x") && e.covers(t, "y");
|
|
@@ -36,20 +37,27 @@ function p(e, n) {
|
|
|
36
37
|
} : {
|
|
37
38
|
start: e.acquisition.point[t],
|
|
38
39
|
end: e.acquisition.point[t]
|
|
39
|
-
};
|
|
40
|
+
}, o;
|
|
40
41
|
return {
|
|
41
42
|
input: e,
|
|
42
43
|
axis: r,
|
|
43
44
|
extent: i,
|
|
44
45
|
range: a,
|
|
45
46
|
covers: (e, t) => m(e, t, a(t)),
|
|
46
|
-
allocate: (n) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
allocate: (n) => {
|
|
48
|
+
if (o?.layout === n) return o.allocation;
|
|
49
|
+
let r = l({
|
|
50
|
+
root: t(n, e.available).root,
|
|
51
|
+
rect: e.rect,
|
|
52
|
+
minimum: (t) => s(t, e.requirements),
|
|
53
|
+
policy: "stop",
|
|
54
|
+
gap: e.requirements.gap
|
|
55
|
+
});
|
|
56
|
+
return o = {
|
|
57
|
+
layout: n,
|
|
58
|
+
allocation: r
|
|
59
|
+
}, r;
|
|
60
|
+
}
|
|
53
61
|
};
|
|
54
62
|
}
|
|
55
63
|
function m(e, t, n) {
|
|
@@ -72,30 +80,30 @@ function h(e, t) {
|
|
|
72
80
|
}
|
|
73
81
|
return r;
|
|
74
82
|
}
|
|
75
|
-
function g({ fit: t, layout: n, parent:
|
|
76
|
-
if (
|
|
77
|
-
let l =
|
|
83
|
+
function g({ fit: t, layout: n, parent: r, index: o }) {
|
|
84
|
+
if (r.node.type !== "split") return;
|
|
85
|
+
let l = r.node.axis === "horizontal" ? "width" : "height", u = r.node.children.map((e) => s(e, t.input.requirements)[l]), d = r.rect[l] - t.input.requirements.gap * (u.length - 1), f = r.node.children.map((n, r) => r === o ? 0 : a({
|
|
78
86
|
members: e(n),
|
|
79
87
|
allocation: t.input.current,
|
|
80
88
|
source: t.input.source
|
|
81
89
|
})?.[l]);
|
|
82
90
|
if (f.some((e) => e === void 0) || y(u) > d) return;
|
|
83
91
|
let p = f.map((e) => e);
|
|
84
|
-
return p[o] = Math.max(u[o], d - y(p)),
|
|
92
|
+
return p[o] = Math.max(u[o], d - y(p)), i(n, r.node, c(p, u, d), t.input.available) ?? n;
|
|
85
93
|
}
|
|
86
94
|
function _(e, t, n) {
|
|
87
|
-
let r = e.allocate(t),
|
|
88
|
-
if (
|
|
95
|
+
let r = e.allocate(t), a = r.regions.find((e) => e.key === n.split(".").slice(0, -1).join("."));
|
|
96
|
+
if (a.node.type !== "split") return;
|
|
89
97
|
let o = r.groups.find((e) => e.key === n), s = Number(n.split(".").at(-1)), c = v({
|
|
90
98
|
fit: e,
|
|
91
99
|
owner: {
|
|
92
|
-
...
|
|
93
|
-
node:
|
|
100
|
+
...a,
|
|
101
|
+
node: a.node
|
|
94
102
|
},
|
|
95
103
|
incoming: o.rect,
|
|
96
104
|
index: s
|
|
97
105
|
});
|
|
98
|
-
if (c) return
|
|
106
|
+
if (c) return i(t, a.node, c, e.input.available) ?? t;
|
|
99
107
|
}
|
|
100
108
|
function v(e) {
|
|
101
109
|
let { fit: t, owner: n, incoming: r, index: i } = e, { axis: a, extent: o } = t, l = n.node.children.map((e) => s(e, t.input.requirements)[o]), u = l.slice(0, i), d = l.slice(i + 1), f = Math.max(n.rect[a] + y(u) + t.input.requirements.gap * i, t.range(a).end - r[o]), p = Math.min(n.rect[a] + n.rect[o] - y(d) - t.input.requirements.gap * d.length - r[o], t.range(a).start);
|
|
@@ -142,7 +150,7 @@ function x(e, t) {
|
|
|
142
150
|
return ["order", "insert"].includes(e.intent.kind) && ["insert", "reorder"].includes(t.kind);
|
|
143
151
|
}
|
|
144
152
|
function S(e, t) {
|
|
145
|
-
return e?.phase === "detached" && !e.blocked && e.allocation === "reserved" &&
|
|
153
|
+
return e?.phase === "detached" && !e.blocked && e.allocation === "reserved" && r(e.source, t);
|
|
146
154
|
}
|
|
147
155
|
function C(e, t) {
|
|
148
156
|
return e?.phase === "detached" && e.blocked && n(e.intent, t);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acquisition-sizing.utils.js","names":["fitAcquiredPlacement","next","describePlacementSlot","input","crossScopeInterior","fit","acquisitionFit","moving","group","id","coversAcquisition","ancestors","fitReceivingPath","layout","fitIncoming","achieved","prior","getContextKey","rect","axis","direction","extent","range","dimension","coversRange","allocateWorkspace","projectLayout","getMinimumWorkspaceDimensions","node","end","path","depth","key","regions","parent","region","receiving","fitAncestor","size","minima","child","budget","extents","slot","index","getAllocatedContextRect","getPanelIds","value","sum","preferred","rebaseProjectedSplit","fitSizes","allocation","owner","incoming","sizes","incomingSizes","before","after","start","position","values","total","resolveSelectedPlacementPlan","blockedSelection","selectedReservation","spatialReservation","current","point","preview","plan","source","matchesPlacementIntent","intent"],"sources":["../../../../src/workspace/utils/placement/acquisition-sizing.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 { allocateWorkspace } from '../geometry/allocation.utils.js';\nimport { fitSizes } from '../geometry/partition.utils.js';\nimport { getMinimumWorkspaceDimensions } from '../geometry/sizing.utils.js';\nimport { matchesPlacementIntent } from '../interaction/drag-preview.utils.js';\nimport { getPanelIds } from '../model/layout.utils.js';\nimport { projectLayout } from '../model/operations.utils.js';\nimport { rebaseProjectedSplit } from '../model/projection.utils.js';\nimport { getAllocatedContextRect, getContextKey } from './context.utils.js';\nimport { describePlacementSlot } from './group-insertion.utils.js';\n\nimport type { WorkspacePlacedRegion } from '../geometry/allocation.utils.js';\nimport type { WorkspaceRequirements } from '../geometry/sizing.utils.js';\nimport type { WorkspaceDragPreview, WorkspaceDropIntent } from '../interaction/drag-preview.utils.js';\nimport type { WorkspaceLayout, WorkspaceSplit } from '../model/layout.utils.js';\nimport type { WorkspacePlacementPlan } from './planner.utils.js';\n\ninterface AcquisitionInput {\n plan: WorkspacePlacementPlan;\n previous: WorkspaceLayout;\n source: string[];\n available: string[];\n current: WorkspacePlacedRegion[];\n rect: Rect;\n acquisition: { rect: Rect; point: Point };\n requirements: WorkspaceRequirements;\n}\n\ninterface Fit {\n input: AcquisitionInput;\n axis: 'x' | 'y';\n extent: 'width' | 'height';\n range: (axis: 'x' | 'y') => { start: number; end: number };\n covers: (rect: Rect, axis: 'x' | 'y') => boolean;\n allocate: (layout: WorkspaceLayout) => ReturnType<typeof allocateWorkspace>;\n}\n\n/** Fits a cross-scope interior reservation to its acquired allocation without retaining a hidden target. */\nexport function fitAcquiredPlacement(input: AcquisitionInput): WorkspacePlacementPlan | undefined {\n const next = describePlacementSlot(input);\n const prior = describePlacementSlot({ ...input, plan: { layout: input.previous } });\n if (!crossScopeInterior(next, prior)) return input.plan;\n const fit = acquisitionFit(input, next.axis);\n const moving = fit\n .allocate(input.plan.layout)\n .groups.find(group => group.group.panels.every(id => input.source.includes(id)));\n if (!moving) return undefined;\n if (coversAcquisition(fit, moving.rect)) return input.plan;\n const ancestors = fitReceivingPath(fit, moving.key);\n const layout = ancestors && fitIncoming(fit, ancestors, moving.key);\n const achieved = layout && fit.allocate(layout).groups.find(group => group.key === moving.key);\n return layout && coversAcquisition(fit, achieved?.rect) ? { ...input.plan, layout } : undefined;\n}\n\nfunction crossScopeInterior(\n next: ReturnType<typeof describePlacementSlot>,\n prior: ReturnType<typeof describePlacementSlot>\n): next is NonNullable<typeof next> {\n return (\n !!next?.previous &&\n !!next.next &&\n !!prior &&\n (next.axis !== prior.axis || getContextKey(next.members) !== getContextKey(prior.members))\n );\n}\n\nfunction coversAcquisition(fit: Fit, rect?: Rect) {\n return !!rect && fit.covers(rect, 'x') && fit.covers(rect, 'y');\n}\n\nfunction acquisitionFit(input: AcquisitionInput, direction: WorkspaceSplit['axis']): Fit {\n const axis = direction === 'horizontal' ? 'x' : 'y';\n const extent = axis === 'x' ? 'width' : 'height';\n const range = (dimension: 'x' | 'y') =>\n dimension === axis\n ? { start: input.acquisition.rect[axis], end: input.acquisition.rect[axis] + input.acquisition.rect[extent] }\n : { start: input.acquisition.point[dimension], end: input.acquisition.point[dimension] };\n return {\n input,\n axis,\n extent,\n range,\n covers: (rect, dimension) => coversRange(rect, dimension, range(dimension)),\n allocate: layout =>\n allocateWorkspace({\n root: projectLayout(layout, input.available).root,\n rect: input.rect,\n minimum: node => getMinimumWorkspaceDimensions(node, input.requirements),\n policy: 'stop',\n gap: input.requirements.gap\n })\n };\n}\n\nfunction coversRange(rect: Rect, axis: 'x' | 'y', range: { start: number; end: number }) {\n const end = rect[axis] + rect[axis === 'x' ? 'width' : 'height'];\n return range.start === range.end\n ? rect[axis] <= range.start && range.start < end\n : rect[axis] <= range.start + 1e-7 && end >= range.end - 1e-7;\n}\n\nfunction fitReceivingPath(fit: Fit, moving: string) {\n const path = moving.split('.');\n let layout: WorkspaceLayout | undefined = fit.input.plan.layout;\n for (let depth = 1; depth < path.length - 1; depth++) {\n if (!layout) return undefined;\n const key = path.slice(0, depth).join('.');\n const regions = fit.allocate(layout).regions;\n const parent = regions.find(region => region.key === key)!;\n const receiving = regions.find(region => region.key === `${key}.${path[depth]}`)!;\n if (parent.node.type !== 'split') return undefined;\n const axis = parent.node.axis === 'horizontal' ? 'x' : 'y';\n if (!fit.covers(receiving.rect, axis)) {\n layout = fitAncestor({ fit, layout, parent, index: Number(path[depth]) });\n }\n }\n return layout;\n}\n\nfunction fitAncestor({\n fit,\n layout,\n parent,\n index\n}: {\n fit: Fit;\n layout: WorkspaceLayout;\n parent: WorkspacePlacedRegion;\n index: number;\n}) {\n if (parent.node.type !== 'split') return undefined;\n const size = parent.node.axis === 'horizontal' ? 'width' : 'height';\n const minima = parent.node.children.map(child => getMinimumWorkspaceDimensions(child, fit.input.requirements)[size]);\n const budget = parent.rect[size] - fit.input.requirements.gap * (minima.length - 1);\n const extents = parent.node.children.map((child, slot) =>\n slot === index\n ? 0\n : getAllocatedContextRect({\n members: getPanelIds(child),\n allocation: fit.input.current,\n source: fit.input.source\n })?.[size]\n );\n if (extents.some(value => value === undefined) || sum(minima) > budget) return undefined;\n const preferred = extents.map(value => value!);\n preferred[index] = Math.max(minima[index]!, budget - sum(preferred));\n return rebaseProjectedSplit(layout, parent.node, fitSizes(preferred, minima, budget), fit.input.available) ?? layout;\n}\n\nfunction fitIncoming(fit: Fit, layout: WorkspaceLayout, key: string) {\n const allocation = fit.allocate(layout);\n const owner = allocation.regions.find(region => region.key === key.split('.').slice(0, -1).join('.'))!;\n if (owner.node.type !== 'split') return undefined;\n const incoming = allocation.groups.find(group => group.key === key)!;\n const index = Number(key.split('.').at(-1));\n const sizes = incomingSizes({ fit, owner: { ...owner, node: owner.node }, incoming: incoming.rect, index });\n if (!sizes) return undefined;\n\n const rebased = rebaseProjectedSplit(layout, owner.node, sizes, fit.input.available);\n return rebased ?? layout;\n}\n\nfunction incomingSizes(input: {\n fit: Fit;\n owner: WorkspacePlacedRegion & { node: WorkspaceSplit };\n incoming: Rect;\n index: number;\n}) {\n const { fit, owner, incoming, index } = input;\n const { axis, extent } = fit;\n const minima = owner.node.children.map(child => getMinimumWorkspaceDimensions(child, fit.input.requirements)[extent]);\n const before = minima.slice(0, index);\n const after = minima.slice(index + 1);\n const start = Math.max(\n owner.rect[axis] + sum(before) + fit.input.requirements.gap * index,\n fit.range(axis).end - incoming[extent]\n );\n const end = Math.min(\n owner.rect[axis] + owner.rect[extent] - sum(after) - fit.input.requirements.gap * after.length - incoming[extent],\n fit.range(axis).start\n );\n if (start > end) return undefined;\n const position = Math.max(start, Math.min(incoming[axis], end));\n return [\n ...fitSizes(\n owner.node.weights.slice(0, index),\n before,\n position - owner.rect[axis] - fit.input.requirements.gap * index\n ),\n incoming[extent],\n ...fitSizes(\n owner.node.weights.slice(index + 1),\n after,\n owner.rect[axis] + owner.rect[extent] - position - incoming[extent] - fit.input.requirements.gap * after.length\n )\n ];\n}\n\nconst sum = (values: number[]) => values.reduce((total, value) => total + value, 0);\n\n/** Reuses the actual selected reservation before considering a different spatial offer. */\nexport function resolveSelectedPlacementPlan(\n input: Omit<AcquisitionInput, 'previous' | 'acquisition'> & {\n previous?: WorkspaceDragPreview;\n acquisition?: { rect: Rect; point: Point };\n clientOrigin: Rect;\n intent: WorkspaceDropIntent;\n }\n): WorkspacePlacementPlan | undefined {\n const prior = input.previous;\n if (blockedSelection(prior, input.intent) && !input.acquisition) return undefined;\n if (!selectedReservation(prior, input.source) || !spatialReservation(prior, input.plan)) return input.plan;\n const current = describePlacementSlot({ ...input, plan: prior });\n const next = describePlacementSlot(input);\n if (current && current.key === next?.key) return { ...input.plan, layout: prior.layout };\n if (!input.acquisition) return input.plan;\n const { rect, point } = input.acquisition;\n return fitAcquiredPlacement({\n ...input,\n previous: prior.layout,\n acquisition: {\n rect: { ...rect, x: rect.x - input.clientOrigin.x, y: rect.y - input.clientOrigin.y },\n point: { x: point.x - input.clientOrigin.x, y: point.y - input.clientOrigin.y }\n }\n });\n}\n\nfunction spatialReservation(preview: WorkspaceDragPreview, plan: WorkspacePlacementPlan) {\n return ['order', 'insert'].includes(preview.intent.kind) && ['insert', 'reorder'].includes(plan.kind);\n}\n\nfunction selectedReservation(\n preview: WorkspaceDragPreview | undefined,\n source: string[]\n): preview is Extract<WorkspaceDragPreview, { phase: 'detached' }> & { allocation: 'reserved' } {\n return (\n preview?.phase === 'detached' &&\n !preview.blocked &&\n preview.allocation === 'reserved' &&\n getContextKey(preview.source) === getContextKey(source)\n );\n}\n\nfunction blockedSelection(preview: WorkspaceDragPreview | undefined, intent: WorkspaceDropIntent) {\n return preview?.phase === 'detached' && preview.blocked && matchesPlacementIntent(preview.intent, intent);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acquisition-sizing.utils.js","names":["fitAcquiredPlacement","next","getGroupInsertion","input","crossScopeInterior","fit","acquisitionFit","moving","group","id","coversAcquisition","ancestors","fitReceivingPath","layout","fitIncoming","achieved","prior","samePanelMembership","rect","axis","direction","extent","range","dimension","lastAllocation","coversRange","allocation","allocateWorkspace","projectLayout","getMinimumWorkspaceDimensions","node","end","path","depth","key","regions","parent","region","receiving","fitAncestor","size","minima","child","budget","extents","childIndex","index","getAllocatedScopeRect","getPanelIds","value","sum","preferred","rebaseProjectedSplit","fitSizes","owner","incoming","sizes","incomingSizes","before","after","start","position","values","total","resolveSelectedPlacementPlan","blockedSelection","selectedReservation","spatialReservation","current","point","preview","plan","source","matchesPlacementIntent","intent"],"sources":["../../../../src/workspace/utils/placement/acquisition-sizing.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 { allocateWorkspace } from '../geometry/allocation.utils.js';\nimport { fitSizes } from '../geometry/partition.utils.js';\nimport { getMinimumWorkspaceDimensions } from '../geometry/sizing.utils.js';\nimport { matchesPlacementIntent } from '../interaction/drag-preview.utils.js';\nimport { getPanelIds } from '../model/layout.utils.js';\nimport { samePanelMembership } from '../model/membership.utils.js';\nimport { projectLayout } from '../model/operations.utils.js';\nimport { rebaseProjectedSplit } from '../model/projection.utils.js';\nimport { getGroupInsertion } from './group-insertion.utils.js';\nimport { getAllocatedScopeRect } from './scope.utils.js';\n\nimport type { WorkspacePlacedRegion } from '../geometry/allocation.utils.js';\nimport type { WorkspaceRequirements } from '../geometry/sizing.utils.js';\nimport type { WorkspaceDragPreview, WorkspaceDropIntent } from '../interaction/drag-preview.utils.js';\nimport type { WorkspaceLayout, WorkspaceSplit } from '../model/layout.utils.js';\nimport type { GroupInsertion } from './group-insertion.utils.js';\nimport type { WorkspacePlacementPlan } from './planner.utils.js';\nimport type { WorkspacePlacementSession } from './session.utils.js';\n\ninterface AcquisitionInput {\n placementSession?: WorkspacePlacementSession;\n plan: WorkspacePlacementPlan;\n previous: WorkspaceLayout;\n source: string[];\n available: string[];\n current: WorkspacePlacedRegion[];\n rect: Rect;\n acquisition: { rect: Rect; point: Point };\n requirements: WorkspaceRequirements;\n}\n\ninterface Fit {\n input: AcquisitionInput;\n axis: 'x' | 'y';\n extent: 'width' | 'height';\n range: (axis: 'x' | 'y') => { start: number; end: number };\n covers: (rect: Rect, axis: 'x' | 'y') => boolean;\n allocate: (layout: WorkspaceLayout) => ReturnType<typeof allocateWorkspace>;\n}\n\n/** Fits a cross-scope interior reservation to its acquired allocation without retaining a hidden target. */\nexport function fitAcquiredPlacement(input: AcquisitionInput): WorkspacePlacementPlan | undefined {\n const next = getGroupInsertion(input);\n const prior = getGroupInsertion({ ...input, plan: { layout: input.previous } });\n if (!crossScopeInterior(next, prior)) return input.plan;\n const fit = acquisitionFit(input, next.axis);\n const moving = fit\n .allocate(input.plan.layout)\n .groups.find(group => group.group.panels.every(id => input.source.includes(id)));\n if (!moving) return undefined;\n if (coversAcquisition(fit, moving.rect)) return input.plan;\n const ancestors = fitReceivingPath(fit, moving.key);\n const layout = ancestors && fitIncoming(fit, ancestors, moving.key);\n const achieved = layout && fit.allocate(layout).groups.find(group => group.key === moving.key);\n return layout && coversAcquisition(fit, achieved?.rect) ? { ...input.plan, layout } : undefined;\n}\n\nfunction crossScopeInterior(\n next: GroupInsertion | undefined,\n prior: GroupInsertion | undefined\n): next is NonNullable<typeof next> {\n return (\n !!next?.previous &&\n !!next.next &&\n !!prior &&\n (next.axis !== prior.axis || !samePanelMembership(next.members, prior.members))\n );\n}\n\nfunction coversAcquisition(fit: Fit, rect?: Rect) {\n return !!rect && fit.covers(rect, 'x') && fit.covers(rect, 'y');\n}\n\nfunction acquisitionFit(input: AcquisitionInput, direction: WorkspaceSplit['axis']): Fit {\n const axis = direction === 'horizontal' ? 'x' : 'y';\n const extent = axis === 'x' ? 'width' : 'height';\n const range = (dimension: 'x' | 'y') =>\n dimension === axis\n ? { start: input.acquisition.rect[axis], end: input.acquisition.rect[axis] + input.acquisition.rect[extent] }\n : { start: input.acquisition.point[dimension], end: input.acquisition.point[dimension] };\n let lastAllocation: { layout: WorkspaceLayout; allocation: ReturnType<typeof allocateWorkspace> } | undefined;\n return {\n input,\n axis,\n extent,\n range,\n covers: (rect, dimension) => coversRange(rect, dimension, range(dimension)),\n allocate: layout => {\n if (lastAllocation?.layout === layout) return lastAllocation.allocation;\n const allocation = allocateWorkspace({\n root: projectLayout(layout, input.available).root,\n rect: input.rect,\n minimum: node => getMinimumWorkspaceDimensions(node, input.requirements),\n policy: 'stop',\n gap: input.requirements.gap\n });\n lastAllocation = { layout, allocation };\n return allocation;\n }\n };\n}\n\nfunction coversRange(rect: Rect, axis: 'x' | 'y', range: { start: number; end: number }) {\n const end = rect[axis] + rect[axis === 'x' ? 'width' : 'height'];\n return range.start === range.end\n ? rect[axis] <= range.start && range.start < end\n : rect[axis] <= range.start + 1e-7 && end >= range.end - 1e-7;\n}\n\nfunction fitReceivingPath(fit: Fit, moving: string) {\n const path = moving.split('.');\n let layout: WorkspaceLayout | undefined = fit.input.plan.layout;\n for (let depth = 1; depth < path.length - 1; depth++) {\n if (!layout) return undefined;\n const key = path.slice(0, depth).join('.');\n const regions = fit.allocate(layout).regions;\n const parent = regions.find(region => region.key === key)!;\n const receiving = regions.find(region => region.key === `${key}.${path[depth]}`)!;\n if (parent.node.type !== 'split') return undefined;\n const axis = parent.node.axis === 'horizontal' ? 'x' : 'y';\n if (!fit.covers(receiving.rect, axis)) {\n layout = fitAncestor({ fit, layout, parent, index: Number(path[depth]) });\n }\n }\n return layout;\n}\n\nfunction fitAncestor({\n fit,\n layout,\n parent,\n index\n}: {\n fit: Fit;\n layout: WorkspaceLayout;\n parent: WorkspacePlacedRegion;\n index: number;\n}) {\n if (parent.node.type !== 'split') return undefined;\n const size = parent.node.axis === 'horizontal' ? 'width' : 'height';\n const minima = parent.node.children.map(child => getMinimumWorkspaceDimensions(child, fit.input.requirements)[size]);\n const budget = parent.rect[size] - fit.input.requirements.gap * (minima.length - 1);\n const extents = parent.node.children.map((child, childIndex) =>\n childIndex === index\n ? 0\n : getAllocatedScopeRect({\n members: getPanelIds(child),\n allocation: fit.input.current,\n source: fit.input.source\n })?.[size]\n );\n if (extents.some(value => value === undefined) || sum(minima) > budget) return undefined;\n const preferred = extents.map(value => value!);\n preferred[index] = Math.max(minima[index]!, budget - sum(preferred));\n return rebaseProjectedSplit(layout, parent.node, fitSizes(preferred, minima, budget), fit.input.available) ?? layout;\n}\n\nfunction fitIncoming(fit: Fit, layout: WorkspaceLayout, key: string) {\n const allocation = fit.allocate(layout);\n const owner = allocation.regions.find(region => region.key === key.split('.').slice(0, -1).join('.'))!;\n if (owner.node.type !== 'split') return undefined;\n const incoming = allocation.groups.find(group => group.key === key)!;\n const index = Number(key.split('.').at(-1));\n const sizes = incomingSizes({ fit, owner: { ...owner, node: owner.node }, incoming: incoming.rect, index });\n if (!sizes) return undefined;\n\n const rebased = rebaseProjectedSplit(layout, owner.node, sizes, fit.input.available);\n return rebased ?? layout;\n}\n\nfunction incomingSizes(input: {\n fit: Fit;\n owner: WorkspacePlacedRegion & { node: WorkspaceSplit };\n incoming: Rect;\n index: number;\n}) {\n const { fit, owner, incoming, index } = input;\n const { axis, extent } = fit;\n const minima = owner.node.children.map(child => getMinimumWorkspaceDimensions(child, fit.input.requirements)[extent]);\n const before = minima.slice(0, index);\n const after = minima.slice(index + 1);\n const start = Math.max(\n owner.rect[axis] + sum(before) + fit.input.requirements.gap * index,\n fit.range(axis).end - incoming[extent]\n );\n const end = Math.min(\n owner.rect[axis] + owner.rect[extent] - sum(after) - fit.input.requirements.gap * after.length - incoming[extent],\n fit.range(axis).start\n );\n if (start > end) return undefined;\n const position = Math.max(start, Math.min(incoming[axis], end));\n return [\n ...fitSizes(\n owner.node.weights.slice(0, index),\n before,\n position - owner.rect[axis] - fit.input.requirements.gap * index\n ),\n incoming[extent],\n ...fitSizes(\n owner.node.weights.slice(index + 1),\n after,\n owner.rect[axis] + owner.rect[extent] - position - incoming[extent] - fit.input.requirements.gap * after.length\n )\n ];\n}\n\nconst sum = (values: number[]) => values.reduce((total, value) => total + value, 0);\n\n/** Reuses the actual selected reservation before considering a different spatial offer. */\nexport function resolveSelectedPlacementPlan(\n input: Omit<AcquisitionInput, 'previous' | 'acquisition'> & {\n previous?: WorkspaceDragPreview;\n acquisition?: { rect: Rect; point: Point };\n clientOrigin: Rect;\n intent: WorkspaceDropIntent;\n }\n): WorkspacePlacementPlan | undefined {\n const prior = input.previous;\n if (blockedSelection(prior, input.intent) && !input.acquisition) return undefined;\n if (!selectedReservation(prior, input.source) || !spatialReservation(prior, input.plan)) return input.plan;\n const current = getGroupInsertion({ ...input, plan: prior });\n const next = getGroupInsertion(input);\n if (current && current.key === next?.key) return { ...input.plan, layout: prior.layout };\n if (!input.acquisition) return input.plan;\n const { rect, point } = input.acquisition;\n return fitAcquiredPlacement({\n ...input,\n previous: prior.layout,\n acquisition: {\n rect: { ...rect, x: rect.x - input.clientOrigin.x, y: rect.y - input.clientOrigin.y },\n point: { x: point.x - input.clientOrigin.x, y: point.y - input.clientOrigin.y }\n }\n });\n}\n\nfunction spatialReservation(preview: WorkspaceDragPreview, plan: WorkspacePlacementPlan) {\n return ['order', 'insert'].includes(preview.intent.kind) && ['insert', 'reorder'].includes(plan.kind);\n}\n\nfunction selectedReservation(\n preview: WorkspaceDragPreview | undefined,\n source: string[]\n): preview is Extract<WorkspaceDragPreview, { phase: 'detached' }> & { allocation: 'reserved' } {\n return (\n preview?.phase === 'detached' &&\n !preview.blocked &&\n preview.allocation === 'reserved' &&\n samePanelMembership(preview.source, source)\n );\n}\n\nfunction blockedSelection(preview: WorkspaceDragPreview | undefined, intent: WorkspaceDropIntent) {\n return preview?.phase === 'detached' && preview.blocked && matchesPlacementIntent(preview.intent, intent);\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { WorkspaceLayout } from '../model/layout.utils.js';
|
|
1
|
+
import type { WorkspaceLayout, WorkspaceSplit } from '../model/layout.utils.js';
|
|
2
2
|
import type { WorkspaceDestination } from '../model/operations.utils.js';
|
|
3
3
|
import type { WorkspaceLayoutProjector } from '../model/projection.utils.js';
|
|
4
|
-
import type { WorkspacePlacementPlan } from './planner.utils.js';
|
|
4
|
+
import type { WorkspacePlacementPlan, WorkspacePlacementPlanner } from './planner.utils.js';
|
|
5
|
+
import type { WorkspacePlacementSession } from './session.utils.js';
|
|
5
6
|
interface InsertionInput {
|
|
6
7
|
layout: WorkspaceLayout;
|
|
7
8
|
source: string[];
|
|
@@ -9,18 +10,23 @@ interface InsertionInput {
|
|
|
9
10
|
available: string[];
|
|
10
11
|
projectLayout?: WorkspaceLayoutProjector;
|
|
11
12
|
}
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
export interface GroupInsertionInputs {
|
|
14
|
+
readonly plan: Pick<WorkspacePlacementPlan, 'layout'>;
|
|
15
|
+
readonly source: string[];
|
|
16
|
+
readonly available: string[];
|
|
17
|
+
readonly projectLayout?: WorkspaceLayoutProjector;
|
|
18
|
+
readonly placementSession?: WorkspacePlacementSession;
|
|
19
|
+
readonly planPlacement?: WorkspacePlacementPlanner;
|
|
20
|
+
}
|
|
21
|
+
export interface GroupInsertion {
|
|
22
|
+
axis: WorkspaceSplit['axis'];
|
|
20
23
|
index: number;
|
|
21
24
|
members: string[];
|
|
22
|
-
previous
|
|
23
|
-
next
|
|
25
|
+
previous?: string[];
|
|
26
|
+
next?: string[];
|
|
24
27
|
key: string;
|
|
25
|
-
}
|
|
28
|
+
}
|
|
29
|
+
export declare function getGroupInsertion(input: GroupInsertionInputs): GroupInsertion | undefined;
|
|
30
|
+
export declare function planGroupInsertion(input: InsertionInput): WorkspacePlacementPlan | undefined;
|
|
31
|
+
export declare function computeGroupInsertion(input: GroupInsertionInputs): GroupInsertion | undefined;
|
|
26
32
|
export {};
|
|
@@ -1,48 +1,51 @@
|
|
|
1
1
|
import { getPanelIds as e, getSplitSide as t } from "../model/layout.utils.js";
|
|
2
2
|
import { createDetachedLayout as n, projectLayout as r } from "../model/operations.utils.js";
|
|
3
|
-
import { findDeepestProjectionCarrier as i,
|
|
3
|
+
import { findDeepestProjectionCarrier as i, rebaseProjectedSplit as a, sameProjectionShape as o } from "../model/projection.utils.js";
|
|
4
4
|
import { findWorkspaceRegion as s, placeRegion as c } from "./region.utils.js";
|
|
5
5
|
// src/workspace/utils/placement/group-insertion.utils.ts
|
|
6
6
|
function l(e) {
|
|
7
|
-
|
|
7
|
+
return e.placementSession && !e.planPlacement ? e.placementSession.getInsertion(e) : S(e);
|
|
8
|
+
}
|
|
9
|
+
function u(e) {
|
|
10
|
+
let t = h(e);
|
|
8
11
|
if (!t) return;
|
|
9
|
-
let n =
|
|
10
|
-
return n ?
|
|
12
|
+
let n = d(e, t);
|
|
13
|
+
return n ? f({
|
|
11
14
|
input: e,
|
|
12
15
|
context: t,
|
|
13
16
|
topology: n
|
|
14
17
|
}) : void 0;
|
|
15
18
|
}
|
|
16
|
-
function
|
|
17
|
-
let { peers:
|
|
19
|
+
function d(a, o) {
|
|
20
|
+
let { peers: s, insertionIndex: l, visible: u, root: d, axis: f } = o, p = s[Math.min(l, s.length - 1)], m = a.projectLayout ?? r, h = i(d, p.node, (e) => {
|
|
18
21
|
let t = n({
|
|
19
22
|
version: 1,
|
|
20
23
|
root: e,
|
|
21
24
|
closed: []
|
|
22
|
-
},
|
|
23
|
-
return
|
|
24
|
-
}),
|
|
25
|
-
if (!
|
|
26
|
-
let
|
|
27
|
-
target: e(
|
|
28
|
-
region:
|
|
29
|
-
position: t(
|
|
25
|
+
}, a.source);
|
|
26
|
+
return m(t, u).root;
|
|
27
|
+
}), g = h && b(d, h);
|
|
28
|
+
if (!g || !h) return;
|
|
29
|
+
let _ = l < s.length, v = {
|
|
30
|
+
target: e(h)[0],
|
|
31
|
+
region: g,
|
|
32
|
+
position: t(f, _ ? "before" : "after")
|
|
30
33
|
};
|
|
31
34
|
return c({
|
|
32
|
-
...
|
|
33
|
-
destination:
|
|
35
|
+
...a,
|
|
36
|
+
destination: v
|
|
34
37
|
});
|
|
35
38
|
}
|
|
36
|
-
function
|
|
37
|
-
let { owner: a, peers: o, visible: s, axis: c } = n, l = (t.projectLayout ?? r)(i.layout, s).root, u = t.source.filter((e) => s.includes(e)), d =
|
|
39
|
+
function f({ input: t, context: n, topology: i }) {
|
|
40
|
+
let { owner: a, peers: o, visible: s, axis: c } = n, l = (t.projectLayout ?? r)(i.layout, s).root, u = t.source.filter((e) => s.includes(e)), d = v(l, u);
|
|
38
41
|
if (!d || d.axis !== c || d.children.length !== o.length + 1) return;
|
|
39
|
-
let f =
|
|
42
|
+
let f = _({
|
|
40
43
|
branch: d,
|
|
41
44
|
peers: o,
|
|
42
45
|
moving: u
|
|
43
46
|
});
|
|
44
47
|
if (!f) return;
|
|
45
|
-
let p =
|
|
48
|
+
let p = x({
|
|
46
49
|
layout: i.layout,
|
|
47
50
|
branch: d,
|
|
48
51
|
weights: f,
|
|
@@ -51,18 +54,18 @@ function d({ input: t, context: n, topology: i }) {
|
|
|
51
54
|
if (p) return {
|
|
52
55
|
kind: "insert",
|
|
53
56
|
layout: p,
|
|
54
|
-
|
|
57
|
+
scope: {
|
|
55
58
|
kind: "rail",
|
|
56
59
|
members: [.../* @__PURE__ */ new Set([...e(a), ...u])]
|
|
57
60
|
}
|
|
58
61
|
};
|
|
59
62
|
}
|
|
60
|
-
function
|
|
63
|
+
function p(e) {
|
|
61
64
|
let { destination: t, layout: n } = e;
|
|
62
65
|
if (!t.region || t.position === "tab") return;
|
|
63
66
|
let i = e.available.filter((e) => !n.closed.includes(e)), a = (e.projectLayout ?? r)(n, i).root, o = s(a, t.region);
|
|
64
67
|
if (!a || !o) return;
|
|
65
|
-
let c = t.position === "left" || t.position === "right" ? "horizontal" : "vertical", l =
|
|
68
|
+
let c = t.position === "left" || t.position === "right" ? "horizontal" : "vertical", l = m({
|
|
66
69
|
root: a,
|
|
67
70
|
target: o,
|
|
68
71
|
key: t.region,
|
|
@@ -76,13 +79,13 @@ function f(e) {
|
|
|
76
79
|
owner: l
|
|
77
80
|
};
|
|
78
81
|
}
|
|
79
|
-
function
|
|
82
|
+
function m(e) {
|
|
80
83
|
if (e.target.type === "split" && e.target.axis === e.axis) return e.target;
|
|
81
84
|
let t = s(e.root, e.key.split(".").slice(0, -1).join("."));
|
|
82
85
|
return t?.type === "split" && t.axis === e.axis ? t : e.target.type === "split" ? e.target : void 0;
|
|
83
86
|
}
|
|
84
|
-
function
|
|
85
|
-
let r =
|
|
87
|
+
function h(t) {
|
|
88
|
+
let r = p(t);
|
|
86
89
|
if (!r) return;
|
|
87
90
|
let { owner: i, target: a, axis: o } = r, s = n({
|
|
88
91
|
version: 1,
|
|
@@ -90,16 +93,16 @@ function m(t) {
|
|
|
90
93
|
closed: []
|
|
91
94
|
}, t.source).root;
|
|
92
95
|
if (!s) return;
|
|
93
|
-
let c =
|
|
96
|
+
let c = g(s, o), l = new Set(e(a).filter((e) => !t.source.includes(e))), u = c.flatMap((t, n) => e(t.node).every((e) => l.has(e)) ? [n] : []);
|
|
94
97
|
if (!u.length) return;
|
|
95
98
|
let d = t.destination.position === "left" || t.destination.position === "top";
|
|
96
99
|
return {
|
|
97
100
|
...r,
|
|
98
101
|
peers: c,
|
|
99
|
-
|
|
102
|
+
insertionIndex: d ? u[0] : u.at(-1) + 1
|
|
100
103
|
};
|
|
101
104
|
}
|
|
102
|
-
function
|
|
105
|
+
function g(e, t) {
|
|
103
106
|
return e.type !== "split" || e.axis !== t ? [{
|
|
104
107
|
node: e,
|
|
105
108
|
weight: 1
|
|
@@ -108,43 +111,43 @@ function h(e, t) {
|
|
|
108
111
|
weight: e.weights[n]
|
|
109
112
|
}));
|
|
110
113
|
}
|
|
111
|
-
function
|
|
114
|
+
function _(e) {
|
|
112
115
|
let t = e.peers.reduce((e, t) => e + t.weight, 0) / e.peers.length, n = e.branch.children.map((n) => {
|
|
113
|
-
if (
|
|
114
|
-
let r = e.peers.findIndex((e) =>
|
|
116
|
+
if (y(n, e.moving)) return t;
|
|
117
|
+
let r = e.peers.findIndex((e) => o(e.node, n));
|
|
115
118
|
if (!(r < 0)) return e.peers[r].weight;
|
|
116
119
|
});
|
|
117
120
|
return n.every((e) => e !== void 0) ? n : void 0;
|
|
118
121
|
}
|
|
119
|
-
function
|
|
122
|
+
function v(e, t) {
|
|
120
123
|
if (e?.type === "split") {
|
|
121
|
-
if (e.children.some((e) => e.type === "group" && e.panels.length > 0 &&
|
|
124
|
+
if (e.children.some((e) => e.type === "group" && e.panels.length > 0 && y(e, t))) return e;
|
|
122
125
|
for (let n of e.children) {
|
|
123
|
-
let e =
|
|
126
|
+
let e = v(n, t);
|
|
124
127
|
if (e) return e;
|
|
125
128
|
}
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
|
-
function
|
|
131
|
+
function y(e, t) {
|
|
129
132
|
return e.type === "group" && e.panels.every((e) => t.includes(e));
|
|
130
133
|
}
|
|
131
|
-
function
|
|
134
|
+
function b(e, t, n = "root") {
|
|
132
135
|
if (e === t) return n;
|
|
133
136
|
if (e.type === "split") for (let [r, i] of e.children.entries()) {
|
|
134
|
-
let e =
|
|
137
|
+
let e = b(i, t, `${n}.${r}`);
|
|
135
138
|
if (e) return e;
|
|
136
139
|
}
|
|
137
140
|
}
|
|
138
|
-
function
|
|
139
|
-
let t =
|
|
141
|
+
function x(e) {
|
|
142
|
+
let t = a(e.layout, e.branch, e.weights, e.available);
|
|
140
143
|
if (t) return t;
|
|
141
144
|
let n = e.weights.reduce((e, t) => e + t, 0);
|
|
142
145
|
return e.branch.weights.every((t, r) => Math.abs(t - e.weights[r] / n) < 1e-10) ? e.layout : void 0;
|
|
143
146
|
}
|
|
144
|
-
function
|
|
145
|
-
let n = t.available.filter((e) => !t.plan.layout.closed.includes(e)), i = t.source.filter((e) => n.includes(e)), a =
|
|
147
|
+
function S(t) {
|
|
148
|
+
let n = t.available.filter((e) => !t.plan.layout.closed.includes(e)), i = t.source.filter((e) => n.includes(e)), a = v((t.projectLayout ?? r)(t.plan.layout, n).root, i);
|
|
146
149
|
if (!a) return;
|
|
147
|
-
let o = a.children.findIndex((e) =>
|
|
150
|
+
let o = a.children.findIndex((e) => y(e, i));
|
|
148
151
|
if (!(o < 0)) return {
|
|
149
152
|
axis: a.axis,
|
|
150
153
|
index: o,
|
|
@@ -154,18 +157,18 @@ function x(t) {
|
|
|
154
157
|
key: JSON.stringify([
|
|
155
158
|
a.axis,
|
|
156
159
|
o,
|
|
157
|
-
|
|
160
|
+
C(t.plan.layout.root),
|
|
158
161
|
t.plan.layout.closed
|
|
159
162
|
])
|
|
160
163
|
};
|
|
161
164
|
}
|
|
162
|
-
function
|
|
165
|
+
function C(e) {
|
|
163
166
|
return e ? e.type === "group" ? [
|
|
164
167
|
"group",
|
|
165
168
|
e.panels,
|
|
166
169
|
e.active
|
|
167
|
-
] : [e.axis, e.children.map(
|
|
170
|
+
] : [e.axis, e.children.map(C)] : null;
|
|
168
171
|
}
|
|
169
|
-
export {
|
|
172
|
+
export { S as computeGroupInsertion, l as getGroupInsertion, u as planGroupInsertion };
|
|
170
173
|
|
|
171
174
|
//# sourceMappingURL=group-insertion.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-insertion.utils.js","names":["planGroupInsertion","context","insertionContext","input","topology","insertionTopology","sizeInsertion","donor","peers","slot","projectLayoutForCandidate","projectLayout","carrier","findDeepestProjectionCarrier","root","getProjectionSignature","residualLayout","createDetachedLayout","node","visible","key","nodeKey","before","destination","getPanelIds","getSplitSide","axis","placeRegion","projectedRoot","moving","id","branch","movingOwner","weights","insertedWeights","layout","insertionWeights","owner","insertionBasis","target","findWorkspaceRegion","insertionOwner","parent","basis","residual","insertionPeers","selected","matches","peer","index","incoming","sum","isMovingGroup","child","weight","found","rebased","rebaseProjectedSplit","total","describePlacementSlot","placementShape"],"sources":["../../../../src/workspace/utils/placement/group-insertion.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { getPanelIds, getSplitSide } from '../model/layout.utils.js';\nimport { createDetachedLayout, projectLayout } from '../model/operations.utils.js';\nimport {\n findDeepestProjectionCarrier,\n getProjectionSignature,\n rebaseProjectedSplit\n} from '../model/projection.utils.js';\nimport { findWorkspaceRegion, placeRegion } from './region.utils.js';\n\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 { WorkspacePlacementPlan } from './planner.utils.js';\n\ninterface InsertionInput {\n layout: WorkspaceLayout;\n source: string[];\n destination: WorkspaceDestination;\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n}\n\nexport function planGroupInsertion(input: InsertionInput): WorkspacePlacementPlan | undefined {\n const context = insertionContext(input);\n if (!context) return undefined;\n const topology = insertionTopology(input, context);\n return topology ? sizeInsertion({ input, context, topology }) : undefined;\n}\n\nfunction insertionTopology(input: InsertionInput, context: NonNullable<ReturnType<typeof insertionContext>>) {\n const { peers, slot, visible, root, axis } = context;\n const donorIndex = Math.min(slot, peers.length - 1);\n const donor = peers[donorIndex]!;\n const projectLayoutForCandidate = input.projectLayout ?? projectLayout;\n const carrier = findDeepestProjectionCarrier(root, getProjectionSignature(donor.node), node => {\n const residualLayout = createDetachedLayout({ version: 1, root: node, closed: [] }, input.source);\n return projectLayoutForCandidate(residualLayout, visible).root;\n });\n const key = carrier && nodeKey(root, carrier);\n if (!key || !carrier) return undefined;\n const before = slot < peers.length;\n const destination: WorkspaceDestination = {\n target: getPanelIds(carrier)[0]!,\n region: key,\n position: getSplitSide(axis, before ? 'before' : 'after')\n };\n const topology = placeRegion({ ...input, destination });\n return topology;\n}\n\nfunction sizeInsertion({\n input,\n context,\n topology\n}: {\n input: InsertionInput;\n context: NonNullable<ReturnType<typeof insertionContext>>;\n topology: WorkspacePlacementPlan;\n}): WorkspacePlacementPlan | undefined {\n const { owner, peers, visible, axis } = context;\n const projectedRoot = (input.projectLayout ?? projectLayout)(topology.layout, visible).root;\n const moving = input.source.filter(id => visible.includes(id));\n const branch = movingOwner(projectedRoot, moving);\n if (!branch || branch.axis !== axis || branch.children.length !== peers.length + 1) return undefined;\n const weights = insertedWeights({\n branch,\n peers,\n moving\n });\n if (!weights) return undefined;\n const layout = insertionWeights({ layout: topology.layout, branch, weights, available: input.available });\n if (!layout) return undefined;\n return {\n kind: 'insert',\n layout,\n context: { kind: 'rail', members: [...new Set([...getPanelIds(owner), ...moving])] }\n };\n}\n\nfunction insertionBasis(input: InsertionInput) {\n const { destination, layout } = input;\n if (!destination.region || destination.position === 'tab') return undefined;\n const visible = input.available.filter(id => !layout.closed.includes(id));\n const root = (input.projectLayout ?? projectLayout)(layout, visible).root;\n const target = findWorkspaceRegion(root, destination.region);\n if (!root || !target) return undefined;\n const axis: WorkspaceSplit['axis'] =\n destination.position === 'left' || destination.position === 'right' ? 'horizontal' : 'vertical';\n const owner = insertionOwner({ root, target, key: destination.region, axis });\n if (!owner) return undefined;\n return {\n visible,\n root,\n target,\n axis,\n owner\n };\n}\n\nfunction insertionOwner(input: {\n root: WorkspaceNode;\n target: WorkspaceNode;\n key: string;\n axis: WorkspaceSplit['axis'];\n}) {\n if (input.target.type === 'split' && input.target.axis === input.axis) return input.target;\n const parent = findWorkspaceRegion(input.root, input.key.split('.').slice(0, -1).join('.'));\n if (parent?.type === 'split' && parent.axis === input.axis) return parent;\n return input.target.type === 'split' ? input.target : undefined;\n}\n\nfunction insertionContext(input: InsertionInput) {\n const basis = insertionBasis(input);\n if (!basis) return undefined;\n const { owner, target, axis } = basis;\n const residual = createDetachedLayout({ version: 1, root: owner, closed: [] }, input.source).root;\n if (!residual) return undefined;\n const peers = insertionPeers(residual, axis);\n const selected = new Set(getPanelIds(target).filter(id => !input.source.includes(id)));\n const matches = peers.flatMap((peer, index) => (getPanelIds(peer.node).every(id => selected.has(id)) ? [index] : []));\n if (!matches.length) return undefined;\n const before = input.destination.position === 'left' || input.destination.position === 'top';\n return { ...basis, peers, slot: before ? matches[0]! : matches.at(-1)! + 1 };\n}\n\nfunction insertionPeers(residual: WorkspaceNode, axis: WorkspaceSplit['axis']) {\n if (residual.type !== 'split' || residual.axis !== axis) return [{ node: residual, weight: 1 }];\n return residual.children.map((node, index) => ({ node, weight: residual.weights[index]! }));\n}\n\nfunction insertedWeights(input: {\n branch: WorkspaceSplit;\n peers: { node: WorkspaceNode; weight: number }[];\n moving: string[];\n}) {\n const incoming = input.peers.reduce((sum, peer) => sum + peer.weight, 0) / input.peers.length;\n const weights = input.branch.children.map(child => {\n if (isMovingGroup(child, input.moving)) return incoming;\n const index = input.peers.findIndex(peer => getProjectionSignature(peer.node) === getProjectionSignature(child));\n if (index < 0) return undefined;\n const weight = input.peers[index]!.weight;\n return weight;\n });\n return weights.every((weight): weight is number => weight !== undefined) ? weights : undefined;\n}\n\nfunction movingOwner(node: WorkspaceNode | null, moving: string[]): WorkspaceSplit | undefined {\n if (node?.type !== 'split') return undefined;\n if (node.children.some(child => child.type === 'group' && child.panels.length > 0 && isMovingGroup(child, moving)))\n return node;\n for (const child of node.children) {\n const found = movingOwner(child, moving);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction isMovingGroup(node: WorkspaceNode, moving: string[]) {\n return node.type === 'group' && node.panels.every(id => moving.includes(id));\n}\n\nfunction nodeKey(node: WorkspaceNode, target: WorkspaceNode, key = 'root'): string | undefined {\n if (node === target) return key;\n if (node.type !== 'split') return undefined;\n for (const [index, child] of node.children.entries()) {\n const found = nodeKey(child, target, `${key}.${index}`);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction insertionWeights(input: {\n layout: WorkspaceLayout;\n branch: WorkspaceSplit;\n weights: number[];\n available: string[];\n}) {\n const rebased = rebaseProjectedSplit(input.layout, input.branch, input.weights, input.available);\n if (rebased) return rebased;\n const total = input.weights.reduce((sum, weight) => sum + weight, 0);\n return input.branch.weights.every((weight, index) => Math.abs(weight - input.weights[index]! / total) < 1e-10)\n ? input.layout\n : undefined;\n}\n\nexport function describePlacementSlot(input: {\n plan: Pick<WorkspacePlacementPlan, 'layout'>;\n source: string[];\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n}) {\n const visible = input.available.filter(id => !input.plan.layout.closed.includes(id));\n const moving = input.source.filter(id => visible.includes(id));\n const owner = movingOwner((input.projectLayout ?? projectLayout)(input.plan.layout, visible).root, moving);\n if (!owner) return undefined;\n const index = owner.children.findIndex(child => isMovingGroup(child, moving));\n if (index < 0) return undefined;\n return {\n axis: owner.axis,\n index,\n members: getPanelIds(owner).filter(id => !moving.includes(id)),\n previous: owner.children[index - 1] ? getPanelIds(owner.children[index - 1]!) : undefined,\n next: owner.children[index + 1] ? getPanelIds(owner.children[index + 1]!) : undefined,\n key: JSON.stringify([owner.axis, index, placementShape(input.plan.layout.root), input.plan.layout.closed])\n };\n}\n\nfunction placementShape(node: WorkspaceNode | null): unknown {\n if (!node) return null;\n return node.type === 'group' ? ['group', node.panels, node.active] : [node.axis, node.children.map(placementShape)];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"group-insertion.utils.js","names":["getGroupInsertion","input","computeGroupInsertion","planGroupInsertion","context","insertionContext","topology","insertionTopology","sizeInsertion","donor","peers","insertionIndex","projectLayoutForCandidate","projectLayout","carrier","findDeepestProjectionCarrier","root","residualLayout","createDetachedLayout","node","visible","key","nodeKey","before","destination","getPanelIds","getSplitSide","axis","placeRegion","projectedRoot","moving","id","branch","movingOwner","weights","insertedWeights","layout","insertionWeights","owner","insertionBasis","target","findWorkspaceRegion","insertionOwner","parent","basis","residual","insertionPeers","selected","matches","peer","index","incoming","sum","isMovingGroup","child","sameProjectionShape","weight","found","rebased","rebaseProjectedSplit","total","placementShape"],"sources":["../../../../src/workspace/utils/placement/group-insertion.utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { getPanelIds, getSplitSide } from '../model/layout.utils.js';\nimport { createDetachedLayout, projectLayout } from '../model/operations.utils.js';\nimport { findDeepestProjectionCarrier, rebaseProjectedSplit, sameProjectionShape } from '../model/projection.utils.js';\nimport { findWorkspaceRegion, placeRegion } from './region.utils.js';\n\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 { WorkspacePlacementPlan, WorkspacePlacementPlanner } from './planner.utils.js';\nimport type { WorkspacePlacementSession } from './session.utils.js';\n\ninterface InsertionInput {\n layout: WorkspaceLayout;\n source: string[];\n destination: WorkspaceDestination;\n available: string[];\n projectLayout?: WorkspaceLayoutProjector;\n}\n\nexport interface GroupInsertionInputs {\n readonly plan: Pick<WorkspacePlacementPlan, 'layout'>;\n readonly source: string[];\n readonly available: string[];\n readonly projectLayout?: WorkspaceLayoutProjector;\n readonly placementSession?: WorkspacePlacementSession;\n readonly planPlacement?: WorkspacePlacementPlanner;\n}\n\nexport interface GroupInsertion {\n axis: WorkspaceSplit['axis'];\n index: number;\n members: string[];\n previous?: string[];\n next?: string[];\n key: string;\n}\n\nexport function getGroupInsertion(input: GroupInsertionInputs): GroupInsertion | undefined {\n return input.placementSession && !input.planPlacement\n ? input.placementSession.getInsertion(input)\n : computeGroupInsertion(input);\n}\n\nexport function planGroupInsertion(input: InsertionInput): WorkspacePlacementPlan | undefined {\n const context = insertionContext(input);\n if (!context) return undefined;\n const topology = insertionTopology(input, context);\n return topology ? sizeInsertion({ input, context, topology }) : undefined;\n}\n\nfunction insertionTopology(input: InsertionInput, context: NonNullable<ReturnType<typeof insertionContext>>) {\n const { peers, insertionIndex, visible, root, axis } = context;\n const donorIndex = Math.min(insertionIndex, peers.length - 1);\n const donor = peers[donorIndex]!;\n const projectLayoutForCandidate = input.projectLayout ?? projectLayout;\n const carrier = findDeepestProjectionCarrier(root, donor.node, node => {\n const residualLayout = createDetachedLayout({ version: 1, root: node, closed: [] }, input.source);\n return projectLayoutForCandidate(residualLayout, visible).root;\n });\n const key = carrier && nodeKey(root, carrier);\n if (!key || !carrier) return undefined;\n const before = insertionIndex < peers.length;\n const destination: WorkspaceDestination = {\n target: getPanelIds(carrier)[0]!,\n region: key,\n position: getSplitSide(axis, before ? 'before' : 'after')\n };\n const topology = placeRegion({ ...input, destination });\n return topology;\n}\n\nfunction sizeInsertion({\n input,\n context,\n topology\n}: {\n input: InsertionInput;\n context: NonNullable<ReturnType<typeof insertionContext>>;\n topology: WorkspacePlacementPlan;\n}): WorkspacePlacementPlan | undefined {\n const { owner, peers, visible, axis } = context;\n const projectedRoot = (input.projectLayout ?? projectLayout)(topology.layout, visible).root;\n const moving = input.source.filter(id => visible.includes(id));\n const branch = movingOwner(projectedRoot, moving);\n if (!branch || branch.axis !== axis || branch.children.length !== peers.length + 1) return undefined;\n const weights = insertedWeights({\n branch,\n peers,\n moving\n });\n if (!weights) return undefined;\n const layout = insertionWeights({ layout: topology.layout, branch, weights, available: input.available });\n if (!layout) return undefined;\n return {\n kind: 'insert',\n layout,\n scope: { kind: 'rail', members: [...new Set([...getPanelIds(owner), ...moving])] }\n };\n}\n\nfunction insertionBasis(input: InsertionInput) {\n const { destination, layout } = input;\n if (!destination.region || destination.position === 'tab') return undefined;\n const visible = input.available.filter(id => !layout.closed.includes(id));\n const root = (input.projectLayout ?? projectLayout)(layout, visible).root;\n const target = findWorkspaceRegion(root, destination.region);\n if (!root || !target) return undefined;\n const axis: WorkspaceSplit['axis'] =\n destination.position === 'left' || destination.position === 'right' ? 'horizontal' : 'vertical';\n const owner = insertionOwner({ root, target, key: destination.region, axis });\n if (!owner) return undefined;\n return {\n visible,\n root,\n target,\n axis,\n owner\n };\n}\n\nfunction insertionOwner(input: {\n root: WorkspaceNode;\n target: WorkspaceNode;\n key: string;\n axis: WorkspaceSplit['axis'];\n}) {\n if (input.target.type === 'split' && input.target.axis === input.axis) return input.target;\n const parent = findWorkspaceRegion(input.root, input.key.split('.').slice(0, -1).join('.'));\n if (parent?.type === 'split' && parent.axis === input.axis) return parent;\n return input.target.type === 'split' ? input.target : undefined;\n}\n\nfunction insertionContext(input: InsertionInput) {\n const basis = insertionBasis(input);\n if (!basis) return undefined;\n const { owner, target, axis } = basis;\n const residual = createDetachedLayout({ version: 1, root: owner, closed: [] }, input.source).root;\n if (!residual) return undefined;\n const peers = insertionPeers(residual, axis);\n const selected = new Set(getPanelIds(target).filter(id => !input.source.includes(id)));\n const matches = peers.flatMap((peer, index) => (getPanelIds(peer.node).every(id => selected.has(id)) ? [index] : []));\n if (!matches.length) return undefined;\n const before = input.destination.position === 'left' || input.destination.position === 'top';\n return { ...basis, peers, insertionIndex: before ? matches[0]! : matches.at(-1)! + 1 };\n}\n\nfunction insertionPeers(residual: WorkspaceNode, axis: WorkspaceSplit['axis']) {\n if (residual.type !== 'split' || residual.axis !== axis) return [{ node: residual, weight: 1 }];\n return residual.children.map((node, index) => ({ node, weight: residual.weights[index]! }));\n}\n\nfunction insertedWeights(input: {\n branch: WorkspaceSplit;\n peers: { node: WorkspaceNode; weight: number }[];\n moving: string[];\n}) {\n const incoming = input.peers.reduce((sum, peer) => sum + peer.weight, 0) / input.peers.length;\n const weights = input.branch.children.map(child => {\n if (isMovingGroup(child, input.moving)) return incoming;\n const index = input.peers.findIndex(peer => sameProjectionShape(peer.node, child));\n if (index < 0) return undefined;\n const weight = input.peers[index]!.weight;\n return weight;\n });\n return weights.every((weight): weight is number => weight !== undefined) ? weights : undefined;\n}\n\nfunction movingOwner(node: WorkspaceNode | null, moving: string[]): WorkspaceSplit | undefined {\n if (node?.type !== 'split') return undefined;\n if (node.children.some(child => child.type === 'group' && child.panels.length > 0 && isMovingGroup(child, moving)))\n return node;\n for (const child of node.children) {\n const found = movingOwner(child, moving);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction isMovingGroup(node: WorkspaceNode, moving: string[]) {\n return node.type === 'group' && node.panels.every(id => moving.includes(id));\n}\n\nfunction nodeKey(node: WorkspaceNode, target: WorkspaceNode, key = 'root'): string | undefined {\n if (node === target) return key;\n if (node.type !== 'split') return undefined;\n for (const [index, child] of node.children.entries()) {\n const found = nodeKey(child, target, `${key}.${index}`);\n if (found) return found;\n }\n return undefined;\n}\n\nfunction insertionWeights(input: {\n layout: WorkspaceLayout;\n branch: WorkspaceSplit;\n weights: number[];\n available: string[];\n}) {\n const rebased = rebaseProjectedSplit(input.layout, input.branch, input.weights, input.available);\n if (rebased) return rebased;\n const total = input.weights.reduce((sum, weight) => sum + weight, 0);\n return input.branch.weights.every((weight, index) => Math.abs(weight - input.weights[index]! / total) < 1e-10)\n ? input.layout\n : undefined;\n}\n\nexport function computeGroupInsertion(input: GroupInsertionInputs): GroupInsertion | undefined {\n const visible = input.available.filter(id => !input.plan.layout.closed.includes(id));\n const moving = input.source.filter(id => visible.includes(id));\n const owner = movingOwner((input.projectLayout ?? projectLayout)(input.plan.layout, visible).root, moving);\n if (!owner) return undefined;\n const index = owner.children.findIndex(child => isMovingGroup(child, moving));\n if (index < 0) return undefined;\n return {\n axis: owner.axis,\n index,\n members: getPanelIds(owner).filter(id => !moving.includes(id)),\n previous: owner.children[index - 1] ? getPanelIds(owner.children[index - 1]!) : undefined,\n next: owner.children[index + 1] ? getPanelIds(owner.children[index + 1]!) : undefined,\n key: JSON.stringify([owner.axis, index, placementShape(input.plan.layout.root), input.plan.layout.closed])\n };\n}\n\nfunction placementShape(node: WorkspaceNode | null): unknown {\n if (!node) return null;\n return node.type === 'group' ? ['group', node.panels, node.active] : [node.axis, node.children.map(placementShape)];\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { WorkspaceLayout } from '../model/layout.utils.js';
|
|
2
2
|
import type { WorkspaceDestination } from '../model/operations.utils.js';
|
|
3
3
|
import type { WorkspaceLayoutProjector } from '../model/projection.utils.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { WorkspacePlacementScope } from './scope.utils.js';
|
|
5
|
+
import type { WorkspacePlacementSession } from './session.utils.js';
|
|
5
6
|
export interface WorkspacePlacementPlan {
|
|
6
7
|
kind: 'reorder' | 'split' | 'tab' | 'insert';
|
|
7
|
-
|
|
8
|
+
scope?: WorkspacePlacementScope;
|
|
8
9
|
layout: WorkspaceLayout;
|
|
9
10
|
}
|
|
10
11
|
interface PlacementInput {
|
|
@@ -18,5 +19,15 @@ interface PlacementInput {
|
|
|
18
19
|
export type WorkspacePlacementPlanner = (input: PlacementInput) => WorkspacePlacementPlan | undefined;
|
|
19
20
|
/** Requires an immutable current layout; projection callbacks are never retained. */
|
|
20
21
|
export declare function createWorkspacePlacementPlanner(): WorkspacePlacementPlanner;
|
|
22
|
+
interface WorkspacePlanningContext {
|
|
23
|
+
currentLayout: WorkspaceLayout;
|
|
24
|
+
source: string[];
|
|
25
|
+
available: string[];
|
|
26
|
+
projectLayout?: WorkspaceLayoutProjector;
|
|
27
|
+
planPlacement?: WorkspacePlacementPlanner;
|
|
28
|
+
placementSession?: WorkspacePlacementSession;
|
|
29
|
+
}
|
|
30
|
+
/** Supplied planners keep their ordinary path; component gestures use their explicit session. */
|
|
31
|
+
export declare function resolvePlacementPlan(context: WorkspacePlanningContext, destination: WorkspaceDestination, operation: PlacementInput['operation']): WorkspacePlacementPlan | undefined;
|
|
21
32
|
export declare function planWorkspacePlacement(input: PlacementInput): WorkspacePlacementPlan | undefined;
|
|
22
33
|
export {};
|