pxd 0.0.61 → 0.0.63
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/LICENSE +21 -0
- package/dist/components/_internal/dismiss-container.d.vue.ts +28 -0
- package/dist/components/_internal/dismiss-container.vue +162 -0
- package/dist/components/_internal/popover-arrow.d.vue.ts +9 -0
- package/dist/components/_internal/popover-arrow.vue +38 -0
- package/dist/components/active-graph/index.vue +4 -4
- package/dist/components/avatar/index.vue +5 -7
- package/dist/components/avatar-group/index.d.vue.ts +0 -1
- package/dist/components/avatar-group/index.vue +1 -1
- package/dist/components/backtop/index.vue +1 -1
- package/dist/components/badge/index.d.vue.ts +5 -1
- package/dist/components/badge/index.vue +18 -4
- package/dist/components/badge/types.d.ts +5 -0
- package/dist/components/book/index.vue +1 -1
- package/dist/components/browser/index.vue +1 -1
- package/dist/components/bubble/index.d.vue.ts +22 -0
- package/dist/components/bubble/index.vue +59 -0
- package/dist/components/bubble/types.d.ts +6 -0
- package/dist/components/button/index.d.vue.ts +0 -2
- package/dist/components/button/index.vue +30 -21
- package/dist/components/button/types.d.ts +3 -2
- package/dist/components/button-group/index.d.vue.ts +14 -0
- package/dist/components/button-group/index.vue +26 -0
- package/dist/components/button-group/types.d.ts +9 -0
- package/dist/components/carousel/index.d.vue.ts +3 -3
- package/dist/components/carousel/index.vue +146 -113
- package/dist/components/carousel/types.d.ts +1 -1
- package/dist/components/carousel-item/index.vue +22 -17
- package/dist/components/checkbox/index.vue +6 -6
- package/dist/components/checkbox-group/index.d.vue.ts +1 -1
- package/dist/components/chip/index.d.vue.ts +1 -5
- package/dist/components/chip/index.vue +4 -4
- package/dist/components/color-selector/index.d.vue.ts +12 -0
- package/dist/components/color-selector/index.vue +64 -0
- package/dist/components/color-selector/types.d.ts +12 -0
- package/dist/components/command-menu/index.d.vue.ts +6 -6
- package/dist/components/command-menu/index.vue +23 -32
- package/dist/components/command-menu/types.d.ts +1 -1
- package/dist/components/command-menu-group/index.vue +15 -6
- package/dist/components/command-menu-group/types.d.ts +1 -1
- package/dist/components/countdown/index.d.vue.ts +11 -11
- package/dist/components/drawer/index.d.vue.ts +8 -8
- package/dist/components/drawer/index.vue +13 -10
- package/dist/components/drawer/types.d.ts +4 -3
- package/dist/components/ellipsis-text/index.d.vue.ts +4 -1
- package/dist/components/ellipsis-text/index.vue +84 -107
- package/dist/components/ellipsis-text/types.d.ts +2 -1
- package/dist/components/error/index.vue +1 -1
- package/dist/components/fader/index.vue +5 -9
- package/dist/components/gauge/index.vue +34 -29
- package/dist/components/grid/index.vue +1 -1
- package/dist/components/grid-item/index.vue +1 -1
- package/dist/components/hold-button/index.d.vue.ts +8 -10
- package/dist/components/hold-button/index.vue +20 -29
- package/dist/components/hold-button/types.d.ts +5 -6
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.js +7 -0
- package/dist/components/input/index.d.vue.ts +8 -8
- package/dist/components/input/index.vue +5 -4
- package/dist/components/intersection-observer/index.vue +4 -4
- package/dist/components/kbd/index.vue +1 -1
- package/dist/components/link-button/index.d.vue.ts +4 -4
- package/dist/components/link-button/index.vue +9 -8
- package/dist/components/link-button/types.d.ts +0 -3
- package/dist/components/list/index.d.vue.ts +10 -15
- package/dist/components/list/index.vue +58 -131
- package/dist/components/list/types.d.ts +4 -4
- package/dist/components/list-item/index.d.vue.ts +2 -2
- package/dist/components/list-item/index.vue +44 -39
- package/dist/components/loading-bar/index.vue +8 -7
- package/dist/components/material/index.vue +24 -46
- package/dist/components/menu/index.d.vue.ts +6 -8
- package/dist/components/menu/index.vue +18 -24
- package/dist/components/menu/types.d.ts +1 -2
- package/dist/components/message/composables/use-group-expand.d.ts +13 -0
- package/dist/components/message/composables/use-group-expand.js +50 -0
- package/dist/components/message/composables/use-message-timer.d.ts +9 -0
- package/dist/components/message/composables/use-message-timer.js +61 -0
- package/dist/components/message/composables/use-promise-message.d.ts +4 -0
- package/dist/components/message/composables/use-promise-message.js +49 -0
- package/dist/components/message/index.d.vue.ts +6 -33
- package/dist/components/message/index.vue +33 -185
- package/dist/components/message/types.d.ts +2 -2
- package/dist/components/message-item/index.vue +26 -2
- package/dist/components/modal/index.d.vue.ts +7 -7
- package/dist/components/modal/index.vue +7 -3
- package/dist/components/modal/types.d.ts +7 -3
- package/dist/components/note/index.vue +2 -2
- package/dist/components/number-input/index.d.vue.ts +5 -4
- package/dist/components/number-input/index.vue +3 -0
- package/dist/components/number-input/types.d.ts +1 -0
- package/dist/components/overlay/index.d.vue.ts +6 -3
- package/dist/components/overlay/index.vue +63 -68
- package/dist/components/overlay/types.d.ts +5 -4
- package/dist/components/pagination/index.vue +2 -2
- package/dist/components/pin-input/index.d.vue.ts +1 -1
- package/dist/components/pin-input/index.vue +7 -6
- package/dist/components/placeholder/index.vue +1 -1
- package/dist/components/popover/index.d.vue.ts +7 -8
- package/dist/components/popover/index.vue +149 -239
- package/dist/components/popover/types.d.ts +5 -5
- package/dist/components/progress/index.vue +1 -1
- package/dist/components/radio/index.vue +2 -2
- package/dist/components/resizable/index.vue +43 -51
- package/dist/components/resizable/types.d.ts +1 -1
- package/dist/components/resizable-handle/index.d.vue.ts +4 -1
- package/dist/components/resizable-handle/index.vue +29 -3
- package/dist/components/resizable-panel/index.vue +3 -7
- package/dist/components/scalable-text/index.d.vue.ts +9 -0
- package/dist/components/scalable-text/index.vue +147 -0
- package/dist/components/scalable-text/types.d.ts +12 -0
- package/dist/components/scrollable/index.d.vue.ts +2 -2
- package/dist/components/scrollable/index.vue +4 -3
- package/dist/components/separator/index.d.vue.ts +6 -0
- package/dist/components/separator/index.vue +18 -0
- package/dist/components/separator/types.d.ts +5 -0
- package/dist/components/skeleton/index.d.vue.ts +1 -1
- package/dist/components/slider/index.d.vue.ts +1 -1
- package/dist/components/slider/index.vue +39 -7
- package/dist/components/snippet/index.vue +16 -13
- package/dist/components/spinner/index.vue +3 -1
- package/dist/components/stack/index.d.vue.ts +1 -1
- package/dist/components/stack/index.vue +1 -1
- package/dist/components/switch/index.d.vue.ts +1 -1
- package/dist/components/switch/index.vue +4 -3
- package/dist/components/switch-item/index.vue +1 -1
- package/dist/components/tabs/index.d.vue.ts +12 -0
- package/dist/components/tabs/index.vue +270 -0
- package/dist/components/tabs/types.d.ts +12 -0
- package/dist/components/tabs-item/index.d.vue.ts +4 -0
- package/dist/components/tabs-item/index.vue +16 -0
- package/dist/components/tabs-item/types.d.ts +10 -0
- package/dist/components/text/index.vue +1 -1
- package/dist/components/textarea/index.d.vue.ts +2 -2
- package/dist/components/textarea/index.vue +1 -1
- package/dist/components/time-picker/index.d.vue.ts +3 -5
- package/dist/components/time-picker/index.vue +53 -45
- package/dist/components/time-picker/types.d.ts +1 -2
- package/dist/components/toggle/index.d.vue.ts +0 -2
- package/dist/components/toggle/index.vue +6 -6
- package/dist/components/toggle-button/index.vue +8 -6
- package/dist/components/tooltip/index.d.vue.ts +1 -1
- package/dist/components/tooltip/index.vue +19 -11
- package/dist/components/tooltip/types.d.ts +2 -2
- package/dist/components/virtual-list/index.d.vue.ts +8 -8
- package/dist/components/virtual-list/index.vue +27 -5
- package/dist/components/virtual-list/types.d.ts +3 -0
- package/dist/composables/index.d.ts +4 -1
- package/dist/composables/index.js +4 -1
- package/dist/composables/use-browser-observer.js +2 -2
- package/dist/composables/use-client-online.js +2 -2
- package/dist/composables/use-color-scheme.js +2 -2
- package/dist/composables/use-countdown.js +3 -2
- package/dist/composables/use-deferred-value.js +2 -2
- package/dist/composables/use-delay-destroy.js +11 -6
- package/dist/composables/use-document-hidden.js +2 -2
- package/dist/composables/use-focus-trap.js +2 -2
- package/dist/composables/use-list-filter.d.ts +11 -0
- package/dist/composables/use-list-filter.js +56 -0
- package/dist/composables/use-list-navigation.d.ts +27 -0
- package/dist/composables/use-list-navigation.js +159 -0
- package/dist/composables/use-lock-scroll.js +12 -12
- package/dist/composables/use-media-query.js +2 -2
- package/dist/composables/use-outside-click.d.ts +1 -1
- package/dist/composables/use-outside-click.js +8 -11
- package/dist/composables/use-overlay-manager.d.ts +18 -0
- package/dist/composables/use-overlay-manager.js +80 -0
- package/dist/composables/use-popover-responsive.d.ts +6 -8
- package/dist/composables/use-popover-responsive.js +9 -12
- package/dist/composables/use-repeat-action.js +2 -2
- package/dist/composables/use-swipe-gesture.d.ts +65 -0
- package/dist/composables/use-swipe-gesture.js +99 -0
- package/dist/composables/use-virtual-list.d.ts +5 -3
- package/dist/composables/use-virtual-list.js +25 -14
- package/dist/composables/use-window-size.js +2 -2
- package/dist/constants/size.d.ts +12 -0
- package/dist/constants/size.js +12 -0
- package/dist/contexts/button.d.ts +5 -0
- package/dist/contexts/button.js +5 -0
- package/dist/contexts/carousel.d.ts +2 -1
- package/dist/contexts/list.d.ts +23 -3
- package/dist/contexts/list.js +6 -2
- package/dist/contexts/resizable.d.ts +3 -11
- package/dist/contexts/tabs.d.ts +15 -0
- package/dist/contexts/tabs.js +2 -0
- package/dist/locales/en-us.d.ts +4 -4
- package/dist/locales/en-us.js +4 -4
- package/dist/locales/zh-cn.d.ts +4 -4
- package/dist/locales/zh-cn.js +4 -4
- package/dist/plugins/dayjs-millisecond-token.js +1 -1
- package/dist/styles/source.css +133 -128
- package/dist/styles/styles.css +2 -2
- package/dist/styles/tw.css +133 -128
- package/dist/types/shared/props.d.ts +1 -0
- package/dist/types/shared/utils.d.ts +1 -4
- package/dist/utils/date.d.ts +3 -3
- package/dist/utils/dom.d.ts +1 -0
- package/dist/utils/dom.js +4 -0
- package/dist/utils/event.d.ts +2 -1
- package/dist/utils/event.js +7 -1
- package/dist/utils/format.d.ts +3 -3
- package/dist/utils/format.js +5 -4
- package/dist/utils/fuzzy-search.d.ts +7 -0
- package/dist/utils/fuzzy-search.js +61 -0
- package/dist/utils/get.d.ts +2 -0
- package/dist/utils/get.js +15 -1
- package/dist/utils/index.d.ts +10 -11
- package/dist/utils/index.js +2 -3
- package/dist/utils/ref.d.ts +2 -2
- package/dist/utils/{throttle.d.ts → timing.d.ts} +1 -0
- package/dist/utils/{throttle.js → timing.js} +4 -2
- package/package.json +40 -37
- package/volar.d.ts +7 -0
- package/dist/components/overlay/overlay-stack.d.ts +0 -3
- package/dist/components/overlay/overlay-stack.js +0 -17
- package/dist/composables/use-pointer-gesture.d.ts +0 -180
- package/dist/composables/use-pointer-gesture.js +0 -406
- package/dist/utils/debounce.d.ts +0 -1
- package/dist/utils/debounce.js +0 -1
- package/dist/utils/regexp.d.ts +0 -8
- package/dist/utils/regexp.js +0 -8
- package/dist/utils/responsive.d.ts +0 -3
- package/dist/utils/responsive.js +0 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed,
|
|
1
|
+
import { computed, onScopeDispose, shallowRef, watchEffect } from "vue";
|
|
2
2
|
import { cachedOn } from "../utils/event.js";
|
|
3
3
|
import { isServer } from "../utils/is.js";
|
|
4
4
|
import { PRESET_MEDIA_QUERIES, useMediaQuery } from "./use-media-query.js";
|
|
@@ -96,7 +96,7 @@ export function useColorScheme(options = {}) {
|
|
|
96
96
|
if (options.syncStatus) {
|
|
97
97
|
unbindSubscriber = cachedOn(window, EVENT_NAME, onToggleModeType);
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
onScopeDispose(() => {
|
|
100
100
|
stopEffect();
|
|
101
101
|
unbindSubscriber();
|
|
102
102
|
cleanupStyleElements();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computed, shallowRef, watch } from "vue";
|
|
2
|
+
import { raf } from "../utils/event.js";
|
|
2
3
|
const UPDATE_INTERVAL = 100;
|
|
3
4
|
export function useCountdown(props, emits) {
|
|
4
5
|
let startTimestamp = -1;
|
|
@@ -80,7 +81,7 @@ export function useCountdown(props, emits) {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
if (now - previousFrameTime < UPDATE_INTERVAL && !isLastFrame) {
|
|
83
|
-
|
|
84
|
+
raf(frame);
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
87
|
previousFrameTime = now;
|
|
@@ -93,7 +94,7 @@ export function useCountdown(props, emits) {
|
|
|
93
94
|
} else {
|
|
94
95
|
timeRef.value = Math.max(0, current);
|
|
95
96
|
}
|
|
96
|
-
|
|
97
|
+
raf(frame);
|
|
97
98
|
}
|
|
98
99
|
const unwatchActive = watch(
|
|
99
100
|
() => props.active,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onScopeDispose, ref, watch } from "vue";
|
|
2
2
|
import { toValue } from "../utils/ref.js";
|
|
3
3
|
export function useDeferredValue(defaultValue, options = {}) {
|
|
4
4
|
const { deep, delay = 300, valueChange } = options;
|
|
@@ -16,7 +16,7 @@ export function useDeferredValue(defaultValue, options = {}) {
|
|
|
16
16
|
},
|
|
17
17
|
{ deep }
|
|
18
18
|
);
|
|
19
|
-
|
|
19
|
+
onScopeDispose(() => {
|
|
20
20
|
unwatch();
|
|
21
21
|
clearTimeout(syncTimeoutId);
|
|
22
22
|
});
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { shallowRef } from "vue";
|
|
2
|
+
import { doubleRaf, caf } from "../utils/event.js";
|
|
2
3
|
import { toValue } from "../utils/ref.js";
|
|
3
4
|
export function useDelayDestroy(value, options = {}) {
|
|
4
5
|
const { delay = 300, renderChange, visibleChange } = options;
|
|
5
6
|
const render = shallowRef(toValue(value));
|
|
6
7
|
const visible = shallowRef(toValue(value));
|
|
7
8
|
let destroyTimeoutId;
|
|
8
|
-
let
|
|
9
|
+
let visibleRafId = 0;
|
|
9
10
|
async function show() {
|
|
10
11
|
return new Promise((resolve) => {
|
|
11
12
|
clearTimeout(destroyTimeoutId);
|
|
@@ -13,19 +14,23 @@ export function useDelayDestroy(value, options = {}) {
|
|
|
13
14
|
render.value = true;
|
|
14
15
|
renderChange?.(render.value);
|
|
15
16
|
}
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
if (visible.value) {
|
|
18
|
+
resolve(visible.value);
|
|
19
|
+
} else {
|
|
20
|
+
caf(visibleRafId);
|
|
21
|
+
visibleRafId = doubleRaf(() => {
|
|
22
|
+
visibleRafId = 0;
|
|
19
23
|
visible.value = true;
|
|
20
24
|
resolve(visible.value);
|
|
21
25
|
visibleChange?.(visible.value);
|
|
22
|
-
}
|
|
26
|
+
});
|
|
23
27
|
}
|
|
24
28
|
});
|
|
25
29
|
}
|
|
26
30
|
function hide() {
|
|
27
31
|
return new Promise((resolve) => {
|
|
28
|
-
|
|
32
|
+
caf(visibleRafId);
|
|
33
|
+
visibleRafId = 0;
|
|
29
34
|
if (visible.value) {
|
|
30
35
|
visible.value = false;
|
|
31
36
|
visibleChange?.(visible.value);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onScopeDispose, onMounted, shallowRef } from "vue";
|
|
2
2
|
import { cachedOn } from "../utils/event.js";
|
|
3
3
|
import { isServer } from "../utils/is.js";
|
|
4
4
|
export function useDocumentHidden(callback) {
|
|
@@ -11,7 +11,7 @@ export function useDocumentHidden(callback) {
|
|
|
11
11
|
onMounted(() => {
|
|
12
12
|
cleanHidden = cachedOn(document, "visibilitychange", toggle);
|
|
13
13
|
});
|
|
14
|
-
|
|
14
|
+
onScopeDispose(() => {
|
|
15
15
|
cleanHidden?.();
|
|
16
16
|
});
|
|
17
17
|
return isHidden;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createFocusTrap } from "focus-trap";
|
|
2
|
-
import {
|
|
2
|
+
import { onScopeDispose, watch } from "vue";
|
|
3
3
|
import { toValue } from "../utils/ref.js";
|
|
4
4
|
const focusTrapStack = [];
|
|
5
5
|
const AUTO_FOCUS_FIRST_SELECTOR = [
|
|
@@ -45,7 +45,7 @@ export function useFocusTrap(container, userOptions = {}) {
|
|
|
45
45
|
},
|
|
46
46
|
{ flush: "post" }
|
|
47
47
|
);
|
|
48
|
-
|
|
48
|
+
onScopeDispose(() => {
|
|
49
49
|
unwatch();
|
|
50
50
|
});
|
|
51
51
|
return {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ListFilterContext } from '../contexts/list';
|
|
2
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
3
|
+
export type ListFilterFn = (text: string, search: string, keywords: string[]) => boolean;
|
|
4
|
+
export interface UseListFilterOptions {
|
|
5
|
+
keyword: Ref<string>;
|
|
6
|
+
filter?: ListFilterFn;
|
|
7
|
+
}
|
|
8
|
+
export interface UseListFilterReturn extends ListFilterContext {
|
|
9
|
+
visibleCount: ComputedRef<number>;
|
|
10
|
+
}
|
|
11
|
+
export declare function useListFilter({ filter, keyword, }: UseListFilterOptions): UseListFilterReturn;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { computed, shallowRef } from "vue";
|
|
2
|
+
import { isMatch } from "../utils/fuzzy-search.js";
|
|
3
|
+
export function useListFilter({
|
|
4
|
+
filter = isMatch,
|
|
5
|
+
keyword
|
|
6
|
+
}) {
|
|
7
|
+
const items = /* @__PURE__ */ new Map();
|
|
8
|
+
const revision = shallowRef(0);
|
|
9
|
+
const filterState = computed(() => {
|
|
10
|
+
void revision.value;
|
|
11
|
+
let visibleCount2 = 0;
|
|
12
|
+
const search = keyword.value;
|
|
13
|
+
const visibleItems = /* @__PURE__ */ new Set();
|
|
14
|
+
const visibleGroupIds = /* @__PURE__ */ new Set();
|
|
15
|
+
for (const [id, item] of items) {
|
|
16
|
+
if (filter(item.getValue(), search, item.getKeywords())) {
|
|
17
|
+
visibleItems.add(id);
|
|
18
|
+
visibleCount2++;
|
|
19
|
+
if (item.groupId) {
|
|
20
|
+
visibleGroupIds.add(item.groupId);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
visibleItems,
|
|
26
|
+
visibleGroupIds,
|
|
27
|
+
visibleCount: visibleCount2
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
const visibleCount = computed(() => filterState.value.visibleCount);
|
|
31
|
+
function registerItem(id, payload) {
|
|
32
|
+
items.set(id, payload);
|
|
33
|
+
revision.value++;
|
|
34
|
+
}
|
|
35
|
+
function unregisterItem(id) {
|
|
36
|
+
if (!items.has(id)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
items.delete(id);
|
|
40
|
+
revision.value++;
|
|
41
|
+
}
|
|
42
|
+
function isItemVisible(id) {
|
|
43
|
+
return filterState.value.visibleItems.has(id);
|
|
44
|
+
}
|
|
45
|
+
function isGroupVisible(id) {
|
|
46
|
+
return filterState.value.visibleGroupIds.has(id);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
searchValue: keyword,
|
|
50
|
+
visibleCount,
|
|
51
|
+
registerItem,
|
|
52
|
+
isItemVisible,
|
|
53
|
+
isGroupVisible,
|
|
54
|
+
unregisterItem
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter, ShallowRef } from 'vue';
|
|
2
|
+
export interface UseListNavigationOptions {
|
|
3
|
+
loop?: MaybeRefOrGetter<boolean>;
|
|
4
|
+
itemSelector?: MaybeRefOrGetter<string>;
|
|
5
|
+
defaultActiveIndex?: MaybeRefOrGetter<number>;
|
|
6
|
+
toggleOnKeyPress?: MaybeRefOrGetter<boolean>;
|
|
7
|
+
onToggle?: (index: number) => void;
|
|
8
|
+
onEnter?: (el: HTMLElement) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface UseListNavigationReturn {
|
|
11
|
+
activeIndex: ShallowRef<number>;
|
|
12
|
+
setActiveIndex: (index: number) => void;
|
|
13
|
+
registerItem: (el: HTMLElement, indexRef: ShallowRef<number>) => void;
|
|
14
|
+
unregisterItem: (el: HTMLElement) => void;
|
|
15
|
+
onKeydown: (ev: KeyboardEvent) => void;
|
|
16
|
+
onPointerOver: (ev: PointerEvent) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Request a re-query of the DOM items. Multiple calls made within the same
|
|
19
|
+
* tick coalesce into a single refresh that runs after `nextTick`. `await`
|
|
20
|
+
* the returned promise when the caller needs `items` to be up-to-date
|
|
21
|
+
* before its next action (e.g. `setFirstAsActive` after a search change).
|
|
22
|
+
*/
|
|
23
|
+
refreshItems: () => Promise<void>;
|
|
24
|
+
setFirstAsActive: () => void;
|
|
25
|
+
isEmpty: () => boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function useListNavigation(containerRef: MaybeRefOrGetter<HTMLElement | undefined>, options: UseListNavigationOptions): UseListNavigationReturn;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { nextTick, shallowRef } from "vue";
|
|
2
|
+
import { toValue, unrefElement } from "../utils/ref.js";
|
|
3
|
+
const DISABLED_KEYS = ["PageUp", "PageDown"];
|
|
4
|
+
const KEY_DIRECTION = {
|
|
5
|
+
ArrowUp: -1,
|
|
6
|
+
ArrowLeft: -1,
|
|
7
|
+
ArrowDown: 1,
|
|
8
|
+
ArrowRight: 1
|
|
9
|
+
};
|
|
10
|
+
function findNextIndex(len, from, dir, loop) {
|
|
11
|
+
if (len === 0) {
|
|
12
|
+
return -1;
|
|
13
|
+
}
|
|
14
|
+
const i = from + dir;
|
|
15
|
+
if (loop) {
|
|
16
|
+
return (i % len + len) % len;
|
|
17
|
+
}
|
|
18
|
+
if (i < 0 || i >= len) {
|
|
19
|
+
return -1;
|
|
20
|
+
}
|
|
21
|
+
return i;
|
|
22
|
+
}
|
|
23
|
+
export function useListNavigation(containerRef, options) {
|
|
24
|
+
const getLoop = () => toValue(options.loop) ?? true;
|
|
25
|
+
const getToggleOnKeyPress = () => toValue(options.toggleOnKeyPress) ?? true;
|
|
26
|
+
const getDefaultActiveIndex = () => toValue(options.defaultActiveIndex) ?? -1;
|
|
27
|
+
const getItemSelector = () => toValue(options.itemSelector) ?? "[data-list-item]";
|
|
28
|
+
const activeIndex = shallowRef(getDefaultActiveIndex());
|
|
29
|
+
const itemIndexRefs = /* @__PURE__ */ new WeakMap();
|
|
30
|
+
let items = [];
|
|
31
|
+
let lastPointerX = -1;
|
|
32
|
+
let lastPointerY = -1;
|
|
33
|
+
let pendingRefresh = null;
|
|
34
|
+
function runRefresh() {
|
|
35
|
+
const container = unrefElement(containerRef);
|
|
36
|
+
items = container ? Array.from(container.querySelectorAll(getItemSelector())) : [];
|
|
37
|
+
items.forEach((el, i) => {
|
|
38
|
+
const ref = itemIndexRefs.get(el);
|
|
39
|
+
if (ref) {
|
|
40
|
+
ref.value = i;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (activeIndex.value >= items.length) {
|
|
44
|
+
activeIndex.value = items.length - 1;
|
|
45
|
+
}
|
|
46
|
+
const fallback = getDefaultActiveIndex();
|
|
47
|
+
if (activeIndex.value === -1 && fallback >= 0 && fallback < items.length) {
|
|
48
|
+
activeIndex.value = fallback;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function refreshItems() {
|
|
52
|
+
if (pendingRefresh) {
|
|
53
|
+
return pendingRefresh;
|
|
54
|
+
}
|
|
55
|
+
pendingRefresh = nextTick().then(() => {
|
|
56
|
+
pendingRefresh = null;
|
|
57
|
+
runRefresh();
|
|
58
|
+
});
|
|
59
|
+
return pendingRefresh;
|
|
60
|
+
}
|
|
61
|
+
function setActiveIndex(index) {
|
|
62
|
+
activeIndex.value = index;
|
|
63
|
+
}
|
|
64
|
+
function setFirstAsActive() {
|
|
65
|
+
activeIndex.value = findNextIndex(items.length, -1, 1, false);
|
|
66
|
+
}
|
|
67
|
+
function isEmpty() {
|
|
68
|
+
return items.length === 0;
|
|
69
|
+
}
|
|
70
|
+
function registerItem(el, indexRef) {
|
|
71
|
+
itemIndexRefs.set(el, indexRef);
|
|
72
|
+
void refreshItems();
|
|
73
|
+
}
|
|
74
|
+
function unregisterItem(el) {
|
|
75
|
+
itemIndexRefs.delete(el);
|
|
76
|
+
void refreshItems();
|
|
77
|
+
}
|
|
78
|
+
function onPointerOver(ev) {
|
|
79
|
+
if (ev.pageX === lastPointerX && ev.pageY === lastPointerY) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
lastPointerX = ev.pageX;
|
|
83
|
+
lastPointerY = ev.pageY;
|
|
84
|
+
const listItem = ev.target.closest(getItemSelector());
|
|
85
|
+
if (!listItem) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const index = itemIndexRefs.get(listItem)?.value ?? -1;
|
|
89
|
+
if (index !== -1) {
|
|
90
|
+
activeIndex.value = index;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function onKeydown(ev) {
|
|
94
|
+
if (!getToggleOnKeyPress() || isEmpty()) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const { key, ctrlKey, metaKey, altKey, shiftKey } = ev;
|
|
98
|
+
if (DISABLED_KEYS.includes(key)) {
|
|
99
|
+
ev.preventDefault();
|
|
100
|
+
ev.stopPropagation();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (ctrlKey || metaKey || altKey || shiftKey) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const len = items.length;
|
|
107
|
+
const current = activeIndex.value;
|
|
108
|
+
if (key === "Enter") {
|
|
109
|
+
if (current < 0 || current >= len) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const el = items[current];
|
|
113
|
+
if (!el) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
ev.preventDefault();
|
|
117
|
+
ev.stopPropagation();
|
|
118
|
+
if (typeof options.onEnter === "function") {
|
|
119
|
+
options.onEnter(el);
|
|
120
|
+
} else {
|
|
121
|
+
el.click();
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let next;
|
|
126
|
+
if (key === "Home") {
|
|
127
|
+
next = findNextIndex(len, -1, 1, false);
|
|
128
|
+
} else if (key === "End") {
|
|
129
|
+
next = findNextIndex(len, len, -1, false);
|
|
130
|
+
} else {
|
|
131
|
+
const dir = KEY_DIRECTION[key];
|
|
132
|
+
if (!dir) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
next = current === -1 ? findNextIndex(len, dir === 1 ? -1 : len, dir, false) : findNextIndex(len, current, dir, getLoop());
|
|
136
|
+
}
|
|
137
|
+
if (next === -1) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
ev.preventDefault();
|
|
141
|
+
ev.stopPropagation();
|
|
142
|
+
if (next !== current) {
|
|
143
|
+
options.onToggle?.(next);
|
|
144
|
+
activeIndex.value = next;
|
|
145
|
+
items[next]?.scrollIntoView({ block: "nearest" });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
activeIndex,
|
|
150
|
+
setActiveIndex,
|
|
151
|
+
registerItem,
|
|
152
|
+
unregisterItem,
|
|
153
|
+
onKeydown,
|
|
154
|
+
onPointerOver,
|
|
155
|
+
refreshItems,
|
|
156
|
+
setFirstAsActive,
|
|
157
|
+
isEmpty
|
|
158
|
+
};
|
|
159
|
+
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
import { hasScrollbar, isScrollable } from "../utils/dom.js";
|
|
2
2
|
import { cachedOff, cachedOn, preventDefaultScroll } from "../utils/event.js";
|
|
3
|
-
let
|
|
3
|
+
let rootTouchMoveLocks = 0;
|
|
4
4
|
export function useLockScroll() {
|
|
5
|
-
const
|
|
5
|
+
const classList = ["pointer-events-none"];
|
|
6
6
|
function isLocked() {
|
|
7
|
-
return
|
|
7
|
+
return rootTouchMoveLocks > 0;
|
|
8
8
|
}
|
|
9
9
|
function lockScroll() {
|
|
10
10
|
if (!isLocked()) {
|
|
11
|
+
const rootEl = document.documentElement;
|
|
11
12
|
cachedOn(document, "touchmove", preventDefaultScroll, { passive: false });
|
|
12
|
-
const
|
|
13
|
-
const { y:
|
|
14
|
-
|
|
15
|
-
if (yScrollbar && yScrollable) {
|
|
13
|
+
const { x: xScrollbar, y: yScrollbar } = hasScrollbar(rootEl);
|
|
14
|
+
const { x: xScrollable, y: yScrollable } = isScrollable(rootEl);
|
|
15
|
+
if (xScrollbar && xScrollable || yScrollbar && yScrollable) {
|
|
16
16
|
classList.push("scrollbar-stable", "scrollbar-disabled");
|
|
17
17
|
}
|
|
18
18
|
rootEl.classList.add(...classList);
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
rootTouchMoveLocks++;
|
|
21
21
|
}
|
|
22
22
|
function unlockScroll() {
|
|
23
|
-
if (
|
|
23
|
+
if (rootTouchMoveLocks <= 0) {
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
if (!
|
|
26
|
+
rootTouchMoveLocks = Math.max(rootTouchMoveLocks - 1, 0);
|
|
27
|
+
if (!rootTouchMoveLocks) {
|
|
28
28
|
cachedOff(document, "touchmove", preventDefaultScroll);
|
|
29
|
-
|
|
29
|
+
document.documentElement.classList.remove(...classList);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { customRef,
|
|
1
|
+
import { customRef, onScopeDispose } from "vue";
|
|
2
2
|
import { cachedOn } from "../utils/event.js";
|
|
3
3
|
import { isServer } from "../utils/is.js";
|
|
4
4
|
export const PRESET_MEDIA_QUERIES = {
|
|
@@ -69,7 +69,7 @@ export function useMediaQuery(condition, callback) {
|
|
|
69
69
|
}
|
|
70
70
|
mediaQuery = void 0;
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
onScopeDispose(() => {
|
|
73
73
|
stop();
|
|
74
74
|
});
|
|
75
75
|
return matches;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MaybeElementRef } from '../types/shared/utils';
|
|
2
2
|
interface Options {
|
|
3
|
+
allowList?: MaybeElementRef<HTMLElement>[];
|
|
3
4
|
isEnabled?: (ev: PointerEvent) => boolean;
|
|
4
|
-
isOutside?: (ev: PointerEvent) => boolean;
|
|
5
5
|
onTrigger?: (ev: PointerEvent) => void;
|
|
6
6
|
}
|
|
7
7
|
export declare function useOutsideClick(container: MaybeElementRef<HTMLElement>, options?: Options): {
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onScopeDispose, watch } from "vue";
|
|
2
2
|
import { cachedOff, cachedOn } from "../utils/event.js";
|
|
3
3
|
import { toValue } from "../utils/ref.js";
|
|
4
4
|
export function useOutsideClick(container, options = {}) {
|
|
5
5
|
function onClick(ev) {
|
|
6
|
-
const { isEnabled
|
|
6
|
+
const { isEnabled } = options;
|
|
7
7
|
if (typeof isEnabled === "function" && !isEnabled(ev)) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!toValue(container).contains(ev.target)) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
10
|
+
const { onTrigger, allowList = [container] } = options;
|
|
11
|
+
const currentTarget = ev.target;
|
|
12
|
+
const isInside = allowList.some((el) => toValue(el)?.contains(currentTarget));
|
|
13
|
+
if (isInside) {
|
|
14
|
+
return;
|
|
18
15
|
}
|
|
19
16
|
onTrigger?.(ev);
|
|
20
17
|
}
|
|
@@ -34,7 +31,7 @@ export function useOutsideClick(container, options = {}) {
|
|
|
34
31
|
unwatch();
|
|
35
32
|
cachedOff(document, "click", onClick);
|
|
36
33
|
}
|
|
37
|
-
|
|
34
|
+
onScopeDispose(() => {
|
|
38
35
|
stop();
|
|
39
36
|
});
|
|
40
37
|
return {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from 'vue';
|
|
2
|
+
interface OverlayManagerOptions {
|
|
3
|
+
enabled?: MaybeRefOrGetter<boolean>;
|
|
4
|
+
lockScrollOnVisible?: MaybeRefOrGetter<boolean>;
|
|
5
|
+
lockScroll: () => void;
|
|
6
|
+
unlockScroll: () => void;
|
|
7
|
+
onPressEscape?: (ev: KeyboardEvent) => void;
|
|
8
|
+
}
|
|
9
|
+
interface OverlayManagerEntry {
|
|
10
|
+
id: symbol;
|
|
11
|
+
onPressEscape: OverlayManagerOptions['onPressEscape'];
|
|
12
|
+
}
|
|
13
|
+
export declare function useOverlayManager(options: OverlayManagerOptions): {
|
|
14
|
+
isTopOverlay: (entry?: OverlayManagerEntry) => boolean;
|
|
15
|
+
registerOverlay: () => void;
|
|
16
|
+
unregisterOverlay: () => void;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { onScopeDispose } from "vue";
|
|
2
|
+
import { cachedOff, cachedOn } from "../utils/event.js";
|
|
3
|
+
import { toValue } from "../utils/ref.js";
|
|
4
|
+
let isKeydownListening = false;
|
|
5
|
+
const overlayStack = [];
|
|
6
|
+
function getTopOverlay() {
|
|
7
|
+
return overlayStack.at(-1);
|
|
8
|
+
}
|
|
9
|
+
function onEscapeKeydown(ev) {
|
|
10
|
+
const entry = getTopOverlay();
|
|
11
|
+
if (!entry) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const { ctrlKey, metaKey, altKey, shiftKey, key } = ev;
|
|
15
|
+
if (ctrlKey || metaKey || altKey || shiftKey || key !== "Escape") {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
entry?.onPressEscape?.(ev);
|
|
19
|
+
}
|
|
20
|
+
function ensureKeydownListener() {
|
|
21
|
+
if (isKeydownListening) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
cachedOn(document, "keydown", onEscapeKeydown);
|
|
25
|
+
isKeydownListening = true;
|
|
26
|
+
}
|
|
27
|
+
function removeKeydownListener() {
|
|
28
|
+
if (!isKeydownListening || overlayStack.length > 0) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
cachedOff(document, "keydown", onEscapeKeydown);
|
|
32
|
+
isKeydownListening = false;
|
|
33
|
+
}
|
|
34
|
+
export function useOverlayManager(options) {
|
|
35
|
+
const { enabled, lockScrollOnVisible, lockScroll, unlockScroll, onPressEscape } = options;
|
|
36
|
+
let isLockedScroll = false;
|
|
37
|
+
const overlayId = Symbol("pxd-overlay-id");
|
|
38
|
+
function isTopOverlay(entry) {
|
|
39
|
+
entry ??= getTopOverlay();
|
|
40
|
+
return entry?.id === overlayId;
|
|
41
|
+
}
|
|
42
|
+
function registerOverlay() {
|
|
43
|
+
if (!toValue(enabled)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const shouldLockScroll = toValue(lockScrollOnVisible);
|
|
47
|
+
if (shouldLockScroll && !isLockedScroll) {
|
|
48
|
+
lockScroll();
|
|
49
|
+
isLockedScroll = true;
|
|
50
|
+
}
|
|
51
|
+
const idx = overlayStack.findIndex((item) => item.id === overlayId);
|
|
52
|
+
if (idx !== -1) {
|
|
53
|
+
overlayStack.splice(idx, 1);
|
|
54
|
+
}
|
|
55
|
+
overlayStack.push({
|
|
56
|
+
id: overlayId,
|
|
57
|
+
onPressEscape
|
|
58
|
+
});
|
|
59
|
+
ensureKeydownListener();
|
|
60
|
+
}
|
|
61
|
+
function unregisterOverlay() {
|
|
62
|
+
const idx = overlayStack.findIndex((item) => item.id === overlayId);
|
|
63
|
+
if (idx !== -1) {
|
|
64
|
+
overlayStack.splice(idx, 1);
|
|
65
|
+
}
|
|
66
|
+
if (isLockedScroll) {
|
|
67
|
+
unlockScroll();
|
|
68
|
+
isLockedScroll = false;
|
|
69
|
+
}
|
|
70
|
+
removeKeydownListener();
|
|
71
|
+
}
|
|
72
|
+
onScopeDispose(() => {
|
|
73
|
+
unregisterOverlay();
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
isTopOverlay,
|
|
77
|
+
registerOverlay,
|
|
78
|
+
unregisterOverlay
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
export declare function usePopoverResponsive(): {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
readonly
|
|
5
|
-
readonly
|
|
6
|
-
readonly transitionType: "fade-slide";
|
|
2
|
+
isAdaptive: import("vue").Ref<boolean, boolean>;
|
|
3
|
+
responsiveClasses: import("vue").ComputedRef<{
|
|
4
|
+
readonly content: "bg-background-100 shadow-border-menu w-full rounded-tl-xl rounded-tr-xl";
|
|
5
|
+
readonly wrapper: "fixed w-full h-full items-end pointer-events-none";
|
|
7
6
|
} | {
|
|
8
|
-
readonly
|
|
9
|
-
readonly
|
|
10
|
-
readonly transitionType: "fade-scale";
|
|
7
|
+
readonly content: "bg-background-100 shadow-border-menu rounded-xl";
|
|
8
|
+
readonly wrapper: "";
|
|
11
9
|
}>;
|
|
12
10
|
};
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
2
|
import { PRESET_MEDIA_QUERIES, useMediaQuery } from "./use-media-query.js";
|
|
3
3
|
export function usePopoverResponsive() {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
if (isXs.value) {
|
|
4
|
+
const isAdaptive = useMediaQuery(PRESET_MEDIA_QUERIES.IS_XS);
|
|
5
|
+
const responsiveClasses = computed(() => {
|
|
6
|
+
if (isAdaptive.value) {
|
|
8
7
|
return {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
transitionType: "fade-slide"
|
|
8
|
+
content: `bg-background-100 shadow-border-menu w-full rounded-tl-xl rounded-tr-xl`,
|
|
9
|
+
wrapper: "fixed w-full h-full items-end pointer-events-none"
|
|
12
10
|
};
|
|
13
11
|
}
|
|
14
12
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
transitionType: "fade-scale"
|
|
13
|
+
content: `bg-background-100 shadow-border-menu rounded-xl`,
|
|
14
|
+
wrapper: ""
|
|
18
15
|
};
|
|
19
16
|
});
|
|
20
17
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
isAdaptive,
|
|
19
|
+
responsiveClasses
|
|
23
20
|
};
|
|
24
21
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onScopeDispose } from "vue";
|
|
2
2
|
import { off, once } from "../utils/event.js";
|
|
3
3
|
import { toValue } from "../utils/ref.js";
|
|
4
4
|
export function useRepeatAction(actionOrOptions) {
|
|
@@ -40,7 +40,7 @@ export function useRepeatAction(actionOrOptions) {
|
|
|
40
40
|
once(document, "pointerup", stop);
|
|
41
41
|
once(document, "pointercancel", stop);
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
onScopeDispose(() => {
|
|
44
44
|
off(document, "pointerup", stop);
|
|
45
45
|
off(document, "pointercancel", stop);
|
|
46
46
|
});
|