pxd 0.0.55 → 0.0.61
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 +18 -4
- package/dist/components/_internal/fragment-container.vue +3 -2
- package/dist/components/active-graph/index.d.vue.ts +2 -3
- package/dist/components/active-graph/index.vue +23 -16
- package/dist/components/active-graph/types.d.ts +4 -3
- package/dist/components/avatar/index.vue +19 -10
- package/dist/components/avatar/types.d.ts +0 -12
- package/dist/components/avatar-group/index.d.vue.ts +2 -2
- package/dist/components/avatar-group/index.vue +4 -3
- package/dist/components/avatar-group/types.d.ts +11 -0
- package/dist/components/badge/index.d.vue.ts +1 -1
- package/dist/components/badge/index.vue +47 -3
- package/dist/components/badge/types.d.ts +24 -1
- package/dist/components/book/index.vue +3 -2
- package/dist/components/browser/index.vue +6 -2
- package/dist/components/button/index.d.vue.ts +1 -1
- package/dist/components/button/index.vue +60 -12
- package/dist/components/carousel/index.d.vue.ts +24 -2
- package/dist/components/carousel/index.vue +341 -28
- package/dist/components/carousel/types.d.ts +2 -2
- package/dist/components/carousel-item/index.d.vue.ts +13 -0
- package/dist/components/carousel-item/index.vue +49 -0
- package/dist/components/checkbox/index.d.vue.ts +1 -5
- package/dist/components/checkbox/index.vue +66 -31
- package/dist/components/checkbox/types.d.ts +2 -14
- package/dist/components/checkbox-group/index.d.vue.ts +2 -7
- package/dist/components/checkbox-group/index.vue +11 -29
- package/dist/components/checkbox-group/types.d.ts +12 -0
- package/dist/components/chip/index.d.vue.ts +1 -1
- package/dist/components/chip/index.vue +31 -2
- package/dist/components/choicebox/index.d.vue.ts +11 -5
- package/dist/components/choicebox/index.vue +36 -54
- package/dist/components/choicebox/types.d.ts +11 -18
- package/dist/components/choicebox-item/index.d.vue.ts +16 -0
- package/dist/components/choicebox-item/index.vue +67 -0
- package/dist/components/choicebox-item/types.d.ts +12 -0
- package/dist/components/collapse/index.d.vue.ts +5 -4
- package/dist/components/collapse/index.vue +47 -30
- package/dist/components/collapse/types.d.ts +2 -5
- package/dist/components/collapse-group/index.d.vue.ts +2 -4
- package/dist/components/collapse-group/index.vue +8 -20
- package/dist/components/collapse-group/types.d.ts +6 -0
- package/dist/components/command-menu/index.vue +6 -7
- package/dist/components/command-menu/types.d.ts +0 -5
- package/dist/components/command-menu-group/index.d.vue.ts +1 -1
- package/dist/components/command-menu-group/index.vue +3 -2
- package/dist/components/command-menu-group/types.d.ts +5 -0
- package/dist/components/config-provider/index.d.vue.ts +3 -3
- package/dist/components/config-provider/index.vue +6 -4
- package/dist/components/countdown/index.vue +3 -2
- package/dist/components/countdown/types.d.ts +2 -2
- package/dist/components/dash-line/index.vue +3 -1
- package/dist/components/description/index.d.vue.ts +1 -1
- package/dist/components/description/index.vue +8 -7
- package/dist/components/description/types.d.ts +1 -1
- package/dist/components/drawer/index.d.vue.ts +3 -2
- package/dist/components/drawer/index.vue +20 -15
- package/dist/components/drawer/types.d.ts +3 -3
- package/dist/components/ellipsis-text/index.d.vue.ts +14 -0
- package/dist/components/ellipsis-text/index.vue +242 -0
- package/dist/components/ellipsis-text/types.d.ts +14 -0
- package/dist/components/empty-state/index.vue +6 -2
- package/dist/components/error/index.d.vue.ts +1 -3
- package/dist/components/error/index.vue +21 -6
- package/dist/components/error/types.d.ts +7 -1
- package/dist/components/fader/index.vue +30 -11
- package/dist/components/fader/types.d.ts +2 -2
- package/dist/components/gauge/index.vue +7 -2
- package/dist/components/grid/index.vue +9 -4
- package/dist/components/grid/types.d.ts +0 -5
- package/dist/components/grid-item/index.d.vue.ts +1 -1
- package/dist/components/grid-item/index.vue +16 -8
- package/dist/components/grid-item/types.d.ts +6 -0
- package/dist/components/hold-button/index.d.vue.ts +2 -2
- package/dist/components/hold-button/index.vue +1 -1
- package/dist/components/index.d.ts +7 -3
- package/dist/components/index.js +7 -3
- package/dist/components/input/index.d.vue.ts +8 -8
- package/dist/components/input/index.vue +54 -21
- package/dist/components/input/types.d.ts +7 -10
- package/dist/components/intersection-observer/index.d.vue.ts +0 -1
- package/dist/components/intersection-observer/index.vue +12 -3
- package/dist/components/kbd/index.vue +1 -1
- package/dist/components/link-button/index.d.vue.ts +1 -1
- package/dist/components/link-button/index.vue +4 -6
- package/dist/components/link-button/types.d.ts +1 -1
- package/dist/components/list/index.d.vue.ts +8 -5
- package/dist/components/list/index.vue +50 -54
- package/dist/components/list/types.d.ts +3 -20
- package/dist/components/list-item/index.d.vue.ts +3 -2
- package/dist/components/list-item/index.vue +44 -18
- package/dist/components/list-item/types.d.ts +15 -0
- package/dist/components/loading-bar/index.vue +33 -2
- package/dist/components/loading-bar/types.d.ts +1 -1
- package/dist/components/loading-dots/index.vue +3 -2
- package/dist/components/menu/index.d.vue.ts +5 -2
- package/dist/components/menu/index.vue +4 -1
- package/dist/components/menu/types.d.ts +5 -0
- package/dist/components/message/index.d.vue.ts +11 -8
- package/dist/components/message/index.vue +4 -12
- package/dist/components/message/types.d.ts +1 -12
- package/dist/components/message-item/index.d.vue.ts +1 -3
- package/dist/components/message-item/index.vue +13 -7
- package/dist/components/message-item/types.d.ts +11 -0
- package/dist/components/modal/index.d.vue.ts +3 -2
- package/dist/components/modal/index.vue +17 -13
- package/dist/components/modal/types.d.ts +3 -3
- package/dist/components/noise-background/index.vue +4 -3
- package/dist/components/note/index.d.vue.ts +1 -2
- package/dist/components/note/index.vue +81 -29
- package/dist/components/note/types.d.ts +10 -2
- package/dist/components/number-input/index.d.vue.ts +5 -4
- package/dist/components/number-input/index.vue +36 -6
- package/dist/components/number-input/types.d.ts +2 -0
- package/dist/components/overlay/index.vue +1 -1
- package/dist/components/overlay/types.d.ts +1 -1
- package/dist/components/pagination/index.vue +5 -3
- package/dist/components/pin-input/index.d.vue.ts +6 -1
- package/dist/components/pin-input/index.vue +60 -23
- package/dist/components/pin-input/types.d.ts +0 -4
- package/dist/components/placeholder/index.vue +14 -11
- package/dist/components/popover/index.vue +116 -78
- package/dist/components/popover/types.d.ts +1 -0
- package/dist/components/progress/index.d.vue.ts +1 -1
- package/dist/components/progress/index.vue +15 -2
- package/dist/components/project-banner/index.d.vue.ts +18 -0
- package/dist/components/project-banner/index.vue +59 -0
- package/dist/components/project-banner/types.d.ts +8 -0
- package/dist/components/radio/index.vue +62 -20
- package/dist/components/radio/types.d.ts +1 -14
- package/dist/components/radio-group/index.d.vue.ts +2 -4
- package/dist/components/radio-group/index.vue +11 -16
- package/dist/components/radio-group/types.d.ts +12 -0
- package/dist/components/resizable/types.d.ts +5 -10
- package/dist/components/resizable-handle/index.vue +1 -1
- package/dist/components/resizable-panel/index.d.vue.ts +1 -1
- package/dist/components/resizable-panel/index.vue +7 -2
- package/dist/components/resizable-panel/types.d.ts +4 -0
- package/dist/components/scrollable/index.d.vue.ts +29 -0
- package/dist/components/scrollable/index.vue +98 -83
- package/dist/components/scrollable/types.d.ts +19 -6
- package/dist/components/skeleton/index.vue +24 -1
- package/dist/components/slider/index.d.vue.ts +6 -6
- package/dist/components/slider/index.vue +86 -44
- package/dist/components/slider/types.d.ts +1 -1
- package/dist/components/snippet/index.vue +28 -2
- package/dist/components/spinner/index.vue +4 -2
- package/dist/components/stack/index.d.vue.ts +2 -2
- package/dist/components/stack/index.vue +35 -3
- package/dist/components/stack/types.d.ts +1 -1
- package/dist/components/status-dot/index.vue +5 -1
- package/dist/components/switch/index.d.vue.ts +10 -1
- package/dist/components/switch/index.vue +35 -44
- package/dist/components/switch/types.d.ts +4 -12
- package/dist/components/switch-item/index.d.vue.ts +14 -0
- package/dist/components/switch-item/index.vue +79 -0
- package/dist/components/switch-item/types.d.ts +9 -0
- package/dist/components/teleport/index.d.vue.ts +1 -1
- package/dist/components/teleport/index.vue +1 -1
- package/dist/components/teleport/types.d.ts +1 -1
- package/dist/components/text/index.d.vue.ts +1 -2
- package/dist/components/text/index.vue +36 -22
- package/dist/components/text/types.d.ts +1 -1
- package/dist/components/textarea/index.d.vue.ts +4 -4
- package/dist/components/textarea/index.vue +33 -4
- package/dist/components/textarea/types.d.ts +0 -1
- package/dist/components/time-picker/index.d.vue.ts +1 -2
- package/dist/components/time-picker/index.vue +43 -9
- package/dist/components/time-picker/types.d.ts +1 -2
- package/dist/components/toggle/index.vue +11 -10
- package/dist/components/toggle-button/index.d.vue.ts +22 -0
- package/dist/components/toggle-button/index.vue +110 -0
- package/dist/components/toggle-button/types.d.ts +16 -0
- package/dist/components/{choicebox-group → toggle-button-group}/index.d.vue.ts +5 -5
- package/dist/components/toggle-button-group/index.vue +68 -0
- package/dist/components/toggle-button-group/types.d.ts +22 -0
- package/dist/components/tooltip/index.d.vue.ts +2 -0
- package/dist/components/tooltip/index.vue +9 -3
- package/dist/components/tooltip/types.d.ts +3 -2
- package/dist/components/virtual-list/index.d.vue.ts +25 -4
- package/dist/components/virtual-list/index.vue +66 -10
- package/dist/components/virtual-list/types.d.ts +9 -4
- package/dist/composables/index.d.ts +2 -2
- package/dist/composables/index.js +2 -2
- package/dist/composables/use-browser-observer.d.ts +5 -5
- package/dist/composables/use-browser-observer.js +23 -20
- package/dist/composables/use-copy-click.js +4 -0
- package/dist/composables/use-countdown.d.ts +2 -2
- package/dist/composables/use-delay-destroy.d.ts +1 -1
- package/dist/composables/use-focus-trap.d.ts +7 -3
- package/dist/composables/use-focus-trap.js +19 -7
- package/dist/composables/use-forward-ref-expose.d.ts +2 -0
- package/dist/composables/use-forward-ref-expose.js +41 -0
- package/dist/composables/use-message.d.ts +4 -7
- package/dist/composables/use-model-value.d.ts +9 -8
- package/dist/composables/use-popover-responsive.d.ts +2 -2
- package/dist/composables/use-popover-responsive.js +3 -3
- package/dist/composables/use-repeat-action.d.ts +1 -1
- package/dist/composables/use-repeat-action.js +2 -2
- package/dist/composables/use-virtual-list.d.ts +21 -12
- package/dist/composables/use-virtual-list.js +90 -158
- package/dist/composables/use-window-size.d.ts +4 -0
- package/dist/composables/use-window-size.js +27 -0
- package/dist/contexts/avatar.d.ts +5 -2
- package/dist/contexts/carousel.d.ts +4 -4
- package/dist/contexts/carousel.js +1 -1
- package/dist/contexts/checkbox.d.ts +7 -2
- package/dist/contexts/choicebox.d.ts +8 -4
- package/dist/contexts/choicebox.js +1 -4
- package/dist/contexts/collapse.d.ts +5 -6
- package/dist/contexts/collapse.js +1 -1
- package/dist/contexts/config-provider.d.ts +5 -0
- package/dist/{composables/use-config-provider-context.js → contexts/config-provider.js} +8 -5
- package/dist/contexts/list.d.ts +1 -1
- package/dist/contexts/radio.d.ts +8 -2
- package/dist/contexts/resizable.d.ts +1 -1
- package/dist/contexts/switch.d.ts +8 -4
- package/dist/contexts/switch.js +1 -2
- package/dist/contexts/toggle-button.d.ts +7 -0
- package/dist/contexts/toggle-button.js +2 -0
- package/dist/styles/source.css +14 -2
- package/dist/styles/styles.css +2 -2
- package/dist/styles/tw.css +14 -2
- package/dist/types/shared/props.d.ts +1 -3
- package/dist/types/shared/utils.d.ts +0 -3
- package/dist/utils/context.d.ts +1 -0
- package/dist/utils/get.d.ts +1 -0
- package/dist/utils/get.js +14 -0
- package/dist/utils/ref.d.ts +1 -1
- package/dist/utils/responsive.js +2 -1
- package/dist/utils/throttle.js +9 -7
- package/dist/utils/uid.d.ts +1 -1
- package/dist/utils/uid.js +2 -2
- package/package.json +23 -21
- package/volar.d.ts +7 -3
- package/dist/components/badge/cn.d.ts +0 -90
- package/dist/components/badge/cn.js +0 -44
- package/dist/components/button/cn.d.ts +0 -121
- package/dist/components/button/cn.js +0 -55
- package/dist/components/carousel-group/index.d.vue.ts +0 -35
- package/dist/components/carousel-group/index.vue +0 -368
- package/dist/components/checkbox/cn.d.ts +0 -67
- package/dist/components/checkbox/cn.js +0 -31
- package/dist/components/chip/cn.d.ts +0 -49
- package/dist/components/chip/cn.js +0 -26
- package/dist/components/choicebox-group/index.vue +0 -65
- package/dist/components/error/cn.d.ts +0 -22
- package/dist/components/error/cn.js +0 -15
- package/dist/components/input/cn.d.ts +0 -73
- package/dist/components/input/cn.js +0 -36
- package/dist/components/list-item/cn.d.ts +0 -22
- package/dist/components/list-item/cn.js +0 -15
- package/dist/components/loading-bar/cn.d.ts +0 -70
- package/dist/components/loading-bar/cn.js +0 -32
- package/dist/components/note/cn.d.ts +0 -121
- package/dist/components/note/cn.js +0 -66
- package/dist/components/pin-input/cn.d.ts +0 -46
- package/dist/components/pin-input/cn.js +0 -25
- package/dist/components/progress/cn.d.ts +0 -19
- package/dist/components/progress/cn.js +0 -14
- package/dist/components/radio/cn.d.ts +0 -46
- package/dist/components/radio/cn.js +0 -42
- package/dist/components/skeleton/cn.d.ts +0 -43
- package/dist/components/skeleton/cn.js +0 -24
- package/dist/components/snippet/cn.d.ts +0 -52
- package/dist/components/snippet/cn.js +0 -27
- package/dist/components/stack/cn.d.ts +0 -70
- package/dist/components/stack/cn.js +0 -33
- package/dist/components/switch/cn.d.ts +0 -16
- package/dist/components/switch/cn.js +0 -13
- package/dist/components/switch-group/index.d.vue.ts +0 -23
- package/dist/components/switch-group/index.vue +0 -54
- package/dist/components/text/cn.d.ts +0 -67
- package/dist/components/text/cn.js +0 -34
- package/dist/components/textarea/cn.d.ts +0 -58
- package/dist/components/textarea/cn.js +0 -30
- package/dist/composables/use-config-provider-context.d.ts +0 -3
- package/dist/composables/use-unique-id-context.d.ts +0 -2
- package/dist/composables/use-unique-id-context.js +0 -11
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, onBeforeUnmount, onMounted,
|
|
3
|
-
import { useResizeObserver } from "../../composables/use-browser-observer";
|
|
2
|
+
import { computed, onBeforeUnmount, onMounted, shallowRef } from "vue";
|
|
3
|
+
import { useMutationObserver, useResizeObserver } from "../../composables/use-browser-observer";
|
|
4
4
|
import { getStyle } from "../../utils/dom";
|
|
5
|
-
import { cachedOff, cachedOn, once } from "../../utils/event";
|
|
5
|
+
import { cachedOff, cachedOn, off, once } from "../../utils/event";
|
|
6
6
|
import { isServer } from "../../utils/is";
|
|
7
7
|
import { throttleByRaf } from "../../utils/throttle";
|
|
8
8
|
import PFader from "../fader/index.vue";
|
|
@@ -12,37 +12,43 @@ defineOptions({
|
|
|
12
12
|
});
|
|
13
13
|
const props = defineProps({
|
|
14
14
|
fader: { type: Boolean, required: false, default: true },
|
|
15
|
+
loading: { type: Boolean, required: false },
|
|
16
|
+
scrollbar: { type: Boolean, required: false, default: true },
|
|
15
17
|
faderSize: { type: Number, required: false },
|
|
16
18
|
faderColor: { type: String, required: false },
|
|
17
19
|
faderDirection: { type: String, required: false },
|
|
18
|
-
scrollbar: { type: Boolean, required: false, default: true },
|
|
19
20
|
wrapperClass: { type: [String, Array, Object], required: false },
|
|
20
21
|
contentClass: { type: [String, Array, Object], required: false },
|
|
21
22
|
contentStyle: { type: [Object, String], required: false },
|
|
22
23
|
scrollbarSize: { type: Number, required: false },
|
|
23
24
|
scrollbarColor: { type: String, required: false },
|
|
24
25
|
scrollbarHoverColor: { type: String, required: false },
|
|
25
|
-
|
|
26
|
-
endThreshold: { type: Number, required: false, default: 10 }
|
|
26
|
+
bottomThreshold: { type: Number, required: false, default: 10 }
|
|
27
27
|
});
|
|
28
|
-
const emits = defineEmits(["scroll", "
|
|
28
|
+
const emits = defineEmits(["scroll", "bottom"]);
|
|
29
29
|
const wrapperRef = shallowRef();
|
|
30
30
|
const contentRef = shallowRef();
|
|
31
|
+
const isScrollableX = shallowRef(false);
|
|
32
|
+
const isScrollableY = shallowRef(false);
|
|
33
|
+
const verticalThumbTop = shallowRef(0);
|
|
34
|
+
const horizontalThumbLeft = shallowRef(0);
|
|
35
|
+
const verticalThumbHeight = shallowRef(0);
|
|
36
|
+
const horizontalThumbWidth = shallowRef(0);
|
|
31
37
|
const MIN_THUMB = 30;
|
|
38
|
+
let triggerRightFired = false;
|
|
39
|
+
let triggerBottomFired = false;
|
|
32
40
|
let dragState = {
|
|
33
41
|
isDragging: false,
|
|
34
42
|
direction: null,
|
|
35
43
|
startClientPos: 0,
|
|
36
44
|
startThumbPos: 0
|
|
37
45
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
horizontalThumbLeft: 0
|
|
45
|
-
});
|
|
46
|
+
let cachedPadding = {
|
|
47
|
+
top: 0,
|
|
48
|
+
bottom: 0,
|
|
49
|
+
left: 0,
|
|
50
|
+
right: 0
|
|
51
|
+
};
|
|
46
52
|
const computedStyle = computed(() => {
|
|
47
53
|
return {
|
|
48
54
|
"--scrollbar-size": props.scrollbarSize,
|
|
@@ -51,23 +57,22 @@ const computedStyle = computed(() => {
|
|
|
51
57
|
};
|
|
52
58
|
});
|
|
53
59
|
const verticalThumbStyle = computed(() => ({
|
|
54
|
-
height: `${
|
|
55
|
-
transform: `translateY(${
|
|
60
|
+
height: `${verticalThumbHeight.value}px`,
|
|
61
|
+
transform: `translateY(${verticalThumbTop.value}px)`
|
|
56
62
|
}));
|
|
57
63
|
const horizontalThumbStyle = computed(() => ({
|
|
58
|
-
width: `${
|
|
59
|
-
transform: `translateX(${
|
|
64
|
+
width: `${horizontalThumbWidth.value}px`,
|
|
65
|
+
transform: `translateX(${horizontalThumbLeft.value}px)`
|
|
60
66
|
}));
|
|
61
67
|
function updateScrollbarMetrics() {
|
|
68
|
+
if (!props.scrollbar) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
62
71
|
const contentEl = contentRef.value;
|
|
63
|
-
if (!contentEl || !
|
|
72
|
+
if (!contentEl || !contentEl.isConnected) {
|
|
64
73
|
return;
|
|
65
74
|
}
|
|
66
|
-
const {
|
|
67
|
-
const pt = Number.parseFloat(paddingTop) || 0;
|
|
68
|
-
const pb = Number.parseFloat(paddingBottom) || 0;
|
|
69
|
-
const pl = Number.parseFloat(paddingLeft) || 0;
|
|
70
|
-
const pr = Number.parseFloat(paddingRight) || 0;
|
|
75
|
+
const { top: pt, bottom: pb, left: pl, right: pr } = cachedPadding;
|
|
71
76
|
const {
|
|
72
77
|
clientWidth: clientW,
|
|
73
78
|
clientHeight: clientH,
|
|
@@ -80,28 +85,26 @@ function updateScrollbarMetrics() {
|
|
|
80
85
|
const effClientH = Math.max(0, clientH - pt - pb);
|
|
81
86
|
const effScrollW = Math.max(effClientW, scrollW - pl - pr);
|
|
82
87
|
const effScrollH = Math.max(effClientH, scrollH - pt - pb);
|
|
83
|
-
const
|
|
84
|
-
const
|
|
88
|
+
const _isScrollableX = effScrollW > effClientW;
|
|
89
|
+
const _isScrollableY = effScrollH > effClientH;
|
|
85
90
|
const verticalRatio = effScrollH > 0 ? effClientH / effScrollH : 0;
|
|
86
91
|
const horizontalRatio = effScrollW > 0 ? effClientW / effScrollW : 0;
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const scrollableWidth = Math.max(0, trackW -
|
|
90
|
-
const scrollableHeight = Math.max(0, trackH -
|
|
92
|
+
const _verticalThumbHeight = Math.max(Math.round(trackH * verticalRatio), MIN_THUMB);
|
|
93
|
+
const _horizontalThumbWidth = Math.max(Math.round(trackW * horizontalRatio), MIN_THUMB);
|
|
94
|
+
const scrollableWidth = Math.max(0, trackW - _horizontalThumbWidth);
|
|
95
|
+
const scrollableHeight = Math.max(0, trackH - _verticalThumbHeight);
|
|
91
96
|
const maxScrollX = Math.max(1, scrollW - clientW);
|
|
92
97
|
const maxScrollY = Math.max(1, scrollH - clientH);
|
|
93
98
|
const verticalScrollPercentage = Math.min(1, Math.max(0, contentEl.scrollTop / maxScrollY));
|
|
94
99
|
const horizontalScrollPercentage = Math.min(1, Math.max(0, contentEl.scrollLeft / maxScrollX));
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
horizontalThumbLeft
|
|
104
|
-
};
|
|
100
|
+
const _verticalThumbTop = verticalScrollPercentage * scrollableHeight;
|
|
101
|
+
const _horizontalThumbLeft = horizontalScrollPercentage * scrollableWidth;
|
|
102
|
+
isScrollableX.value = _isScrollableX;
|
|
103
|
+
isScrollableY.value = _isScrollableY;
|
|
104
|
+
verticalThumbHeight.value = _verticalThumbHeight;
|
|
105
|
+
horizontalThumbWidth.value = _horizontalThumbWidth;
|
|
106
|
+
verticalThumbTop.value = _verticalThumbTop;
|
|
107
|
+
horizontalThumbLeft.value = _horizontalThumbLeft;
|
|
105
108
|
}
|
|
106
109
|
const throttledUpdate = throttleByRaf(updateScrollbarMetrics);
|
|
107
110
|
let lastScrollTop = 0;
|
|
@@ -134,17 +137,26 @@ function onContainerScroll(ev) {
|
|
|
134
137
|
movedY = currTop !== lastScrollTop;
|
|
135
138
|
movedX = currLeft !== lastScrollLeft;
|
|
136
139
|
}
|
|
137
|
-
const
|
|
140
|
+
const threshold = props.bottomThreshold ?? 0;
|
|
138
141
|
if (movedY) {
|
|
139
|
-
const
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
+
const scrollBottom = Math.floor(currTop + el.clientHeight);
|
|
143
|
+
if (scrollBottom >= el.scrollHeight - threshold) {
|
|
144
|
+
if (!triggerBottomFired) {
|
|
145
|
+
triggerBottomFired = true;
|
|
146
|
+
emits("bottom", "vertical", ev);
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
triggerBottomFired = false;
|
|
142
150
|
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
} else if (movedX) {
|
|
152
|
+
const scrollRight = Math.floor(currLeft + el.clientWidth);
|
|
153
|
+
if (scrollRight >= el.scrollWidth - threshold) {
|
|
154
|
+
if (!triggerRightFired) {
|
|
155
|
+
triggerRightFired = true;
|
|
156
|
+
emits("bottom", "horizontal", ev);
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
triggerRightFired = false;
|
|
148
160
|
}
|
|
149
161
|
}
|
|
150
162
|
lastScrollTop = currTop;
|
|
@@ -160,7 +172,7 @@ function startDragVertical(e) {
|
|
|
160
172
|
isDragging: true,
|
|
161
173
|
direction: "vertical",
|
|
162
174
|
startClientPos: e.clientY,
|
|
163
|
-
startThumbPos:
|
|
175
|
+
startThumbPos: verticalThumbTop.value
|
|
164
176
|
};
|
|
165
177
|
cachedOn(document, "mousemove", onDragMove);
|
|
166
178
|
once(document, "mouseup", onEndDrag);
|
|
@@ -175,7 +187,7 @@ function startDragHorizontal(e) {
|
|
|
175
187
|
isDragging: true,
|
|
176
188
|
direction: "horizontal",
|
|
177
189
|
startClientPos: e.clientX,
|
|
178
|
-
startThumbPos:
|
|
190
|
+
startThumbPos: horizontalThumbLeft.value
|
|
179
191
|
};
|
|
180
192
|
cachedOn(document, "mousemove", onDragMove);
|
|
181
193
|
once(document, "mouseup", onEndDrag);
|
|
@@ -190,23 +202,23 @@ function onDragMove(e) {
|
|
|
190
202
|
}
|
|
191
203
|
if (dragState.direction === "vertical") {
|
|
192
204
|
const trackH = wrapperRef.value.clientHeight ?? contentEl.clientHeight;
|
|
193
|
-
const thumbH =
|
|
205
|
+
const thumbH = verticalThumbHeight.value;
|
|
194
206
|
const scrollableH = Math.max(0, trackH - thumbH);
|
|
195
207
|
const delta2 = e.clientY - dragState.startClientPos;
|
|
196
208
|
const newThumbTop = Math.max(0, Math.min(scrollableH, dragState.startThumbPos + delta2));
|
|
197
209
|
const maxScroll2 = Math.max(0, contentEl.scrollHeight - contentEl.clientHeight);
|
|
198
210
|
contentEl.scrollTop = scrollableH > 0 ? newThumbTop / scrollableH * maxScroll2 : 0;
|
|
199
|
-
|
|
211
|
+
verticalThumbTop.value = newThumbTop;
|
|
200
212
|
return;
|
|
201
213
|
}
|
|
202
214
|
const trackW = wrapperRef.value.clientWidth ?? contentEl.clientWidth;
|
|
203
|
-
const thumbW =
|
|
215
|
+
const thumbW = horizontalThumbWidth.value;
|
|
204
216
|
const scrollableW = Math.max(0, trackW - thumbW);
|
|
205
217
|
const delta = e.clientX - dragState.startClientPos;
|
|
206
218
|
const newThumbLeft = Math.max(0, Math.min(scrollableW, dragState.startThumbPos + delta));
|
|
207
219
|
const maxScroll = Math.max(0, contentEl.scrollWidth - contentEl.clientWidth);
|
|
208
220
|
contentEl.scrollLeft = scrollableW > 0 ? newThumbLeft / scrollableW * maxScroll : 0;
|
|
209
|
-
|
|
221
|
+
horizontalThumbLeft.value = newThumbLeft;
|
|
210
222
|
}
|
|
211
223
|
function onEndDrag(ev) {
|
|
212
224
|
ev.stopPropagation();
|
|
@@ -223,7 +235,26 @@ function scrollTo(top, left) {
|
|
|
223
235
|
contentRef.value.scrollTo({ top, left });
|
|
224
236
|
}
|
|
225
237
|
if (props.scrollbar) {
|
|
226
|
-
useResizeObserver(
|
|
238
|
+
useResizeObserver(wrapperRef, throttledUpdate);
|
|
239
|
+
useMutationObserver(contentRef, throttledUpdate, { childList: true, subtree: true });
|
|
240
|
+
}
|
|
241
|
+
function getContainerPadding() {
|
|
242
|
+
const contentEl = contentRef.value;
|
|
243
|
+
if (!contentEl) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const { paddingTop, paddingRight, paddingBottom, paddingLeft } = getStyle(contentEl);
|
|
247
|
+
cachedPadding = {
|
|
248
|
+
top: Number.parseFloat(paddingTop) || 0,
|
|
249
|
+
bottom: Number.parseFloat(paddingBottom) || 0,
|
|
250
|
+
left: Number.parseFloat(paddingLeft) || 0,
|
|
251
|
+
right: Number.parseFloat(paddingRight) || 0
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function forceUpdate() {
|
|
255
|
+
throttledUpdate.cancel();
|
|
256
|
+
getContainerPadding();
|
|
257
|
+
updateScrollbarMetrics();
|
|
227
258
|
}
|
|
228
259
|
onMounted(async () => {
|
|
229
260
|
if (isServer()) {
|
|
@@ -232,25 +263,24 @@ onMounted(async () => {
|
|
|
232
263
|
if (!props.scrollbar && !props.fader) {
|
|
233
264
|
return;
|
|
234
265
|
}
|
|
235
|
-
|
|
266
|
+
getContainerPadding();
|
|
236
267
|
requestAnimationFrame(updateScrollbarMetrics);
|
|
237
268
|
});
|
|
238
269
|
onBeforeUnmount(() => {
|
|
239
|
-
cachedOff(window, "resize", updateScrollbarMetrics);
|
|
240
|
-
cachedOff(document, "mousemove", onDragMove);
|
|
241
|
-
cachedOff(document, "mouseup", onEndDrag);
|
|
242
270
|
throttledUpdate.cancel();
|
|
271
|
+
cachedOff(document, "mousemove", onDragMove);
|
|
272
|
+
off(document, "mouseup", onEndDrag);
|
|
243
273
|
});
|
|
244
274
|
defineExpose({
|
|
245
275
|
scrollTo,
|
|
246
|
-
forceUpdate
|
|
276
|
+
forceUpdate
|
|
247
277
|
});
|
|
248
278
|
</script>
|
|
249
279
|
|
|
250
280
|
<template>
|
|
251
281
|
<div
|
|
252
282
|
ref="wrapperRef"
|
|
253
|
-
class="pxd-scrollable group/scrollable relative flex overflow-hidden hover:[--o:1] pointer-fine:[--o:0]"
|
|
283
|
+
class="pxd-scrollable group/scrollable relative flex flex-col overflow-hidden hover:[--o:1] pointer-fine:[--o:0]"
|
|
254
284
|
:class="wrapperClass"
|
|
255
285
|
:style="computedStyle"
|
|
256
286
|
v-bind="$attrs"
|
|
@@ -259,7 +289,7 @@ defineExpose({
|
|
|
259
289
|
ref="contentRef"
|
|
260
290
|
:class="contentClass"
|
|
261
291
|
:style="contentStyle"
|
|
262
|
-
class="pxd-scrollable--content relative scrollbar-
|
|
292
|
+
class="pxd-scrollable--content relative scrollbar-none h-full max-h-inherit max-w-full flex-1 shrink-0 overflow-scroll intrinsic-size-auto"
|
|
263
293
|
@scroll.passive="onContainerScroll"
|
|
264
294
|
>
|
|
265
295
|
<slot />
|
|
@@ -275,7 +305,7 @@ defineExpose({
|
|
|
275
305
|
|
|
276
306
|
<template v-if="scrollbar">
|
|
277
307
|
<div
|
|
278
|
-
v-if="
|
|
308
|
+
v-if="isScrollableX"
|
|
279
309
|
aria-hidden="true"
|
|
280
310
|
class="pxd-scrollable--scrollbar-x left-0 right-0 bottom-0 absolute touch-none opacity-(--o) delay-1000 select-none group-hover/scrollable:delay-0 active:opacity-100 motion-safe:transition-opacity"
|
|
281
311
|
>
|
|
@@ -287,7 +317,7 @@ defineExpose({
|
|
|
287
317
|
</div>
|
|
288
318
|
|
|
289
319
|
<div
|
|
290
|
-
v-if="
|
|
320
|
+
v-if="isScrollableY"
|
|
291
321
|
aria-hidden="true"
|
|
292
322
|
class="pxd-scrollable--scrollbar-y top-0 right-0 bottom-0 absolute touch-none opacity-(--o) delay-1000 select-none group-hover/scrollable:delay-0 active:opacity-100 motion-safe:transition-opacity"
|
|
293
323
|
>
|
|
@@ -301,21 +331,6 @@ defineExpose({
|
|
|
301
331
|
</div>
|
|
302
332
|
</template>
|
|
303
333
|
|
|
304
|
-
<style
|
|
305
|
-
.pxd-scrollable--scrollbar-x {
|
|
306
|
-
height: calc(var(--scrollbar-size, 6) * 1px);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.pxd-scrollable--scrollbar-y {
|
|
310
|
-
width: calc(var(--scrollbar-size, 6) * 1px);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
.pxd-scrollable--thumb {
|
|
314
|
-
background-color: var(--scrollbar-color, var(--color-gray-alpha-300));
|
|
315
|
-
|
|
316
|
-
&:hover,
|
|
317
|
-
&:active {
|
|
318
|
-
background-color: var(--scrollbar-hover-color, var(--color-gray-alpha-500));
|
|
319
|
-
}
|
|
320
|
-
}
|
|
334
|
+
<style>
|
|
335
|
+
.pxd-scrollable--scrollbar-x{height:calc(var(--scrollbar-size, 6)*1px)}.pxd-scrollable--scrollbar-y{width:calc(var(--scrollbar-size, 6)*1px)}.pxd-scrollable--thumb{background-color:var(--scrollbar-color,var(--color-gray-alpha-300))}.pxd-scrollable--thumb:active,.pxd-scrollable--thumb:hover{background-color:var(--scrollbar-hover-color,var(--color-gray-alpha-500))}
|
|
321
336
|
</style>
|
|
@@ -1,24 +1,37 @@
|
|
|
1
|
+
import type { ComponentClass, ComponentDirection, Nullable } from '../../types/shared'
|
|
1
2
|
import type { CSSProperties } from 'vue'
|
|
2
3
|
|
|
3
|
-
import type { ComponentClass, ComponentDirection } from '../../types/shared'
|
|
4
|
-
|
|
5
4
|
export interface ScrollableProps {
|
|
6
5
|
fader?: boolean
|
|
6
|
+
loading?: boolean
|
|
7
|
+
scrollbar?: boolean
|
|
7
8
|
faderSize?: number
|
|
8
9
|
faderColor?: string
|
|
9
10
|
faderDirection?: ComponentDirection | 'both'
|
|
10
|
-
scrollbar?: boolean
|
|
11
11
|
wrapperClass?: ComponentClass
|
|
12
12
|
contentClass?: ComponentClass
|
|
13
13
|
contentStyle?: CSSProperties | string
|
|
14
14
|
scrollbarSize?: number
|
|
15
15
|
scrollbarColor?: string
|
|
16
16
|
scrollbarHoverColor?: string
|
|
17
|
-
|
|
18
|
-
endThreshold?: number
|
|
17
|
+
bottomThreshold?: number
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
export interface ScrollableEmits {
|
|
22
21
|
scroll: [Event]
|
|
23
|
-
|
|
22
|
+
bottom: [ComponentDirection, Event]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ScrollableDragState {
|
|
26
|
+
isDragging: boolean
|
|
27
|
+
direction: Nullable<ComponentDirection>
|
|
28
|
+
startClientPos: number
|
|
29
|
+
startThumbPos: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ScrollableCachedPadding {
|
|
33
|
+
top: number
|
|
34
|
+
bottom: number
|
|
35
|
+
left: number
|
|
36
|
+
right: number
|
|
24
37
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
2
3
|
import { computed } from "vue";
|
|
3
4
|
import { getCssUnitValue, increaseWithUnit } from "../../utils/format";
|
|
4
|
-
import { skeletonVariant } from "./cn";
|
|
5
5
|
defineOptions({
|
|
6
6
|
name: "PSkeleton",
|
|
7
7
|
inheritAttrs: false
|
|
@@ -14,6 +14,29 @@ const props = defineProps({
|
|
|
14
14
|
boxHeight: { type: [String, Number], required: false },
|
|
15
15
|
shape: { type: String, required: false, default: "default" }
|
|
16
16
|
});
|
|
17
|
+
const skeletonVariant = tv({
|
|
18
|
+
base: "pxd-skeleton relative block shrink-0 overflow-hidden",
|
|
19
|
+
variants: {
|
|
20
|
+
loading: {
|
|
21
|
+
true: "loading invisible content-visibility-auto intrinsic-size-auto",
|
|
22
|
+
false: ""
|
|
23
|
+
},
|
|
24
|
+
shape: {
|
|
25
|
+
default: "rounded-md",
|
|
26
|
+
square: "rounded-none",
|
|
27
|
+
rounded: "rounded-full"
|
|
28
|
+
},
|
|
29
|
+
animated: {
|
|
30
|
+
true: "animated after:default-animation-timing-function!",
|
|
31
|
+
false: ""
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
loading: true,
|
|
36
|
+
shape: "default",
|
|
37
|
+
animated: true
|
|
38
|
+
}
|
|
39
|
+
});
|
|
17
40
|
const computedStyle = computed(() => {
|
|
18
41
|
const { width, height, boxHeight } = props;
|
|
19
42
|
const styles = {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { SliderProps } from './types';
|
|
2
2
|
declare const __VLS_export: import("vue").DefineComponent<SliderProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
3
|
-
change: (args_0: NonNullable<number | [
|
|
4
|
-
"update:modelValue": (args_0: NonNullable<number | [
|
|
3
|
+
change: (args_0: NonNullable<number | number[] | null | undefined>) => any;
|
|
4
|
+
"update:modelValue": (args_0: NonNullable<number | number[] | null | undefined>) => any;
|
|
5
5
|
}, string, import("vue").PublicProps, Readonly<SliderProps> & Readonly<{
|
|
6
|
-
onChange?: ((args_0: NonNullable<number | [
|
|
7
|
-
"onUpdate:modelValue"?: ((args_0: NonNullable<number | [
|
|
6
|
+
onChange?: ((args_0: NonNullable<number | number[] | null | undefined>) => any) | undefined;
|
|
7
|
+
"onUpdate:modelValue"?: ((args_0: NonNullable<number | number[] | null | undefined>) => any) | undefined;
|
|
8
8
|
}>, {
|
|
9
|
-
variant: import("../../types/shared").ComponentVariant | "secondary";
|
|
10
9
|
max: number;
|
|
11
|
-
|
|
10
|
+
variant: import("../../types/shared").ComponentVariant | "secondary";
|
|
11
|
+
modelValue: number | number[] | null;
|
|
12
12
|
min: number;
|
|
13
13
|
step: number;
|
|
14
14
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, onBeforeUnmount, shallowRef } from "vue";
|
|
3
|
-
import { useConfigProvider } from "../../composables/use-config-provider-context";
|
|
4
3
|
import { useModelValue } from "../../composables/use-model-value";
|
|
4
|
+
import { useConfigProvider } from "../../contexts/config-provider";
|
|
5
5
|
import { cachedOff, cachedOn, once } from "../../utils/event";
|
|
6
|
+
import { NOOP } from "../../utils/event";
|
|
6
7
|
import { getFallbackValue } from "../../utils/get";
|
|
8
|
+
import { throttleByRaf } from "../../utils/throttle";
|
|
7
9
|
defineOptions({
|
|
8
10
|
name: "PSlider",
|
|
11
|
+
inheritAttrs: false,
|
|
9
12
|
model: {
|
|
10
13
|
prop: "modelValue",
|
|
11
14
|
event: "update:modelValue"
|
|
@@ -44,14 +47,14 @@ const VARIANTS = {
|
|
|
44
47
|
error: "hsl(var(--color-red-700-value))"
|
|
45
48
|
};
|
|
46
49
|
let isDragging = false;
|
|
47
|
-
let
|
|
48
|
-
let
|
|
50
|
+
let sliderRect = null;
|
|
51
|
+
let lastClientX = null;
|
|
49
52
|
const configProvider = useConfigProvider();
|
|
50
53
|
const sliderRef = shallowRef();
|
|
51
54
|
const modelValue = useModelValue(props, emits);
|
|
52
55
|
const activeThumb = shallowRef();
|
|
53
56
|
const computedSize = computed(() => getFallbackValue(props.size, SIZES, configProvider.size));
|
|
54
|
-
const
|
|
57
|
+
const valueRange = computed(() => {
|
|
55
58
|
if (props.range) {
|
|
56
59
|
return Array.isArray(modelValue.value) ? modelValue.value : [props.min, modelValue.value];
|
|
57
60
|
}
|
|
@@ -62,8 +65,8 @@ function getPercentage(value) {
|
|
|
62
65
|
const range = max - min;
|
|
63
66
|
return Math.max(0, Math.min(100, (value - min) / range * 100));
|
|
64
67
|
}
|
|
65
|
-
const startPercentage = computed(() => getPercentage(
|
|
66
|
-
const endPercentage = computed(() => getPercentage(
|
|
68
|
+
const startPercentage = computed(() => getPercentage(valueRange.value[0]));
|
|
69
|
+
const endPercentage = computed(() => getPercentage(valueRange.value[1]));
|
|
67
70
|
const trackStyle = computed(() => {
|
|
68
71
|
const backgroundColor = props.disabled ? "var(--color-gray-alpha-400)" : getFallbackValue(props.variant, VARIANTS, "primary");
|
|
69
72
|
if (props.range) {
|
|
@@ -82,7 +85,7 @@ function updateValueFromPosition(clientX) {
|
|
|
82
85
|
if (!sliderRef.value || !activeThumb.value) {
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
85
|
-
const rect = sliderRef.value.getBoundingClientRect();
|
|
88
|
+
const rect = sliderRect ?? sliderRef.value.getBoundingClientRect();
|
|
86
89
|
const posPercentage = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
|
|
87
90
|
const range = props.max - props.min;
|
|
88
91
|
const rawValue = props.min + posPercentage * range;
|
|
@@ -91,7 +94,7 @@ function updateValueFromPosition(clientX) {
|
|
|
91
94
|
Math.min(props.max, props.step > 0 ? Math.round(rawValue / props.step) * props.step : rawValue)
|
|
92
95
|
);
|
|
93
96
|
if (props.range) {
|
|
94
|
-
const newValueArray = [...
|
|
97
|
+
const newValueArray = [...valueRange.value];
|
|
95
98
|
if (activeThumb.value === "start") {
|
|
96
99
|
newValueArray[0] = newValue;
|
|
97
100
|
if (newValue > newValueArray[1]) {
|
|
@@ -107,28 +110,23 @@ function updateValueFromPosition(clientX) {
|
|
|
107
110
|
activeThumb.value = "start";
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
|
-
if (
|
|
113
|
+
if (valueRange.value[0] !== newValueArray[0] || valueRange.value[1] !== newValueArray[1]) {
|
|
111
114
|
modelValue.value = newValueArray;
|
|
112
115
|
}
|
|
113
116
|
} else if (modelValue.value !== newValue) {
|
|
114
117
|
modelValue.value = newValue;
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
+
const scheduleUpdate = throttleByRaf(() => {
|
|
121
|
+
if (lastClientX !== null) {
|
|
122
|
+
updateValueFromPosition(lastClientX);
|
|
120
123
|
}
|
|
121
|
-
|
|
122
|
-
animationFrameId = null;
|
|
123
|
-
if (lastClientX !== null) {
|
|
124
|
-
updateValueFromPosition(lastClientX);
|
|
125
|
-
}
|
|
126
|
-
if (isDragging) {
|
|
127
|
-
scheduleUpdate();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
124
|
+
});
|
|
131
125
|
function startDragging(ev, thumb) {
|
|
126
|
+
if (!sliderRef.value) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
sliderRect = sliderRef.value.getBoundingClientRect();
|
|
132
130
|
isDragging = true;
|
|
133
131
|
activeThumb.value = thumb;
|
|
134
132
|
lastClientX = ev.clientX;
|
|
@@ -148,11 +146,9 @@ function handleMove(ev) {
|
|
|
148
146
|
function endDragging() {
|
|
149
147
|
isDragging = false;
|
|
150
148
|
lastClientX = null;
|
|
149
|
+
sliderRect = null;
|
|
151
150
|
activeThumb.value = null;
|
|
152
|
-
|
|
153
|
-
cancelAnimationFrame(animationFrameId);
|
|
154
|
-
animationFrameId = null;
|
|
155
|
-
}
|
|
151
|
+
scheduleUpdate.cancel();
|
|
156
152
|
cachedOff(document, "pointermove", handleMove);
|
|
157
153
|
cachedOff(document, "pointercancel", endDragging);
|
|
158
154
|
}
|
|
@@ -184,14 +180,43 @@ function initModelValue() {
|
|
|
184
180
|
if (props.range && !Array.isArray(modelValue.value)) {
|
|
185
181
|
modelValue.value = [props.min, modelValue.value];
|
|
186
182
|
} else if (!props.range && Array.isArray(modelValue.value)) {
|
|
187
|
-
modelValue.value = modelValue.value[1];
|
|
183
|
+
modelValue.value = modelValue.value[1] ?? 0;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function onThumbKeydown(ev) {
|
|
187
|
+
if (props.disabled) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const { code } = ev;
|
|
191
|
+
const delta = code === "ArrowLeft" ? -props.step : code === "ArrowRight" ? props.step : 0;
|
|
192
|
+
if (!delta) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
ev.preventDefault();
|
|
196
|
+
const target = ev.target;
|
|
197
|
+
const isStart = target.dataset.rangeStart === "true";
|
|
198
|
+
if (props.range) {
|
|
199
|
+
const [startVal, endVal] = valueRange.value;
|
|
200
|
+
const newRange = [startVal, endVal];
|
|
201
|
+
if (isStart) {
|
|
202
|
+
newRange[0] = Math.max(props.min, Math.min(endVal, startVal + delta));
|
|
203
|
+
} else {
|
|
204
|
+
newRange[1] = Math.max(startVal, Math.min(props.max, endVal + delta));
|
|
205
|
+
}
|
|
206
|
+
if (newRange[0] !== startVal || newRange[1] !== endVal) {
|
|
207
|
+
modelValue.value = newRange;
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
const current = modelValue.value;
|
|
211
|
+
const newValue = Math.max(props.min, Math.min(props.max, current + delta));
|
|
212
|
+
if (newValue !== current) {
|
|
213
|
+
modelValue.value = newValue;
|
|
214
|
+
}
|
|
188
215
|
}
|
|
189
216
|
}
|
|
190
217
|
initModelValue();
|
|
191
218
|
onBeforeUnmount(() => {
|
|
192
|
-
|
|
193
|
-
cancelAnimationFrame(animationFrameId);
|
|
194
|
-
}
|
|
219
|
+
scheduleUpdate.cancel();
|
|
195
220
|
cachedOff(document, "pointermove", handleMove);
|
|
196
221
|
cachedOff(document, "pointerup", endDragging);
|
|
197
222
|
cachedOff(document, "pointercancel", endDragging);
|
|
@@ -200,9 +225,10 @@ onBeforeUnmount(() => {
|
|
|
200
225
|
|
|
201
226
|
<template>
|
|
202
227
|
<div
|
|
228
|
+
v-bind="$attrs"
|
|
203
229
|
ref="sliderRef"
|
|
204
230
|
:role="range ? 'group' : 'slider'"
|
|
205
|
-
class="pxd-slider group/slider relative flex touch-none items-center rounded-full bg-gray-200 select-none"
|
|
231
|
+
class="pxd-slider group/slider relative flex w-full max-w-full shrink-0 touch-none items-center rounded-full bg-gray-200 select-none"
|
|
206
232
|
:class="[{ 'cursor-not-allowed': disabled }, computedSize.track]"
|
|
207
233
|
@pointerdown.prevent="onWrapperPointerdown"
|
|
208
234
|
>
|
|
@@ -210,27 +236,43 @@ onBeforeUnmount(() => {
|
|
|
210
236
|
|
|
211
237
|
<div
|
|
212
238
|
v-if="props.range"
|
|
213
|
-
|
|
214
|
-
:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
]"
|
|
239
|
+
tabindex="0"
|
|
240
|
+
:data-dragging="isDragging && activeThumb === 'start'"
|
|
241
|
+
:data-range-start="true"
|
|
242
|
+
class="pxd-slider--thumb group rounded-xs absolute -translate-x-1/2 touch-none appearance-none bg-none self-focus-ring outline-none hover:z-1 active:[--slider-thumb-scale:1.3] motion-safe:before:transition-all pointer-fine:hover:[--slider-thumb-scale:1.3]"
|
|
243
|
+
:class="[{ 'pointer-events-none': disabled }, computedSize.thumb]"
|
|
218
244
|
:style="{ left: `${startPercentage}%` }"
|
|
245
|
+
@keydown="onThumbKeydown"
|
|
246
|
+
@contextmenu.prevent="NOOP"
|
|
219
247
|
@pointerdown.prevent.stop="startDragging($event, 'start')"
|
|
220
|
-
|
|
248
|
+
>
|
|
249
|
+
<span
|
|
250
|
+
class="py-1 px-1.5 text-xs -top-8 shadow-sm pointer-events-none absolute left-1/2 -translate-x-1/2 rounded-md bg-gray-1000 whitespace-nowrap text-gray-100 opacity-0 select-none group-hover:opacity-100 group-data-[dragging=true]:opacity-100 motion-safe:transition-opacity"
|
|
251
|
+
>
|
|
252
|
+
{{ valueRange[0] }}
|
|
253
|
+
</span>
|
|
254
|
+
</div>
|
|
221
255
|
|
|
222
256
|
<div
|
|
223
|
-
|
|
224
|
-
:
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
]"
|
|
257
|
+
tabindex="0"
|
|
258
|
+
:data-range-start="range ? false : true"
|
|
259
|
+
:data-dragging="isDragging && activeThumb === 'end'"
|
|
260
|
+
class="pxd-slider--thumb group rounded-xs absolute -translate-x-1/2 touch-none appearance-auto bg-none self-focus-ring outline-none hover:z-1 active:[--slider-thumb-scale:1.3] motion-safe:before:transition-all pointer-fine:hover:[--slider-thumb-scale:1.3]"
|
|
261
|
+
:class="[{ 'pointer-events-none': disabled }, computedSize.thumb]"
|
|
228
262
|
:style="{ left: `${endPercentage}%` }"
|
|
263
|
+
@keydown="onThumbKeydown"
|
|
264
|
+
@contextmenu.prevent="NOOP"
|
|
229
265
|
@pointerdown.prevent.stop="startDragging($event, 'end')"
|
|
230
|
-
|
|
266
|
+
>
|
|
267
|
+
<span
|
|
268
|
+
class="py-1 px-1.5 text-xs -top-8 shadow-sm pointer-events-none absolute left-1/2 -translate-x-1/2 rounded-md bg-gray-1000 whitespace-nowrap text-gray-100 opacity-0 select-none group-hover:opacity-100 group-data-[dragging=true]:opacity-100 motion-safe:transition-opacity"
|
|
269
|
+
>
|
|
270
|
+
{{ valueRange[1] }}
|
|
271
|
+
</span>
|
|
272
|
+
</div>
|
|
231
273
|
</div>
|
|
232
274
|
</template>
|
|
233
275
|
|
|
234
276
|
<style>
|
|
235
|
-
.pxd-slider--thumb{box-shadow:0 0 0 1px var(--color-gray-alpha-500),0 1px 2px var(--color-gray-alpha-100)}.pxd-slider--thumb:after{
|
|
277
|
+
.pxd-slider--thumb[data-dragging=true]{--slider-thumb-scale:1.3}.pxd-slider--thumb:after,.pxd-slider--thumb:before{border-radius:inherit;content:"";left:50%;position:absolute;top:50%;transform:translate3d(-50%,-50%,0) scale(var(--slider-thumb-scale,1))}.pxd-slider--thumb:before{background-color:#fff;box-shadow:0 0 0 1px var(--color-gray-alpha-500),0 1px 2px var(--color-gray-alpha-100);height:100%;width:100%}.dark .pxd-slider--thumb:before{box-shadow:0 0 0 1px #000,0 1px 2px #0000000a}.pxd-slider--thumb:after{height:200%;width:200%}.pxd-slider:active .pxd-slider--thumb,.pxd-slider:active .pxd-slider--track{will-change:width,left}
|
|
236
278
|
</style>
|