pxd 0.0.39 → 0.0.41
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/README.md +9 -3
- package/dist/components/active-graph/index.vue +10 -5
- package/dist/components/backtop/index.vue +75 -0
- package/dist/components/badge/index.vue +9 -7
- package/dist/components/book/index.vue +3 -3
- package/dist/components/browser/index.vue +2 -2
- package/dist/components/checkbox/index.vue +4 -3
- package/dist/components/checkbox-group/index.vue +1 -1
- package/dist/components/choicebox-group/index.vue +1 -1
- package/dist/components/command-menu/index.vue +124 -0
- package/dist/components/command-menu-group/index.vue +18 -0
- package/dist/components/command-menu-item/index.vue +13 -0
- package/dist/components/countdown/index.vue +2 -1
- package/dist/components/drawer/index.vue +26 -26
- package/dist/components/error/index.vue +2 -2
- package/dist/components/fader/index.vue +31 -17
- package/dist/components/grid/index.vue +2 -2
- package/dist/components/grid-item/index.vue +2 -2
- package/dist/components/hold-button/index.vue +1 -1
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.js +7 -0
- package/dist/components/input/index.vue +18 -10
- package/dist/components/intersection-observer/index.vue +5 -5
- package/dist/components/kbd/index.vue +21 -8
- package/dist/components/{intersection-observer/content.vue → keep-alive-container/index.vue} +3 -1
- package/dist/components/list/index.vue +100 -92
- package/dist/components/list-item/index.vue +35 -33
- package/dist/components/loading-bar/index.vue +149 -0
- package/dist/components/material/index.vue +8 -8
- package/dist/components/menu/index.vue +26 -16
- package/dist/components/message/index.vue +28 -18
- package/dist/components/modal/index.vue +32 -36
- package/dist/components/note/index.vue +1 -1
- package/dist/components/overlay/index.vue +77 -24
- package/dist/components/pagination/index.vue +2 -2
- package/dist/components/placeholder/index.vue +13 -6
- package/dist/components/popover/index.vue +97 -87
- package/dist/components/progress/index.vue +1 -1
- package/dist/components/radio/index.vue +4 -3
- package/dist/components/radio-group/index.vue +1 -1
- package/dist/components/scrollable/index.vue +161 -94
- package/dist/components/slider/index.vue +7 -7
- package/dist/components/stack/index.vue +4 -4
- package/dist/components/switch/index.vue +1 -1
- package/dist/components/text/index.vue +1 -1
- package/dist/components/theme-switcher/index.vue +6 -2
- package/dist/components/time-picker/index.vue +281 -0
- package/dist/components/tooltip/index.vue +7 -7
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/index.js +1 -0
- package/dist/composables/use-browser-observer.d.ts +5 -5
- package/dist/composables/use-color-scheme.d.ts +5 -1
- package/dist/composables/use-color-scheme.js +20 -1
- package/dist/composables/use-config-provider-context.d.ts +1 -1
- package/dist/composables/use-countdown.d.ts +6 -0
- package/dist/composables/use-countdown.js +21 -7
- package/dist/composables/use-delay-destroy.d.ts +4 -4
- package/dist/composables/use-delay-destroy.js +15 -11
- package/dist/composables/use-focus-trap.d.ts +2 -2
- package/dist/composables/use-focus-trap.js +6 -6
- package/dist/composables/use-loading-bar.d.ts +25 -0
- package/dist/composables/use-loading-bar.js +27 -0
- package/dist/composables/use-media-query.js +1 -1
- package/dist/composables/use-message.d.ts +4 -1
- package/dist/composables/use-message.js +18 -0
- package/dist/composables/use-pointer-gesture.d.ts +2 -2
- package/dist/composables/use-pointer-gesture.js +3 -3
- package/dist/composables/use-repeat-action.d.ts +2 -2
- package/dist/composables/use-repeat-action.js +5 -5
- package/dist/composables/use-virtual-list.d.ts +1 -1
- package/dist/contexts/avatar.d.ts +1 -1
- package/dist/contexts/carousel.d.ts +1 -1
- package/dist/contexts/checkbox.d.ts +1 -1
- package/dist/contexts/choicebox.d.ts +2 -2
- package/dist/contexts/collapse.d.ts +1 -1
- package/dist/contexts/list.d.ts +5 -6
- package/dist/contexts/list.js +3 -3
- package/dist/contexts/radio.d.ts +1 -1
- package/dist/contexts/resizable.d.ts +1 -1
- package/dist/contexts/switch.d.ts +2 -2
- package/dist/{components/carousel → dist/components/keep-alive-container}/index.vue.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/locales/en-us.d.ts +15 -7
- package/dist/locales/en-us.js +17 -9
- package/dist/locales/zh-cn.d.ts +15 -7
- package/dist/locales/zh-cn.js +17 -9
- package/dist/{components → src/components}/active-graph/index.vue.d.ts +7 -5
- package/dist/{components → src/components}/avatar-group/index.vue.d.ts +1 -1
- package/dist/src/components/backtop/index.vue.d.ts +20 -0
- package/dist/{components → src/components}/badge/index.vue.d.ts +2 -1
- package/dist/{components → src/components}/book/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/browser/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/button/index.vue.d.ts +1 -1
- package/dist/{components/intersection-observer/content.vue.d.ts → src/components/carousel/index.vue.d.ts} +1 -1
- package/dist/{components → src/components}/carousel-group/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/chip/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/choicebox/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/choicebox-group/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/collapse/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/collapse-group/index.vue.d.ts +1 -1
- package/dist/src/components/command-menu/index.vue.d.ts +39 -0
- package/dist/src/components/command-menu-group/index.vue.d.ts +16 -0
- package/dist/src/components/command-menu-item/index.vue.d.ts +12 -0
- package/dist/{components → src/components}/config-provider/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/description/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/drawer/index.vue.d.ts +19 -14
- package/dist/{components → src/components}/empty-state/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/error/index.vue.d.ts +1 -1
- package/dist/src/components/fader/index.vue.d.ts +11 -0
- package/dist/{components → src/components}/gauge/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/grid/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/grid-item/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/hold-button/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/input/index.vue.d.ts +9 -4
- package/dist/{components → src/components}/intersection-observer/index.vue.d.ts +3 -3
- package/dist/{components → src/components}/kbd/index.vue.d.ts +8 -5
- package/dist/src/components/keep-alive-container/index.vue.d.ts +12 -0
- package/dist/{components → src/components}/link-button/index.vue.d.ts +1 -1
- package/dist/src/components/list/index.vue.d.ts +40 -0
- package/dist/{components → src/components}/list-item/index.vue.d.ts +4 -4
- package/dist/src/components/loading-bar/index.vue.d.ts +14 -0
- package/dist/{components → src/components}/loading-dots/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/material/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/menu/index.vue.d.ts +11 -7
- package/dist/{components → src/components}/message/index.vue.d.ts +13 -13
- package/dist/{components → src/components}/modal/index.vue.d.ts +19 -14
- package/dist/{components → src/components}/more-button/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/note/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/number-input/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/overlay/index.vue.d.ts +3 -4
- package/dist/{components → src/components}/pagination/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/pin-input/index.vue.d.ts +1 -1
- package/dist/src/components/placeholder/index.vue.d.ts +9 -0
- package/dist/{components → src/components}/popover/index.vue.d.ts +10 -8
- package/dist/{components → src/components}/progress/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/radio/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/radio-group/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/resizable/index.vue.d.ts +1 -1
- package/dist/src/components/resizable-handle/index.vue.d.ts +2 -0
- package/dist/{components → src/components}/resizable-panel/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/skeleton/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/slider/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/snippet/index.vue.d.ts +1 -1
- package/dist/src/components/spinner/index.vue.d.ts +2 -0
- package/dist/{components → src/components}/stack/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/status-dot/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/switch/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/switch-group/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/teleport/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/text/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/textarea/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/theme-switcher/index.vue.d.ts +1 -1
- package/dist/src/components/time-picker/index.vue.d.ts +25 -0
- package/dist/{components → src/components}/toggle/index.vue.d.ts +1 -1
- package/dist/{components → src/components}/tooltip/index.vue.d.ts +3 -5
- package/dist/{components → src/components}/virtual-list/index.vue.d.ts +1 -1
- package/dist/src/composables/use-browser-observer.d.ts +12 -0
- package/dist/src/composables/use-color-scheme.d.ts +11 -0
- package/dist/src/composables/use-config-provider-context.d.ts +7 -0
- package/dist/src/composables/use-copy-click.d.ts +4 -0
- package/dist/src/composables/use-countdown.d.ts +60 -0
- package/dist/src/composables/use-delay-change.d.ts +7 -0
- package/dist/src/composables/use-delay-destroy.d.ts +13 -0
- package/dist/src/composables/use-focus-trap.d.ts +4 -0
- package/dist/src/composables/use-loading-bar.d.ts +25 -0
- package/dist/src/composables/use-media-query.d.ts +15 -0
- package/dist/src/composables/use-message.d.ts +33 -0
- package/dist/src/composables/use-model-value.d.ts +11 -0
- package/dist/src/composables/use-pointer-gesture.d.ts +180 -0
- package/dist/src/composables/use-repeat-action.d.ts +16 -0
- package/dist/src/composables/use-unique-id-context.d.ts +2 -0
- package/dist/src/composables/use-virtual-list.d.ts +16 -0
- package/dist/src/contexts/avatar.d.ts +2 -0
- package/dist/src/contexts/carousel.d.ts +13 -0
- package/dist/src/contexts/checkbox.d.ts +2 -0
- package/dist/src/contexts/choicebox.d.ts +4 -0
- package/dist/src/contexts/collapse.d.ts +8 -0
- package/dist/src/contexts/list.d.ts +8 -0
- package/dist/src/contexts/radio.d.ts +2 -0
- package/dist/src/contexts/resizable.d.ts +35 -0
- package/dist/src/contexts/switch.d.ts +4 -0
- package/dist/src/locales/en-us.d.ts +42 -0
- package/dist/src/plugins/dayjs-millisecond-token.d.ts +3 -0
- package/dist/src/types/components/time-picker.d.ts +4 -0
- package/dist/src/utils/context.d.ts +17 -0
- package/dist/src/utils/date.d.ts +26 -0
- package/dist/src/utils/debounce/index.d.ts +73 -0
- package/dist/src/utils/debounce.d.ts +1 -0
- package/dist/src/utils/dom.d.ts +40 -0
- package/dist/{utils/events.d.ts → src/utils/event.d.ts} +1 -0
- package/dist/src/utils/format.d.ts +25 -0
- package/dist/src/utils/get.d.ts +11 -0
- package/dist/src/utils/is.d.ts +4 -0
- package/dist/src/utils/ref.d.ts +5 -0
- package/dist/src/utils/regexp.d.ts +8 -0
- package/dist/src/utils/responsive.d.ts +3 -0
- package/dist/src/utils/throttle/index.d.ts +53 -0
- package/dist/src/utils/throttle.d.ts +1 -0
- package/dist/src/utils/uid.d.ts +1 -0
- package/dist/styles/styles.css +2 -2
- package/dist/styles/tw.css +18 -1
- package/dist/types/components/list.d.ts +4 -3
- package/dist/types/components/time-picker.d.ts +4 -0
- package/dist/types/components/time-picker.js +0 -0
- package/dist/types/shared/utils.d.ts +5 -2
- package/dist/utils/date.d.ts +3 -3
- package/dist/utils/debounce/compat.d.ts +143 -0
- package/dist/utils/debounce/compat.js +47 -0
- package/dist/utils/debounce/index.d.ts +73 -0
- package/dist/utils/debounce/index.js +60 -0
- package/dist/utils/debounce.d.ts +1 -73
- package/dist/utils/debounce.js +1 -60
- package/dist/utils/event.d.ts +9 -0
- package/dist/utils/{events.js → event.js} +3 -0
- package/dist/utils/format.d.ts +4 -1
- package/dist/utils/format.js +6 -0
- package/dist/utils/ref.d.ts +2 -5
- package/dist/utils/regexp.d.ts +4 -0
- package/dist/utils/regexp.js +4 -0
- package/dist/utils/responsive.d.ts +2 -1
- package/dist/utils/responsive.js +4 -1
- package/dist/utils/throttle/compat.d.ts +79 -0
- package/dist/utils/throttle/compat.js +9 -0
- package/dist/utils/throttle/index.d.ts +53 -0
- package/dist/utils/throttle/index.js +34 -0
- package/dist/utils/throttle.d.ts +1 -53
- package/dist/utils/throttle.js +1 -34
- package/dist/utils/uid.js +1 -1
- package/package.json +11 -11
- package/volar.d.ts +7 -0
- package/dist/components/fader/index.vue.d.ts +0 -11
- package/dist/components/list/index.vue.d.ts +0 -29
- package/dist/components/placeholder/index.vue.d.ts +0 -8
- package/dist/components/resizable-handle/index.vue.d.ts +0 -2
- package/dist/components/spinner/index.vue.d.ts +0 -2
- /package/dist/{components → src/components}/avatar/index.vue.d.ts +0 -0
- /package/dist/{components → src/components}/checkbox/index.vue.d.ts +0 -0
- /package/dist/{components → src/components}/checkbox-group/index.vue.d.ts +0 -0
- /package/dist/{components → src/components}/countdown/index.vue.d.ts +0 -0
|
@@ -1,106 +1,86 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
3
|
-
import { provideListContext
|
|
4
|
-
import {
|
|
2
|
+
import { nextTick, onBeforeUnmount, onMounted, shallowRef } from "vue";
|
|
3
|
+
import { provideListContext } from "../../contexts/list";
|
|
4
|
+
import { optimizedOff, optimizedOn } from "../../utils/event";
|
|
5
5
|
import { getCssUnitValue } from "../../utils/format";
|
|
6
6
|
import { isServer } from "../../utils/is";
|
|
7
7
|
import { throttle } from "../../utils/throttle";
|
|
8
8
|
import PListItem from "../list-item/index.vue";
|
|
9
9
|
import PScrollable from "../scrollable/index.vue";
|
|
10
10
|
defineOptions({
|
|
11
|
-
name: "PList"
|
|
11
|
+
name: "PList",
|
|
12
|
+
inheritAttrs: false
|
|
12
13
|
});
|
|
13
14
|
const props = defineProps({
|
|
15
|
+
loop: { type: Boolean, required: false, default: true },
|
|
14
16
|
width: { type: [String, Number], required: false },
|
|
15
17
|
options: { type: Array, required: false, default: () => [] },
|
|
16
|
-
|
|
18
|
+
keyListener: { type: Boolean, required: false, default: true },
|
|
19
|
+
itemTransition: { type: Boolean, required: false, default: true }
|
|
17
20
|
});
|
|
18
|
-
const emits = defineEmits(["
|
|
21
|
+
const emits = defineEmits(["toggle", "select"]);
|
|
22
|
+
const activeValue = shallowRef("");
|
|
23
|
+
const containerRef = shallowRef();
|
|
19
24
|
const ITEM_CLASS = "pxd-list-item";
|
|
20
|
-
const
|
|
21
|
-
const initialIndex = Number.NaN;
|
|
22
|
-
const activeIndex = shallowRef(initialIndex);
|
|
23
|
-
const increaseIndex = shallowRef(0);
|
|
24
|
-
const allItems = shallowRef([]);
|
|
25
|
-
const computedStyle = computed(() => {
|
|
26
|
-
return {
|
|
27
|
-
width: getCssUnitValue(props.width)
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
function registerListItem(el) {
|
|
31
|
-
if (!allItems.value.includes(el)) {
|
|
32
|
-
allItems.value.push(el);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function unregisterListItem(el) {
|
|
36
|
-
const index = allItems.value.indexOf(el);
|
|
37
|
-
if (index >= 0) {
|
|
38
|
-
allItems.value.splice(index, 1);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function getItemData(index) {
|
|
42
|
-
const element = allItems.value[index];
|
|
43
|
-
if (!element) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
const { disabled, type = "default" } = element.dataset;
|
|
47
|
-
return {
|
|
48
|
-
disabled: disabled === "true",
|
|
49
|
-
type
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function getCorrectIndex(dir, index) {
|
|
53
|
-
const nextIndex = dir === "prev" ? index - 1 : index + 1;
|
|
54
|
-
const length = allItems.value.length;
|
|
55
|
-
if (nextIndex < 0) {
|
|
56
|
-
return length - 1;
|
|
57
|
-
}
|
|
58
|
-
if (nextIndex >= length) {
|
|
59
|
-
return 0;
|
|
60
|
-
}
|
|
61
|
-
const item = getItemData(nextIndex);
|
|
62
|
-
if (item?.disabled) {
|
|
63
|
-
return getCorrectIndex(dir, nextIndex);
|
|
64
|
-
}
|
|
65
|
-
return nextIndex;
|
|
66
|
-
}
|
|
25
|
+
const itemSelector = `.${ITEM_CLASS}:not([data-disabled="true"])`;
|
|
67
26
|
const PREV_KEYS = ["ArrowUp", "ArrowLeft"];
|
|
68
27
|
const NEXT_KEYS = ["ArrowDown", "ArrowRight"];
|
|
69
|
-
const FUNCTION_KEYS = ["Enter", "
|
|
28
|
+
const FUNCTION_KEYS = ["Enter", "Tab", "Home", "End"];
|
|
70
29
|
const PREVENT_DEFAULT_KEYS = [...FUNCTION_KEYS, ...PREV_KEYS, ...NEXT_KEYS];
|
|
71
|
-
const
|
|
30
|
+
const listItemKeys = [];
|
|
31
|
+
const listItemsMap = /* @__PURE__ */ new Map();
|
|
72
32
|
const containerKeydownThrottled = throttle((ev) => {
|
|
73
|
-
const count = allItems.value.length;
|
|
74
|
-
if (count === 0) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
33
|
const { key } = ev;
|
|
78
34
|
if (key === "Tab") {
|
|
79
35
|
return;
|
|
80
36
|
}
|
|
81
37
|
if (key === "Enter") {
|
|
82
|
-
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (key === "Escape" && props.closeOnPressEscape) {
|
|
86
|
-
emits("close");
|
|
38
|
+
listItemsMap.get(activeValue.value)?.click();
|
|
87
39
|
return;
|
|
88
40
|
}
|
|
41
|
+
let newActiveValue = "";
|
|
89
42
|
if (PREV_KEYS.includes(key)) {
|
|
90
|
-
|
|
91
|
-
|
|
43
|
+
if (activeValue.value) {
|
|
44
|
+
const index = listItemKeys.indexOf(activeValue.value);
|
|
45
|
+
if (props.loop) {
|
|
46
|
+
const prevIndex = (index - 1 + listItemKeys.length) % listItemKeys.length;
|
|
47
|
+
newActiveValue = listItemKeys[prevIndex];
|
|
48
|
+
} else if (index > 0) {
|
|
49
|
+
newActiveValue = listItemKeys[index - 1];
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
newActiveValue = listItemKeys.at(-1);
|
|
53
|
+
}
|
|
92
54
|
} else if (NEXT_KEYS.includes(key)) {
|
|
93
|
-
|
|
94
|
-
|
|
55
|
+
if (activeValue.value) {
|
|
56
|
+
const index = listItemKeys.indexOf(activeValue.value);
|
|
57
|
+
if (props.loop) {
|
|
58
|
+
const nextIndex = (index + 1) % listItemKeys.length;
|
|
59
|
+
newActiveValue = listItemKeys[nextIndex];
|
|
60
|
+
} else if (index < listItemKeys.length - 1) {
|
|
61
|
+
newActiveValue = listItemKeys[index + 1];
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
newActiveValue = listItemKeys.at(0);
|
|
65
|
+
}
|
|
66
|
+
} else if (key === "Home") {
|
|
67
|
+
newActiveValue = listItemKeys.at(0);
|
|
68
|
+
} else if (key === "End") {
|
|
69
|
+
newActiveValue = listItemKeys.at(-1);
|
|
95
70
|
}
|
|
96
|
-
if (
|
|
71
|
+
if (!newActiveValue) {
|
|
97
72
|
return;
|
|
98
73
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
74
|
+
if (activeValue.value !== newActiveValue) {
|
|
75
|
+
emits("toggle");
|
|
76
|
+
activeValue.value = newActiveValue;
|
|
77
|
+
}
|
|
78
|
+
listItemsMap.get(activeValue.value)?.scrollIntoView({ block: "nearest" });
|
|
79
|
+
}, 100, { edges: ["leading"] });
|
|
103
80
|
function onContainerKeydown(ev) {
|
|
81
|
+
if (!props.keyListener || listItemKeys.length === 0) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
104
84
|
if (PREVENT_DEFAULT_KEYS.includes(ev.key)) {
|
|
105
85
|
ev.preventDefault();
|
|
106
86
|
}
|
|
@@ -109,45 +89,73 @@ function onContainerKeydown(ev) {
|
|
|
109
89
|
}
|
|
110
90
|
function onPointerOver(ev) {
|
|
111
91
|
const target = ev.target;
|
|
112
|
-
const listItem = target.closest(
|
|
113
|
-
|
|
92
|
+
const listItem = target.closest(`.${ITEM_CLASS}`);
|
|
93
|
+
const itemValue = listItem?.dataset.value;
|
|
94
|
+
if (!listItem || itemValue === void 0) {
|
|
114
95
|
return;
|
|
115
96
|
}
|
|
116
|
-
|
|
97
|
+
activeValue.value = itemValue;
|
|
117
98
|
}
|
|
118
|
-
function onOptionClick(ev,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
emits("
|
|
99
|
+
function onOptionClick(ev, item) {
|
|
100
|
+
const { as, onClick, ...option } = item;
|
|
101
|
+
activeValue.value = "";
|
|
102
|
+
emits("select", ev, option);
|
|
103
|
+
}
|
|
104
|
+
function updateListItem() {
|
|
105
|
+
listItemsMap.clear();
|
|
106
|
+
listItemKeys.splice(0);
|
|
107
|
+
Array.from(containerRef.value.querySelectorAll(itemSelector)).forEach((el) => {
|
|
108
|
+
const key = el.dataset.value;
|
|
109
|
+
listItemsMap.set(key, el);
|
|
110
|
+
listItemKeys.push(key);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function isNoVisibleItem() {
|
|
114
|
+
return listItemsMap.size === 0;
|
|
115
|
+
}
|
|
116
|
+
function setActiveValue(newValue = "") {
|
|
117
|
+
activeValue.value = newValue;
|
|
118
|
+
}
|
|
119
|
+
function setActiveValueToFirst() {
|
|
120
|
+
setActiveValue(listItemKeys[0]);
|
|
122
121
|
}
|
|
123
|
-
provideListItemIndexContext(increaseIndex);
|
|
124
122
|
provideListContext({
|
|
125
|
-
|
|
126
|
-
onOptionClick
|
|
127
|
-
registerListItem,
|
|
128
|
-
unregisterListItem
|
|
123
|
+
activeValue,
|
|
124
|
+
onOptionClick
|
|
129
125
|
});
|
|
130
|
-
onMounted(() => {
|
|
126
|
+
onMounted(async () => {
|
|
131
127
|
if (isServer) {
|
|
132
128
|
return;
|
|
133
129
|
}
|
|
134
|
-
|
|
130
|
+
await nextTick();
|
|
131
|
+
updateListItem();
|
|
132
|
+
optimizedOn(document, "keydown", onContainerKeydown);
|
|
135
133
|
});
|
|
136
134
|
onBeforeUnmount(() => {
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
listItemsMap.clear();
|
|
136
|
+
listItemKeys.splice(0);
|
|
137
|
+
optimizedOff(document, "keydown", onContainerKeydown);
|
|
138
|
+
});
|
|
139
|
+
defineExpose({
|
|
140
|
+
setActiveValue,
|
|
141
|
+
updateListItem,
|
|
142
|
+
isNoVisibleItem,
|
|
143
|
+
setActiveValueToFirst
|
|
139
144
|
});
|
|
140
145
|
</script>
|
|
141
146
|
|
|
142
147
|
<template>
|
|
143
148
|
<ul
|
|
149
|
+
ref="containerRef"
|
|
144
150
|
role="list"
|
|
145
151
|
tabindex="-1"
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
:data-transition="itemTransition"
|
|
153
|
+
class="pxd-list group/list max-w-full list-none bg-background-100 outline-none"
|
|
154
|
+
:style="{ width: getCssUnitValue(width) }"
|
|
155
|
+
v-bind="$attrs"
|
|
148
156
|
@pointerover="onPointerOver"
|
|
149
157
|
>
|
|
150
|
-
<PScrollable class="max-h-
|
|
158
|
+
<PScrollable class="p-2 h-full max-h-inherit rounded-inherit" fader-direction="vertical">
|
|
151
159
|
<slot>
|
|
152
160
|
<PListItem
|
|
153
161
|
v-for="(option, index) in options"
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed,
|
|
3
|
-
import { useListContext,
|
|
2
|
+
import { computed, nextTick, onMounted, shallowRef } from "vue";
|
|
3
|
+
import { useListContext, useListFilterValue } from "../../contexts/list";
|
|
4
|
+
import { unrefElement } from "../../utils/ref";
|
|
5
|
+
import { getUniqueId } from "../../utils/uid";
|
|
4
6
|
defineOptions({
|
|
5
7
|
name: "PListItem"
|
|
6
8
|
});
|
|
@@ -13,40 +15,40 @@ const props = defineProps({
|
|
|
13
15
|
});
|
|
14
16
|
const emits = defineEmits(["click"]);
|
|
15
17
|
const {
|
|
16
|
-
|
|
17
|
-
onOptionClick
|
|
18
|
-
registerListItem,
|
|
19
|
-
unregisterListItem
|
|
18
|
+
activeValue,
|
|
19
|
+
onOptionClick
|
|
20
20
|
} = useListContext();
|
|
21
|
-
const
|
|
22
|
-
const
|
|
21
|
+
const uniqueId = getUniqueId();
|
|
22
|
+
const filterValue = useListFilterValue();
|
|
23
23
|
const itemRef = shallowRef();
|
|
24
|
-
const
|
|
24
|
+
const currentValue = shallowRef("");
|
|
25
25
|
const itemTypeMap = {
|
|
26
|
-
error: "text-red-900 data-[selected=true]:bg-red-100",
|
|
27
|
-
warning: "text-amber-900 data-[selected=true]:bg-amber-100",
|
|
28
|
-
default: "text-foreground data-[selected=true]:bg-gray-alpha-100"
|
|
26
|
+
error: "text-red-900 pointer-coarse:active:bg-red-100 pointer-fine:data-[selected=true]:bg-red-100",
|
|
27
|
+
warning: "text-amber-900 pointer-coarse:active:bg-amber-100 pointer-fine:data-[selected=true]:bg-amber-100",
|
|
28
|
+
default: "text-foreground pointer-coarse:active:bg-gray-alpha-100 pointer-fine:data-[selected=true]:bg-gray-alpha-100",
|
|
29
|
+
separator: "!h-0 !w-auto px-0 m-1.5 border-b"
|
|
29
30
|
};
|
|
30
|
-
const
|
|
31
|
+
const isVisible = computed(() => filterValue?.value ? currentValue.value.includes(filterValue.value) : true);
|
|
32
|
+
const isSelected = computed(() => activeValue.value === uniqueId);
|
|
33
|
+
const isDisabled = computed(() => props.disabled || props.type === "separator");
|
|
31
34
|
const computedClass = computed(() => {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
const { type = "default" } = props;
|
|
36
|
+
const classes = ["pxd-list-item h-10 gap-3 px-2 text-sm flex w-full cursor-pointer items-center rounded-md outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:text-gray-700 group-data-[transition=true]/list:motion-safe:transition-colors"];
|
|
37
|
+
if (type in itemTypeMap) {
|
|
38
|
+
classes.push(itemTypeMap[type]);
|
|
35
39
|
}
|
|
36
40
|
return classes.join(" ");
|
|
37
41
|
});
|
|
38
42
|
function onItemClick(ev) {
|
|
39
|
-
emits("click", ev,
|
|
40
|
-
onOptionClick?.(ev,
|
|
43
|
+
emits("click", ev, props);
|
|
44
|
+
onOptionClick?.(ev, props);
|
|
41
45
|
}
|
|
42
|
-
onMounted(() => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (unregisterListItem) {
|
|
49
|
-
unregisterListItem(itemRef.value);
|
|
46
|
+
onMounted(async () => {
|
|
47
|
+
await nextTick();
|
|
48
|
+
if (props.label) {
|
|
49
|
+
currentValue.value = `${String(props.label || "")}${props.description || ""}`.toLowerCase().replace(/\s/g, "");
|
|
50
|
+
} else {
|
|
51
|
+
currentValue.value = (unrefElement(itemRef.value)?.textContent || "").toLowerCase().replace(/\s/g, "");
|
|
50
52
|
}
|
|
51
53
|
});
|
|
52
54
|
</script>
|
|
@@ -54,20 +56,20 @@ onUnmounted(() => {
|
|
|
54
56
|
<template>
|
|
55
57
|
<Component
|
|
56
58
|
:is="as"
|
|
59
|
+
v-if="isVisible"
|
|
57
60
|
ref="itemRef"
|
|
58
61
|
tabindex="-1"
|
|
59
62
|
role="listitem"
|
|
60
63
|
:data-type="type"
|
|
61
|
-
:data-
|
|
62
|
-
:data-disabled="disabled"
|
|
64
|
+
:data-value="uniqueId"
|
|
63
65
|
:data-selected="isSelected"
|
|
64
|
-
|
|
66
|
+
:data-disabled="isDisabled"
|
|
65
67
|
:class="computedClass"
|
|
66
|
-
@click="onItemClick"
|
|
68
|
+
@click.prevent.stop="onItemClick"
|
|
67
69
|
>
|
|
68
|
-
<slot>
|
|
69
|
-
<span
|
|
70
|
-
<span v-if="description" class="text-
|
|
70
|
+
<slot v-if="type !== 'separator'">
|
|
71
|
+
<span>{{ label }}</span>
|
|
72
|
+
<span v-if="description" class="text-foreground-secondary">{{ description }}</span>
|
|
71
73
|
</slot>
|
|
72
74
|
</component>
|
|
73
75
|
</template>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, onBeforeUnmount, onMounted, shallowRef } from "vue";
|
|
3
|
+
import {
|
|
4
|
+
ERROR_LOADING_BAR_EVENT_NAME,
|
|
5
|
+
FINISH_LOADING_BAR_EVENT_NAME,
|
|
6
|
+
INCREASE_LOADING_BAR_EVENT_NAME,
|
|
7
|
+
START_LOADING_BAR_EVENT_NAME
|
|
8
|
+
} from "../../composables/use-loading-bar";
|
|
9
|
+
import { optimizedOff, optimizedOn } from "../../utils/event";
|
|
10
|
+
import { clampValue } from "../../utils/format";
|
|
11
|
+
import { isServer } from "../../utils/is";
|
|
12
|
+
import PTeleport from "../teleport/index.vue";
|
|
13
|
+
defineOptions({
|
|
14
|
+
name: "PLoadingBar",
|
|
15
|
+
inheritAttrs: false
|
|
16
|
+
});
|
|
17
|
+
const props = defineProps({
|
|
18
|
+
to: { type: null, required: false },
|
|
19
|
+
group: { type: String, required: false, default: "default" },
|
|
20
|
+
minimum: { type: Number, required: false, default: 0.08 },
|
|
21
|
+
trickle: { type: Boolean, required: false, default: true },
|
|
22
|
+
trickleThreshold: { type: Number, required: false, default: 300 }
|
|
23
|
+
});
|
|
24
|
+
let hideTimerId;
|
|
25
|
+
let prevTimestamp = 0;
|
|
26
|
+
let prevAnimationKey = 0;
|
|
27
|
+
const status = shallowRef("finish");
|
|
28
|
+
const hidden = shallowRef(false);
|
|
29
|
+
const progress = shallowRef(0);
|
|
30
|
+
const computedClass = computed(() => {
|
|
31
|
+
const _status = status.value;
|
|
32
|
+
return {
|
|
33
|
+
"opacity-0": hidden.value,
|
|
34
|
+
"bg-primary": _status === "running" || _status === "finish",
|
|
35
|
+
"bg-red-900": _status === "error"
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
function getIncreaseDelta(n) {
|
|
39
|
+
if (n >= 0 && n < 0.2) {
|
|
40
|
+
return 0.1;
|
|
41
|
+
} else if (n >= 0.2 && n < 0.5) {
|
|
42
|
+
return 0.04;
|
|
43
|
+
} else if (n >= 0.5 && n < 0.8) {
|
|
44
|
+
return 0.02;
|
|
45
|
+
} else if (n >= 0.8 && n < 0.98) {
|
|
46
|
+
return 5e-3;
|
|
47
|
+
} else {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function increaseProgress(n) {
|
|
52
|
+
if (progress.value >= 1) {
|
|
53
|
+
cancelAnimationFrame(prevAnimationKey);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const now = performance.now();
|
|
57
|
+
const delta = now - prevTimestamp;
|
|
58
|
+
const threshold = props.trickleThreshold || 200;
|
|
59
|
+
if (delta < threshold && props.trickle) {
|
|
60
|
+
prevAnimationKey = requestAnimationFrame(() => increaseProgress());
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
prevTimestamp = now;
|
|
64
|
+
const amount = n || getIncreaseDelta(progress.value);
|
|
65
|
+
progress.value = clampValue(progress.value + amount, 0, 0.994);
|
|
66
|
+
if (amount === 0 || !props.trickle) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
prevAnimationKey = requestAnimationFrame(() => increaseProgress());
|
|
70
|
+
}
|
|
71
|
+
function onStartProgress({ detail }) {
|
|
72
|
+
if (detail.group !== props.group) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
hidden.value = false;
|
|
76
|
+
status.value = "running";
|
|
77
|
+
clearTimeout(hideTimerId);
|
|
78
|
+
progress.value = props.minimum;
|
|
79
|
+
if (!props.trickle) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
prevTimestamp = 0;
|
|
83
|
+
requestAnimationFrame(() => increaseProgress());
|
|
84
|
+
}
|
|
85
|
+
function onErrorProgress({ detail }) {
|
|
86
|
+
if (detail.group !== props.group) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
cancelAnimationFrame(prevAnimationKey);
|
|
90
|
+
clearTimeout(hideTimerId);
|
|
91
|
+
status.value = "error";
|
|
92
|
+
hidden.value = false;
|
|
93
|
+
progress.value = 1;
|
|
94
|
+
hideTimerId = setTimeout(() => {
|
|
95
|
+
hidden.value = true;
|
|
96
|
+
}, 300);
|
|
97
|
+
}
|
|
98
|
+
function onFinishProgress({ detail }) {
|
|
99
|
+
if (detail.group !== props.group) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
cancelAnimationFrame(prevAnimationKey);
|
|
103
|
+
clearTimeout(hideTimerId);
|
|
104
|
+
status.value = "finish";
|
|
105
|
+
hidden.value = false;
|
|
106
|
+
progress.value = 1;
|
|
107
|
+
hideTimerId = setTimeout(() => {
|
|
108
|
+
hidden.value = true;
|
|
109
|
+
}, 300);
|
|
110
|
+
}
|
|
111
|
+
function onIncreaseProgress({ detail }) {
|
|
112
|
+
if (detail.group !== props.group) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
increaseProgress(detail.value);
|
|
116
|
+
}
|
|
117
|
+
onMounted(() => {
|
|
118
|
+
if (isServer) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
optimizedOn(window, START_LOADING_BAR_EVENT_NAME, onStartProgress);
|
|
122
|
+
optimizedOn(window, ERROR_LOADING_BAR_EVENT_NAME, onErrorProgress);
|
|
123
|
+
optimizedOn(window, FINISH_LOADING_BAR_EVENT_NAME, onFinishProgress);
|
|
124
|
+
optimizedOn(window, INCREASE_LOADING_BAR_EVENT_NAME, onIncreaseProgress);
|
|
125
|
+
});
|
|
126
|
+
onBeforeUnmount(() => {
|
|
127
|
+
optimizedOff(window, START_LOADING_BAR_EVENT_NAME, onStartProgress);
|
|
128
|
+
optimizedOff(window, ERROR_LOADING_BAR_EVENT_NAME, onErrorProgress);
|
|
129
|
+
optimizedOff(window, FINISH_LOADING_BAR_EVENT_NAME, onFinishProgress);
|
|
130
|
+
optimizedOff(window, INCREASE_LOADING_BAR_EVENT_NAME, onIncreaseProgress);
|
|
131
|
+
});
|
|
132
|
+
</script>
|
|
133
|
+
|
|
134
|
+
<template>
|
|
135
|
+
<PTeleport :to="to">
|
|
136
|
+
<div
|
|
137
|
+
aria-hidden="true"
|
|
138
|
+
class="pxd-loading-bar top-0 left-0 right-0 h-0.5 pointer-events-none z-10 max-w-full overflow-hidden"
|
|
139
|
+
:class="to ? 'absolute' : 'fixed'"
|
|
140
|
+
v-bind="$attrs"
|
|
141
|
+
>
|
|
142
|
+
<div
|
|
143
|
+
class="pxd-loading-bar--inner size-full origin-left rounded-r-full motion-safe:transition-all"
|
|
144
|
+
:class="computedClass"
|
|
145
|
+
:style="{ transform: `scaleX(${progress})` }"
|
|
146
|
+
/>
|
|
147
|
+
</div>
|
|
148
|
+
</PTeleport>
|
|
149
|
+
</template>
|
|
@@ -18,35 +18,35 @@ defineProps({
|
|
|
18
18
|
<style lang="postcss">
|
|
19
19
|
.pxd-material {
|
|
20
20
|
&.default {
|
|
21
|
-
border-radius:
|
|
21
|
+
border-radius: calc(var(--radius) - 2px);
|
|
22
22
|
box-shadow: var(--shadow-border-default);
|
|
23
23
|
}
|
|
24
24
|
&.small {
|
|
25
|
-
border-radius:
|
|
25
|
+
border-radius: calc(var(--radius) - 2px);
|
|
26
26
|
box-shadow: var(--shadow-border-small);
|
|
27
27
|
}
|
|
28
28
|
&.medium {
|
|
29
|
-
border-radius:
|
|
29
|
+
border-radius: calc(var(--radius) + 6px);
|
|
30
30
|
box-shadow: var(--shadow-border-medium);
|
|
31
31
|
}
|
|
32
32
|
&.large {
|
|
33
|
-
border-radius:
|
|
33
|
+
border-radius: calc(var(--radius) + 6px);
|
|
34
34
|
box-shadow: var(--shadow-border-large);
|
|
35
35
|
}
|
|
36
36
|
&.tooltip {
|
|
37
|
-
border-radius:
|
|
37
|
+
border-radius: calc(var(--radius) - 2px);
|
|
38
38
|
box-shadow: var(--shadow-border-tooltip);
|
|
39
39
|
}
|
|
40
40
|
&.menu {
|
|
41
|
-
border-radius:
|
|
41
|
+
border-radius: calc(var(--radius) + 6px);
|
|
42
42
|
box-shadow: var(--shadow-border-menu);
|
|
43
43
|
}
|
|
44
44
|
&.modal {
|
|
45
|
-
border-radius:
|
|
45
|
+
border-radius: calc(var(--radius) + 6px);
|
|
46
46
|
box-shadow: var(--shadow-border-modal);
|
|
47
47
|
}
|
|
48
48
|
&.fullscreen {
|
|
49
|
-
border-radius:
|
|
49
|
+
border-radius: calc(var(--radius) + 8px);
|
|
50
50
|
box-shadow: var(--shadow-border-fullscreen);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -3,34 +3,44 @@ import { shallowRef } from "vue";
|
|
|
3
3
|
import PList from "../list/index.vue";
|
|
4
4
|
import PPopover from "../popover/index.vue";
|
|
5
5
|
defineOptions({
|
|
6
|
-
name: "PMenu"
|
|
6
|
+
name: "PMenu",
|
|
7
|
+
inheritAttrs: false
|
|
7
8
|
});
|
|
8
9
|
defineProps({
|
|
9
10
|
width: { type: [String, Number], required: false },
|
|
10
11
|
options: { type: Array, required: false, default: () => [] },
|
|
11
|
-
position: { type: null, required: false, default: "bottom-start" }
|
|
12
|
+
position: { type: null, required: false, default: "bottom-start" },
|
|
13
|
+
closeOnPressEscape: { type: Boolean, required: false, default: true }
|
|
12
14
|
});
|
|
13
|
-
const emits = defineEmits(["
|
|
14
|
-
const
|
|
15
|
-
function
|
|
16
|
-
|
|
15
|
+
const emits = defineEmits(["change", "select"]);
|
|
16
|
+
const popoverVisible = shallowRef(false);
|
|
17
|
+
function showPopover() {
|
|
18
|
+
popoverVisible.value = true;
|
|
17
19
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
+
function hidePopover() {
|
|
21
|
+
popoverVisible.value = false;
|
|
22
|
+
}
|
|
23
|
+
function onOptionClick(ev, item) {
|
|
24
|
+
emits("select", ev, item);
|
|
25
|
+
hidePopover();
|
|
20
26
|
}
|
|
21
27
|
</script>
|
|
22
28
|
|
|
23
29
|
<template>
|
|
24
30
|
<PPopover
|
|
25
|
-
|
|
26
|
-
trigger="click"
|
|
27
|
-
class="pxd-menu"
|
|
31
|
+
enterable
|
|
28
32
|
scroll-hidden
|
|
33
|
+
class="pxd-menu"
|
|
34
|
+
trigger="manual"
|
|
29
35
|
:show-delay="0"
|
|
30
36
|
:hide-delay="100"
|
|
31
37
|
:position="position"
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
disabled-show-transition
|
|
39
|
+
:visible="popoverVisible"
|
|
40
|
+
:close-on-press-escape="closeOnPressEscape"
|
|
41
|
+
v-bind="$attrs"
|
|
42
|
+
@outside-click="hidePopover"
|
|
43
|
+
@trigger-click="showPopover"
|
|
34
44
|
>
|
|
35
45
|
<slot />
|
|
36
46
|
|
|
@@ -38,9 +48,9 @@ function onOptionClick(ev, index) {
|
|
|
38
48
|
<PList
|
|
39
49
|
:width="width"
|
|
40
50
|
:options="options"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@
|
|
51
|
+
:key-listener="popoverVisible"
|
|
52
|
+
class="max-h-68 rounded-xl bg-background-100 shadow-border-menu"
|
|
53
|
+
@select="onOptionClick"
|
|
44
54
|
>
|
|
45
55
|
<slot name="items" />
|
|
46
56
|
</PList>
|