@maas/vue-equipment 0.21.6 → 0.22.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/nuxt/module.json +1 -1
- package/dist/nuxt/module.mjs +7 -0
- package/dist/plugins/MagicCommand/demo/DefaultView.vue +57 -0
- package/dist/plugins/MagicCommand/demo/DefaultView.vue.d.ts +2 -0
- package/dist/plugins/MagicCommand/demo/DemoItem.vue +18 -0
- package/dist/plugins/MagicCommand/demo/DemoItem.vue.d.ts +21 -0
- package/dist/plugins/MagicCommand/demo/ProjectView.vue +55 -0
- package/dist/plugins/MagicCommand/demo/ProjectView.vue.d.ts +2 -0
- package/dist/plugins/MagicCommand/index.d.ts +8 -0
- package/dist/plugins/MagicCommand/index.mjs +28 -0
- package/dist/plugins/MagicCommand/nuxt.d.ts +0 -0
- package/dist/plugins/MagicCommand/nuxt.mjs +27 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommand.vue +180 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommand.vue.d.ts +43 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandBody.vue +86 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandBody.vue.d.ts +9 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandFooter.vue +5 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandFooter.vue.d.ts +9 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandGroup.vue +5 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandGroup.vue.d.ts +9 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandHead.vue +5 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandHead.vue.d.ts +9 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandItem.vue +91 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandItem.vue.d.ts +44 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandView.vue +49 -0
- package/dist/plugins/MagicCommand/src/components/MagicCommandView.vue.d.ts +36 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandCallback.d.ts +22 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandCallback.mjs +61 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandItem.d.ts +9 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandItem.mjs +54 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandScroll.d.ts +7 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandScroll.mjs +44 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandStore.d.ts +20 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandStore.mjs +48 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandView.d.ts +6 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandView.mjs +25 -0
- package/dist/plugins/MagicCommand/src/composables/useCommandApi.d.ts +21 -0
- package/dist/plugins/MagicCommand/src/composables/useCommandApi.mjs +85 -0
- package/dist/plugins/MagicCommand/src/composables/useCommandEmitter.d.ts +15 -0
- package/dist/plugins/MagicCommand/src/composables/useCommandEmitter.mjs +9 -0
- package/dist/plugins/MagicCommand/src/symbols/index.d.ts +5 -0
- package/dist/plugins/MagicCommand/src/symbols/index.mjs +3 -0
- package/dist/plugins/MagicCommand/src/types/index.d.ts +30 -0
- package/dist/plugins/MagicCommand/src/types/index.mjs +0 -0
- package/dist/plugins/MagicCommand/src/utils/defaultOptions.d.ts +5 -0
- package/dist/plugins/MagicCommand/src/utils/defaultOptions.mjs +23 -0
- package/dist/plugins/MagicDrawer/src/composables/useDrawerApi.mjs +3 -1
- package/dist/plugins/MagicScroll/src/components/MagicScrollMotion.vue +2 -2
- package/dist/plugins/MagicScroll/src/components/MagicScrollMotion.vue.d.ts +2 -2
- package/dist/plugins/MagicScroll/src/components/MagicScrollTransform.vue.d.ts +1 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.mjs +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="magic-command-item"
|
|
4
|
+
ref="elRef"
|
|
5
|
+
:data-id="mappedId"
|
|
6
|
+
:aria-selected="isActive"
|
|
7
|
+
>
|
|
8
|
+
<slot :is-active="isActive" />
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts" setup>
|
|
13
|
+
import {
|
|
14
|
+
ref,
|
|
15
|
+
computed,
|
|
16
|
+
inject,
|
|
17
|
+
toValue,
|
|
18
|
+
nextTick,
|
|
19
|
+
onMounted,
|
|
20
|
+
onUnmounted,
|
|
21
|
+
} from 'vue'
|
|
22
|
+
import { useEventListener, onKeyStroke } from '@vueuse/core'
|
|
23
|
+
import { uuid } from '@maas/vue-equipment/utils'
|
|
24
|
+
import { useCommandStore } from '../composables/private/useCommandStore'
|
|
25
|
+
import { useCommandItem } from '../composables/private/useCommandItem'
|
|
26
|
+
import { CommandInstanceId } from '../symbols'
|
|
27
|
+
|
|
28
|
+
interface Props {
|
|
29
|
+
id?: string
|
|
30
|
+
default?: boolean
|
|
31
|
+
callback: Function | false
|
|
32
|
+
listener?: ('click' | 'hover')[]
|
|
33
|
+
keys?: string[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
37
|
+
listener: () => ['click'],
|
|
38
|
+
keys: () => ['Enter'],
|
|
39
|
+
})
|
|
40
|
+
const elRef = ref<HTMLElement | undefined>(undefined)
|
|
41
|
+
|
|
42
|
+
const commandId = inject(CommandInstanceId, '')
|
|
43
|
+
const { selectItem, activeItem } = useCommandItem(commandId)
|
|
44
|
+
|
|
45
|
+
const mappedId = computed(() => {
|
|
46
|
+
return props.id || uuid()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const isActive = computed(() => {
|
|
50
|
+
return toValue(mappedId) === activeItem.value
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
function listenerCallback() {
|
|
54
|
+
selectItem(mappedId.value)
|
|
55
|
+
nextTick(() => {
|
|
56
|
+
if (props.callback) {
|
|
57
|
+
props.callback()
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
useEventListener(elRef, props.listener, listenerCallback)
|
|
63
|
+
|
|
64
|
+
if (props.keys.length) {
|
|
65
|
+
onKeyStroke(props.keys, () => (isActive.value ? listenerCallback() : null))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const { addItem, removeItem } = useCommandStore()
|
|
69
|
+
|
|
70
|
+
onMounted(() => {
|
|
71
|
+
if (toValue(commandId)) {
|
|
72
|
+
addItem(toValue(commandId), mappedId.value)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
nextTick(() => {
|
|
76
|
+
if (props.default) {
|
|
77
|
+
selectItem(mappedId.value)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
onUnmounted(() => {
|
|
83
|
+
if (toValue(commandId)) {
|
|
84
|
+
removeItem(toValue(commandId), mappedId.value)
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<style>
|
|
90
|
+
.magic-command-item{cursor:pointer}
|
|
91
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
id?: string;
|
|
3
|
+
default?: boolean;
|
|
4
|
+
callback: Function | false;
|
|
5
|
+
listener?: ('click' | 'hover')[];
|
|
6
|
+
keys?: string[];
|
|
7
|
+
}
|
|
8
|
+
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
|
|
9
|
+
listener: () => string[];
|
|
10
|
+
keys: () => string[];
|
|
11
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
|
|
12
|
+
listener: () => string[];
|
|
13
|
+
keys: () => string[];
|
|
14
|
+
}>>>, {
|
|
15
|
+
keys: string[];
|
|
16
|
+
listener: ("click" | "hover")[];
|
|
17
|
+
}, {}>, {
|
|
18
|
+
default?(_: {
|
|
19
|
+
isActive: boolean;
|
|
20
|
+
}): any;
|
|
21
|
+
}>;
|
|
22
|
+
export default _default;
|
|
23
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
24
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
25
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
26
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
27
|
+
} : {
|
|
28
|
+
type: import('vue').PropType<T[K]>;
|
|
29
|
+
required: true;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type __VLS_WithDefaults<P, D> = {
|
|
33
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
|
|
34
|
+
default: D[K];
|
|
35
|
+
}> : P[K];
|
|
36
|
+
};
|
|
37
|
+
type __VLS_Prettify<T> = {
|
|
38
|
+
[K in keyof T]: T[K];
|
|
39
|
+
} & {};
|
|
40
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
41
|
+
new (): {
|
|
42
|
+
$slots: S;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="magic-command-view" v-if="isActive">
|
|
3
|
+
<slot />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { computed, inject, toValue, onMounted, onUnmounted } from 'vue'
|
|
9
|
+
import { uuid } from '@maas/vue-equipment/utils'
|
|
10
|
+
import { useCommandStore } from '../composables/private/useCommandStore'
|
|
11
|
+
import { useCommandView } from '../composables/private/useCommandView'
|
|
12
|
+
import { CommandInstanceId } from '../symbols'
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
id?: string
|
|
16
|
+
default?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(defineProps<Props>(), { default: false })
|
|
20
|
+
const commandId = inject(CommandInstanceId, '')
|
|
21
|
+
|
|
22
|
+
const { activeView, selectView } = useCommandView()
|
|
23
|
+
|
|
24
|
+
const mappedId = computed(() => {
|
|
25
|
+
return props.id || uuid()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const isActive = computed(() => {
|
|
29
|
+
return toValue(mappedId) === activeView.value
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const { addView, removeView } = useCommandStore()
|
|
33
|
+
|
|
34
|
+
onMounted(() => {
|
|
35
|
+
if (toValue(commandId)) {
|
|
36
|
+
addView(toValue(commandId), mappedId.value)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (props.default) {
|
|
40
|
+
selectView(mappedId.value)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
onUnmounted(() => {
|
|
45
|
+
if (toValue(commandId)) {
|
|
46
|
+
removeView(toValue(commandId), mappedId.value)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
</script>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
id?: string;
|
|
3
|
+
default?: boolean;
|
|
4
|
+
}
|
|
5
|
+
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
|
|
6
|
+
default: boolean;
|
|
7
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
|
|
8
|
+
default: boolean;
|
|
9
|
+
}>>>, {
|
|
10
|
+
default: boolean;
|
|
11
|
+
}, {}>, {
|
|
12
|
+
default?(_: {}): any;
|
|
13
|
+
}>;
|
|
14
|
+
export default _default;
|
|
15
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
16
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
17
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
18
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
19
|
+
} : {
|
|
20
|
+
type: import('vue').PropType<T[K]>;
|
|
21
|
+
required: true;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
type __VLS_WithDefaults<P, D> = {
|
|
25
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
|
|
26
|
+
default: D[K];
|
|
27
|
+
}> : P[K];
|
|
28
|
+
};
|
|
29
|
+
type __VLS_Prettify<T> = {
|
|
30
|
+
[K in keyof T]: T[K];
|
|
31
|
+
} & {};
|
|
32
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
33
|
+
new (): {
|
|
34
|
+
$slots: S;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Ref, type MaybeRef } from 'vue';
|
|
2
|
+
import type { CommandOptions } from '../../types.js';
|
|
3
|
+
type UseCommandCallbackArgs = {
|
|
4
|
+
id: MaybeRef<string>;
|
|
5
|
+
mappedOptions: CommandOptions;
|
|
6
|
+
addScrollLockPadding: () => void;
|
|
7
|
+
removeScrollLockPadding: () => void;
|
|
8
|
+
lockScroll: () => void;
|
|
9
|
+
unlockScroll: () => void;
|
|
10
|
+
trapFocus: () => void;
|
|
11
|
+
releaseFocus: () => void;
|
|
12
|
+
wrapperActive: Ref<boolean>;
|
|
13
|
+
};
|
|
14
|
+
export declare function useCommandCallback(args: UseCommandCallbackArgs): {
|
|
15
|
+
onBeforeEnter: (_el: Element) => void;
|
|
16
|
+
onEnter: (_el: Element) => void;
|
|
17
|
+
onAfterEnter: (_el: Element) => Promise<void>;
|
|
18
|
+
onBeforeLeave: (_el: Element) => void;
|
|
19
|
+
onLeave: (_el: Element) => void;
|
|
20
|
+
onAfterLeave: (_el: Element) => void;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { toValue, nextTick } from "vue";
|
|
2
|
+
import { useCommandEmitter } from "./../useCommandEmitter.mjs";
|
|
3
|
+
export function useCommandCallback(args) {
|
|
4
|
+
const {
|
|
5
|
+
id,
|
|
6
|
+
mappedOptions,
|
|
7
|
+
addScrollLockPadding,
|
|
8
|
+
removeScrollLockPadding,
|
|
9
|
+
lockScroll,
|
|
10
|
+
unlockScroll,
|
|
11
|
+
trapFocus,
|
|
12
|
+
releaseFocus,
|
|
13
|
+
wrapperActive
|
|
14
|
+
} = args;
|
|
15
|
+
function onBeforeEnter(_el) {
|
|
16
|
+
useCommandEmitter().emit("beforeEnter", toValue(id));
|
|
17
|
+
if (mappedOptions.scrollLock) {
|
|
18
|
+
if (mappedOptions.scrollLockPadding) {
|
|
19
|
+
addScrollLockPadding();
|
|
20
|
+
}
|
|
21
|
+
lockScroll();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function onEnter(_el) {
|
|
25
|
+
useCommandEmitter().emit("enter", toValue(id));
|
|
26
|
+
}
|
|
27
|
+
async function onAfterEnter(_el) {
|
|
28
|
+
useCommandEmitter().emit("afterEnter", toValue(id));
|
|
29
|
+
if (mappedOptions.focusTrap) {
|
|
30
|
+
await nextTick();
|
|
31
|
+
trapFocus();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function onBeforeLeave(_el) {
|
|
35
|
+
useCommandEmitter().emit("beforeLeave", toValue(id));
|
|
36
|
+
}
|
|
37
|
+
function onLeave(_el) {
|
|
38
|
+
useCommandEmitter().emit("leave", toValue(id));
|
|
39
|
+
}
|
|
40
|
+
function onAfterLeave(_el) {
|
|
41
|
+
useCommandEmitter().emit("afterLeave", toValue(id));
|
|
42
|
+
if (mappedOptions.scrollLock) {
|
|
43
|
+
unlockScroll();
|
|
44
|
+
if (mappedOptions.scrollLockPadding) {
|
|
45
|
+
removeScrollLockPadding();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (mappedOptions.focusTrap) {
|
|
49
|
+
releaseFocus();
|
|
50
|
+
}
|
|
51
|
+
wrapperActive.value = false;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
onBeforeEnter,
|
|
55
|
+
onEnter,
|
|
56
|
+
onAfterEnter,
|
|
57
|
+
onBeforeLeave,
|
|
58
|
+
onLeave,
|
|
59
|
+
onAfterLeave
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type MaybeRef } from 'vue';
|
|
2
|
+
export declare function useCommandItem(id: MaybeRef<string>): {
|
|
3
|
+
nextItem: (loop?: boolean) => void;
|
|
4
|
+
prevItem: (loop?: boolean) => void;
|
|
5
|
+
selectItem: (id: string) => void;
|
|
6
|
+
selectLastItem: () => void;
|
|
7
|
+
activeItem: import("vue").Ref<string | undefined>;
|
|
8
|
+
lastActiveItem: import("vue").Ref<string | undefined>;
|
|
9
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ref, computed, watch } from "vue";
|
|
2
|
+
import { useCommandStore } from "./useCommandStore.mjs";
|
|
3
|
+
import { toValue } from "@vueuse/core";
|
|
4
|
+
const activeItem = ref(void 0);
|
|
5
|
+
const lastActiveItem = ref(void 0);
|
|
6
|
+
const watcherActive = ref(false);
|
|
7
|
+
export function useCommandItem(id) {
|
|
8
|
+
const instance = computed(() => findInstance(toValue(id)));
|
|
9
|
+
const items = computed(() => instance.value?.items);
|
|
10
|
+
const { findInstance } = useCommandStore();
|
|
11
|
+
function nextItem(loop = false) {
|
|
12
|
+
if (items.value) {
|
|
13
|
+
const index = items.value.indexOf(activeItem.value || "");
|
|
14
|
+
const hasNext = items.value[index + 1] !== void 0;
|
|
15
|
+
if (hasNext) {
|
|
16
|
+
selectItem(items.value[index + 1]);
|
|
17
|
+
} else if (loop) {
|
|
18
|
+
selectItem(items.value[0]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function prevItem(loop = false) {
|
|
23
|
+
if (items.value) {
|
|
24
|
+
const index = items.value.indexOf(activeItem.value || "");
|
|
25
|
+
const hasPrev = items.value[index - 1] !== void 0;
|
|
26
|
+
if (hasPrev) {
|
|
27
|
+
selectItem(items.value[index - 1]);
|
|
28
|
+
} else if (loop) {
|
|
29
|
+
selectItem(items.value[items.value.length - 1]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function selectItem(id2) {
|
|
34
|
+
activeItem.value = id2;
|
|
35
|
+
}
|
|
36
|
+
function selectLastItem() {
|
|
37
|
+
activeItem.value = lastActiveItem.value;
|
|
38
|
+
}
|
|
39
|
+
if (!watcherActive.value) {
|
|
40
|
+
watcherActive.value = true;
|
|
41
|
+
watch(activeItem, (_newItem, oldItem) => {
|
|
42
|
+
if (oldItem)
|
|
43
|
+
lastActiveItem.value = oldItem;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
nextItem,
|
|
48
|
+
prevItem,
|
|
49
|
+
selectItem,
|
|
50
|
+
selectLastItem,
|
|
51
|
+
activeItem,
|
|
52
|
+
lastActiveItem
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type MaybeRef } from 'vue';
|
|
2
|
+
export declare function useCommandScroll(parent: MaybeRef<HTMLElement | undefined>): {
|
|
3
|
+
isElementAbove: (element: MaybeRef<HTMLElement>) => boolean;
|
|
4
|
+
isElementBelow: (element: MaybeRef<HTMLElement>) => boolean;
|
|
5
|
+
findElement: (id: string) => HTMLElement | null;
|
|
6
|
+
scrollInFromBottom: (element: HTMLElement) => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { toValue, computed } from "vue";
|
|
2
|
+
export function useCommandScroll(parent) {
|
|
3
|
+
const mappedParent = computed(
|
|
4
|
+
() => toValue(parent) || document.documentElement
|
|
5
|
+
);
|
|
6
|
+
const paddingTop = computed(
|
|
7
|
+
() => parseFloat(getCssValue(mappedParent.value, "padding-top"))
|
|
8
|
+
);
|
|
9
|
+
const paddingBottom = computed(
|
|
10
|
+
() => parseFloat(getCssValue(mappedParent.value, "padding-bottom"))
|
|
11
|
+
);
|
|
12
|
+
function getCssValue(el, style) {
|
|
13
|
+
return getComputedStyle(el, null).getPropertyValue(style);
|
|
14
|
+
}
|
|
15
|
+
function isElementAbove(element) {
|
|
16
|
+
const elementRect = toValue(element).getBoundingClientRect();
|
|
17
|
+
const parentRect = mappedParent.value.getBoundingClientRect();
|
|
18
|
+
const parentTop = parentRect.top + paddingTop.value;
|
|
19
|
+
return elementRect.top < parentTop;
|
|
20
|
+
}
|
|
21
|
+
function isElementBelow(element) {
|
|
22
|
+
const elementRect = toValue(element).getBoundingClientRect();
|
|
23
|
+
const parentRect = mappedParent.value.getBoundingClientRect();
|
|
24
|
+
const parentBottom = parentRect.height + parentRect.top - paddingBottom.value;
|
|
25
|
+
return elementRect.bottom >= parentBottom;
|
|
26
|
+
}
|
|
27
|
+
function findElement(id) {
|
|
28
|
+
return mappedParent.value.querySelector(`[data-id="${id}"]`);
|
|
29
|
+
}
|
|
30
|
+
function scrollInFromBottom(element) {
|
|
31
|
+
const elementRect = element.getBoundingClientRect();
|
|
32
|
+
const parentRect = mappedParent.value.getBoundingClientRect();
|
|
33
|
+
const scrollAmount = elementRect.bottom - parentRect.bottom + paddingBottom.value;
|
|
34
|
+
mappedParent.value.scrollBy({
|
|
35
|
+
top: scrollAmount
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
isElementAbove,
|
|
40
|
+
isElementBelow,
|
|
41
|
+
findElement,
|
|
42
|
+
scrollInFromBottom
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type CommandInstance = {
|
|
2
|
+
id: string;
|
|
3
|
+
items: string[];
|
|
4
|
+
views: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function useCommandStore(): {
|
|
7
|
+
commandStore: import("vue").Ref<{
|
|
8
|
+
id: string;
|
|
9
|
+
items: string[];
|
|
10
|
+
views: string[];
|
|
11
|
+
}[]>;
|
|
12
|
+
addInstance: (id: string) => void;
|
|
13
|
+
findInstance: (id: string) => CommandInstance;
|
|
14
|
+
removeInstance: (id: string) => void;
|
|
15
|
+
addItem: (id: string, item: string) => void;
|
|
16
|
+
removeItem: (id: string, item: string) => void;
|
|
17
|
+
addView: (id: string, view: string) => void;
|
|
18
|
+
removeView: (id: string, view: string) => void;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
let commandStore = ref([]);
|
|
3
|
+
export function useCommandStore() {
|
|
4
|
+
function addInstance(id) {
|
|
5
|
+
commandStore.value.push({ id, items: [], views: [] });
|
|
6
|
+
}
|
|
7
|
+
function findInstance(id) {
|
|
8
|
+
const instance = commandStore.value.find((instance2) => {
|
|
9
|
+
return instance2.id === id;
|
|
10
|
+
});
|
|
11
|
+
return instance;
|
|
12
|
+
}
|
|
13
|
+
function removeInstance(id) {
|
|
14
|
+
commandStore.value = commandStore.value.filter(
|
|
15
|
+
(x) => x.id !== id
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function addItem(id, item) {
|
|
19
|
+
const instance = findInstance(id);
|
|
20
|
+
instance.items.push(item);
|
|
21
|
+
}
|
|
22
|
+
function removeItem(id, item) {
|
|
23
|
+
const instance = findInstance(id);
|
|
24
|
+
if (instance) {
|
|
25
|
+
instance.items = instance.items.filter((x) => x !== item);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function addView(id, view) {
|
|
29
|
+
const instance = findInstance(id);
|
|
30
|
+
instance.views.push(view);
|
|
31
|
+
}
|
|
32
|
+
function removeView(id, view) {
|
|
33
|
+
const instance = findInstance(id);
|
|
34
|
+
if (instance) {
|
|
35
|
+
instance.views = instance.views.filter((x) => x !== view);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
commandStore,
|
|
40
|
+
addInstance,
|
|
41
|
+
findInstance,
|
|
42
|
+
removeInstance,
|
|
43
|
+
addItem,
|
|
44
|
+
removeItem,
|
|
45
|
+
addView,
|
|
46
|
+
removeView
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ref, watch } from "vue";
|
|
2
|
+
const activeView = ref(void 0);
|
|
3
|
+
const lastActiveView = ref(void 0);
|
|
4
|
+
const watcherActive = ref(false);
|
|
5
|
+
export function useCommandView() {
|
|
6
|
+
function selectView(id) {
|
|
7
|
+
activeView.value = id;
|
|
8
|
+
}
|
|
9
|
+
function selectLastView() {
|
|
10
|
+
activeView.value = lastActiveView.value;
|
|
11
|
+
}
|
|
12
|
+
if (!watcherActive.value) {
|
|
13
|
+
watcherActive.value = true;
|
|
14
|
+
watch(activeView, (_newView, oldView) => {
|
|
15
|
+
if (oldView)
|
|
16
|
+
lastActiveView.value = oldView;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
selectView,
|
|
21
|
+
selectLastView,
|
|
22
|
+
activeView,
|
|
23
|
+
lastActiveView
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type MaybeRef } from 'vue';
|
|
2
|
+
import { type MaybeElementRef } from '@vueuse/core';
|
|
3
|
+
import { type CommandOptions } from '../types/index.js';
|
|
4
|
+
export type UseCommandApiOptions = Pick<CommandOptions, 'scrollLock'> & {
|
|
5
|
+
focusTarget: MaybeElementRef;
|
|
6
|
+
};
|
|
7
|
+
export declare function useCommandApi(id: MaybeRef<string>, options?: UseCommandApiOptions): {
|
|
8
|
+
isActive: import("vue").ComputedRef<boolean>;
|
|
9
|
+
open: () => void;
|
|
10
|
+
close: () => void;
|
|
11
|
+
trapFocus: () => void;
|
|
12
|
+
releaseFocus: () => void;
|
|
13
|
+
lockScroll: () => void;
|
|
14
|
+
unlockScroll: () => void;
|
|
15
|
+
addScrollLockPadding: () => void;
|
|
16
|
+
removeScrollLockPadding: () => void;
|
|
17
|
+
selectItem: (id: string) => void;
|
|
18
|
+
selectLastItem: () => void;
|
|
19
|
+
selectView: (id: string) => void;
|
|
20
|
+
selectLastView: () => void;
|
|
21
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ref, computed, toValue } from "vue";
|
|
2
|
+
import { defu } from "defu";
|
|
3
|
+
import { useScrollLock } from "@vueuse/core";
|
|
4
|
+
import { useFocusTrap } from "@vueuse/integrations/useFocusTrap";
|
|
5
|
+
import { uuid, matchClass } from "@maas/vue-equipment/utils";
|
|
6
|
+
import { useCommandStore } from "./private/useCommandStore.mjs";
|
|
7
|
+
import { useCommandItem } from "./private/useCommandItem.mjs";
|
|
8
|
+
import { useCommandView } from "./private/useCommandView.mjs";
|
|
9
|
+
const defaultOptions = {
|
|
10
|
+
focusTarget: void 0,
|
|
11
|
+
scrollLock: true
|
|
12
|
+
};
|
|
13
|
+
export function useCommandApi(id, options) {
|
|
14
|
+
const positionFixedElements = ref([]);
|
|
15
|
+
const mappedId = computed(() => toValue(id) || uuid());
|
|
16
|
+
const mappedOptions = defu(options, defaultOptions);
|
|
17
|
+
const focusTrap = mappedOptions.focusTarget ? useFocusTrap(mappedOptions.focusTarget) : void 0;
|
|
18
|
+
const scrollLock = mappedOptions.scrollLock && typeof window !== "undefined" ? useScrollLock(document.body) : ref(false);
|
|
19
|
+
const isActive = computed(
|
|
20
|
+
() => commandStore.value.map((item) => item.id).includes(mappedId.value)
|
|
21
|
+
);
|
|
22
|
+
const { commandStore, addInstance, removeInstance } = useCommandStore();
|
|
23
|
+
function open() {
|
|
24
|
+
addInstance(mappedId.value);
|
|
25
|
+
}
|
|
26
|
+
function close() {
|
|
27
|
+
removeInstance(mappedId.value);
|
|
28
|
+
}
|
|
29
|
+
function trapFocus() {
|
|
30
|
+
if (focusTrap) {
|
|
31
|
+
focusTrap.activate();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function releaseFocus() {
|
|
35
|
+
if (focusTrap) {
|
|
36
|
+
focusTrap.deactivate();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function lockScroll() {
|
|
40
|
+
scrollLock.value = true;
|
|
41
|
+
}
|
|
42
|
+
function unlockScroll() {
|
|
43
|
+
scrollLock.value = false;
|
|
44
|
+
}
|
|
45
|
+
function addScrollLockPadding() {
|
|
46
|
+
if (typeof window === "undefined")
|
|
47
|
+
return;
|
|
48
|
+
const exclude = new RegExp(/magic-command(__backdrop)?/);
|
|
49
|
+
const scrollbarWidth = window.innerWidth - document.body.offsetWidth;
|
|
50
|
+
document.body.style.setProperty("--scrollbar-width", `${scrollbarWidth}px`);
|
|
51
|
+
document.body.style.paddingRight = "var(--scrollbar-width)";
|
|
52
|
+
positionFixedElements.value = [
|
|
53
|
+
...document.body.getElementsByTagName("*")
|
|
54
|
+
].filter(
|
|
55
|
+
(x) => getComputedStyle(x, null).getPropertyValue("position") === "fixed" && !matchClass(x, exclude)
|
|
56
|
+
);
|
|
57
|
+
positionFixedElements.value.forEach(
|
|
58
|
+
(elem) => elem.style.paddingRight = "var(--scrollbar-width)"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function removeScrollLockPadding() {
|
|
62
|
+
document.body.style.paddingRight = "";
|
|
63
|
+
document.body.style.removeProperty("--scrollbar-width");
|
|
64
|
+
positionFixedElements.value.forEach(
|
|
65
|
+
(elem) => elem.style.paddingRight = ""
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
const { selectItem, selectLastItem } = useCommandItem(mappedId);
|
|
69
|
+
const { selectView, selectLastView } = useCommandView();
|
|
70
|
+
return {
|
|
71
|
+
isActive,
|
|
72
|
+
open,
|
|
73
|
+
close,
|
|
74
|
+
trapFocus,
|
|
75
|
+
releaseFocus,
|
|
76
|
+
lockScroll,
|
|
77
|
+
unlockScroll,
|
|
78
|
+
addScrollLockPadding,
|
|
79
|
+
removeScrollLockPadding,
|
|
80
|
+
selectItem,
|
|
81
|
+
selectLastItem,
|
|
82
|
+
selectView,
|
|
83
|
+
selectLastView
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CommandEvents } from '../types.js';
|
|
2
|
+
export declare function useCommandEmitter(): {
|
|
3
|
+
on: {
|
|
4
|
+
<Key extends keyof CommandEvents>(type: Key, handler: import("mitt").Handler<CommandEvents[Key]>): void;
|
|
5
|
+
(type: "*", handler: import("mitt").WildcardHandler<CommandEvents>): void;
|
|
6
|
+
};
|
|
7
|
+
off: {
|
|
8
|
+
<Key_1 extends keyof CommandEvents>(type: Key_1, handler?: import("mitt").Handler<CommandEvents[Key_1]> | undefined): void;
|
|
9
|
+
(type: "*", handler: import("mitt").WildcardHandler<CommandEvents>): void;
|
|
10
|
+
};
|
|
11
|
+
emit: {
|
|
12
|
+
<Key_2 extends keyof CommandEvents>(type: Key_2, event: CommandEvents[Key_2]): void;
|
|
13
|
+
<Key_3 extends keyof CommandEvents>(type: undefined extends CommandEvents[Key_3] ? Key_3 : never): void;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { InjectionKey, MaybeRef } from 'vue';
|
|
2
|
+
import type { CommandOptions } from '../types.js';
|
|
3
|
+
declare const CommandInstanceId: InjectionKey<MaybeRef<string>>;
|
|
4
|
+
declare const CommandOptionsKey: InjectionKey<CommandOptions>;
|
|
5
|
+
export { CommandInstanceId, CommandOptionsKey };
|