@witchcraft/layout 0.1.3 → 0.2.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/README.md +27 -24
- package/dist/module.json +1 -1
- package/dist/runtime/components/FrameDragHandle.d.vue.ts +15 -0
- package/dist/runtime/components/FrameDragHandle.vue +28 -0
- package/dist/runtime/components/FrameDragHandle.vue.d.ts +15 -0
- package/dist/runtime/components/LayoutDecos.d.vue.ts +2 -4
- package/dist/runtime/components/LayoutDecos.vue +10 -29
- package/dist/runtime/components/LayoutDecos.vue.d.ts +2 -4
- package/dist/runtime/components/LayoutEdges.d.vue.ts +3 -3
- package/dist/runtime/components/LayoutEdges.vue +8 -8
- package/dist/runtime/components/LayoutEdges.vue.d.ts +3 -3
- package/dist/runtime/components/LayoutFrame.d.vue.ts +1 -1
- package/dist/runtime/components/LayoutFrame.vue +0 -1
- package/dist/runtime/components/LayoutFrame.vue.d.ts +1 -1
- package/dist/runtime/components/LayoutShapeSquare.d.vue.ts +3 -1
- package/dist/runtime/components/LayoutShapeSquare.vue.d.ts +3 -1
- package/dist/runtime/components/LayoutWindow.d.vue.ts +26 -12
- package/dist/runtime/components/LayoutWindow.vue +95 -84
- package/dist/runtime/components/LayoutWindow.vue.d.ts +26 -12
- package/dist/runtime/composables/useFrames.d.ts +15 -13
- package/dist/runtime/composables/useFrames.js +59 -39
- package/dist/runtime/demo/App.vue +116 -30
- package/dist/runtime/demo/DemoControls.d.vue.ts +4 -1
- package/dist/runtime/demo/DemoControls.vue +98 -4
- package/dist/runtime/demo/DemoControls.vue.d.ts +4 -1
- package/dist/runtime/drag/CloseAction.d.ts +26 -5
- package/dist/runtime/drag/CloseAction.js +87 -40
- package/dist/runtime/drag/DragActionHandler.d.ts +20 -8
- package/dist/runtime/drag/DragActionHandler.js +47 -12
- package/dist/runtime/drag/FrameDragAction.d.ts +45 -0
- package/dist/runtime/drag/FrameDragAction.js +143 -0
- package/dist/runtime/drag/SplitAction.d.ts +32 -11
- package/dist/runtime/drag/SplitAction.js +82 -24
- package/dist/runtime/drag/createDefaultHandlers.d.ts +9 -0
- package/dist/runtime/drag/createDefaultHandlers.js +10 -0
- package/dist/runtime/drag/defaultDragActions.d.ts +9 -0
- package/dist/runtime/drag/defaultDragActions.js +10 -0
- package/dist/runtime/drag/types.d.ts +82 -13
- package/dist/runtime/drag/types.js +1 -0
- package/dist/runtime/helpers/createZoneSideClipPath.d.ts +12 -0
- package/dist/runtime/helpers/createZoneSideClipPath.js +17 -0
- package/dist/runtime/helpers/doEdgesOverlap.d.ts +3 -1
- package/dist/runtime/helpers/doEdgesOverlap.js +5 -5
- package/dist/runtime/helpers/getDockBoundaries.d.ts +19 -0
- package/dist/runtime/helpers/getDockBoundaries.js +14 -0
- package/dist/runtime/helpers/getEdgeLength.d.ts +2 -0
- package/dist/runtime/helpers/getEdgeLength.js +5 -0
- package/dist/runtime/helpers/getIntersections.js +2 -2
- package/dist/runtime/helpers/getIntersectionsCss.js +2 -2
- package/dist/runtime/helpers/getMoveEdgeInfo.js +2 -2
- package/dist/runtime/helpers/getResizeLimit.js +2 -2
- package/dist/runtime/helpers/getShapeSquareCss.js +2 -2
- package/dist/runtime/helpers/getVisualEdgeCss.js +2 -2
- package/dist/runtime/helpers/getVisualEdges.d.ts +1 -1
- package/dist/runtime/helpers/getVisualEdges.js +4 -3
- package/dist/runtime/helpers/index.d.ts +4 -0
- package/dist/runtime/helpers/index.js +4 -0
- package/dist/runtime/helpers/isEdgeEqual.js +2 -4
- package/dist/runtime/helpers/isWindowEdge.js +2 -2
- package/dist/runtime/helpers/isWindowEdgePoint.js +2 -2
- package/dist/runtime/helpers/moveEdge.js +2 -2
- package/dist/runtime/helpers/numberToScaledPercent.d.ts +1 -1
- package/dist/runtime/helpers/numberToScaledPercent.js +2 -2
- package/dist/runtime/helpers/numberToScaledSize.js +2 -2
- package/dist/runtime/helpers/rotateFrames.d.ts +7 -0
- package/dist/runtime/helpers/rotateFrames.js +36 -0
- package/dist/runtime/helpers/scaledPointToPx.d.ts +13 -0
- package/dist/runtime/helpers/scaledPointToPx.js +7 -0
- package/dist/runtime/helpers/toWindowCoord.js +2 -2
- package/dist/runtime/layout/applyFrameChanges.d.ts +10 -0
- package/dist/runtime/layout/applyFrameChanges.js +29 -0
- package/dist/runtime/layout/createSplitDecoFromDrag.d.ts +6 -1
- package/dist/runtime/layout/createSplitDecoFromDrag.js +4 -4
- package/dist/runtime/layout/createSplitDecoShapes.d.ts +7 -0
- package/dist/runtime/layout/{createSplitDecoEdge.js → createSplitDecoShapes.js} +6 -3
- package/dist/runtime/layout/debugFrame.js +2 -1
- package/dist/runtime/layout/findSafeSplitEdge.js +2 -2
- package/dist/runtime/layout/frameCreate.js +2 -2
- package/dist/runtime/layout/getCloseFrameInfo.d.ts +7 -6
- package/dist/runtime/layout/getCloseFrameInfo.js +10 -3
- package/dist/runtime/layout/getDragZones.d.ts +8 -0
- package/dist/runtime/layout/getDragZones.js +32 -0
- package/dist/runtime/layout/getFillEmptySpaceInfo.d.ts +65 -0
- package/dist/runtime/layout/getFillEmptySpaceInfo.js +69 -0
- package/dist/runtime/layout/getFrameCollapseInfo.d.ts +13 -0
- package/dist/runtime/layout/getFrameCollapseInfo.js +93 -0
- package/dist/runtime/layout/getFrameDockInfo.d.ts +9 -0
- package/dist/runtime/layout/getFrameDockInfo.js +82 -0
- package/dist/runtime/layout/getFrameDragZones.d.ts +16 -0
- package/dist/runtime/layout/getFrameDragZones.js +74 -0
- package/dist/runtime/layout/getFrameRearrangeInfo.d.ts +139 -0
- package/dist/runtime/layout/getFrameRearrangeInfo.js +87 -0
- package/dist/runtime/layout/getFrameSplitInfo.d.ts +7 -5
- package/dist/runtime/layout/getFrameSplitInfo.js +10 -3
- package/dist/runtime/layout/getFrameSwapInfo.d.ts +9 -0
- package/dist/runtime/layout/getFrameSwapInfo.js +27 -0
- package/dist/runtime/layout/getFrameTo.js +2 -2
- package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +12 -0
- package/dist/runtime/layout/getFrameUncollapseInfo.js +88 -0
- package/dist/runtime/layout/getFrameUndockInfo.d.ts +13 -0
- package/dist/runtime/layout/getFrameUndockInfo.js +51 -0
- package/dist/runtime/layout/getFramesRedistributeInfo.d.ts +29 -0
- package/dist/runtime/layout/getFramesRedistributeInfo.js +53 -0
- package/dist/runtime/layout/getWindowDragZones.d.ts +6 -0
- package/dist/runtime/layout/getWindowDragZones.js +49 -0
- package/dist/runtime/layout/index.d.ts +14 -5
- package/dist/runtime/layout/index.js +14 -5
- package/dist/runtime/layout/isPointInRect.d.ts +7 -0
- package/dist/runtime/layout/{isPointInFrame.js → isPointInRect.js} +1 -1
- package/dist/runtime/layout/resizeFrame.js +2 -2
- package/dist/runtime/settings.d.ts +41 -16
- package/dist/runtime/settings.js +95 -53
- package/dist/runtime/types/index.d.ts +324 -54
- package/dist/runtime/types/index.js +54 -20
- package/package.json +28 -29
- package/src/runtime/components/FrameDragHandle.vue +30 -0
- package/src/runtime/components/LayoutDecos.vue +12 -36
- package/src/runtime/components/LayoutEdges.vue +27 -23
- package/src/runtime/components/LayoutFrame.vue +6 -5
- package/src/runtime/components/LayoutShapeSquare.vue +9 -3
- package/src/runtime/components/LayoutWindow.vue +110 -101
- package/src/runtime/composables/useFrames.ts +80 -50
- package/src/runtime/demo/App.vue +126 -36
- package/src/runtime/demo/DemoControls.vue +115 -6
- package/src/runtime/drag/CloseAction.ts +106 -44
- package/src/runtime/drag/DragActionHandler.ts +71 -20
- package/src/runtime/drag/FrameDragAction.ts +202 -0
- package/src/runtime/drag/SplitAction.ts +106 -34
- package/src/runtime/drag/createDefaultHandlers.ts +19 -0
- package/src/runtime/drag/defaultDragActions.ts +19 -0
- package/src/runtime/drag/types.ts +90 -20
- package/src/runtime/helpers/createZoneSideClipPath.ts +41 -0
- package/src/runtime/helpers/doEdgesOverlap.ts +11 -5
- package/src/runtime/helpers/getDockBoundaries.ts +36 -0
- package/src/runtime/helpers/getEdgeLength.ts +10 -0
- package/src/runtime/helpers/getIntersections.ts +2 -2
- package/src/runtime/helpers/getIntersectionsCss.ts +2 -2
- package/src/runtime/helpers/getMoveEdgeInfo.ts +2 -2
- package/src/runtime/helpers/getResizeLimit.ts +2 -2
- package/src/runtime/helpers/getShapeSquareCss.ts +2 -2
- package/src/runtime/helpers/getVisualEdgeCss.ts +2 -2
- package/src/runtime/helpers/getVisualEdges.ts +5 -4
- package/src/runtime/helpers/index.ts +4 -0
- package/src/runtime/helpers/isEdgeEqual.ts +2 -4
- package/src/runtime/helpers/isWindowEdge.ts +2 -2
- package/src/runtime/helpers/isWindowEdgePoint.ts +2 -2
- package/src/runtime/helpers/moveEdge.ts +2 -2
- package/src/runtime/helpers/numberToScaledPercent.ts +3 -3
- package/src/runtime/helpers/numberToScaledSize.ts +2 -2
- package/src/runtime/helpers/rotateFrames.ts +45 -0
- package/src/runtime/helpers/scaledPointToPx.ts +13 -0
- package/src/runtime/helpers/toWindowCoord.ts +2 -2
- package/src/runtime/layout/applyFrameChanges.ts +39 -0
- package/src/runtime/layout/createSplitDecoFromDrag.ts +12 -6
- package/src/runtime/layout/{createSplitDecoEdge.ts → createSplitDecoShapes.ts} +17 -7
- package/src/runtime/layout/debugFrame.ts +1 -1
- package/src/runtime/layout/findSafeSplitEdge.ts +3 -3
- package/src/runtime/layout/frameCreate.ts +2 -2
- package/src/runtime/layout/getCloseFrameInfo.ts +21 -8
- package/src/runtime/layout/getDragZones.ts +48 -0
- package/src/runtime/layout/getFillEmptySpaceInfo.ts +177 -0
- package/src/runtime/layout/getFrameCollapseInfo.ts +164 -0
- package/src/runtime/layout/getFrameDockInfo.ts +126 -0
- package/src/runtime/layout/getFrameDragZones.ts +100 -0
- package/src/runtime/layout/getFrameRearrangeInfo.ts +261 -0
- package/src/runtime/layout/getFrameSplitInfo.ts +21 -8
- package/src/runtime/layout/getFrameSwapInfo.ts +45 -0
- package/src/runtime/layout/getFrameTo.ts +2 -2
- package/src/runtime/layout/getFrameUncollapseInfo.ts +160 -0
- package/src/runtime/layout/getFrameUndockInfo.ts +97 -0
- package/src/runtime/layout/getFramesRedistributeInfo.ts +98 -0
- package/src/runtime/layout/getWindowDragZones.ts +59 -0
- package/src/runtime/layout/index.ts +14 -5
- package/src/runtime/layout/isPointInRect.ts +7 -0
- package/src/runtime/layout/resizeFrame.ts +2 -2
- package/src/runtime/settings.ts +69 -49
- package/src/runtime/types/index.ts +143 -28
- package/dist/runtime/layout/closeFrame.d.ts +0 -5
- package/dist/runtime/layout/closeFrame.js +0 -13
- package/dist/runtime/layout/closeFrames.d.ts +0 -2
- package/dist/runtime/layout/closeFrames.js +0 -8
- package/dist/runtime/layout/createSplitDecoEdge.d.ts +0 -2
- package/dist/runtime/layout/frameSplit.d.ts +0 -16
- package/dist/runtime/layout/frameSplit.js +0 -9
- package/dist/runtime/layout/isPointInFrame.d.ts +0 -2
- package/src/runtime/layout/closeFrame.ts +0 -33
- package/src/runtime/layout/closeFrames.ts +0 -14
- package/src/runtime/layout/frameSplit.ts +0 -31
- package/src/runtime/layout/isPointInFrame.ts +0 -7
|
@@ -1,57 +1,88 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- overflow hidden is because the borders inside will make it overflow -->
|
|
3
|
-
<div
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
<div
|
|
4
|
+
:class="twMerge(
|
|
5
|
+
`
|
|
6
|
+
layout-wrapper
|
|
7
|
+
flex
|
|
8
|
+
flex-col
|
|
9
|
+
`,
|
|
8
10
|
isDragging && `dragging cursor-pointer`,
|
|
9
11
|
requestType && `request-${requestType}`,
|
|
10
12
|
$attrs.class
|
|
11
13
|
)"
|
|
12
|
-
ref="windowEl"
|
|
13
14
|
v-bind="{ ...$attrs, class: void 0 }"
|
|
14
15
|
>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
<!-- we need the size withot borders for correct px calculations -->
|
|
17
|
+
<div class="
|
|
18
|
+
layout-window
|
|
19
|
+
relative
|
|
20
|
+
overflow-hidden
|
|
21
|
+
flex-1
|
|
22
|
+
" ref="windowEl">
|
|
23
|
+
<template v-if="windowEl && win">
|
|
24
|
+
<LayoutFrameComponent
|
|
25
|
+
:frame="frame"
|
|
26
|
+
:is-active-frame="frame.id === win.activeFrame"
|
|
27
|
+
v-for="frame of frames"
|
|
28
|
+
:key="frame.id"
|
|
29
|
+
v-bind="frameProps"
|
|
30
|
+
@focus="windowSetActiveFrame(win, frame.id)"
|
|
31
|
+
>
|
|
32
|
+
<slot :name="`frame-${frame.id}`" v-bind="{ frame }"/>
|
|
33
|
+
</LayoutFrameComponent>
|
|
34
|
+
<LayoutEdgesComponent
|
|
35
|
+
:win="win"
|
|
36
|
+
:active-frame="win.activeFrame ? frames[win.activeFrame] : void 0"
|
|
37
|
+
:edges="visualEdges"
|
|
38
|
+
:intersections="intersections"
|
|
39
|
+
:dragging-edge="draggingEdges.length === 1 ? draggingEdges[0] : void 0"
|
|
40
|
+
:dragging-intersection="draggingIntersection"
|
|
41
|
+
v-bind="edgesProps"
|
|
42
|
+
@drag-start="dragStart"
|
|
43
|
+
/>
|
|
44
|
+
<LayoutDecosComponent
|
|
45
|
+
:shapes="shapes"
|
|
46
|
+
/>
|
|
47
|
+
<slot name="extra-decos"/>
|
|
48
|
+
</template>
|
|
49
|
+
</div>
|
|
50
|
+
<Teleport
|
|
51
|
+
v-if="isDragging === 'frame' && frameDragFrameId && dragPoint"
|
|
52
|
+
:to="ghostTeleportTo"
|
|
53
|
+
defer
|
|
54
|
+
>
|
|
55
|
+
<div
|
|
56
|
+
class="fixed z-[9999] pointer-events-none"
|
|
57
|
+
:style="{
|
|
58
|
+
left: dragPoint.x / settings.maxInt * win.pxWidth + win.pxX + 'px',
|
|
59
|
+
top: dragPoint.y / settings.maxInt * win.pxHeight + win.pxY + 'px',
|
|
60
|
+
width: frames[frameDragFrameId] ? frames[frameDragFrameId].width / settings.maxInt * win.pxWidth + 'px' : void 0,
|
|
61
|
+
height: frames[frameDragFrameId] ? frames[frameDragFrameId].height / settings.maxInt * win.pxHeight + 'px' : void 0
|
|
62
|
+
}"
|
|
22
63
|
>
|
|
23
|
-
<slot
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
v-bind="edgesProps"
|
|
33
|
-
@drag-start="dragStart"
|
|
34
|
-
/>
|
|
35
|
-
<LayoutDecosComponent
|
|
36
|
-
:frames="frames"
|
|
37
|
-
:split-decos="splitDecos"
|
|
38
|
-
:close-decos="closeDecos"
|
|
39
|
-
/>
|
|
40
|
-
<slot name="extra-decos"/>
|
|
41
|
-
</template>
|
|
42
|
-
<Teleport v-if="instructionsTeleportTo && filteredUsageInstructions.length > 0" defer :to="instructionsTeleportTo">
|
|
64
|
+
<slot
|
|
65
|
+
:id="frameDragFrameId"
|
|
66
|
+
:name="`frame-drag-ghost`"
|
|
67
|
+
>
|
|
68
|
+
<div class="frame-drag-ghost border border-neutral-500 bg-white/50 w-10 h-10"/>
|
|
69
|
+
</slot>
|
|
70
|
+
</div>
|
|
71
|
+
</Teleport>
|
|
72
|
+
<Teleport v-if="textHintsTeleportTo && textHints.length > 0" :to="textHintsTeleportTo" defer>
|
|
43
73
|
<span aria-live="polite">
|
|
44
74
|
<span
|
|
45
|
-
class="
|
|
46
|
-
|
|
75
|
+
:class="twMerge(`
|
|
76
|
+
text-hint
|
|
77
|
+
after:content-['\u2503']
|
|
47
78
|
last:after:content-none
|
|
48
79
|
after:mx-1
|
|
49
|
-
after:text-
|
|
50
|
-
"
|
|
51
|
-
v-for="instruction of
|
|
52
|
-
:key="instruction"
|
|
80
|
+
after:text-neutral-500
|
|
81
|
+
`, instruction.classes)"
|
|
82
|
+
v-for="instruction of textHints"
|
|
83
|
+
:key="instruction.text"
|
|
53
84
|
>
|
|
54
|
-
{{ instruction }}
|
|
85
|
+
{{ instruction.text }}
|
|
55
86
|
</span>
|
|
56
87
|
</span>
|
|
57
88
|
</Teleport>
|
|
@@ -61,62 +92,34 @@
|
|
|
61
92
|
<script setup>
|
|
62
93
|
import { useGlobalResizeObserver } from "@witchcraft/ui/composables/useGlobalResizeObserver";
|
|
63
94
|
import { twMerge } from "@witchcraft/ui/utils/twMerge";
|
|
64
|
-
import { computed, ref, useAttrs, watch } from "vue";
|
|
65
|
-
import {} from "vue";
|
|
95
|
+
import { computed, provide, reactive, ref, useAttrs, watch } from "vue";
|
|
66
96
|
import LayoutDecosComponent from "./LayoutDecos.vue";
|
|
67
97
|
import LayoutEdgesComponent from "./LayoutEdges.vue";
|
|
68
98
|
import LayoutFrameComponent from "./LayoutFrame.vue";
|
|
69
99
|
import { useFrames } from "../composables/useFrames.js";
|
|
70
|
-
import {
|
|
100
|
+
import { createDefaultHandlers } from "../drag/createDefaultHandlers.js";
|
|
71
101
|
import { DragActionHandler } from "../drag/DragActionHandler";
|
|
72
|
-
import {
|
|
73
|
-
import {} from "../drag/types.js";
|
|
102
|
+
import { dragContextInjectionKey } from "../drag/types.js";
|
|
74
103
|
import { updateWindowWithEvent } from "../helpers/updateWindowSizeWithEvent.js";
|
|
75
104
|
import { windowSetActiveFrame } from "../layout/windowSetActiveFrame.js";
|
|
76
|
-
import {} from "../
|
|
105
|
+
import { settings } from "../settings.js";
|
|
77
106
|
const $attrs = useAttrs();
|
|
78
107
|
const win = defineModel("win", { type: Object, ...{ required: true } });
|
|
79
108
|
const props = defineProps({
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
instructionsTeleportTo: { type: null, required: true },
|
|
109
|
+
actionHandlers: { type: Array, required: false, default: void 0 },
|
|
110
|
+
textHints: { type: Array, required: false, default: () => [] },
|
|
111
|
+
textHintsTeleportTo: { type: null, required: true, default: void 0 },
|
|
112
|
+
ghostTeleportTo: { type: String, required: false, default: "#root" },
|
|
85
113
|
allowWindowSizeUpdate: { type: Boolean, required: false, default: true },
|
|
86
114
|
frameProps: { type: Object, required: false },
|
|
87
115
|
edgesProps: { type: Object, required: false }
|
|
88
116
|
});
|
|
89
117
|
const emit = defineEmits(["isShowingDrag", "dragState"]);
|
|
90
|
-
const filteredUsageInstructions = computed(() => Object.values(props.usageInstructions).filter((_) => _ !== void 0).map((_) => _));
|
|
91
|
-
const splitKeyHandler = props.splitKeyHandler ?? ((e, state2) => e.altKey || state2.isDraggingFromWindowEdge);
|
|
92
|
-
const closeKeyHandler = props.closeKeyHandler ?? ((e) => {
|
|
93
|
-
if (e.ctrlKey && e.shiftKey) {
|
|
94
|
-
return "force";
|
|
95
|
-
}
|
|
96
|
-
if (e.shiftKey) return true;
|
|
97
|
-
return false;
|
|
98
|
-
});
|
|
99
118
|
const windowEl = ref(null);
|
|
100
|
-
const showDragging = ref(true);
|
|
101
|
-
const closeDecos = ref([]);
|
|
102
|
-
const splitDecos = ref([]);
|
|
103
119
|
const requestType = ref();
|
|
104
120
|
const dragActionHandler = new DragActionHandler(
|
|
105
|
-
(type, _e, state2) => type === "move" ? !state2.isDraggingFromWindowEdge : void 0,
|
|
106
121
|
[
|
|
107
|
-
|
|
108
|
-
splitKeyHandler,
|
|
109
|
-
((decos) => splitDecos.value = decos),
|
|
110
|
-
{
|
|
111
|
-
onStart: () => showDragging.value = false,
|
|
112
|
-
onCancel: () => showDragging.value = true
|
|
113
|
-
}
|
|
114
|
-
),
|
|
115
|
-
new CloseAction(
|
|
116
|
-
closeKeyHandler,
|
|
117
|
-
((decos) => closeDecos.value = decos)
|
|
118
|
-
),
|
|
119
|
-
...props.additionalDragActions
|
|
122
|
+
...props.actionHandlers ?? createDefaultHandlers()
|
|
120
123
|
],
|
|
121
124
|
{
|
|
122
125
|
onEvent: (e, cancel) => {
|
|
@@ -134,20 +137,27 @@ const dragActionHandler = new DragActionHandler(
|
|
|
134
137
|
}
|
|
135
138
|
}
|
|
136
139
|
);
|
|
140
|
+
dragActionHandler.shapes = reactive([]);
|
|
141
|
+
dragActionHandler.textHints = reactive({ actions: [], errors: [] });
|
|
142
|
+
const shapes = dragActionHandler.shapes;
|
|
143
|
+
const dragContext = useFrames(
|
|
144
|
+
win,
|
|
145
|
+
dragActionHandler
|
|
146
|
+
);
|
|
137
147
|
const {
|
|
138
148
|
dragStart,
|
|
149
|
+
dragPoint,
|
|
139
150
|
visualEdges,
|
|
140
151
|
isDragging,
|
|
141
152
|
draggingEdges,
|
|
142
153
|
draggingIntersection,
|
|
143
154
|
frames,
|
|
144
155
|
intersections,
|
|
145
|
-
state
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
);
|
|
156
|
+
state,
|
|
157
|
+
frameDragFrameId,
|
|
158
|
+
showDragging
|
|
159
|
+
} = dragContext;
|
|
160
|
+
provide(dragContextInjectionKey, dragContext);
|
|
151
161
|
function getWindowOffset() {
|
|
152
162
|
const windowElRect = windowEl.value.getBoundingClientRect();
|
|
153
163
|
return {
|
|
@@ -178,6 +188,7 @@ watch(showDragging, () => emit("isShowingDrag", showDragging.value));
|
|
|
178
188
|
defineExpose({
|
|
179
189
|
state,
|
|
180
190
|
win,
|
|
181
|
-
updateWindowSize
|
|
191
|
+
updateWindowSize,
|
|
192
|
+
dragActionHandler
|
|
182
193
|
});
|
|
183
194
|
</script>
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import { DragActionHandler } from "../drag/DragActionHandler";
|
|
1
2
|
import { type DragState, type IDragAction } from "../drag/types.js";
|
|
2
|
-
import {
|
|
3
|
+
import type { LayoutEdgesProps, LayoutFrameProps, LayoutWindow } from "../types/index.js";
|
|
3
4
|
type __VLS_Props = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
|
|
6
|
+
actionHandlers?: IDragAction[];
|
|
7
|
+
textHints?: {
|
|
8
|
+
text: string;
|
|
9
|
+
classes?: string;
|
|
10
|
+
}[];
|
|
11
|
+
textHintsTeleportTo: string | undefined;
|
|
12
|
+
ghostTeleportTo?: string;
|
|
9
13
|
/**
|
|
10
14
|
* You might need to temporarily disable updating the window size while transitioning, depending on your layout.
|
|
11
15
|
*
|
|
@@ -23,9 +27,13 @@ type __VLS_PublicProps = __VLS_Props & {
|
|
|
23
27
|
};
|
|
24
28
|
declare var __VLS_9: any, __VLS_10: {
|
|
25
29
|
frame: any;
|
|
26
|
-
}, __VLS_22: {}
|
|
30
|
+
}, __VLS_22: {}, __VLS_29: any, __VLS_30: {
|
|
31
|
+
id: any;
|
|
32
|
+
};
|
|
27
33
|
type __VLS_Slots = {} & {
|
|
28
34
|
[K in NonNullable<typeof __VLS_9>]?: (props: typeof __VLS_10) => any;
|
|
35
|
+
} & {
|
|
36
|
+
[K in NonNullable<typeof __VLS_29>]?: (props: typeof __VLS_30) => any;
|
|
29
37
|
} & {
|
|
30
38
|
'extra-decos'?: (props: typeof __VLS_22) => any;
|
|
31
39
|
};
|
|
@@ -39,7 +47,9 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
|
|
|
39
47
|
x: number;
|
|
40
48
|
y: number;
|
|
41
49
|
} | undefined;
|
|
42
|
-
isDragging:
|
|
50
|
+
isDragging: false | "edge" | "frame";
|
|
51
|
+
showDragging: boolean;
|
|
52
|
+
draggingFrameId: string | undefined;
|
|
43
53
|
draggingEdges: {
|
|
44
54
|
startX: number;
|
|
45
55
|
startY: number;
|
|
@@ -85,6 +95,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
|
|
|
85
95
|
}>;
|
|
86
96
|
win: import("vue").ModelRef<import("../types/index.js").BaseLayoutWindow, string, import("../types/index.js").BaseLayoutWindow, import("../types/index.js").BaseLayoutWindow>;
|
|
87
97
|
updateWindowSize: typeof updateWindowSize;
|
|
98
|
+
dragActionHandler: DragActionHandler<IDragAction[], import("@alanscodelog/utils").RecordFromArray<IDragAction[], "name">>;
|
|
88
99
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
89
100
|
"update:win": (value: import("../types/index.js").BaseLayoutWindow) => any;
|
|
90
101
|
} & {
|
|
@@ -95,10 +106,13 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
|
|
|
95
106
|
onDragState?: ((value: DragState) => any) | undefined;
|
|
96
107
|
"onUpdate:win"?: ((value: import("../types/index.js").BaseLayoutWindow) => any) | undefined;
|
|
97
108
|
}>, {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
109
|
+
actionHandlers: IDragAction[];
|
|
110
|
+
textHints: {
|
|
111
|
+
text: string;
|
|
112
|
+
classes?: string;
|
|
113
|
+
}[];
|
|
114
|
+
textHintsTeleportTo: string | undefined;
|
|
115
|
+
ghostTeleportTo: string;
|
|
102
116
|
allowWindowSizeUpdate: boolean;
|
|
103
117
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
104
118
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
import type { Ref } from "vue";
|
|
2
|
-
import type { DragChangeHandler, DragState } from "../drag/types.js";
|
|
3
|
-
import type {
|
|
4
|
-
export declare function useFrames(win: Ref<LayoutWindow>,
|
|
5
|
-
/** Whether to show merged the moved frames while dragging. */
|
|
6
|
-
showDragging: Ref<boolean>, handler: {
|
|
2
|
+
import type { DragChangeHandler, DragChangeResult, DragState, EdgeDragStartData, FrameDragStartData } from "../drag/types.js";
|
|
3
|
+
import type { IntersectionEntry, LayoutFrame, LayoutWindow } from "../types/index.js";
|
|
4
|
+
export declare function useFrames(win: Ref<LayoutWindow>, handler: {
|
|
7
5
|
eventHandler: (e: KeyboardEvent, state: DragState, forceRecalculateEdges: () => void) => void;
|
|
8
6
|
/**
|
|
9
|
-
* Called when the drag coordinates change (during any event). Should return true to allow the edges to be moved, or false to prevent it.
|
|
7
|
+
* Called when the drag coordinates change (during any event). Should return true to allow the edges to be updated/moved, or false to prevent it.
|
|
8
|
+
*
|
|
9
|
+
* Can return anything for the end event as it's ignored.
|
|
10
10
|
*
|
|
11
11
|
* Can be used to save some context/info to later apply safely during onDragApply.
|
|
12
12
|
*/
|
|
13
|
-
onDragChange: DragChangeHandler;
|
|
13
|
+
onDragChange: (...args: Parameters<DragChangeHandler>) => DragChangeResult;
|
|
14
14
|
/**
|
|
15
15
|
* Called when drag will be applied. If dragEnd was called with apply false, it will not be called.
|
|
16
16
|
* Return false to not apply the regular drag end changes (i.e. return false to reset to the position before dragging).
|
|
17
17
|
*/
|
|
18
18
|
onDragApply: ((state: DragState, forceRecalculateEdges: () => void) => boolean);
|
|
19
19
|
}): {
|
|
20
|
-
dragStart: (e: PointerEvent,
|
|
21
|
-
edge?: Edge;
|
|
22
|
-
intersection?: IntersectionEntry;
|
|
23
|
-
}) => void;
|
|
20
|
+
dragStart: <T extends "edge" | "frame">(e: PointerEvent, type: T, data: T extends "edge" ? EdgeDragStartData : FrameDragStartData) => void;
|
|
24
21
|
dragEnd: (e?: PointerEvent, { apply }?: {
|
|
25
22
|
apply?: boolean;
|
|
26
23
|
}) => void;
|
|
27
24
|
cancel: () => void;
|
|
25
|
+
dragMove: (e: PointerEvent) => void;
|
|
28
26
|
dragDirections: Ref<{
|
|
29
27
|
horizontal: "up" | "down" | "left" | "right" | undefined;
|
|
30
28
|
vertical: "up" | "down" | "left" | "right" | undefined;
|
|
@@ -39,7 +37,7 @@ showDragging: Ref<boolean>, handler: {
|
|
|
39
37
|
x: number;
|
|
40
38
|
y: number;
|
|
41
39
|
} | undefined>;
|
|
42
|
-
isDragging: Ref<
|
|
40
|
+
isDragging: Ref<false | "edge" | "frame", false | "edge" | "frame">;
|
|
43
41
|
draggingEdges: Ref<{
|
|
44
42
|
startX: number;
|
|
45
43
|
startY: number;
|
|
@@ -133,7 +131,9 @@ showDragging: Ref<boolean>, handler: {
|
|
|
133
131
|
x: number;
|
|
134
132
|
y: number;
|
|
135
133
|
} | undefined;
|
|
136
|
-
isDragging:
|
|
134
|
+
isDragging: false | "edge" | "frame";
|
|
135
|
+
showDragging: boolean;
|
|
136
|
+
draggingFrameId: string | undefined;
|
|
137
137
|
draggingEdges: {
|
|
138
138
|
startX: number;
|
|
139
139
|
startY: number;
|
|
@@ -177,4 +177,6 @@ showDragging: Ref<boolean>, handler: {
|
|
|
177
177
|
isDraggingFromWindowEdge: boolean;
|
|
178
178
|
win: import("../types/index.js").BaseLayoutWindow;
|
|
179
179
|
}>;
|
|
180
|
+
showDragging: Ref<boolean, boolean>;
|
|
181
|
+
frameDragFrameId: Ref<string | undefined, string | undefined>;
|
|
180
182
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { debounce } from "@alanscodelog/utils/debounce";
|
|
2
2
|
import { keys } from "@alanscodelog/utils/keys";
|
|
3
|
-
import { computed, onBeforeUnmount, onMounted, ref,
|
|
3
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
4
4
|
import { DragDirectionStore } from "../drag/DragDirectionStore.js";
|
|
5
5
|
import { cloneFrame } from "../helpers/cloneFrame.js";
|
|
6
6
|
import { getIntersections } from "../helpers/getIntersections.js";
|
|
@@ -9,8 +9,8 @@ import { isWindowEdge } from "../helpers/isWindowEdge.js";
|
|
|
9
9
|
import { moveEdge } from "../helpers/moveEdge.js";
|
|
10
10
|
import { toWindowCoord } from "../helpers/toWindowCoord.js";
|
|
11
11
|
import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js";
|
|
12
|
-
import {
|
|
13
|
-
export function useFrames(win,
|
|
12
|
+
import { isPointInRect } from "../layout/isPointInRect.js";
|
|
13
|
+
export function useFrames(win, handler) {
|
|
14
14
|
const draggingEdges = ref([]);
|
|
15
15
|
const touchingFrames = ref([]);
|
|
16
16
|
const allTouchingFrames = computed(() => {
|
|
@@ -24,17 +24,19 @@ export function useFrames(win, showDragging, handler) {
|
|
|
24
24
|
});
|
|
25
25
|
const touchingFramesArrays = computed(() => touchingFrames.value.map((entry) => Object.values(entry)));
|
|
26
26
|
const isDragging = ref(false);
|
|
27
|
+
const showDragging = ref(false);
|
|
27
28
|
const dragPoint = ref();
|
|
28
29
|
const dragDirections = ref({});
|
|
29
30
|
const draggingIntersection = ref(void 0);
|
|
30
31
|
const isDraggingFromWindowEdge = ref(false);
|
|
32
|
+
const frameDragFrameId = ref();
|
|
31
33
|
const frames = computed(
|
|
32
34
|
() => isDragging.value && showDragging.value ? { ...win.value.frames, ...allTouchingFrames.value } : win.value.frames
|
|
33
35
|
);
|
|
34
36
|
const dragHoveredFrame = computed(() => {
|
|
35
37
|
if (isDragging.value) {
|
|
36
38
|
for (const id of keys(frames.value)) {
|
|
37
|
-
if (
|
|
39
|
+
if (isPointInRect(frames.value[id], dragPoint.value)) {
|
|
38
40
|
return frames.value[id];
|
|
39
41
|
}
|
|
40
42
|
}
|
|
@@ -46,10 +48,11 @@ export function useFrames(win, showDragging, handler) {
|
|
|
46
48
|
const debounceGetDraggableEdges = debounce((f) => {
|
|
47
49
|
visualEdges.value = getVisualEdges(f, { includeWindowEdges: true });
|
|
48
50
|
}, 50, {});
|
|
49
|
-
|
|
51
|
+
watch([isDragging, frames], () => {
|
|
50
52
|
if (isDragging.value) return;
|
|
51
53
|
debounceGetDraggableEdges(Object.values(frames.value));
|
|
52
|
-
});
|
|
54
|
+
}, { deep: true });
|
|
55
|
+
debounceGetDraggableEdges(Object.values(frames.value));
|
|
53
56
|
function forceRecalculateEdges() {
|
|
54
57
|
visualEdges.value = getVisualEdges(Object.values(frames.value), { includeWindowEdges: true });
|
|
55
58
|
}
|
|
@@ -60,6 +63,8 @@ export function useFrames(win, showDragging, handler) {
|
|
|
60
63
|
dragDirections: dragDirections.value,
|
|
61
64
|
dragPoint: dragPoint.value,
|
|
62
65
|
isDragging: isDragging.value,
|
|
66
|
+
showDragging: showDragging.value,
|
|
67
|
+
draggingFrameId: frameDragFrameId.value,
|
|
63
68
|
draggingEdges: draggingEdges.value,
|
|
64
69
|
draggingIntersection: draggingIntersection.value,
|
|
65
70
|
visualEdges: visualEdges.value,
|
|
@@ -78,10 +83,12 @@ export function useFrames(win, showDragging, handler) {
|
|
|
78
83
|
isDragging.value = false;
|
|
79
84
|
dragPoint.value = void 0;
|
|
80
85
|
touchingFrames.value = [];
|
|
86
|
+
frameDragFrameId.value = void 0;
|
|
81
87
|
dragDirStore.reset();
|
|
88
|
+
showDragging.value = false;
|
|
82
89
|
forceRecalculateEdges();
|
|
83
90
|
}
|
|
84
|
-
function dragStart(e,
|
|
91
|
+
function dragStart(e, type, data) {
|
|
85
92
|
controller = new AbortController();
|
|
86
93
|
controller.signal.addEventListener("abort", () => resetState());
|
|
87
94
|
e.preventDefault();
|
|
@@ -89,31 +96,38 @@ export function useFrames(win, showDragging, handler) {
|
|
|
89
96
|
window.addEventListener("pointerup", dragEnd, { signal: controller.signal });
|
|
90
97
|
const point = toWindowCoord(win.value, e);
|
|
91
98
|
dragPoint.value = point;
|
|
92
|
-
isDragging.value = true;
|
|
93
|
-
draggingIntersection.value = intersection;
|
|
94
|
-
draggingEdges.value = edge ? [edge] : [
|
|
95
|
-
...draggingIntersection.value?.sharedEdges.horizontal ?? [],
|
|
96
|
-
...draggingIntersection.value?.sharedEdges.vertical ?? []
|
|
97
|
-
];
|
|
98
99
|
dragDirStore.update(point);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
isDragging.value = type;
|
|
101
|
+
showDragging.value = true;
|
|
102
|
+
if (type === "frame") {
|
|
103
|
+
frameDragFrameId.value = data.frameId;
|
|
104
|
+
} else {
|
|
105
|
+
const { edge, intersection } = data;
|
|
106
|
+
draggingIntersection.value = intersection;
|
|
107
|
+
draggingEdges.value = edge ? [edge] : [
|
|
108
|
+
...draggingIntersection.value?.sharedEdges.horizontal ?? [],
|
|
109
|
+
...draggingIntersection.value?.sharedEdges.vertical ?? []
|
|
110
|
+
];
|
|
111
|
+
isDraggingFromWindowEdge.value = draggingEdges.value.some((_) => isWindowEdge(_));
|
|
112
|
+
const framesArray = Object.values(win.value.frames);
|
|
113
|
+
touchingFrames.value = [];
|
|
114
|
+
const clones = /* @__PURE__ */ new Map();
|
|
115
|
+
for (let i = 0; i < draggingEdges.value.length; i++) {
|
|
116
|
+
const draggingEdge = draggingEdges.value[i];
|
|
117
|
+
touchingFrames.value[i] = {};
|
|
118
|
+
for (const { frame } of findFramesTouchingEdge(draggingEdge, framesArray)) {
|
|
119
|
+
if (!clones.has(frame.id)) {
|
|
120
|
+
const clone = cloneFrame(frame);
|
|
121
|
+
touchingFrames.value[i][frame.id] = clone;
|
|
122
|
+
clones.set(frame.id, clone);
|
|
123
|
+
} else {
|
|
124
|
+
touchingFrames.value[i][frame.id] = clones.get(frame.id);
|
|
125
|
+
}
|
|
113
126
|
}
|
|
114
127
|
}
|
|
115
128
|
}
|
|
116
|
-
handler.onDragChange("start", e, state.value, forceRecalculateEdges, cancel);
|
|
129
|
+
const res = handler.onDragChange("start", e, state.value, forceRecalculateEdges, cancel);
|
|
130
|
+
showDragging.value = res.showDragging ?? true;
|
|
117
131
|
}
|
|
118
132
|
function dragMove(e) {
|
|
119
133
|
e.preventDefault();
|
|
@@ -121,17 +135,20 @@ export function useFrames(win, showDragging, handler) {
|
|
|
121
135
|
const didChange = dragDirStore.update(point);
|
|
122
136
|
dragPoint.value = point;
|
|
123
137
|
if (!didChange) return;
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
const res = handler.onDragChange("move", e, state.value, forceRecalculateEdges, cancel);
|
|
139
|
+
showDragging.value = res.showDragging ?? true;
|
|
140
|
+
if (!res.updateEdges) return;
|
|
141
|
+
if (isDragging.value === "edge") {
|
|
142
|
+
requestAnimationFrame(() => {
|
|
143
|
+
for (let i = 0; i < draggingEdges.value.length; i++) {
|
|
144
|
+
const draggingEdge = draggingEdges.value[i];
|
|
145
|
+
if (draggingEdge) {
|
|
146
|
+
moveEdge(touchingFramesArrays.value[i], draggingEdge, point);
|
|
147
|
+
}
|
|
131
148
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
149
|
+
forceRecalculateEdges();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
135
152
|
}
|
|
136
153
|
function dragEnd(e, { apply = true } = {}) {
|
|
137
154
|
if (e) {
|
|
@@ -166,6 +183,7 @@ export function useFrames(win, showDragging, handler) {
|
|
|
166
183
|
dragStart,
|
|
167
184
|
dragEnd,
|
|
168
185
|
cancel,
|
|
186
|
+
dragMove,
|
|
169
187
|
dragDirections,
|
|
170
188
|
dragPoint,
|
|
171
189
|
isDragging,
|
|
@@ -179,6 +197,8 @@ export function useFrames(win, showDragging, handler) {
|
|
|
179
197
|
intersections,
|
|
180
198
|
isDraggingFromWindowEdge,
|
|
181
199
|
forceRecalculateEdges,
|
|
182
|
-
state
|
|
200
|
+
state,
|
|
201
|
+
showDragging,
|
|
202
|
+
frameDragFrameId
|
|
183
203
|
};
|
|
184
204
|
}
|