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