@maas/vue-equipment 0.30.2 → 0.30.3
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/nuxt/module.json +1 -1
- package/dist/plugins/MagicCommand/src/components/MagicCommandItem.vue +2 -2
- package/dist/plugins/MagicCommand/src/components/MagicCommandView.vue +1 -1
- package/dist/plugins/MagicMenu/src/components/MagicMenuContent.vue +43 -27
- package/dist/plugins/MagicMenu/src/components/MagicMenuItem.vue +0 -1
- package/dist/plugins/MagicMenu/src/components/MagicMenuView.vue +0 -1
- package/dist/plugins/MagicMenu/src/composables/private/useMenuCursor.d.ts +2 -11
- package/dist/plugins/MagicMenu/src/composables/private/useMenuCursor.mjs +46 -85
- package/package.json +1 -1
package/dist/nuxt/module.json
CHANGED
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
onMounted,
|
|
20
20
|
onUnmounted,
|
|
21
21
|
} from 'vue'
|
|
22
|
-
import { useEventListener, onKeyStroke } from '@vueuse/core'
|
|
23
22
|
import { uuid } from '@maas/vue-equipment/utils'
|
|
23
|
+
import { useEventListener, onKeyStroke } from '@vueuse/core'
|
|
24
24
|
import { useCommandStore } from '../composables/private/useCommandStore'
|
|
25
25
|
import { useCommandItem } from '../composables/private/useCommandItem'
|
|
26
26
|
import { MagicCommandInstanceId } from '../symbols'
|
|
@@ -43,7 +43,7 @@ const commandId = inject(MagicCommandInstanceId, '')
|
|
|
43
43
|
const { selectItem, activeItem } = useCommandItem(commandId)
|
|
44
44
|
|
|
45
45
|
const mappedId = computed(() => {
|
|
46
|
-
return props.id
|
|
46
|
+
return props.id ?? uuid()
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
const isActive = computed(() => {
|
|
@@ -31,6 +31,20 @@
|
|
|
31
31
|
</magic-menu-float>
|
|
32
32
|
</div>
|
|
33
33
|
</transition>
|
|
34
|
+
<span
|
|
35
|
+
v-for="point in coords"
|
|
36
|
+
:style="{
|
|
37
|
+
background: 'red',
|
|
38
|
+
position: 'fixed',
|
|
39
|
+
top: point.y + 'px',
|
|
40
|
+
left: point.x + 'px',
|
|
41
|
+
width: '4px',
|
|
42
|
+
height: '4px',
|
|
43
|
+
zIndex: 1000,
|
|
44
|
+
pointerEvents: 'none',
|
|
45
|
+
transform: 'translate(-50%, -50%)',
|
|
46
|
+
}"
|
|
47
|
+
/>
|
|
34
48
|
</teleport>
|
|
35
49
|
</template>
|
|
36
50
|
|
|
@@ -124,20 +138,6 @@ const {
|
|
|
124
138
|
wrapperActive,
|
|
125
139
|
})
|
|
126
140
|
|
|
127
|
-
// Handle cursor
|
|
128
|
-
const mappedClick = computed(() => view?.click)
|
|
129
|
-
const mappedPlacement = computed(() => view?.placement ?? 'bottom')
|
|
130
|
-
const mappedTrigger = computed(
|
|
131
|
-
() => document.querySelector(`[data-id="${viewId}-trigger"]`) as HTMLElement
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
const { destroy, initialize, isInsideTriangle, isInsideTo } = useMenuCursor({
|
|
135
|
-
from: mappedTrigger,
|
|
136
|
-
to: contentRef,
|
|
137
|
-
placement: mappedPlacement,
|
|
138
|
-
click: mappedClick,
|
|
139
|
-
})
|
|
140
|
-
|
|
141
141
|
// Handle state
|
|
142
142
|
async function onOpen() {
|
|
143
143
|
wrapperActive.value = true
|
|
@@ -152,14 +152,6 @@ function onClose() {
|
|
|
152
152
|
innerActive.value = false
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
function disableCursor() {
|
|
156
|
-
state.input.disabled = [...state.input.disabled, 'pointer']
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function enableCursor() {
|
|
160
|
-
state.input.disabled = state.input.disabled.filter((x) => x !== 'pointer')
|
|
161
|
-
}
|
|
162
|
-
|
|
163
155
|
watch(
|
|
164
156
|
() => view?.active,
|
|
165
157
|
async (value) => {
|
|
@@ -171,6 +163,24 @@ watch(
|
|
|
171
163
|
}
|
|
172
164
|
)
|
|
173
165
|
|
|
166
|
+
// Handle cursor
|
|
167
|
+
const {
|
|
168
|
+
coords,
|
|
169
|
+
destroy,
|
|
170
|
+
initialize,
|
|
171
|
+
isInsideTriangle,
|
|
172
|
+
isInsideTo,
|
|
173
|
+
isInsideFrom,
|
|
174
|
+
} = useMenuCursor(view!)
|
|
175
|
+
|
|
176
|
+
function disableCursor() {
|
|
177
|
+
state.input.disabled = [...state.input.disabled, 'pointer']
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function enableCursor() {
|
|
181
|
+
state.input.disabled = state.input.disabled.filter((x) => x !== 'pointer')
|
|
182
|
+
}
|
|
183
|
+
|
|
174
184
|
watch(isInsideTriangle, (value) => {
|
|
175
185
|
if (value) {
|
|
176
186
|
disableCursor()
|
|
@@ -182,17 +192,23 @@ watch(isInsideTriangle, (value) => {
|
|
|
182
192
|
watch(isInsideTo, (value) => {
|
|
183
193
|
if (value) {
|
|
184
194
|
enableCursor()
|
|
185
|
-
}
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
const isOutside = computed(
|
|
199
|
+
() => !isInsideTo.value && !isInsideFrom.value && !isInsideTriangle.value
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
watch(isOutside, (value, oldValue) => {
|
|
203
|
+
if (value && !oldValue) {
|
|
186
204
|
switch (state.options.mode) {
|
|
187
205
|
case 'navigation':
|
|
188
|
-
|
|
189
|
-
view!.active = false
|
|
190
|
-
}
|
|
206
|
+
view!.active = false
|
|
191
207
|
}
|
|
192
208
|
}
|
|
193
209
|
})
|
|
194
210
|
|
|
195
|
-
onBeforeUnmount(
|
|
211
|
+
onBeforeUnmount(() => {
|
|
196
212
|
destroy()
|
|
197
213
|
})
|
|
198
214
|
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import type { Placement } from '@floating-ui/vue';
|
|
4
|
-
interface UseMenuCursorArgs {
|
|
5
|
-
from: MaybeRef<HTMLElement | undefined>;
|
|
6
|
-
to: MaybeRef<HTMLElement | undefined>;
|
|
7
|
-
placement: MaybeRef<Placement>;
|
|
8
|
-
click: MaybeRef<Coordinates | undefined>;
|
|
9
|
-
}
|
|
10
|
-
export declare function useMenuCursor(args: UseMenuCursorArgs): {
|
|
1
|
+
import type { MenuView } from '../../types.js';
|
|
2
|
+
export declare function useMenuCursor(view: MenuView): {
|
|
11
3
|
coords: import("vue").Ref<{
|
|
12
4
|
x: number;
|
|
13
5
|
y: number;
|
|
@@ -18,4 +10,3 @@ export declare function useMenuCursor(args: UseMenuCursorArgs): {
|
|
|
18
10
|
initialize: () => void;
|
|
19
11
|
destroy: () => void;
|
|
20
12
|
};
|
|
21
|
-
export {};
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import { ref
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
useResizeObserver,
|
|
6
|
-
usePointer
|
|
7
|
-
} from "@vueuse/core";
|
|
8
|
-
export function useMenuCursor(args) {
|
|
9
|
-
const cancelListener = ref(new AbortController());
|
|
10
|
-
const { x, y } = usePointer();
|
|
11
|
-
const { from, to, placement, click } = args;
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
import { useEventListener } from "@vueuse/core";
|
|
3
|
+
export function useMenuCursor(view) {
|
|
4
|
+
let cancelListener = new AbortController();
|
|
12
5
|
const coords = ref([
|
|
13
6
|
{ x: 0, y: 0 },
|
|
14
7
|
{ x: 0, y: 0 },
|
|
@@ -19,7 +12,7 @@ export function useMenuCursor(args) {
|
|
|
19
12
|
const isInsideTriangle = ref(false);
|
|
20
13
|
function extendTriangle(vertices, pixelAmount) {
|
|
21
14
|
const [a, b, c] = vertices;
|
|
22
|
-
switch (
|
|
15
|
+
switch (view?.placement) {
|
|
23
16
|
case "bottom":
|
|
24
17
|
case "bottom-start":
|
|
25
18
|
case "bottom-end":
|
|
@@ -66,8 +59,8 @@ export function useMenuCursor(args) {
|
|
|
66
59
|
coords.value = [a, b, c];
|
|
67
60
|
return [a, b, c];
|
|
68
61
|
}
|
|
69
|
-
function isPointInTriangle(
|
|
70
|
-
const { p, a, b, c } =
|
|
62
|
+
function isPointInTriangle(args) {
|
|
63
|
+
const { p, a, b, c } = args;
|
|
71
64
|
const v0 = { x: c.x - a.x, y: c.y - a.y };
|
|
72
65
|
const v1 = { x: b.x - a.x, y: b.y - a.y };
|
|
73
66
|
const v2 = { x: p.x - a.x, y: p.y - a.y };
|
|
@@ -81,37 +74,29 @@ export function useMenuCursor(args) {
|
|
|
81
74
|
const v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
82
75
|
return u >= 0 && v >= 0 && u + v <= 1;
|
|
83
76
|
}
|
|
84
|
-
function isPointInRectangle(
|
|
85
|
-
const { p, top, left, bottom, right } =
|
|
77
|
+
function isPointInRectangle(args) {
|
|
78
|
+
const { p, top, left, bottom, right } = args;
|
|
86
79
|
return p.x >= left && p.x <= right && p.y >= top && p.y <= bottom;
|
|
87
80
|
}
|
|
88
|
-
function triangleOverlap(cursor,
|
|
89
|
-
const fromBounding = useElementBounding(from2, {
|
|
90
|
-
windowScroll: false,
|
|
91
|
-
windowResize: false
|
|
92
|
-
});
|
|
93
|
-
const toBounding = useElementBounding(to2, {
|
|
94
|
-
windowScroll: false,
|
|
95
|
-
windowResize: false
|
|
96
|
-
});
|
|
81
|
+
function triangleOverlap(cursor, fromBounding, toBounding) {
|
|
97
82
|
const { top, left, bottom, right } = toBounding;
|
|
98
|
-
const centerPoint =
|
|
99
|
-
x: (fromBounding.left
|
|
100
|
-
y: (fromBounding.top
|
|
83
|
+
const centerPoint = view.click ? view.click : {
|
|
84
|
+
x: (fromBounding.left + fromBounding.right) / 2,
|
|
85
|
+
y: (fromBounding.top + fromBounding.bottom) / 2
|
|
101
86
|
};
|
|
102
87
|
const sidePoints = [];
|
|
103
|
-
switch (
|
|
88
|
+
switch (view.placement) {
|
|
104
89
|
case "top":
|
|
105
90
|
case "top-start":
|
|
106
91
|
case "top-end":
|
|
107
92
|
case "bottom":
|
|
108
93
|
case "bottom-start":
|
|
109
94
|
case "bottom-end":
|
|
110
|
-
const topDist = Math.abs(top
|
|
111
|
-
const bottomDist = Math.abs(bottom
|
|
95
|
+
const topDist = Math.abs(top - centerPoint.y);
|
|
96
|
+
const bottomDist = Math.abs(bottom - centerPoint.y);
|
|
112
97
|
const mappedY = topDist < bottomDist ? top : bottom;
|
|
113
|
-
sidePoints.push({ x: left
|
|
114
|
-
sidePoints.push({ x: right
|
|
98
|
+
sidePoints.push({ x: left, y: mappedY });
|
|
99
|
+
sidePoints.push({ x: right, y: mappedY });
|
|
115
100
|
break;
|
|
116
101
|
case "right":
|
|
117
102
|
case "right-start":
|
|
@@ -119,11 +104,11 @@ export function useMenuCursor(args) {
|
|
|
119
104
|
case "left":
|
|
120
105
|
case "left-start":
|
|
121
106
|
case "left-end":
|
|
122
|
-
const rightDist = Math.abs(right
|
|
123
|
-
const leftDist = Math.abs(left
|
|
107
|
+
const rightDist = Math.abs(right - centerPoint.x);
|
|
108
|
+
const leftDist = Math.abs(left - centerPoint.x);
|
|
124
109
|
const mappedX = rightDist < leftDist ? right : left;
|
|
125
|
-
sidePoints.push({ x: mappedX
|
|
126
|
-
sidePoints.push({ x: mappedX
|
|
110
|
+
sidePoints.push({ x: mappedX, y: top });
|
|
111
|
+
sidePoints.push({ x: mappedX, y: bottom });
|
|
127
112
|
break;
|
|
128
113
|
}
|
|
129
114
|
const [a, b, c] = extendTriangle(
|
|
@@ -137,69 +122,45 @@ export function useMenuCursor(args) {
|
|
|
137
122
|
c
|
|
138
123
|
});
|
|
139
124
|
}
|
|
140
|
-
function elementOverlap(cursor,
|
|
141
|
-
const { top, left, bottom, right } =
|
|
142
|
-
windowScroll: false,
|
|
143
|
-
windowResize: false
|
|
144
|
-
});
|
|
125
|
+
function elementOverlap(cursor, bounding) {
|
|
126
|
+
const { top, left, bottom, right } = bounding;
|
|
145
127
|
return isPointInRectangle({
|
|
146
128
|
p: cursor,
|
|
147
|
-
top
|
|
148
|
-
left
|
|
149
|
-
bottom
|
|
150
|
-
right
|
|
129
|
+
top,
|
|
130
|
+
left,
|
|
131
|
+
bottom,
|
|
132
|
+
right
|
|
151
133
|
});
|
|
152
134
|
}
|
|
153
135
|
function onMousemove(e) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
function toMouseleave(e) {
|
|
169
|
-
isInsideTo.value = false;
|
|
170
|
-
}
|
|
171
|
-
function onResize() {
|
|
172
|
-
const cursor = { x: x.value, y: y.value };
|
|
173
|
-
isInsideFrom.value = elementOverlap(cursor, from);
|
|
174
|
-
isInsideTo.value = elementOverlap(cursor, to);
|
|
175
|
-
isInsideTriangle.value = triangleOverlap(cursor, from, to);
|
|
136
|
+
const from = document.querySelector(
|
|
137
|
+
`[data-id="${view?.id}-trigger"]`
|
|
138
|
+
);
|
|
139
|
+
const to = document.querySelector(
|
|
140
|
+
`[data-id="${view?.id}-content"] .magic-menu-content__inner`
|
|
141
|
+
);
|
|
142
|
+
if (from && to) {
|
|
143
|
+
const cursor = { x: e.clientX, y: e.clientY };
|
|
144
|
+
const fromBounding = from.getBoundingClientRect();
|
|
145
|
+
const toBounding = to.getBoundingClientRect();
|
|
146
|
+
isInsideFrom.value = elementOverlap(cursor, fromBounding);
|
|
147
|
+
isInsideTo.value = elementOverlap(cursor, toBounding);
|
|
148
|
+
isInsideTriangle.value = triangleOverlap(cursor, fromBounding, toBounding);
|
|
149
|
+
}
|
|
176
150
|
}
|
|
177
151
|
function initialize() {
|
|
178
|
-
cancelListener.
|
|
179
|
-
cancelListener
|
|
180
|
-
useEventListener(from, "mouseenter", fromMouseenter, {
|
|
181
|
-
signal: cancelListener.value.signal
|
|
182
|
-
});
|
|
183
|
-
useEventListener(from, "mouseleave", fromMouseleave, {
|
|
184
|
-
signal: cancelListener.value.signal
|
|
185
|
-
});
|
|
186
|
-
useEventListener(to, "mouseenter", toMouseenter, {
|
|
187
|
-
signal: cancelListener.value.signal
|
|
188
|
-
});
|
|
189
|
-
useEventListener(to, "mouseleave", toMouseleave, {
|
|
190
|
-
signal: cancelListener.value.signal
|
|
191
|
-
});
|
|
152
|
+
cancelListener.abort();
|
|
153
|
+
cancelListener = new AbortController();
|
|
192
154
|
useEventListener(document, "mousemove", onMousemove, {
|
|
193
|
-
signal: cancelListener.
|
|
155
|
+
signal: cancelListener.signal
|
|
194
156
|
});
|
|
195
|
-
useResizeObserver(to, onResize);
|
|
196
157
|
}
|
|
197
158
|
function destroy() {
|
|
198
159
|
coords.value = [];
|
|
199
160
|
isInsideFrom.value = false;
|
|
200
161
|
isInsideTo.value = false;
|
|
201
162
|
isInsideTriangle.value = false;
|
|
202
|
-
cancelListener.
|
|
163
|
+
cancelListener.abort();
|
|
203
164
|
}
|
|
204
165
|
return {
|
|
205
166
|
coords,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maas/vue-equipment",
|
|
3
3
|
"description": "A magic collection of Vue composables, plugins, components and directives",
|
|
4
|
-
"version": "0.30.
|
|
4
|
+
"version": "0.30.3",
|
|
5
5
|
"author": "Robin Scholz <https://github.com/robinscholz>, Christoph Jeworutzki <https://github.com/ChristophJeworutzki>",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@antfu/ni": "^0.21.12",
|