@maas/vue-equipment 0.22.1 → 0.22.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/nuxt/module.mjs +1 -1
- package/dist/plugins/MagicCommand/demo/DefaultView.vue +29 -7
- package/dist/plugins/MagicCommand/demo/DefaultView.vue.d.ts +13 -1
- package/dist/plugins/MagicCommand/demo/ProjectView.vue +1 -3
- package/dist/plugins/MagicCommand/src/components/MagicCommand.vue +1 -2
- package/dist/plugins/MagicCommand/src/components/MagicCommandBody.vue +8 -3
- package/dist/plugins/MagicCommand/src/components/MagicCommandItem.vue +2 -1
- package/dist/plugins/MagicCommand/src/components/MagicCommandView.vue +29 -3
- package/dist/plugins/MagicCommand/src/composables/private/useCommandItem.mjs +10 -6
- package/dist/plugins/MagicCommand/src/composables/private/useCommandScroll.d.ts +1 -0
- package/dist/plugins/MagicCommand/src/composables/private/useCommandScroll.mjs +10 -1
- package/dist/plugins/MagicCommand/src/composables/private/useCommandStore.d.ts +10 -2
- package/dist/plugins/MagicCommand/src/composables/private/useCommandStore.mjs +15 -2
- package/package.json +1 -1
package/dist/nuxt/module.json
CHANGED
package/dist/nuxt/module.mjs
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
:default="true"
|
|
5
5
|
class="bg-neutral-800 border border-solid border-neutral-600 w-[40rem] max-h-[30rem] rounded-xl overflow-hidden flex flex-col"
|
|
6
6
|
>
|
|
7
|
-
<magic-command-head class="
|
|
7
|
+
<magic-command-head class="px-2 pt-2">
|
|
8
8
|
<div class="w-full border border-neutral-600 p-3 border-b-solid">
|
|
9
|
-
<
|
|
10
|
-
<input type="text" placeholder="Search" />
|
|
11
|
-
</magic-command-input>
|
|
9
|
+
<input type="text" placeholder="Search" />
|
|
12
10
|
</div>
|
|
13
11
|
</magic-command-head>
|
|
14
|
-
<magic-command-body class="h-full
|
|
12
|
+
<magic-command-body class="h-full py-2">
|
|
15
13
|
<magic-command-group>
|
|
16
14
|
<h2 class="p-4 text-xs text-neutral-600">Suggestions</h2>
|
|
17
15
|
<magic-command-item
|
|
@@ -21,9 +19,21 @@
|
|
|
21
19
|
>
|
|
22
20
|
<demo-item :is-active="isActive">View Projects</demo-item>
|
|
23
21
|
</magic-command-item>
|
|
22
|
+
<magic-command-item v-slot="{ isActive }" :callback="toggleDynamicItem">
|
|
23
|
+
<demo-item :is-active="isActive"
|
|
24
|
+
>{{ dynamic ? 'Remove' : 'Add ' }} Filter</demo-item
|
|
25
|
+
>
|
|
26
|
+
</magic-command-item>
|
|
24
27
|
</magic-command-group>
|
|
25
28
|
<magic-command-group>
|
|
26
29
|
<h2 class="p-4 text-xs text-neutral-600">Filter</h2>
|
|
30
|
+
<magic-command-item
|
|
31
|
+
v-slot="{ isActive }"
|
|
32
|
+
v-if="dynamic"
|
|
33
|
+
:callback="() => itemCallback('dynamic')"
|
|
34
|
+
>
|
|
35
|
+
<demo-item :is-active="isActive">All</demo-item>
|
|
36
|
+
</magic-command-item>
|
|
27
37
|
<magic-command-item
|
|
28
38
|
v-for="nth in 20"
|
|
29
39
|
:key="nth"
|
|
@@ -38,16 +48,28 @@
|
|
|
38
48
|
</template>
|
|
39
49
|
|
|
40
50
|
<script setup lang="ts">
|
|
41
|
-
import { inject } from 'vue'
|
|
51
|
+
import { ref, inject } from 'vue'
|
|
42
52
|
import { useCommandApi, CommandInstanceId } from '@maas/vue-equipment/plugins'
|
|
43
53
|
import DemoItem from './DemoItem.vue'
|
|
44
54
|
|
|
55
|
+
interface Props {
|
|
56
|
+
hasDynamicItem?: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
defineProps<Props>()
|
|
60
|
+
|
|
45
61
|
const commandId = inject(CommandInstanceId, '')
|
|
46
62
|
|
|
47
63
|
const commandApi = useCommandApi(commandId)
|
|
48
64
|
const { selectView } = commandApi
|
|
49
65
|
|
|
50
|
-
|
|
66
|
+
const dynamic = ref(false)
|
|
67
|
+
|
|
68
|
+
function toggleDynamicItem() {
|
|
69
|
+
dynamic.value = !dynamic.value
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function itemCallback(nth: number | string) {
|
|
51
73
|
console.log(nth)
|
|
52
74
|
}
|
|
53
75
|
|
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
interface Props {
|
|
2
|
+
hasDynamicItem?: boolean;
|
|
3
|
+
}
|
|
4
|
+
declare const _default: import("vue").DefineComponent<__VLS_TypePropsToRuntimeProps<Props>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToRuntimeProps<Props>>>, {}, {}>;
|
|
2
5
|
export default _default;
|
|
6
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
7
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
8
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
9
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
10
|
+
} : {
|
|
11
|
+
type: import('vue').PropType<T[K]>;
|
|
12
|
+
required: true;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
>
|
|
6
6
|
<magic-command-head class="p-2">
|
|
7
7
|
<div class="w-full border border-neutral-600 p-3 border-b-solid">
|
|
8
|
-
<
|
|
9
|
-
<input type="text" placeholder="Search Projects" />
|
|
10
|
-
</magic-command-input>
|
|
8
|
+
<input type="text" placeholder="Search Projects" />
|
|
11
9
|
</div>
|
|
12
10
|
</magic-command-head>
|
|
13
11
|
<magic-command-body class="h-full pb-2">
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
class="magic-command"
|
|
11
11
|
:id="toValue(id)"
|
|
12
12
|
:class="toValue(props.class)"
|
|
13
|
-
@click.self="close"
|
|
14
13
|
aria-command="true"
|
|
15
14
|
>
|
|
16
15
|
<transition
|
|
@@ -176,5 +175,5 @@ provide(CommandOptionsKey, mappedOptions)
|
|
|
176
175
|
</script>
|
|
177
176
|
|
|
178
177
|
<style>
|
|
179
|
-
:root{--magic-command-z-index:999;--magic-command-backdrop-color:rgba(0,0,0,.5);--magic-command-backdrop-filter:unset;--magic-command-content-align-items:center;--magic-command-content-justify-content:center;--magic-command-content-overflow-y:auto}@keyframes magic-command-content-enter{0%{opacity:0;transform:translateY(2rem)}to{opacity:1;transform:translateY(0)}}@keyframes magic-command-content-leave{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(1.02)}}.magic-command{align-items:center;background:transparent;border:none;color:inherit;display:flex;height:100%;inset:0;justify-content:center;padding:0;position:fixed;width:100%;z-index:var(--magic-command-z-index)}.magic-command__content{-webkit-overflow-scrolling:touch;align-items:var(--magic-command-content-align-items);display:flex;justify-content:var(--magic-command-content-justify-content);max-height:100%;overflow-y:var(--magic-command-content-overflow-y);scroll-behavior:smooth;width:100%}.magic-command__backdrop{-webkit-backdrop-filter:var(--magic-command-backdrop-filter);backdrop-filter:var(--magic-command-backdrop-filter);background-color:var(--magic-command-backdrop-color);bottom:0;height:100%;left:0;position:fixed;right:0;top:0;width:100%;z-index:-1}.magic-command--content-enter-active{animation:magic-command-content-enter .3s ease}.magic-command--content-leave-active{animation:magic-command-content-leave .3s ease}@media (prefers-reduced-motion){.magic-command--content-enter-active{animation:fade-in .3s ease}.magic-command--content-leave-active{animation:fade-out .3s ease}}.magic-command--backdrop-enter-active{animation:fade-in .3s ease}.magic-command--backdrop-leave-active{animation:fade-out .3s ease}
|
|
178
|
+
:root{--magic-command-z-index:999;--magic-command-backdrop-color:rgba(0,0,0,.5);--magic-command-backdrop-filter:unset;--magic-command-content-align-items:center;--magic-command-content-justify-content:center;--magic-command-content-overflow-y:auto}@keyframes magic-command-content-enter{0%{opacity:0;transform:translateY(2rem)}to{opacity:1;transform:translateY(0)}}@keyframes magic-command-content-leave{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(1.02)}}.magic-command{align-items:center;background:transparent;border:none;color:inherit;display:flex;height:100%;inset:0;justify-content:center;padding:0;pointer-events:none;position:fixed;width:100%;z-index:var(--magic-command-z-index)}.magic-command__content{-webkit-overflow-scrolling:touch;align-items:var(--magic-command-content-align-items);display:flex;justify-content:var(--magic-command-content-justify-content);max-height:100%;overflow-y:var(--magic-command-content-overflow-y);pointer-events:auto;scroll-behavior:smooth;width:100%}.magic-command__backdrop{-webkit-backdrop-filter:var(--magic-command-backdrop-filter);backdrop-filter:var(--magic-command-backdrop-filter);background-color:var(--magic-command-backdrop-color);bottom:0;height:100%;left:0;pointer-events:auto;position:fixed;right:0;top:0;width:100%;z-index:-1}.magic-command--content-enter-active{animation:magic-command-content-enter .3s ease}.magic-command--content-leave-active{animation:magic-command-content-leave .3s ease}@media (prefers-reduced-motion){.magic-command--content-enter-active{animation:fade-in .3s ease}.magic-command--content-leave-active{animation:fade-out .3s ease}}.magic-command--backdrop-enter-active{animation:fade-in .3s ease}.magic-command--backdrop-leave-active{animation:fade-out .3s ease}
|
|
180
179
|
</style>
|
|
@@ -19,8 +19,13 @@ const commandId = inject(CommandInstanceId, '')
|
|
|
19
19
|
const options = inject(CommandOptionsKey, {} as CommandOptions)
|
|
20
20
|
|
|
21
21
|
const { activeItem, nextItem, prevItem } = useCommandItem(commandId)
|
|
22
|
-
const {
|
|
23
|
-
|
|
22
|
+
const {
|
|
23
|
+
findElement,
|
|
24
|
+
isElementAbove,
|
|
25
|
+
isElementBelow,
|
|
26
|
+
scrollInFromBottom,
|
|
27
|
+
scrollInFromTop,
|
|
28
|
+
} = useCommandScroll(elRef)
|
|
24
29
|
|
|
25
30
|
const keys = useMagicKeys()
|
|
26
31
|
|
|
@@ -72,7 +77,7 @@ watch(activeItem, async (value) => {
|
|
|
72
77
|
const element = findElement(value)
|
|
73
78
|
if (element) {
|
|
74
79
|
if (isElementAbove(element)) {
|
|
75
|
-
element
|
|
80
|
+
scrollInFromTop(element)
|
|
76
81
|
} else if (isElementBelow(element)) {
|
|
77
82
|
scrollInFromBottom(element)
|
|
78
83
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div
|
|
3
3
|
class="magic-command-item"
|
|
4
4
|
ref="elRef"
|
|
5
|
-
:data-id="mappedId"
|
|
5
|
+
:data-item-id="mappedId"
|
|
6
6
|
:aria-selected="isActive"
|
|
7
7
|
>
|
|
8
8
|
<slot :is-active="isActive" />
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
nextTick,
|
|
19
19
|
onMounted,
|
|
20
20
|
onUnmounted,
|
|
21
|
+
getCurrentInstance,
|
|
21
22
|
} from 'vue'
|
|
22
23
|
import { useEventListener, onKeyStroke } from '@vueuse/core'
|
|
23
24
|
import { uuid } from '@maas/vue-equipment/utils'
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="magic-command-view" v-if="isActive">
|
|
2
|
+
<div class="magic-command-view" v-if="isActive" ref="elRef">
|
|
3
3
|
<slot />
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ref,
|
|
10
|
+
computed,
|
|
11
|
+
inject,
|
|
12
|
+
toValue,
|
|
13
|
+
onMounted,
|
|
14
|
+
onUnmounted,
|
|
15
|
+
watch,
|
|
16
|
+
nextTick,
|
|
17
|
+
} from 'vue'
|
|
9
18
|
import { uuid } from '@maas/vue-equipment/utils'
|
|
10
19
|
import { useCommandStore } from '../composables/private/useCommandStore'
|
|
11
20
|
import { useCommandView } from '../composables/private/useCommandView'
|
|
@@ -18,6 +27,7 @@ interface Props {
|
|
|
18
27
|
|
|
19
28
|
const props = withDefaults(defineProps<Props>(), { default: false })
|
|
20
29
|
const commandId = inject(CommandInstanceId, '')
|
|
30
|
+
const elRef = ref<HTMLElement | undefined>(undefined)
|
|
21
31
|
|
|
22
32
|
const { activeView, selectView } = useCommandView()
|
|
23
33
|
|
|
@@ -29,7 +39,11 @@ const isActive = computed(() => {
|
|
|
29
39
|
return toValue(mappedId) === activeView.value
|
|
30
40
|
})
|
|
31
41
|
|
|
32
|
-
const
|
|
42
|
+
const items = computed(() => {
|
|
43
|
+
return findInstance(toValue(commandId))?.items
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const { addView, removeView, findInstance, sortItems } = useCommandStore()
|
|
33
47
|
|
|
34
48
|
onMounted(() => {
|
|
35
49
|
if (toValue(commandId)) {
|
|
@@ -46,4 +60,16 @@ onUnmounted(() => {
|
|
|
46
60
|
removeView(toValue(commandId), mappedId.value)
|
|
47
61
|
}
|
|
48
62
|
})
|
|
63
|
+
|
|
64
|
+
// Update sorting for MagicCommandItems
|
|
65
|
+
watch(
|
|
66
|
+
() => items.value.length,
|
|
67
|
+
() => {
|
|
68
|
+
nextTick(() => {
|
|
69
|
+
if (elRef.value) {
|
|
70
|
+
sortItems(toValue(commandId), elRef.value)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
)
|
|
49
75
|
</script>
|
|
@@ -10,23 +10,27 @@ export function useCommandItem(id) {
|
|
|
10
10
|
const { findInstance } = useCommandStore();
|
|
11
11
|
function nextItem(loop = false) {
|
|
12
12
|
if (items.value) {
|
|
13
|
-
const index = items.value.
|
|
13
|
+
const index = items.value.findIndex(
|
|
14
|
+
(item) => item.id === activeItem.value
|
|
15
|
+
);
|
|
14
16
|
const hasNext = items.value[index + 1] !== void 0;
|
|
15
17
|
if (hasNext) {
|
|
16
|
-
selectItem(items.value[index + 1]);
|
|
18
|
+
selectItem(items.value[index + 1].id);
|
|
17
19
|
} else if (loop) {
|
|
18
|
-
selectItem(items.value[0]);
|
|
20
|
+
selectItem(items.value[0].id);
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
function prevItem(loop = false) {
|
|
23
25
|
if (items.value) {
|
|
24
|
-
const index = items.value.
|
|
26
|
+
const index = items.value.findIndex(
|
|
27
|
+
(item) => item.id === activeItem.value
|
|
28
|
+
);
|
|
25
29
|
const hasPrev = items.value[index - 1] !== void 0;
|
|
26
30
|
if (hasPrev) {
|
|
27
|
-
selectItem(items.value[index - 1]);
|
|
31
|
+
selectItem(items.value[index - 1].id);
|
|
28
32
|
} else if (loop) {
|
|
29
|
-
selectItem(items.value[items.value.length - 1]);
|
|
33
|
+
selectItem(items.value[items.value.length - 1].id);
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
36
|
}
|
|
@@ -3,5 +3,6 @@ export declare function useCommandScroll(parent: MaybeRef<HTMLElement | undefine
|
|
|
3
3
|
isElementAbove: (element: MaybeRef<HTMLElement>) => boolean;
|
|
4
4
|
isElementBelow: (element: MaybeRef<HTMLElement>) => boolean;
|
|
5
5
|
findElement: (id: string) => HTMLElement | null;
|
|
6
|
+
scrollInFromTop: (element: HTMLElement) => void;
|
|
6
7
|
scrollInFromBottom: (element: HTMLElement) => void;
|
|
7
8
|
};
|
|
@@ -25,7 +25,15 @@ export function useCommandScroll(parent) {
|
|
|
25
25
|
return elementRect.bottom >= parentBottom;
|
|
26
26
|
}
|
|
27
27
|
function findElement(id) {
|
|
28
|
-
return mappedParent.value.querySelector(`[data-id="${id}"]`);
|
|
28
|
+
return mappedParent.value.querySelector(`[data-item-id="${id}"]`);
|
|
29
|
+
}
|
|
30
|
+
function scrollInFromTop(element) {
|
|
31
|
+
const elementRect = element.getBoundingClientRect();
|
|
32
|
+
const parentRect = mappedParent.value.getBoundingClientRect();
|
|
33
|
+
const scrollAmount = elementRect.top - parentRect.top - paddingTop.value;
|
|
34
|
+
mappedParent.value.scrollBy({
|
|
35
|
+
top: scrollAmount
|
|
36
|
+
});
|
|
29
37
|
}
|
|
30
38
|
function scrollInFromBottom(element) {
|
|
31
39
|
const elementRect = element.getBoundingClientRect();
|
|
@@ -39,6 +47,7 @@ export function useCommandScroll(parent) {
|
|
|
39
47
|
isElementAbove,
|
|
40
48
|
isElementBelow,
|
|
41
49
|
findElement,
|
|
50
|
+
scrollInFromTop,
|
|
42
51
|
scrollInFromBottom
|
|
43
52
|
};
|
|
44
53
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
type Item = {
|
|
2
|
+
index: number;
|
|
3
|
+
id: string;
|
|
4
|
+
};
|
|
1
5
|
type CommandInstance = {
|
|
2
6
|
id: string;
|
|
3
|
-
items:
|
|
7
|
+
items: Item[];
|
|
4
8
|
views: string[];
|
|
5
9
|
};
|
|
6
10
|
export declare function useCommandStore(): {
|
|
7
11
|
commandStore: import("vue").Ref<{
|
|
8
12
|
id: string;
|
|
9
|
-
items:
|
|
13
|
+
items: {
|
|
14
|
+
index: number;
|
|
15
|
+
id: string;
|
|
16
|
+
}[];
|
|
10
17
|
views: string[];
|
|
11
18
|
}[]>;
|
|
12
19
|
addInstance: (id: string) => void;
|
|
@@ -14,6 +21,7 @@ export declare function useCommandStore(): {
|
|
|
14
21
|
removeInstance: (id: string) => void;
|
|
15
22
|
addItem: (id: string, item: string) => void;
|
|
16
23
|
removeItem: (id: string, item: string) => void;
|
|
24
|
+
sortItems: (id: string, parent: HTMLElement) => void;
|
|
17
25
|
addView: (id: string, view: string) => void;
|
|
18
26
|
removeView: (id: string, view: string) => void;
|
|
19
27
|
};
|
|
@@ -15,14 +15,26 @@ export function useCommandStore() {
|
|
|
15
15
|
(x) => x.id !== id
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
|
+
function sortItems(id, parent) {
|
|
19
|
+
const instance = findInstance(id);
|
|
20
|
+
const itemElements = parent.querySelectorAll("[data-item-id]");
|
|
21
|
+
itemElements.forEach((el, index) => {
|
|
22
|
+
const itemId = el.dataset.itemId;
|
|
23
|
+
const item = instance.items.find((item2) => item2.id === itemId);
|
|
24
|
+
if (item) {
|
|
25
|
+
item.index = index;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
instance.items.sort((a, b) => a.index - b.index);
|
|
29
|
+
}
|
|
18
30
|
function addItem(id, item) {
|
|
19
31
|
const instance = findInstance(id);
|
|
20
|
-
instance.items.push(item);
|
|
32
|
+
instance.items.push({ index: -1, id: item });
|
|
21
33
|
}
|
|
22
34
|
function removeItem(id, item) {
|
|
23
35
|
const instance = findInstance(id);
|
|
24
36
|
if (instance) {
|
|
25
|
-
instance.items = instance.items.filter((x) => x !== item);
|
|
37
|
+
instance.items = instance.items.filter((x) => x.id !== item);
|
|
26
38
|
}
|
|
27
39
|
}
|
|
28
40
|
function addView(id, view) {
|
|
@@ -42,6 +54,7 @@ export function useCommandStore() {
|
|
|
42
54
|
removeInstance,
|
|
43
55
|
addItem,
|
|
44
56
|
removeItem,
|
|
57
|
+
sortItems,
|
|
45
58
|
addView,
|
|
46
59
|
removeView
|
|
47
60
|
};
|
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.22.
|
|
4
|
+
"version": "0.22.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",
|