layplux 2.0.0 → 2.0.1
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/dist/cjs/components/center-view/index.cjs +18 -28
- package/dist/cjs/components/corner-glow/index.cjs +11 -28
- package/dist/cjs/components/dropdown/index.cjs +136 -130
- package/dist/cjs/components/icon/index.cjs +29 -51
- package/dist/cjs/components/index.cjs +24 -25
- package/dist/cjs/components/panel-view/index.cjs +111 -114
- package/dist/cjs/components/popup/index.cjs +166 -151
- package/dist/cjs/components/title/index.cjs +34 -47
- package/dist/cjs/components/tooltip/index.cjs +70 -61
- package/dist/cjs/components/widget/index.cjs +52 -72
- package/dist/cjs/index.cjs +13 -40
- package/dist/cjs/layout/glass-overlay.cjs +15 -28
- package/dist/cjs/layout/layered-manager.cjs +20 -29
- package/dist/cjs/layout/layplux.cjs +19 -32
- package/dist/cjs/layout/root-pane.cjs +20 -38
- package/dist/cjs/layout/skeleton/bottom-area.cjs +26 -43
- package/dist/cjs/layout/skeleton/bottom-left-area.cjs +12 -29
- package/dist/cjs/layout/skeleton/bottom-right-area.cjs +11 -28
- package/dist/cjs/layout/skeleton/center-area.cjs +278 -371
- package/dist/cjs/layout/skeleton/index.cjs +7 -24
- package/dist/cjs/layout/skeleton/left-bottom-area.cjs +12 -29
- package/dist/cjs/layout/skeleton/left-top-area.cjs +12 -29
- package/dist/cjs/layout/skeleton/right-bottom-area.cjs +11 -28
- package/dist/cjs/layout/skeleton/right-top-area.cjs +11 -28
- package/dist/cjs/layout/skeleton/skeleton.cjs +55 -60
- package/dist/cjs/layout/skeleton/top-area.cjs +26 -43
- package/dist/cjs/locales/en-US.cjs +11 -30
- package/dist/cjs/locales/index.cjs +12 -30
- package/dist/cjs/locales/zh-CN.cjs +11 -30
- package/dist/cjs/managers/area.cjs +12 -25
- package/dist/cjs/managers/index.cjs +12 -20
- package/dist/cjs/managers/pane.cjs +12 -26
- package/dist/cjs/managers/skeleton.cjs +112 -124
- package/dist/cjs/managers/theme.cjs +8 -29
- package/dist/cjs/managers/widget-container.cjs +31 -31
- package/dist/cjs/managers/widget.cjs +63 -50
- package/dist/cjs/types/config.cjs +2 -16
- package/dist/cjs/types/index.cjs +2 -18
- package/dist/cjs/types/locale.cjs +2 -16
- package/dist/cjs/utils/event-bus.cjs +53 -49
- package/dist/cjs/utils/focus-tracker.cjs +66 -42
- package/dist/cjs/utils/index.cjs +23 -31
- package/dist/cjs/utils/unique-id.cjs +5 -24
- package/dist/cjs/utils/vue.cjs +20 -30
- package/dist/esm/components/center-view/index.mjs +15 -7
- package/dist/esm/components/corner-glow/index.mjs +8 -7
- package/dist/esm/components/dropdown/index.mjs +117 -101
- package/dist/esm/components/icon/index.mjs +24 -30
- package/dist/esm/components/index.mjs +7 -8
- package/dist/esm/components/panel-view/index.mjs +107 -98
- package/dist/esm/components/popup/index.mjs +155 -130
- package/dist/esm/components/title/index.mjs +29 -24
- package/dist/esm/components/tooltip/index.mjs +67 -40
- package/dist/esm/components/widget/index.mjs +45 -48
- package/dist/esm/index.mjs +4 -10
- package/dist/esm/layout/glass-overlay.mjs +12 -7
- package/dist/esm/layout/layered-manager.mjs +17 -8
- package/dist/esm/layout/layplux.mjs +14 -11
- package/dist/esm/layout/root-pane.mjs +16 -16
- package/dist/esm/layout/skeleton/bottom-area.mjs +23 -22
- package/dist/esm/layout/skeleton/bottom-left-area.mjs +9 -8
- package/dist/esm/layout/skeleton/bottom-right-area.mjs +8 -7
- package/dist/esm/layout/skeleton/center-area.mjs +251 -333
- package/dist/esm/layout/skeleton/index.mjs +1 -4
- package/dist/esm/layout/skeleton/left-bottom-area.mjs +9 -8
- package/dist/esm/layout/skeleton/left-top-area.mjs +9 -8
- package/dist/esm/layout/skeleton/right-bottom-area.mjs +8 -7
- package/dist/esm/layout/skeleton/right-top-area.mjs +8 -7
- package/dist/esm/layout/skeleton/skeleton.mjs +52 -39
- package/dist/esm/layout/skeleton/top-area.mjs +23 -22
- package/dist/esm/locales/en-US.mjs +9 -10
- package/dist/esm/locales/index.mjs +7 -9
- package/dist/esm/locales/zh-CN.mjs +9 -10
- package/dist/esm/managers/area.mjs +10 -5
- package/dist/esm/managers/index.mjs +3 -3
- package/dist/esm/managers/pane.mjs +9 -5
- package/dist/esm/managers/skeleton.mjs +97 -95
- package/dist/esm/managers/theme.mjs +6 -9
- package/dist/esm/managers/widget-container.mjs +28 -10
- package/dist/esm/managers/widget.mjs +55 -25
- package/dist/esm/types/config.mjs +1 -0
- package/dist/esm/types/index.mjs +1 -1
- package/dist/esm/types/locale.mjs +1 -0
- package/dist/esm/utils/event-bus.mjs +46 -17
- package/dist/esm/utils/focus-tracker.mjs +63 -23
- package/dist/esm/utils/index.mjs +7 -10
- package/dist/esm/utils/unique-id.mjs +3 -4
- package/dist/esm/utils/vue.mjs +13 -5
- package/dist/types/managers/skeleton.d.ts.map +1 -1
- package/dist/umd/index.js +0 -2
- package/package.json +11 -8
|
@@ -1,467 +1,374 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var center_area_exports = {};
|
|
20
|
-
__export(center_area_exports, {
|
|
21
|
-
CenterArea: () => CenterArea
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(center_area_exports);
|
|
24
|
-
var import_jsx_runtime = require("vue/jsx-runtime");
|
|
25
|
-
var import_vue = require("vue");
|
|
26
|
-
var import_components = require("../../components");
|
|
27
|
-
const CenterArea = (0, import_vue.defineComponent)({
|
|
28
|
-
name: "CenterArea",
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vue = require('vue');
|
|
4
|
+
var index = require('../../components/panel-view/index.cjs');
|
|
5
|
+
|
|
6
|
+
function _isSlot(s) {
|
|
7
|
+
return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
|
|
8
|
+
}
|
|
9
|
+
const CenterArea = vue.defineComponent({
|
|
10
|
+
name: 'CenterArea',
|
|
29
11
|
props: {
|
|
30
12
|
skeleton: Object,
|
|
31
13
|
centerArea: Object
|
|
32
14
|
},
|
|
33
15
|
setup(props) {
|
|
16
|
+
// ─── FocusTracker 全局挂载 ────────────────────────────────────────────
|
|
17
|
+
// 监听 document click,点击面板外自动触发 onBlur(DockUnpinned 自动收起)
|
|
34
18
|
let unmountFocusTracker = null;
|
|
35
|
-
|
|
19
|
+
vue.onMounted(() => {
|
|
36
20
|
unmountFocusTracker = props.skeleton?.focusTracker.mount(window) ?? null;
|
|
37
21
|
});
|
|
38
|
-
|
|
22
|
+
vue.onUnmounted(() => {
|
|
39
23
|
unmountFocusTracker?.();
|
|
40
24
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
25
|
+
|
|
26
|
+
// ─── 面板尺寸状态 ─────────────────────────────────────────────────────
|
|
27
|
+
const leftWidth = vue.ref(340);
|
|
28
|
+
const rightWidth = vue.ref(340);
|
|
29
|
+
const bottomHeight = vue.ref(300);
|
|
30
|
+
|
|
31
|
+
// 上下 / 左右内部分割比例 (0~1)
|
|
32
|
+
const leftSplitRatio = vue.ref(0.5);
|
|
33
|
+
const rightSplitRatio = vue.ref(0.5);
|
|
34
|
+
const bottomSplitRatio = vue.ref(0.5);
|
|
35
|
+
|
|
36
|
+
// ─── 通用拖拽 ─────────────────────────────────────────────────────────
|
|
47
37
|
function startDrag(e, axis, onMove) {
|
|
48
38
|
e.preventDefault();
|
|
49
|
-
const startPos = axis ===
|
|
50
|
-
const onMouseMove =
|
|
39
|
+
const startPos = axis === 'x' ? e.clientX : e.clientY;
|
|
40
|
+
const onMouseMove = ev => onMove((axis === 'x' ? ev.clientX : ev.clientY) - startPos);
|
|
51
41
|
const onMouseUp = () => {
|
|
52
|
-
window.removeEventListener(
|
|
53
|
-
window.removeEventListener(
|
|
42
|
+
window.removeEventListener('mousemove', onMouseMove);
|
|
43
|
+
window.removeEventListener('mouseup', onMouseUp);
|
|
54
44
|
};
|
|
55
|
-
window.addEventListener(
|
|
56
|
-
window.addEventListener(
|
|
45
|
+
window.addEventListener('mousemove', onMouseMove);
|
|
46
|
+
window.addEventListener('mouseup', onMouseUp);
|
|
57
47
|
}
|
|
48
|
+
|
|
49
|
+
// 左侧整体宽度
|
|
58
50
|
function dragLeftWidth(e) {
|
|
59
51
|
const base = leftWidth.value;
|
|
60
|
-
startDrag(e,
|
|
52
|
+
startDrag(e, 'x', d => {
|
|
61
53
|
leftWidth.value = Math.max(160, Math.min(600, base + d));
|
|
62
54
|
});
|
|
63
55
|
}
|
|
56
|
+
// 右侧整体宽度(向左拖拽变宽,delta 取反)
|
|
64
57
|
function dragRightWidth(e) {
|
|
65
58
|
const base = rightWidth.value;
|
|
66
|
-
startDrag(e,
|
|
59
|
+
startDrag(e, 'x', d => {
|
|
67
60
|
rightWidth.value = Math.max(160, Math.min(600, base - d));
|
|
68
61
|
});
|
|
69
62
|
}
|
|
63
|
+
// 底部整体高度(向上拖拽变高,delta 取反)
|
|
70
64
|
function dragBottomHeight(e) {
|
|
71
65
|
const base = bottomHeight.value;
|
|
72
|
-
startDrag(e,
|
|
66
|
+
startDrag(e, 'y', d => {
|
|
73
67
|
bottomHeight.value = Math.max(80, Math.min(600, base - d));
|
|
74
68
|
});
|
|
75
69
|
}
|
|
70
|
+
// 左侧内部上下分割
|
|
76
71
|
function dragLeftSplit(e, totalHeight) {
|
|
77
72
|
const base = leftSplitRatio.value;
|
|
78
|
-
startDrag(e,
|
|
73
|
+
startDrag(e, 'y', d => {
|
|
79
74
|
leftSplitRatio.value = Math.max(0.15, Math.min(0.85, base + d / totalHeight));
|
|
80
75
|
});
|
|
81
76
|
}
|
|
77
|
+
// 右侧内部上下分割
|
|
82
78
|
function dragRightSplit(e, totalHeight) {
|
|
83
79
|
const base = rightSplitRatio.value;
|
|
84
|
-
startDrag(e,
|
|
80
|
+
startDrag(e, 'y', d => {
|
|
85
81
|
rightSplitRatio.value = Math.max(0.15, Math.min(0.85, base + d / totalHeight));
|
|
86
82
|
});
|
|
87
83
|
}
|
|
84
|
+
// 底部内部左右分割
|
|
88
85
|
function dragBottomSplit(e, totalWidth) {
|
|
89
86
|
const base = bottomSplitRatio.value;
|
|
90
|
-
startDrag(e,
|
|
87
|
+
startDrag(e, 'x', d => {
|
|
91
88
|
bottomSplitRatio.value = Math.max(0.15, Math.min(0.85, base + d / totalWidth));
|
|
92
89
|
});
|
|
93
90
|
}
|
|
91
|
+
|
|
92
|
+
// ─── 辅助 ─────────────────────────────────────────────────────────────
|
|
94
93
|
function getActiveWidget(activeId) {
|
|
95
94
|
if (!activeId) return null;
|
|
96
|
-
return props.skeleton?.widgets.find(
|
|
95
|
+
return props.skeleton?.widgets.find(w => w.name === activeId) ?? null;
|
|
97
96
|
}
|
|
98
97
|
function isDocked(activeId) {
|
|
99
98
|
const mode = getActiveWidget(activeId)?.pane.viewMode.value;
|
|
100
|
-
return mode ===
|
|
99
|
+
return mode === 'DockPinned' || mode === 'DockUnpinned';
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
105
|
-
const leftBottomWidget = (
|
|
106
|
-
|
|
107
|
-
);
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
);
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
);
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
);
|
|
126
|
-
const isRightTopVisible = (0, import_vue.computed)(
|
|
127
|
-
() => isDocked(props.skeleton?.rightTopArea.container.activeId.value ?? null)
|
|
128
|
-
);
|
|
129
|
-
const isRightBottomVisible = (0, import_vue.computed)(
|
|
130
|
-
() => isDocked(props.skeleton?.rightBottomArea.container.activeId.value ?? null)
|
|
131
|
-
);
|
|
132
|
-
const isBottomLeftVisible = (0, import_vue.computed)(
|
|
133
|
-
() => isDocked(props.skeleton?.bottomLeftArea.container.activeId.value ?? null)
|
|
134
|
-
);
|
|
135
|
-
const isBottomRightVisible = (0, import_vue.computed)(
|
|
136
|
-
() => isDocked(props.skeleton?.bottomRightArea.container.activeId.value ?? null)
|
|
137
|
-
);
|
|
138
|
-
const isLeftVisible = (0, import_vue.computed)(() => isLeftTopVisible.value || isLeftBottomVisible.value);
|
|
139
|
-
const isRightVisible = (0, import_vue.computed)(() => isRightTopVisible.value || isRightBottomVisible.value);
|
|
140
|
-
const isBottomVisible = (0, import_vue.computed)(() => isBottomLeftVisible.value || isBottomRightVisible.value);
|
|
101
|
+
|
|
102
|
+
// ─── 各侧 active widget ───────────────────────────────────────────────
|
|
103
|
+
const leftTopWidget = vue.computed(() => getActiveWidget(props.skeleton?.leftTopArea.container.activeId.value ?? null));
|
|
104
|
+
const leftBottomWidget = vue.computed(() => getActiveWidget(props.skeleton?.leftBottomArea.container.activeId.value ?? null));
|
|
105
|
+
const rightTopWidget = vue.computed(() => getActiveWidget(props.skeleton?.rightTopArea.container.activeId.value ?? null));
|
|
106
|
+
const rightBottomWidget = vue.computed(() => getActiveWidget(props.skeleton?.rightBottomArea.container.activeId.value ?? null));
|
|
107
|
+
const bottomLeftWidget = vue.computed(() => getActiveWidget(props.skeleton?.bottomLeftArea.container.activeId.value ?? null));
|
|
108
|
+
const bottomRightWidget = vue.computed(() => getActiveWidget(props.skeleton?.bottomRightArea.container.activeId.value ?? null));
|
|
109
|
+
|
|
110
|
+
// ─── 各面板 docked 可见性 ─────────────────────────────────────────────
|
|
111
|
+
const isLeftTopVisible = vue.computed(() => isDocked(props.skeleton?.leftTopArea.container.activeId.value ?? null));
|
|
112
|
+
const isLeftBottomVisible = vue.computed(() => isDocked(props.skeleton?.leftBottomArea.container.activeId.value ?? null));
|
|
113
|
+
const isRightTopVisible = vue.computed(() => isDocked(props.skeleton?.rightTopArea.container.activeId.value ?? null));
|
|
114
|
+
const isRightBottomVisible = vue.computed(() => isDocked(props.skeleton?.rightBottomArea.container.activeId.value ?? null));
|
|
115
|
+
const isBottomLeftVisible = vue.computed(() => isDocked(props.skeleton?.bottomLeftArea.container.activeId.value ?? null));
|
|
116
|
+
const isBottomRightVisible = vue.computed(() => isDocked(props.skeleton?.bottomRightArea.container.activeId.value ?? null));
|
|
117
|
+
|
|
118
|
+
// 整侧可见(有任意一个 docked 就显示侧栏容器)
|
|
119
|
+
const isLeftVisible = vue.computed(() => isLeftTopVisible.value || isLeftBottomVisible.value);
|
|
120
|
+
const isRightVisible = vue.computed(() => isRightTopVisible.value || isRightBottomVisible.value);
|
|
121
|
+
const isBottomVisible = vue.computed(() => isBottomLeftVisible.value || isBottomRightVisible.value);
|
|
122
|
+
|
|
123
|
+
// ─── Undocked widget(每侧独立,从 focusedId 里找) ───────────────────
|
|
141
124
|
function makeUndockedWidget(side) {
|
|
142
|
-
return
|
|
125
|
+
return vue.computed(() => {
|
|
143
126
|
const sk = props.skeleton;
|
|
144
127
|
const w = getActiveWidget(sk?.focusedId.value ?? null);
|
|
145
|
-
if (!w || w.pane.viewMode.value !==
|
|
128
|
+
if (!w || w.pane.viewMode.value !== 'Undock') return null;
|
|
146
129
|
const areaMap = {
|
|
147
130
|
left: [sk?.leftTopArea, sk?.leftBottomArea],
|
|
148
131
|
right: [sk?.rightTopArea, sk?.rightBottomArea],
|
|
149
132
|
bottom: [sk?.bottomLeftArea, sk?.bottomRightArea]
|
|
150
133
|
};
|
|
151
|
-
const belongs = areaMap[side].some(
|
|
152
|
-
(a) => a?.container.items.value.some((i) => i.name === w.name)
|
|
153
|
-
);
|
|
134
|
+
const belongs = areaMap[side].some(a => a?.container.items.value.some(i => i.name === w.name));
|
|
154
135
|
return belongs ? w : null;
|
|
155
136
|
});
|
|
156
137
|
}
|
|
157
|
-
const leftUndockedWidget = makeUndockedWidget(
|
|
158
|
-
const rightUndockedWidget = makeUndockedWidget(
|
|
159
|
-
const bottomUndockedWidget = makeUndockedWidget(
|
|
160
|
-
const isLeftUndockedVisible =
|
|
161
|
-
const isRightUndockedVisible =
|
|
162
|
-
const isBottomUndockedVisible =
|
|
163
|
-
|
|
138
|
+
const leftUndockedWidget = makeUndockedWidget('left');
|
|
139
|
+
const rightUndockedWidget = makeUndockedWidget('right');
|
|
140
|
+
const bottomUndockedWidget = makeUndockedWidget('bottom');
|
|
141
|
+
const isLeftUndockedVisible = vue.computed(() => leftUndockedWidget.value !== null);
|
|
142
|
+
const isRightUndockedVisible = vue.computed(() => rightUndockedWidget.value !== null);
|
|
143
|
+
const isBottomUndockedVisible = vue.computed(() => bottomUndockedWidget.value !== null);
|
|
144
|
+
|
|
145
|
+
// ─── Teleport 目标 map ────────────────────────────────────────────────
|
|
146
|
+
const teleportTargets = vue.computed(() => {
|
|
164
147
|
const sk = props.skeleton;
|
|
165
148
|
const map = {};
|
|
166
149
|
if (!sk) return map;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
);
|
|
171
|
-
sk.leftBottomArea.container.items.value.forEach(
|
|
172
|
-
|
|
173
|
-
);
|
|
174
|
-
sk.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
);
|
|
180
|
-
sk.bottomLeftArea.container.items.value.forEach(
|
|
181
|
-
(w) => sideIndex.set(w.name, "#bottom-undocked-area")
|
|
182
|
-
);
|
|
183
|
-
sk.bottomRightArea.container.items.value.forEach(
|
|
184
|
-
(w) => sideIndex.set(w.name, "#bottom-undocked-area")
|
|
185
|
-
);
|
|
150
|
+
|
|
151
|
+
// widgetName -> 所属侧的 undocked 锚点(仅表达归属,不代表一定能传送过去)
|
|
152
|
+
const sideIndex = new Map();
|
|
153
|
+
sk.leftTopArea.container.items.value.forEach(w => sideIndex.set(w.name, '#left-undocked-area'));
|
|
154
|
+
sk.leftBottomArea.container.items.value.forEach(w => sideIndex.set(w.name, '#left-undocked-area'));
|
|
155
|
+
sk.rightTopArea.container.items.value.forEach(w => sideIndex.set(w.name, '#right-undocked-area'));
|
|
156
|
+
sk.rightBottomArea.container.items.value.forEach(w => sideIndex.set(w.name, '#right-undocked-area'));
|
|
157
|
+
sk.bottomLeftArea.container.items.value.forEach(w => sideIndex.set(w.name, '#bottom-undocked-area'));
|
|
158
|
+
sk.bottomRightArea.container.items.value.forEach(w => sideIndex.set(w.name, '#bottom-undocked-area'));
|
|
159
|
+
|
|
160
|
+
// 每个 undocked 锚点当前唯一获得传送权的 widgetName
|
|
161
|
+
// 规则:focusedId 优先;若 focusedId 不属于该侧则该侧无 undocked 显示
|
|
186
162
|
const focusedName = sk.focusedId.value;
|
|
187
163
|
const undockWinner = {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
164
|
+
'#left-undocked-area': null,
|
|
165
|
+
'#right-undocked-area': null,
|
|
166
|
+
'#bottom-undocked-area': null
|
|
191
167
|
};
|
|
192
168
|
if (focusedName) {
|
|
193
|
-
const focusedWidget = sk.widgets.find(
|
|
194
|
-
if (focusedWidget?.pane.viewMode.value ===
|
|
169
|
+
const focusedWidget = sk.widgets.find(w => w.name === focusedName);
|
|
170
|
+
if (focusedWidget?.pane.viewMode.value === 'Undock') {
|
|
195
171
|
const anchor = sideIndex.get(focusedName);
|
|
196
172
|
if (anchor) undockWinner[anchor] = focusedName;
|
|
197
173
|
}
|
|
198
174
|
}
|
|
175
|
+
|
|
176
|
+
// activeId -> docked 锚点
|
|
199
177
|
const dockTargets = {
|
|
200
|
-
[sk.leftTopArea.container.activeId.value ??
|
|
201
|
-
[sk.leftBottomArea.container.activeId.value ??
|
|
202
|
-
[sk.rightTopArea.container.activeId.value ??
|
|
203
|
-
[sk.rightBottomArea.container.activeId.value ??
|
|
204
|
-
[sk.bottomLeftArea.container.activeId.value ??
|
|
205
|
-
[sk.bottomRightArea.container.activeId.value ??
|
|
178
|
+
[sk.leftTopArea.container.activeId.value ?? '']: '#left-top-area',
|
|
179
|
+
[sk.leftBottomArea.container.activeId.value ?? '']: '#left-bottom-area',
|
|
180
|
+
[sk.rightTopArea.container.activeId.value ?? '']: '#right-top-area',
|
|
181
|
+
[sk.rightBottomArea.container.activeId.value ?? '']: '#right-bottom-area',
|
|
182
|
+
[sk.bottomLeftArea.container.activeId.value ?? '']: '#bottom-left-area',
|
|
183
|
+
[sk.bottomRightArea.container.activeId.value ?? '']: '#bottom-right-area'
|
|
206
184
|
};
|
|
207
|
-
delete dockTargets[
|
|
208
|
-
sk.widgets.filter(
|
|
209
|
-
if (w.pane.viewMode.value ===
|
|
210
|
-
const anchor = sideIndex.get(w.name) ??
|
|
211
|
-
|
|
185
|
+
delete dockTargets[''];
|
|
186
|
+
sk.widgets.filter(w => w.type === 'panel').forEach(w => {
|
|
187
|
+
if (w.pane.viewMode.value === 'Undock') {
|
|
188
|
+
const anchor = sideIndex.get(w.name) ?? '#widget-offscreen';
|
|
189
|
+
// 只有赢得该锚点的 widget 才能传送过去,其余保活在 offscreen
|
|
190
|
+
map[w.name] = undockWinner[anchor] === w.name ? anchor : '#widget-offscreen';
|
|
212
191
|
} else {
|
|
213
|
-
map[w.name] = dockTargets[w.name] ??
|
|
192
|
+
map[w.name] = dockTargets[w.name] ?? '#widget-offscreen';
|
|
214
193
|
}
|
|
215
194
|
});
|
|
216
195
|
return map;
|
|
217
196
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
197
|
+
|
|
198
|
+
// ─── Center widget Teleport 目标 ──────────────────────────────────────
|
|
199
|
+
const centerWidgetNames = vue.computed(() => {
|
|
200
|
+
const names = new Set();
|
|
201
|
+
props.centerArea?.container.items.value.forEach(w => names.add(w.name));
|
|
221
202
|
return names;
|
|
222
203
|
});
|
|
223
|
-
const centerTargets =
|
|
204
|
+
const centerTargets = vue.computed(() => {
|
|
224
205
|
const activeId = props.centerArea?.container.activeId.value ?? null;
|
|
225
206
|
const map = {};
|
|
226
|
-
props.centerArea?.container.items.value.forEach(
|
|
227
|
-
map[w.name] = w.name === activeId ?
|
|
207
|
+
props.centerArea?.container.items.value.forEach(w => {
|
|
208
|
+
map[w.name] = w.name === activeId ? '#center-area' : '#center-offscreen';
|
|
228
209
|
});
|
|
229
210
|
return map;
|
|
230
211
|
});
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
const
|
|
235
|
-
const
|
|
236
|
-
const
|
|
212
|
+
|
|
213
|
+
// ─── 内部分割高度 / 宽度(CSS calc 字符串) ───────────────────────────
|
|
214
|
+
const leftTopHeight = vue.computed(() => `calc((100% - 4px) * ${leftSplitRatio.value})`);
|
|
215
|
+
const leftBottomHeight = vue.computed(() => `calc((100% - 4px) * ${1 - leftSplitRatio.value})`);
|
|
216
|
+
const rightTopHeight = vue.computed(() => `calc((100% - 4px) * ${rightSplitRatio.value})`);
|
|
217
|
+
const rightBottomHeight = vue.computed(() => `calc((100% - 4px) * ${1 - rightSplitRatio.value})`);
|
|
218
|
+
const bottomLeftWidth = vue.computed(() => `calc((100% - 4px) * ${bottomSplitRatio.value})`);
|
|
219
|
+
const bottomRightWidth = vue.computed(() => `calc((100% - 4px) * ${1 - bottomSplitRatio.value})`);
|
|
237
220
|
return () => {
|
|
238
221
|
if (!props.skeleton) return null;
|
|
239
222
|
const sk = props.skeleton;
|
|
240
223
|
const leftBoth = isLeftTopVisible.value && isLeftBottomVisible.value;
|
|
241
224
|
const rightBoth = isRightTopVisible.value && isRightBottomVisible.value;
|
|
242
225
|
const bottomBoth = isBottomLeftVisible.value && isBottomRightVisible.value;
|
|
243
|
-
return
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
{
|
|
388
|
-
anchor: "right-top-area",
|
|
389
|
-
widget: rightTopWidget.value ?? void 0,
|
|
390
|
-
"v-show": isRightTopVisible.value,
|
|
391
|
-
style: rightBoth ? { height: rightTopHeight.value, flex: "none" } : {}
|
|
392
|
-
}
|
|
393
|
-
),
|
|
394
|
-
rightBoth && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
395
|
-
"div",
|
|
396
|
-
{
|
|
397
|
-
class: "layplux-resize-handle layplux-resize-handle--y",
|
|
398
|
-
onMousedown: (e) => dragRightSplit(
|
|
399
|
-
e,
|
|
400
|
-
e.currentTarget.closest(
|
|
401
|
-
".layplux-center-area__docked-panels"
|
|
402
|
-
).clientHeight
|
|
403
|
-
)
|
|
404
|
-
}
|
|
405
|
-
),
|
|
406
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
407
|
-
import_components.PanelView,
|
|
408
|
-
{
|
|
409
|
-
anchor: "right-bottom-area",
|
|
410
|
-
widget: rightBottomWidget.value ?? void 0,
|
|
411
|
-
"v-show": isRightBottomVisible.value,
|
|
412
|
-
style: rightBoth ? { height: rightBottomHeight.value, flex: "none" } : {}
|
|
413
|
-
}
|
|
414
|
-
)
|
|
415
|
-
] })
|
|
416
|
-
}
|
|
417
|
-
)
|
|
418
|
-
] }),
|
|
419
|
-
isBottomVisible.value && !isBottomUndockedVisible.value && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
420
|
-
"div",
|
|
421
|
-
{
|
|
422
|
-
class: "layplux-resize-handle layplux-resize-handle--y layplux-resize-handle--bottom-edge",
|
|
423
|
-
onMousedown: dragBottomHeight
|
|
424
|
-
}
|
|
425
|
-
),
|
|
426
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
427
|
-
"div",
|
|
428
|
-
{
|
|
429
|
-
class: "layplux-center-area__bottom",
|
|
430
|
-
"v-show": isBottomVisible.value,
|
|
431
|
-
style: { height: `${bottomHeight.value}px` },
|
|
432
|
-
children: [
|
|
433
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
434
|
-
import_components.PanelView,
|
|
435
|
-
{
|
|
436
|
-
anchor: "bottom-left-area",
|
|
437
|
-
widget: bottomLeftWidget.value ?? void 0,
|
|
438
|
-
"v-show": isBottomLeftVisible.value,
|
|
439
|
-
style: bottomBoth ? { width: bottomLeftWidth.value, flex: "none" } : {}
|
|
440
|
-
}
|
|
441
|
-
),
|
|
442
|
-
bottomBoth && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
443
|
-
"div",
|
|
444
|
-
{
|
|
445
|
-
class: "layplux-resize-handle layplux-resize-handle--x",
|
|
446
|
-
onMousedown: (e) => dragBottomSplit(
|
|
447
|
-
e,
|
|
448
|
-
e.currentTarget.closest(".layplux-center-area__bottom").clientWidth
|
|
449
|
-
)
|
|
450
|
-
}
|
|
451
|
-
),
|
|
452
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
453
|
-
import_components.PanelView,
|
|
454
|
-
{
|
|
455
|
-
anchor: "bottom-right-area",
|
|
456
|
-
widget: bottomRightWidget.value ?? void 0,
|
|
457
|
-
"v-show": isBottomRightVisible.value,
|
|
458
|
-
style: bottomBoth ? { width: bottomRightWidth.value, flex: "none" } : {}
|
|
459
|
-
}
|
|
460
|
-
)
|
|
461
|
-
]
|
|
462
|
-
}
|
|
463
|
-
)
|
|
464
|
-
] });
|
|
226
|
+
return vue.createVNode("div", {
|
|
227
|
+
"class": "layplux-center-area"
|
|
228
|
+
}, [vue.createVNode("div", {
|
|
229
|
+
"id": "widget-offscreen",
|
|
230
|
+
"style": "display:none;"
|
|
231
|
+
}, null), vue.createVNode("div", {
|
|
232
|
+
"id": "center-offscreen",
|
|
233
|
+
"style": "display:none;"
|
|
234
|
+
}, null), sk.widgets.filter(w => w.type === 'panel' && !centerWidgetNames.value.has(w.name)).map(w => {
|
|
235
|
+
let _slot;
|
|
236
|
+
return vue.createVNode(vue.Teleport, {
|
|
237
|
+
"defer": true,
|
|
238
|
+
"key": w.name,
|
|
239
|
+
"to": teleportTargets.value[w.name] ?? '#widget-offscreen'
|
|
240
|
+
}, _isSlot(_slot = w.renderContent()) ? _slot : {
|
|
241
|
+
default: () => [_slot]
|
|
242
|
+
});
|
|
243
|
+
}), props.centerArea?.container.items.value.map(w => {
|
|
244
|
+
let _slot2;
|
|
245
|
+
return vue.createVNode(vue.Teleport, {
|
|
246
|
+
"defer": true,
|
|
247
|
+
"key": w.name,
|
|
248
|
+
"to": centerTargets.value[w.name] ?? '#center-offscreen'
|
|
249
|
+
}, _isSlot(_slot2 = w.renderContent()) ? _slot2 : {
|
|
250
|
+
default: () => [_slot2]
|
|
251
|
+
});
|
|
252
|
+
}), vue.withDirectives(vue.createVNode("div", {
|
|
253
|
+
"class": "layplux-panel--undocked layplux-panel--undocked-left",
|
|
254
|
+
"style": {
|
|
255
|
+
width: `${leftWidth.value}px`
|
|
256
|
+
}
|
|
257
|
+
}, [vue.createVNode(index.PanelView, {
|
|
258
|
+
"anchor": "left-undocked-area",
|
|
259
|
+
"widget": leftUndockedWidget.value ?? undefined
|
|
260
|
+
}, null), vue.createVNode("div", {
|
|
261
|
+
"class": "layplux-resize-handle layplux-resize-handle--x layplux-resize-handle--edge-right",
|
|
262
|
+
"onMousedown": dragLeftWidth
|
|
263
|
+
}, null)]), [[vue.vShow, isLeftUndockedVisible.value]]), vue.withDirectives(vue.createVNode("div", {
|
|
264
|
+
"class": "layplux-panel--undocked layplux-panel--undocked-right",
|
|
265
|
+
"style": {
|
|
266
|
+
width: `${rightWidth.value}px`
|
|
267
|
+
}
|
|
268
|
+
}, [vue.createVNode("div", {
|
|
269
|
+
"class": "layplux-resize-handle layplux-resize-handle--x layplux-resize-handle--edge-left",
|
|
270
|
+
"onMousedown": dragRightWidth
|
|
271
|
+
}, null), vue.createVNode(index.PanelView, {
|
|
272
|
+
"anchor": "right-undocked-area",
|
|
273
|
+
"widget": rightUndockedWidget.value ?? undefined
|
|
274
|
+
}, null)]), [[vue.vShow, isRightUndockedVisible.value]]), vue.withDirectives(vue.createVNode("div", {
|
|
275
|
+
"class": "layplux-panel--undocked layplux-panel--undocked-bottom",
|
|
276
|
+
"style": {
|
|
277
|
+
height: `${bottomHeight.value}px`
|
|
278
|
+
}
|
|
279
|
+
}, [vue.createVNode("div", {
|
|
280
|
+
"class": "layplux-resize-handle layplux-resize-handle--y layplux-resize-handle--edge-top",
|
|
281
|
+
"onMousedown": dragBottomHeight
|
|
282
|
+
}, null), vue.createVNode(index.PanelView, {
|
|
283
|
+
"anchor": "bottom-undocked-area",
|
|
284
|
+
"widget": bottomUndockedWidget.value ?? undefined
|
|
285
|
+
}, null)]), [[vue.vShow, isBottomUndockedVisible.value]]), vue.createVNode("div", {
|
|
286
|
+
"class": "layplux-center-area__main"
|
|
287
|
+
}, [vue.withDirectives(vue.createVNode("div", {
|
|
288
|
+
"class": "layplux-center-area__left",
|
|
289
|
+
"style": {
|
|
290
|
+
width: `${leftWidth.value}px`
|
|
291
|
+
}
|
|
292
|
+
}, [vue.createVNode("div", {
|
|
293
|
+
"class": "layplux-center-area__docked-panels"
|
|
294
|
+
}, [vue.withDirectives(vue.createVNode(index.PanelView, {
|
|
295
|
+
"anchor": "left-top-area",
|
|
296
|
+
"widget": leftTopWidget.value ?? undefined,
|
|
297
|
+
"style": leftBoth ? {
|
|
298
|
+
height: leftTopHeight.value,
|
|
299
|
+
flex: 'none'
|
|
300
|
+
} : {}
|
|
301
|
+
}, null), [[vue.vShow, isLeftTopVisible.value]]), leftBoth && vue.createVNode("div", {
|
|
302
|
+
"class": "layplux-resize-handle layplux-resize-handle--y",
|
|
303
|
+
"onMousedown": e => dragLeftSplit(e, e.currentTarget.closest('.layplux-center-area__docked-panels').clientHeight)
|
|
304
|
+
}, null), vue.withDirectives(vue.createVNode(index.PanelView, {
|
|
305
|
+
"anchor": "left-bottom-area",
|
|
306
|
+
"widget": leftBottomWidget.value ?? undefined,
|
|
307
|
+
"style": leftBoth ? {
|
|
308
|
+
height: leftBottomHeight.value,
|
|
309
|
+
flex: 'none'
|
|
310
|
+
} : {}
|
|
311
|
+
}, null), [[vue.vShow, isLeftBottomVisible.value]])])]), [[vue.vShow, isLeftVisible.value]]), isLeftVisible.value && !isLeftUndockedVisible.value && vue.createVNode("div", {
|
|
312
|
+
"class": "layplux-resize-handle layplux-resize-handle--x",
|
|
313
|
+
"onMousedown": dragLeftWidth
|
|
314
|
+
}, null), vue.createVNode("div", {
|
|
315
|
+
"id": "center-area",
|
|
316
|
+
"class": "layplux-center-area__editor"
|
|
317
|
+
}, null), isRightVisible.value && !isRightUndockedVisible.value && vue.createVNode("div", {
|
|
318
|
+
"class": "layplux-resize-handle layplux-resize-handle--x",
|
|
319
|
+
"onMousedown": dragRightWidth
|
|
320
|
+
}, null), vue.withDirectives(vue.createVNode("div", {
|
|
321
|
+
"class": "layplux-center-area__right",
|
|
322
|
+
"style": {
|
|
323
|
+
width: `${rightWidth.value}px`
|
|
324
|
+
}
|
|
325
|
+
}, [vue.createVNode("div", {
|
|
326
|
+
"class": "layplux-center-area__docked-panels"
|
|
327
|
+
}, [vue.withDirectives(vue.createVNode(index.PanelView, {
|
|
328
|
+
"anchor": "right-top-area",
|
|
329
|
+
"widget": rightTopWidget.value ?? undefined,
|
|
330
|
+
"style": rightBoth ? {
|
|
331
|
+
height: rightTopHeight.value,
|
|
332
|
+
flex: 'none'
|
|
333
|
+
} : {}
|
|
334
|
+
}, null), [[vue.vShow, isRightTopVisible.value]]), rightBoth && vue.createVNode("div", {
|
|
335
|
+
"class": "layplux-resize-handle layplux-resize-handle--y",
|
|
336
|
+
"onMousedown": e => dragRightSplit(e, e.currentTarget.closest('.layplux-center-area__docked-panels').clientHeight)
|
|
337
|
+
}, null), vue.withDirectives(vue.createVNode(index.PanelView, {
|
|
338
|
+
"anchor": "right-bottom-area",
|
|
339
|
+
"widget": rightBottomWidget.value ?? undefined,
|
|
340
|
+
"style": rightBoth ? {
|
|
341
|
+
height: rightBottomHeight.value,
|
|
342
|
+
flex: 'none'
|
|
343
|
+
} : {}
|
|
344
|
+
}, null), [[vue.vShow, isRightBottomVisible.value]])])]), [[vue.vShow, isRightVisible.value]])]), isBottomVisible.value && !isBottomUndockedVisible.value && vue.createVNode("div", {
|
|
345
|
+
"class": "layplux-resize-handle layplux-resize-handle--y layplux-resize-handle--bottom-edge",
|
|
346
|
+
"onMousedown": dragBottomHeight
|
|
347
|
+
}, null), vue.withDirectives(vue.createVNode("div", {
|
|
348
|
+
"class": "layplux-center-area__bottom",
|
|
349
|
+
"style": {
|
|
350
|
+
height: `${bottomHeight.value}px`
|
|
351
|
+
}
|
|
352
|
+
}, [vue.withDirectives(vue.createVNode(index.PanelView, {
|
|
353
|
+
"anchor": "bottom-left-area",
|
|
354
|
+
"widget": bottomLeftWidget.value ?? undefined,
|
|
355
|
+
"style": bottomBoth ? {
|
|
356
|
+
width: bottomLeftWidth.value,
|
|
357
|
+
flex: 'none'
|
|
358
|
+
} : {}
|
|
359
|
+
}, null), [[vue.vShow, isBottomLeftVisible.value]]), bottomBoth && vue.createVNode("div", {
|
|
360
|
+
"class": "layplux-resize-handle layplux-resize-handle--x",
|
|
361
|
+
"onMousedown": e => dragBottomSplit(e, e.currentTarget.closest('.layplux-center-area__bottom').clientWidth)
|
|
362
|
+
}, null), vue.withDirectives(vue.createVNode(index.PanelView, {
|
|
363
|
+
"anchor": "bottom-right-area",
|
|
364
|
+
"widget": bottomRightWidget.value ?? undefined,
|
|
365
|
+
"style": bottomBoth ? {
|
|
366
|
+
width: bottomRightWidth.value,
|
|
367
|
+
flex: 'none'
|
|
368
|
+
} : {}
|
|
369
|
+
}, null), [[vue.vShow, isBottomRightVisible.value]])]), [[vue.vShow, isBottomVisible.value]])]);
|
|
465
370
|
};
|
|
466
371
|
}
|
|
467
372
|
});
|
|
373
|
+
|
|
374
|
+
exports.CenterArea = CenterArea;
|