@maas/vue-equipment 0.30.1 → 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 +77 -14
- package/dist/plugins/MagicMenu/src/components/MagicMenuFloat.vue +2 -2
- package/dist/plugins/MagicMenu/src/components/MagicMenuItem.vue +1 -2
- package/dist/plugins/MagicMenu/src/components/MagicMenuProvider.vue +1 -5
- package/dist/plugins/MagicMenu/src/components/MagicMenuRemote.vue +12 -3
- package/dist/plugins/MagicMenu/src/components/MagicMenuTrigger.vue +21 -31
- package/dist/plugins/MagicMenu/src/components/MagicMenuView.vue +0 -1
- package/dist/plugins/MagicMenu/src/composables/private/useMenuCallback.d.ts +2 -1
- package/dist/plugins/MagicMenu/src/composables/private/useMenuCallback.mjs +2 -1
- package/dist/plugins/MagicMenu/src/composables/private/useMenuChannel.mjs +0 -3
- package/dist/plugins/MagicMenu/src/composables/private/useMenuCursor.d.ts +12 -0
- package/dist/plugins/MagicMenu/src/composables/private/useMenuCursor.mjs +173 -0
- package/dist/plugins/MagicMenu/src/composables/private/useMenuItem.mjs +2 -2
- package/dist/plugins/MagicMenu/src/composables/private/useMenuKeyListener.mjs +4 -4
- package/dist/plugins/MagicMenu/src/composables/private/useMenuTrigger.d.ts +1 -3
- package/dist/plugins/MagicMenu/src/composables/private/useMenuTrigger.mjs +2 -180
- package/dist/plugins/MagicMenu/src/composables/private/useMenuView.d.ts +2 -1
- package/dist/plugins/MagicMenu/src/composables/private/useMenuView.mjs +24 -13
- package/dist/plugins/MagicMenu/src/composables/useMagicMenu.d.ts +1 -1
- package/dist/plugins/MagicMenu/src/composables/useMagicMenu.mjs +1 -1
- package/dist/plugins/MagicMenu/src/types/index.d.ts +1 -5
- package/dist/plugins/MagicMenu/src/utils/defaultOptions.mjs +3 -3
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue.d.ts +1 -1
- 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
|
|
|
@@ -44,8 +58,13 @@ import {
|
|
|
44
58
|
computed,
|
|
45
59
|
type MaybeRef,
|
|
46
60
|
type ComponentPublicInstance,
|
|
61
|
+
onBeforeUnmount,
|
|
47
62
|
} from 'vue'
|
|
48
63
|
import { useMenuView } from '../composables/private/useMenuView'
|
|
64
|
+
import { useMenuState } from '../composables/private/useMenuState'
|
|
65
|
+
import { useMenuCallback } from '../composables/private/useMenuCallback'
|
|
66
|
+
import { useMenuDOM } from '../composables/private/useMenuDOM'
|
|
67
|
+
import { useMenuCursor } from '../composables/private/useMenuCursor'
|
|
49
68
|
import {
|
|
50
69
|
MagicMenuInstanceId,
|
|
51
70
|
MagicMenuViewId,
|
|
@@ -54,9 +73,6 @@ import {
|
|
|
54
73
|
|
|
55
74
|
import '@maas/vue-equipment/utils/css/animations/fade-in.css'
|
|
56
75
|
import '@maas/vue-equipment/utils/css/animations/fade-out.css'
|
|
57
|
-
import { useMenuState } from '../composables/private/useMenuState'
|
|
58
|
-
import { useMenuCallback } from '../composables/private/useMenuCallback'
|
|
59
|
-
import { useMenuDOM } from '../composables/private/useMenuDOM'
|
|
60
76
|
|
|
61
77
|
defineOptions({
|
|
62
78
|
inheritAttrs: false,
|
|
@@ -101,6 +117,10 @@ const mappedTransition = computed(() => {
|
|
|
101
117
|
}
|
|
102
118
|
})
|
|
103
119
|
|
|
120
|
+
// Split isActive into two values to animate content smoothly
|
|
121
|
+
const innerActive = ref(false)
|
|
122
|
+
const wrapperActive = ref(false)
|
|
123
|
+
|
|
104
124
|
const { lockScroll, unlockScroll } = useMenuDOM()
|
|
105
125
|
const {
|
|
106
126
|
onBeforeEnter,
|
|
@@ -115,27 +135,21 @@ const {
|
|
|
115
135
|
viewId,
|
|
116
136
|
lockScroll,
|
|
117
137
|
unlockScroll,
|
|
138
|
+
wrapperActive,
|
|
118
139
|
})
|
|
119
140
|
|
|
120
|
-
// Split isActive into two values to animate content smoothly
|
|
121
|
-
const innerActive = ref(false)
|
|
122
|
-
const wrapperActive = ref(false)
|
|
123
|
-
|
|
124
141
|
// Handle state
|
|
125
142
|
async function onOpen() {
|
|
126
143
|
wrapperActive.value = true
|
|
127
144
|
await nextTick()
|
|
128
145
|
innerActive.value = true
|
|
129
146
|
await nextTick()
|
|
130
|
-
|
|
131
|
-
view.children.content = contentRef.value
|
|
132
|
-
}
|
|
147
|
+
initialize()
|
|
133
148
|
}
|
|
134
149
|
|
|
135
|
-
|
|
150
|
+
function onClose() {
|
|
151
|
+
destroy()
|
|
136
152
|
innerActive.value = false
|
|
137
|
-
await nextTick()
|
|
138
|
-
wrapperActive.value = false
|
|
139
153
|
}
|
|
140
154
|
|
|
141
155
|
watch(
|
|
@@ -149,9 +163,58 @@ watch(
|
|
|
149
163
|
}
|
|
150
164
|
)
|
|
151
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
|
+
|
|
184
|
+
watch(isInsideTriangle, (value) => {
|
|
185
|
+
if (value) {
|
|
186
|
+
disableCursor()
|
|
187
|
+
} else {
|
|
188
|
+
enableCursor()
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
watch(isInsideTo, (value) => {
|
|
193
|
+
if (value) {
|
|
194
|
+
enableCursor()
|
|
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) {
|
|
204
|
+
switch (state.options.mode) {
|
|
205
|
+
case 'navigation':
|
|
206
|
+
view!.active = false
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
onBeforeUnmount(() => {
|
|
212
|
+
destroy()
|
|
213
|
+
})
|
|
214
|
+
|
|
152
215
|
provide(MagicMenuContentId, `${viewId}-content`)
|
|
153
216
|
</script>
|
|
154
217
|
|
|
155
218
|
<style>
|
|
156
|
-
.magic-menu-content{-webkit-user-select:none;-moz-user-select:none;user-select:none}.magic-menu-content__inner{border:0;padding:0}.magic-menu-
|
|
219
|
+
.magic-menu-content{-webkit-user-select:none;-moz-user-select:none;user-select:none}.magic-menu-content__inner{border:0;padding:0}.magic-menu-content--initial-enter-active{animation:fade-in 0ms ease}.magic-menu-content--final-leave-active{animation:fade-out .2s ease}.magic-menu-content--nested-enter-active{animation:fade-in .3s ease}
|
|
157
220
|
</style>
|
|
@@ -161,7 +161,7 @@ const mappedReferenceEl = computed(() => {
|
|
|
161
161
|
},
|
|
162
162
|
}
|
|
163
163
|
} else {
|
|
164
|
-
return
|
|
164
|
+
return document.querySelector(`[data-id="${viewId}-trigger"]`)
|
|
165
165
|
}
|
|
166
166
|
})
|
|
167
167
|
|
|
@@ -221,5 +221,5 @@ const polygonPoints = computed(() => {
|
|
|
221
221
|
</script>
|
|
222
222
|
|
|
223
223
|
<style>
|
|
224
|
-
.magic-menu-float{display:flex
|
|
224
|
+
.magic-menu-float{display:flex}.magic-menu-float.-top{flex-direction:column-reverse}.magic-menu-float.-bottom{flex-direction:column}.magic-menu-float.-left{flex-direction:row-reverse}.magic-menu-float.-right{flex-direction:row}.magic-menu-float__arrow{color:var(--magic-menu-float-arrow-color,inherit);height:var(--magic-menu-float-arrow-height,.75rem);width:var(--magic-menu-float-arrow-width,.75rem)}.magic-menu-float__arrow svg{height:100%;width:100%}
|
|
225
225
|
</style>
|
|
@@ -53,7 +53,6 @@ if (!viewId) {
|
|
|
53
53
|
if (!contentId) {
|
|
54
54
|
throw new Error('MagicMenuItem must be nested inside MagicMenuContent')
|
|
55
55
|
}
|
|
56
|
-
|
|
57
56
|
const mappedId = computed(() => props.id ?? `magic-menu-item-${uuid()}`)
|
|
58
57
|
|
|
59
58
|
// Register item
|
|
@@ -93,7 +92,7 @@ function guardedUnselect() {
|
|
|
93
92
|
unselectItem(mappedId.value)
|
|
94
93
|
} else {
|
|
95
94
|
// If there is a nested active view,
|
|
96
|
-
//
|
|
95
|
+
// unselect the item once it is closed
|
|
97
96
|
watch(
|
|
98
97
|
() => nestedView.value?.active,
|
|
99
98
|
(value) => {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script lang="ts" setup>
|
|
14
|
-
import { computed, inject } from 'vue'
|
|
14
|
+
import { computed, inject, watch } from 'vue'
|
|
15
15
|
import { useMenuView } from '../composables/private/useMenuView'
|
|
16
16
|
import { useMenuChannel } from '../composables/private/useMenuChannel'
|
|
17
17
|
import { MagicMenuInstanceId, MagicMenuViewId } from '../symbols'
|
|
@@ -56,11 +56,11 @@ const mappedTrigger = computed<Interaction[]>(
|
|
|
56
56
|
const { getView } = useMenuView(instanceId)
|
|
57
57
|
const view = getView(viewId)
|
|
58
58
|
|
|
59
|
-
const {
|
|
59
|
+
const { initializeChannel, deleteChannel } = useMenuChannel({
|
|
60
60
|
instanceId,
|
|
61
61
|
viewId,
|
|
62
62
|
})
|
|
63
|
-
|
|
63
|
+
let channel = initializeChannel({ id: mappedChannelId.value })
|
|
64
64
|
|
|
65
65
|
const { onClick, onMouseenter } = useMenuRemote({
|
|
66
66
|
viewId,
|
|
@@ -68,6 +68,15 @@ const { onClick, onMouseenter } = useMenuRemote({
|
|
|
68
68
|
mappedChannelId,
|
|
69
69
|
mappedTrigger,
|
|
70
70
|
})
|
|
71
|
+
|
|
72
|
+
watch(
|
|
73
|
+
() => view?.active,
|
|
74
|
+
() => {
|
|
75
|
+
// Reset if parent view changes
|
|
76
|
+
deleteChannel(mappedChannelId.value)
|
|
77
|
+
channel = initializeChannel({ id: mappedChannelId.value })
|
|
78
|
+
}
|
|
79
|
+
)
|
|
71
80
|
</script>
|
|
72
81
|
|
|
73
82
|
<style>
|
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
@click="onClick"
|
|
9
9
|
@contextmenu="onClick"
|
|
10
10
|
@mouseenter="onMouseenter"
|
|
11
|
-
@mouseleave="onMouseleave"
|
|
12
11
|
>
|
|
13
12
|
<slot :is-active="view?.active" :is-disabled="mappedDisabled" />
|
|
14
13
|
</div>
|
|
15
14
|
</template>
|
|
16
15
|
|
|
17
16
|
<script lang="ts" setup>
|
|
18
|
-
import { computed, inject, onBeforeUnmount, ref, watch } from 'vue'
|
|
17
|
+
import { computed, inject, onBeforeUnmount, ref, toValue, watch } from 'vue'
|
|
19
18
|
import { useMenuState } from '../composables/private/useMenuState'
|
|
20
19
|
import { useMenuView } from '../composables/private/useMenuView'
|
|
21
20
|
import { useMenuItem } from '../composables/private/useMenuItem'
|
|
@@ -27,6 +26,7 @@ import {
|
|
|
27
26
|
} from '../symbols'
|
|
28
27
|
|
|
29
28
|
import type { Interaction } from '../types'
|
|
29
|
+
import { onKeyStroke } from '@vueuse/core'
|
|
30
30
|
|
|
31
31
|
interface MagicMenuTriggerProps {
|
|
32
32
|
disabled?: boolean
|
|
@@ -68,20 +68,16 @@ const mappedTrigger = computed<Interaction[]>(() => {
|
|
|
68
68
|
switch (state.options.mode) {
|
|
69
69
|
case 'menubar':
|
|
70
70
|
return view?.parent.item
|
|
71
|
-
? ['mouseenter', '
|
|
71
|
+
? ['mouseenter', 'click']
|
|
72
72
|
: state.active
|
|
73
73
|
? ['mouseenter', 'click']
|
|
74
74
|
: ['click']
|
|
75
75
|
case 'dropdown':
|
|
76
|
-
return view?.parent.item
|
|
77
|
-
? ['mouseenter', 'mouseleave', 'click']
|
|
78
|
-
: ['click']
|
|
76
|
+
return view?.parent.item ? ['mouseenter', 'click'] : ['click']
|
|
79
77
|
case 'context':
|
|
80
|
-
return view?.parent.item
|
|
81
|
-
? ['mouseenter', 'mouseleave', 'click']
|
|
82
|
-
: ['right-click']
|
|
78
|
+
return view?.parent.item ? ['mouseenter', 'click'] : ['right-click']
|
|
83
79
|
case 'navigation':
|
|
84
|
-
return ['mouseenter'
|
|
80
|
+
return ['mouseenter']
|
|
85
81
|
}
|
|
86
82
|
})
|
|
87
83
|
|
|
@@ -93,32 +89,26 @@ const mappedTabindex = computed(() => {
|
|
|
93
89
|
}
|
|
94
90
|
})
|
|
95
91
|
|
|
96
|
-
const {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
// Initialize watcher
|
|
107
|
-
initialize()
|
|
92
|
+
const { onMouseenter, onClick, onEnter } = useMenuTrigger({
|
|
93
|
+
instanceId,
|
|
94
|
+
viewId,
|
|
95
|
+
itemId,
|
|
96
|
+
mappedDisabled,
|
|
97
|
+
mappedTrigger,
|
|
98
|
+
elRef,
|
|
99
|
+
})
|
|
108
100
|
|
|
109
101
|
watch(
|
|
110
|
-
|
|
111
|
-
(value) => {
|
|
112
|
-
if (
|
|
113
|
-
|
|
102
|
+
() => view?.active,
|
|
103
|
+
async (value) => {
|
|
104
|
+
if (value) {
|
|
105
|
+
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
106
|
+
toValue(elRef)?.blur()
|
|
114
107
|
}
|
|
115
|
-
}
|
|
116
|
-
{ immediate: true }
|
|
108
|
+
}
|
|
117
109
|
)
|
|
118
110
|
|
|
119
|
-
|
|
120
|
-
destroy()
|
|
121
|
-
})
|
|
111
|
+
onKeyStroke('Enter', onEnter)
|
|
122
112
|
</script>
|
|
123
113
|
|
|
124
114
|
<style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MaybeRef } from 'vue';
|
|
1
|
+
import { type MaybeRef, type Ref } from 'vue';
|
|
2
2
|
import type { MenuState } from '../../types.js';
|
|
3
3
|
type UseMenuCallbackArgs = {
|
|
4
4
|
state: MenuState;
|
|
@@ -6,6 +6,7 @@ type UseMenuCallbackArgs = {
|
|
|
6
6
|
viewId: string;
|
|
7
7
|
lockScroll: () => void;
|
|
8
8
|
unlockScroll: () => void;
|
|
9
|
+
wrapperActive: Ref<boolean>;
|
|
9
10
|
};
|
|
10
11
|
export declare function useMenuCallback(args: UseMenuCallbackArgs): {
|
|
11
12
|
onBeforeEnter: (_el: Element) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toValue } from "vue";
|
|
2
2
|
import { useMagicEmitter } from "@maas/vue-equipment/plugins";
|
|
3
3
|
export function useMenuCallback(args) {
|
|
4
|
-
const { state, instanceId, viewId, lockScroll, unlockScroll } = args;
|
|
4
|
+
const { state, instanceId, viewId, lockScroll, unlockScroll, wrapperActive } = args;
|
|
5
5
|
const emitter = useMagicEmitter();
|
|
6
6
|
function onBeforeEnter(_el) {
|
|
7
7
|
emitter.emit("beforeEnter", { id: toValue(instanceId), view: viewId });
|
|
@@ -44,6 +44,7 @@ export function useMenuCallback(args) {
|
|
|
44
44
|
unlockScroll();
|
|
45
45
|
break;
|
|
46
46
|
}
|
|
47
|
+
wrapperActive.value = false;
|
|
47
48
|
}
|
|
48
49
|
return {
|
|
49
50
|
onBeforeEnter,
|
|
@@ -7,9 +7,6 @@ export function useMenuChannel(args) {
|
|
|
7
7
|
const state = initializeState();
|
|
8
8
|
const { getView } = useMenuView(instanceId);
|
|
9
9
|
const view = getView(viewId);
|
|
10
|
-
if (!view) {
|
|
11
|
-
throw new Error(`View ${viewId} not found`);
|
|
12
|
-
}
|
|
13
10
|
function createChannel(args2) {
|
|
14
11
|
const { id } = args2;
|
|
15
12
|
const channel = {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { MenuView } from '../../types.js';
|
|
2
|
+
export declare function useMenuCursor(view: MenuView): {
|
|
3
|
+
coords: import("vue").Ref<{
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
}[]>;
|
|
7
|
+
isInsideFrom: import("vue").Ref<boolean>;
|
|
8
|
+
isInsideTo: import("vue").Ref<boolean>;
|
|
9
|
+
isInsideTriangle: import("vue").Ref<boolean>;
|
|
10
|
+
initialize: () => void;
|
|
11
|
+
destroy: () => void;
|
|
12
|
+
};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
import { useEventListener } from "@vueuse/core";
|
|
3
|
+
export function useMenuCursor(view) {
|
|
4
|
+
let cancelListener = new AbortController();
|
|
5
|
+
const coords = ref([
|
|
6
|
+
{ x: 0, y: 0 },
|
|
7
|
+
{ x: 0, y: 0 },
|
|
8
|
+
{ x: 0, y: 0 }
|
|
9
|
+
]);
|
|
10
|
+
const isInsideFrom = ref(false);
|
|
11
|
+
const isInsideTo = ref(false);
|
|
12
|
+
const isInsideTriangle = ref(false);
|
|
13
|
+
function extendTriangle(vertices, pixelAmount) {
|
|
14
|
+
const [a, b, c] = vertices;
|
|
15
|
+
switch (view?.placement) {
|
|
16
|
+
case "bottom":
|
|
17
|
+
case "bottom-start":
|
|
18
|
+
case "bottom-end":
|
|
19
|
+
case "top":
|
|
20
|
+
case "top-start":
|
|
21
|
+
case "top-end":
|
|
22
|
+
switch (true) {
|
|
23
|
+
case (a.y < b.y && a.y < c.y):
|
|
24
|
+
b.y += pixelAmount;
|
|
25
|
+
b.x -= pixelAmount;
|
|
26
|
+
c.y += pixelAmount;
|
|
27
|
+
c.x += pixelAmount;
|
|
28
|
+
break;
|
|
29
|
+
case (a.y > b.y && a.y > c.y):
|
|
30
|
+
b.y -= pixelAmount;
|
|
31
|
+
b.x -= pixelAmount;
|
|
32
|
+
c.y -= pixelAmount;
|
|
33
|
+
c.x += pixelAmount;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
case "right":
|
|
38
|
+
case "right-start":
|
|
39
|
+
case "right-end":
|
|
40
|
+
case "left":
|
|
41
|
+
case "left-start":
|
|
42
|
+
case "left-end":
|
|
43
|
+
switch (true) {
|
|
44
|
+
case (a.x < b.x && a.x < c.x):
|
|
45
|
+
b.x += pixelAmount;
|
|
46
|
+
b.y -= pixelAmount;
|
|
47
|
+
c.x += pixelAmount;
|
|
48
|
+
c.y += pixelAmount;
|
|
49
|
+
break;
|
|
50
|
+
case (a.x > b.x && a.x > c.x):
|
|
51
|
+
b.x -= pixelAmount;
|
|
52
|
+
b.y -= pixelAmount;
|
|
53
|
+
c.x -= pixelAmount;
|
|
54
|
+
c.y += pixelAmount;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
coords.value = [a, b, c];
|
|
60
|
+
return [a, b, c];
|
|
61
|
+
}
|
|
62
|
+
function isPointInTriangle(args) {
|
|
63
|
+
const { p, a, b, c } = args;
|
|
64
|
+
const v0 = { x: c.x - a.x, y: c.y - a.y };
|
|
65
|
+
const v1 = { x: b.x - a.x, y: b.y - a.y };
|
|
66
|
+
const v2 = { x: p.x - a.x, y: p.y - a.y };
|
|
67
|
+
const dot00 = v0.x * v0.x + v0.y * v0.y;
|
|
68
|
+
const dot01 = v0.x * v1.x + v0.y * v1.y;
|
|
69
|
+
const dot02 = v0.x * v2.x + v0.y * v2.y;
|
|
70
|
+
const dot11 = v1.x * v1.x + v1.y * v1.y;
|
|
71
|
+
const dot12 = v1.x * v2.x + v1.y * v2.y;
|
|
72
|
+
const invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
|
73
|
+
const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
74
|
+
const v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
75
|
+
return u >= 0 && v >= 0 && u + v <= 1;
|
|
76
|
+
}
|
|
77
|
+
function isPointInRectangle(args) {
|
|
78
|
+
const { p, top, left, bottom, right } = args;
|
|
79
|
+
return p.x >= left && p.x <= right && p.y >= top && p.y <= bottom;
|
|
80
|
+
}
|
|
81
|
+
function triangleOverlap(cursor, fromBounding, toBounding) {
|
|
82
|
+
const { top, left, bottom, right } = toBounding;
|
|
83
|
+
const centerPoint = view.click ? view.click : {
|
|
84
|
+
x: (fromBounding.left + fromBounding.right) / 2,
|
|
85
|
+
y: (fromBounding.top + fromBounding.bottom) / 2
|
|
86
|
+
};
|
|
87
|
+
const sidePoints = [];
|
|
88
|
+
switch (view.placement) {
|
|
89
|
+
case "top":
|
|
90
|
+
case "top-start":
|
|
91
|
+
case "top-end":
|
|
92
|
+
case "bottom":
|
|
93
|
+
case "bottom-start":
|
|
94
|
+
case "bottom-end":
|
|
95
|
+
const topDist = Math.abs(top - centerPoint.y);
|
|
96
|
+
const bottomDist = Math.abs(bottom - centerPoint.y);
|
|
97
|
+
const mappedY = topDist < bottomDist ? top : bottom;
|
|
98
|
+
sidePoints.push({ x: left, y: mappedY });
|
|
99
|
+
sidePoints.push({ x: right, y: mappedY });
|
|
100
|
+
break;
|
|
101
|
+
case "right":
|
|
102
|
+
case "right-start":
|
|
103
|
+
case "right-end":
|
|
104
|
+
case "left":
|
|
105
|
+
case "left-start":
|
|
106
|
+
case "left-end":
|
|
107
|
+
const rightDist = Math.abs(right - centerPoint.x);
|
|
108
|
+
const leftDist = Math.abs(left - centerPoint.x);
|
|
109
|
+
const mappedX = rightDist < leftDist ? right : left;
|
|
110
|
+
sidePoints.push({ x: mappedX, y: top });
|
|
111
|
+
sidePoints.push({ x: mappedX, y: bottom });
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
const [a, b, c] = extendTriangle(
|
|
115
|
+
[centerPoint, sidePoints[0], sidePoints[1]],
|
|
116
|
+
16
|
|
117
|
+
);
|
|
118
|
+
return isPointInTriangle({
|
|
119
|
+
p: cursor,
|
|
120
|
+
a,
|
|
121
|
+
b,
|
|
122
|
+
c
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function elementOverlap(cursor, bounding) {
|
|
126
|
+
const { top, left, bottom, right } = bounding;
|
|
127
|
+
return isPointInRectangle({
|
|
128
|
+
p: cursor,
|
|
129
|
+
top,
|
|
130
|
+
left,
|
|
131
|
+
bottom,
|
|
132
|
+
right
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function onMousemove(e) {
|
|
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
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function initialize() {
|
|
152
|
+
cancelListener.abort();
|
|
153
|
+
cancelListener = new AbortController();
|
|
154
|
+
useEventListener(document, "mousemove", onMousemove, {
|
|
155
|
+
signal: cancelListener.signal
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function destroy() {
|
|
159
|
+
coords.value = [];
|
|
160
|
+
isInsideFrom.value = false;
|
|
161
|
+
isInsideTo.value = false;
|
|
162
|
+
isInsideTriangle.value = false;
|
|
163
|
+
cancelListener.abort();
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
coords,
|
|
167
|
+
isInsideFrom,
|
|
168
|
+
isInsideTo,
|
|
169
|
+
isInsideTriangle,
|
|
170
|
+
initialize,
|
|
171
|
+
destroy
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -5,7 +5,7 @@ export function useMenuItem(args) {
|
|
|
5
5
|
const { instanceId, viewId } = args;
|
|
6
6
|
const { initializeState } = useMenuState(instanceId);
|
|
7
7
|
const state = initializeState();
|
|
8
|
-
const { getView,
|
|
8
|
+
const { getView, unselectDescendingViews } = useMenuView(instanceId);
|
|
9
9
|
const view = getView(viewId);
|
|
10
10
|
if (!view) {
|
|
11
11
|
throw new Error(`View ${viewId} not found`);
|
|
@@ -53,7 +53,7 @@ export function useMenuItem(args) {
|
|
|
53
53
|
if (instance) {
|
|
54
54
|
instance.active = true;
|
|
55
55
|
unselectSiblings(id);
|
|
56
|
-
|
|
56
|
+
unselectDescendingViews(viewId);
|
|
57
57
|
if (view) {
|
|
58
58
|
state.input.view = view.id;
|
|
59
59
|
}
|
|
@@ -7,7 +7,7 @@ export function useMenuKeyListener(instanceId) {
|
|
|
7
7
|
const {
|
|
8
8
|
selectView,
|
|
9
9
|
unselectView,
|
|
10
|
-
|
|
10
|
+
unselectUnrelatedViews,
|
|
11
11
|
unselectAllViews,
|
|
12
12
|
getView,
|
|
13
13
|
getNextView,
|
|
@@ -101,11 +101,11 @@ export function useMenuKeyListener(instanceId) {
|
|
|
101
101
|
if (prevIndex >= 0) {
|
|
102
102
|
const { selectItem } = useMenuItem({ instanceId, viewId });
|
|
103
103
|
selectItem(enabledItems[prevIndex]?.id);
|
|
104
|
-
|
|
104
|
+
unselectUnrelatedViews(viewId);
|
|
105
105
|
} else if (prevIndex !== -1) {
|
|
106
106
|
const { selectItem } = useMenuItem({ instanceId, viewId });
|
|
107
107
|
selectItem(enabledItems[enabledItems.length - 1]?.id);
|
|
108
|
-
|
|
108
|
+
unselectUnrelatedViews(viewId);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
function onArrowDown(e) {
|
|
@@ -125,7 +125,7 @@ export function useMenuKeyListener(instanceId) {
|
|
|
125
125
|
if (nextIndex >= 0) {
|
|
126
126
|
const { selectItem } = useMenuItem({ instanceId, viewId });
|
|
127
127
|
selectItem(enabledItems[nextIndex]?.id);
|
|
128
|
-
|
|
128
|
+
unselectUnrelatedViews(viewId);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
function onEscape(e) {
|
|
@@ -11,8 +11,6 @@ type UseMenuTriggerArgs = {
|
|
|
11
11
|
export declare function useMenuTrigger(args: UseMenuTriggerArgs): {
|
|
12
12
|
onMouseenter: () => void;
|
|
13
13
|
onClick: (e: MouseEvent) => void;
|
|
14
|
-
|
|
15
|
-
initialize: () => void;
|
|
16
|
-
destroy: () => void;
|
|
14
|
+
onEnter: (e: KeyboardEvent) => void;
|
|
17
15
|
};
|
|
18
16
|
export {};
|
|
@@ -1,139 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ref,
|
|
3
|
-
computed,
|
|
4
|
-
watch,
|
|
5
|
-
toValue
|
|
6
|
-
} from "vue";
|
|
7
|
-
import {
|
|
8
|
-
useEventListener,
|
|
9
|
-
useElementBounding,
|
|
10
|
-
useMagicKeys,
|
|
11
|
-
useFocus,
|
|
12
|
-
onKeyStroke
|
|
13
|
-
} from "@vueuse/core";
|
|
1
|
+
import { useMagicKeys, useFocus } from "@vueuse/core";
|
|
14
2
|
import { useMenuView } from "./useMenuView.mjs";
|
|
15
3
|
import { useMenuState } from "./useMenuState.mjs";
|
|
16
4
|
export function useMenuTrigger(args) {
|
|
17
5
|
const { instanceId, viewId, itemId, mappedTrigger, mappedDisabled, elRef } = args;
|
|
18
|
-
let cancelPointermove = void 0;
|
|
19
|
-
const mouseleaveCoordinates = ref(void 0);
|
|
20
6
|
const { getView, selectView, unselectView } = useMenuView(instanceId);
|
|
21
7
|
const view = getView(viewId);
|
|
22
8
|
const { initializeState } = useMenuState(instanceId);
|
|
23
9
|
const state = initializeState();
|
|
24
10
|
const { focused } = useFocus(elRef);
|
|
25
|
-
const isInsideTriangle = ref(false);
|
|
26
|
-
const isInsideTrigger = ref(false);
|
|
27
|
-
const isInsideContent = ref(false);
|
|
28
|
-
const isOutside = computed(() => {
|
|
29
|
-
return !isInsideTrigger.value && !isInsideContent.value && !isInsideTriangle.value;
|
|
30
|
-
});
|
|
31
11
|
const { shift, control } = useMagicKeys();
|
|
32
|
-
function resetState() {
|
|
33
|
-
mouseleaveCoordinates.value = void 0;
|
|
34
|
-
isInsideTriangle.value = false;
|
|
35
|
-
}
|
|
36
|
-
function disableCursor() {
|
|
37
|
-
state.input.disabled = [...state.input.disabled, "pointer"];
|
|
38
|
-
}
|
|
39
|
-
function enableCursor() {
|
|
40
|
-
state.input.disabled = state.input.disabled.filter((x) => x !== "pointer");
|
|
41
|
-
}
|
|
42
|
-
function extendTriangle(vertices, pixelAmount) {
|
|
43
|
-
const centroid = {
|
|
44
|
-
x: (vertices[0].x + vertices[1].x + vertices[2].x) / 3,
|
|
45
|
-
y: (vertices[0].y + vertices[1].y + vertices[2].y) / 3
|
|
46
|
-
};
|
|
47
|
-
function extendPoint(vertex) {
|
|
48
|
-
const dir = {
|
|
49
|
-
x: vertex.x - centroid.x,
|
|
50
|
-
y: vertex.y - centroid.y
|
|
51
|
-
};
|
|
52
|
-
const distance = Math.sqrt(dir.x * dir.x + dir.y * dir.y);
|
|
53
|
-
const unitDir = {
|
|
54
|
-
x: dir.x / distance,
|
|
55
|
-
y: dir.y / distance
|
|
56
|
-
};
|
|
57
|
-
const scaledDir = {
|
|
58
|
-
x: unitDir.x * pixelAmount,
|
|
59
|
-
y: unitDir.y * pixelAmount
|
|
60
|
-
};
|
|
61
|
-
return {
|
|
62
|
-
x: vertex.x + scaledDir.x,
|
|
63
|
-
y: vertex.y + scaledDir.y
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
return [
|
|
67
|
-
extendPoint(vertices[0]),
|
|
68
|
-
extendPoint(vertices[1]),
|
|
69
|
-
extendPoint(vertices[2])
|
|
70
|
-
];
|
|
71
|
-
}
|
|
72
|
-
function isPointInTriangle(args2) {
|
|
73
|
-
const { p, a, b, c } = args2;
|
|
74
|
-
const v0 = { x: c.x - a.x, y: c.y - a.y };
|
|
75
|
-
const v1 = { x: b.x - a.x, y: b.y - a.y };
|
|
76
|
-
const v2 = { x: p.x - a.x, y: p.y - a.y };
|
|
77
|
-
const dot00 = v0.x * v0.x + v0.y * v0.y;
|
|
78
|
-
const dot01 = v0.x * v1.x + v0.y * v1.y;
|
|
79
|
-
const dot02 = v0.x * v2.x + v0.y * v2.y;
|
|
80
|
-
const dot11 = v1.x * v1.x + v1.y * v1.y;
|
|
81
|
-
const dot12 = v1.x * v2.x + v1.y * v2.y;
|
|
82
|
-
const invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
|
83
|
-
const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
84
|
-
const v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
85
|
-
return u >= 0 && v >= 0 && u + v <= 1;
|
|
86
|
-
}
|
|
87
|
-
function isPointInRectangle(args2) {
|
|
88
|
-
const { p, top, left, bottom, right } = args2;
|
|
89
|
-
return p.x >= left && p.x <= right && p.y >= top && p.y <= bottom;
|
|
90
|
-
}
|
|
91
|
-
async function onPointermove(e) {
|
|
92
|
-
if (!mouseleaveCoordinates.value || !view?.children.content) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const mouseCoordinates = { x: e.clientX, y: e.clientY };
|
|
96
|
-
const { top, left, bottom, right } = useElementBounding(
|
|
97
|
-
view.children.content
|
|
98
|
-
);
|
|
99
|
-
const {
|
|
100
|
-
top: topTrigger,
|
|
101
|
-
left: leftTrigger,
|
|
102
|
-
bottom: bottomTrigger,
|
|
103
|
-
right: rightTrigger
|
|
104
|
-
} = useElementBounding(elRef);
|
|
105
|
-
const rightDistance = Math.abs(right.value - mouseleaveCoordinates.value.x);
|
|
106
|
-
const leftDistance = Math.abs(left.value - mouseleaveCoordinates.value.x);
|
|
107
|
-
const mappedX = rightDistance < leftDistance ? right : left;
|
|
108
|
-
const [a, b, c] = extendTriangle(
|
|
109
|
-
[
|
|
110
|
-
mouseleaveCoordinates.value,
|
|
111
|
-
{ x: mappedX.value, y: top.value },
|
|
112
|
-
{ x: mappedX.value, y: bottom.value }
|
|
113
|
-
],
|
|
114
|
-
16
|
|
115
|
-
);
|
|
116
|
-
isInsideTriangle.value = isPointInTriangle({
|
|
117
|
-
p: mouseCoordinates,
|
|
118
|
-
a,
|
|
119
|
-
b,
|
|
120
|
-
c
|
|
121
|
-
});
|
|
122
|
-
isInsideContent.value = isPointInRectangle({
|
|
123
|
-
p: mouseCoordinates,
|
|
124
|
-
top: top.value,
|
|
125
|
-
left: left.value,
|
|
126
|
-
bottom: bottom.value,
|
|
127
|
-
right: right.value
|
|
128
|
-
});
|
|
129
|
-
isInsideTrigger.value = isPointInRectangle({
|
|
130
|
-
p: mouseCoordinates,
|
|
131
|
-
top: topTrigger.value,
|
|
132
|
-
left: leftTrigger.value,
|
|
133
|
-
bottom: bottomTrigger.value,
|
|
134
|
-
right: rightTrigger.value
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
12
|
function onRightClick(e) {
|
|
138
13
|
switch (e.button) {
|
|
139
14
|
case 2:
|
|
@@ -162,8 +37,6 @@ export function useMenuTrigger(args) {
|
|
|
162
37
|
}
|
|
163
38
|
}
|
|
164
39
|
function onMouseenter() {
|
|
165
|
-
cancelPointermove?.();
|
|
166
|
-
resetState();
|
|
167
40
|
if (mappedTrigger.value.includes("mouseenter") && !mappedDisabled.value && viewId && view) {
|
|
168
41
|
if (mappedTrigger.value[0].includes("mouseenter")) {
|
|
169
42
|
state.active = true;
|
|
@@ -173,9 +46,6 @@ export function useMenuTrigger(args) {
|
|
|
173
46
|
if (!itemId) {
|
|
174
47
|
state.input.view = viewId;
|
|
175
48
|
}
|
|
176
|
-
if (itemId) {
|
|
177
|
-
disableCursor();
|
|
178
|
-
}
|
|
179
49
|
}
|
|
180
50
|
}
|
|
181
51
|
}
|
|
@@ -211,57 +81,9 @@ export function useMenuTrigger(args) {
|
|
|
211
81
|
}
|
|
212
82
|
}
|
|
213
83
|
}
|
|
214
|
-
function onMouseleave(e) {
|
|
215
|
-
if (mappedTrigger.value.includes("mouseleave") && viewId) {
|
|
216
|
-
mouseleaveCoordinates.value = { x: e.clientX, y: e.clientY };
|
|
217
|
-
cancelPointermove = useEventListener("pointermove", onPointermove);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
function initialize() {
|
|
221
|
-
watch(
|
|
222
|
-
() => view?.active,
|
|
223
|
-
async (value) => {
|
|
224
|
-
if (value) {
|
|
225
|
-
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
226
|
-
toValue(elRef)?.blur();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
);
|
|
230
|
-
watch(isInsideTriangle, async (value, oldValue) => {
|
|
231
|
-
if (value && !oldValue) {
|
|
232
|
-
disableCursor();
|
|
233
|
-
} else if (!value && oldValue) {
|
|
234
|
-
enableCursor();
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
watch(isInsideContent, (value, oldValue) => {
|
|
238
|
-
if (value && !oldValue) {
|
|
239
|
-
cancelPointermove?.();
|
|
240
|
-
resetState();
|
|
241
|
-
enableCursor();
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
watch(isOutside, (value, oldValue) => {
|
|
245
|
-
if (!cancelPointermove) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (value && !oldValue) {
|
|
249
|
-
unselectView(viewId);
|
|
250
|
-
cancelPointermove();
|
|
251
|
-
enableCursor();
|
|
252
|
-
resetState();
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
onKeyStroke("Enter", onEnter);
|
|
256
|
-
}
|
|
257
|
-
function destroy() {
|
|
258
|
-
cancelPointermove?.();
|
|
259
|
-
}
|
|
260
84
|
return {
|
|
261
85
|
onMouseenter,
|
|
262
86
|
onClick,
|
|
263
|
-
|
|
264
|
-
initialize,
|
|
265
|
-
destroy
|
|
87
|
+
onEnter
|
|
266
88
|
};
|
|
267
89
|
}
|
|
@@ -14,7 +14,8 @@ export declare function useMenuView(instanceId: MaybeRef<string>): {
|
|
|
14
14
|
getParentView: (id: string) => MenuView | undefined;
|
|
15
15
|
selectView: (id: string) => void;
|
|
16
16
|
unselectView: (id: string) => void;
|
|
17
|
-
|
|
17
|
+
unselectUnrelatedViews: (id: string) => void;
|
|
18
|
+
unselectDescendingViews: (id: string) => void;
|
|
18
19
|
unselectAllViews: () => void;
|
|
19
20
|
};
|
|
20
21
|
export {};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
reactive,
|
|
3
|
+
computed,
|
|
4
|
+
toValue
|
|
5
|
+
} from "vue";
|
|
2
6
|
import { useMenuState } from "./useMenuState.mjs";
|
|
3
7
|
export function useMenuView(instanceId) {
|
|
4
8
|
const { initializeState } = useMenuState(instanceId);
|
|
@@ -16,10 +20,6 @@ export function useMenuView(instanceId) {
|
|
|
16
20
|
const view = {
|
|
17
21
|
id,
|
|
18
22
|
parent,
|
|
19
|
-
children: {
|
|
20
|
-
trigger: void 0,
|
|
21
|
-
content: void 0
|
|
22
|
-
},
|
|
23
23
|
active: false,
|
|
24
24
|
items: [],
|
|
25
25
|
channels: [],
|
|
@@ -69,17 +69,23 @@ export function useMenuView(instanceId) {
|
|
|
69
69
|
const parentId = view?.parent.views[view.parent.views.length - 1];
|
|
70
70
|
return getView(parentId ?? "");
|
|
71
71
|
}
|
|
72
|
-
function
|
|
73
|
-
const
|
|
72
|
+
function getUnrelatedViews(id) {
|
|
73
|
+
const argView = getView(id);
|
|
74
74
|
return state.views?.filter(
|
|
75
|
-
(view) => !
|
|
75
|
+
(view) => !view.parent.views.includes(id) && !argView?.parent.views.includes(view.id) && view.id !== id
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function getDescendingViews(id) {
|
|
79
|
+
const argView = getView(id);
|
|
80
|
+
return state.views?.filter(
|
|
81
|
+
(view) => view.id !== id && !argView?.parent.views.includes(view.id)
|
|
76
82
|
);
|
|
77
83
|
}
|
|
78
84
|
function selectView(id) {
|
|
79
85
|
const instance = getView(id);
|
|
80
86
|
if (instance) {
|
|
81
87
|
instance.active = true;
|
|
82
|
-
|
|
88
|
+
unselectUnrelatedViews(id);
|
|
83
89
|
}
|
|
84
90
|
}
|
|
85
91
|
function unselectView(id) {
|
|
@@ -88,9 +94,13 @@ export function useMenuView(instanceId) {
|
|
|
88
94
|
instance.active = false;
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
|
-
function
|
|
92
|
-
const
|
|
93
|
-
|
|
97
|
+
function unselectUnrelatedViews(id) {
|
|
98
|
+
const unrelatedViews = getUnrelatedViews(id);
|
|
99
|
+
unrelatedViews.forEach((view) => view.active = false);
|
|
100
|
+
}
|
|
101
|
+
function unselectDescendingViews(id) {
|
|
102
|
+
const descendingViews = getDescendingViews(id);
|
|
103
|
+
descendingViews.forEach((view) => view.active = false);
|
|
94
104
|
}
|
|
95
105
|
function unselectAllViews() {
|
|
96
106
|
state.views?.forEach((view) => {
|
|
@@ -110,7 +120,8 @@ export function useMenuView(instanceId) {
|
|
|
110
120
|
getParentView,
|
|
111
121
|
selectView,
|
|
112
122
|
unselectView,
|
|
113
|
-
|
|
123
|
+
unselectUnrelatedViews,
|
|
124
|
+
unselectDescendingViews,
|
|
114
125
|
unselectAllViews
|
|
115
126
|
};
|
|
116
127
|
}
|
|
@@ -9,7 +9,7 @@ export interface MagicMenuOptions {
|
|
|
9
9
|
nested?: string;
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
export type Interaction = 'click' | 'mouseenter' | '
|
|
12
|
+
export type Interaction = 'click' | 'mouseenter' | 'right-click';
|
|
13
13
|
export type Coordinates = {
|
|
14
14
|
x: number;
|
|
15
15
|
y: number;
|
|
@@ -32,10 +32,6 @@ export interface MenuView {
|
|
|
32
32
|
item: string;
|
|
33
33
|
views: string[];
|
|
34
34
|
};
|
|
35
|
-
children: {
|
|
36
|
-
trigger?: HTMLElement;
|
|
37
|
-
content?: HTMLElement;
|
|
38
|
-
};
|
|
39
35
|
placement: Placement;
|
|
40
36
|
click?: Coordinates;
|
|
41
37
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const defaultOptions = {
|
|
2
2
|
mode: "menubar",
|
|
3
3
|
transition: {
|
|
4
|
-
initial: "magic-menu-
|
|
5
|
-
final: "magic-menu-
|
|
6
|
-
nested: "magic-menu-
|
|
4
|
+
initial: "magic-menu-content--initial",
|
|
5
|
+
final: "magic-menu-content--final",
|
|
6
|
+
nested: "magic-menu-content--nested"
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
9
|
export { defaultOptions };
|
|
@@ -24,7 +24,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
24
24
|
loop: boolean;
|
|
25
25
|
srcType: MagicPlayerSourceType;
|
|
26
26
|
autoplay: boolean;
|
|
27
|
-
preload: "metadata" | "
|
|
27
|
+
preload: "metadata" | "none" | "auto";
|
|
28
28
|
}, {}>, {
|
|
29
29
|
default?(_: {}): any;
|
|
30
30
|
}>;
|
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",
|