pxd 0.0.60 → 0.0.62

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.
Files changed (242) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/_internal/dismiss-container.d.vue.ts +28 -0
  3. package/dist/components/_internal/dismiss-container.vue +162 -0
  4. package/dist/components/_internal/popover-arrow.d.vue.ts +9 -0
  5. package/dist/components/_internal/popover-arrow.vue +38 -0
  6. package/dist/components/active-graph/index.vue +5 -5
  7. package/dist/components/avatar/index.vue +5 -7
  8. package/dist/components/avatar-group/index.d.vue.ts +0 -1
  9. package/dist/components/avatar-group/index.vue +1 -1
  10. package/dist/components/backtop/index.vue +1 -1
  11. package/dist/components/badge/index.d.vue.ts +6 -2
  12. package/dist/components/badge/index.vue +19 -5
  13. package/dist/components/badge/types.d.ts +5 -0
  14. package/dist/components/book/index.vue +1 -1
  15. package/dist/components/browser/index.vue +1 -1
  16. package/dist/components/bubble/index.d.vue.ts +22 -0
  17. package/dist/components/bubble/index.vue +59 -0
  18. package/dist/components/bubble/types.d.ts +6 -0
  19. package/dist/components/button/index.d.vue.ts +0 -2
  20. package/dist/components/button/index.vue +31 -22
  21. package/dist/components/button/types.d.ts +3 -2
  22. package/dist/components/button-group/index.d.vue.ts +14 -0
  23. package/dist/components/button-group/index.vue +26 -0
  24. package/dist/components/button-group/types.d.ts +9 -0
  25. package/dist/components/carousel/index.d.vue.ts +3 -3
  26. package/dist/components/carousel/index.vue +146 -113
  27. package/dist/components/carousel/types.d.ts +1 -1
  28. package/dist/components/carousel-item/index.vue +22 -17
  29. package/dist/components/checkbox/index.vue +7 -7
  30. package/dist/components/checkbox-group/index.d.vue.ts +1 -1
  31. package/dist/components/chip/index.d.vue.ts +1 -5
  32. package/dist/components/chip/index.vue +5 -5
  33. package/dist/components/choicebox/index.vue +1 -1
  34. package/dist/components/collapse-group/index.vue +1 -1
  35. package/dist/components/color-selector/index.d.vue.ts +12 -0
  36. package/dist/components/color-selector/index.vue +64 -0
  37. package/dist/components/color-selector/types.d.ts +12 -0
  38. package/dist/components/command-menu/index.d.vue.ts +6 -6
  39. package/dist/components/command-menu/index.vue +24 -33
  40. package/dist/components/command-menu/types.d.ts +1 -1
  41. package/dist/components/command-menu-group/index.vue +15 -6
  42. package/dist/components/command-menu-group/types.d.ts +1 -1
  43. package/dist/components/config-provider/index.d.vue.ts +1 -1
  44. package/dist/components/countdown/index.d.vue.ts +11 -11
  45. package/dist/components/drawer/index.d.vue.ts +8 -8
  46. package/dist/components/drawer/index.vue +13 -10
  47. package/dist/components/drawer/types.d.ts +4 -3
  48. package/dist/components/ellipsis-text/index.d.vue.ts +4 -1
  49. package/dist/components/ellipsis-text/index.vue +86 -109
  50. package/dist/components/ellipsis-text/types.d.ts +2 -1
  51. package/dist/components/error/index.vue +2 -2
  52. package/dist/components/fader/index.vue +5 -9
  53. package/dist/components/gauge/index.vue +34 -29
  54. package/dist/components/grid/index.vue +1 -1
  55. package/dist/components/grid-item/index.vue +1 -1
  56. package/dist/components/hold-button/index.d.vue.ts +8 -10
  57. package/dist/components/hold-button/index.vue +15 -27
  58. package/dist/components/hold-button/types.d.ts +5 -6
  59. package/dist/components/index.d.ts +7 -0
  60. package/dist/components/index.js +7 -0
  61. package/dist/components/input/index.d.vue.ts +8 -8
  62. package/dist/components/input/index.vue +7 -6
  63. package/dist/components/intersection-observer/index.vue +4 -4
  64. package/dist/components/kbd/index.vue +2 -2
  65. package/dist/components/link-button/index.d.vue.ts +4 -4
  66. package/dist/components/link-button/index.vue +5 -7
  67. package/dist/components/link-button/types.d.ts +0 -3
  68. package/dist/components/list/index.d.vue.ts +10 -15
  69. package/dist/components/list/index.vue +58 -131
  70. package/dist/components/list/types.d.ts +4 -4
  71. package/dist/components/list-item/index.d.vue.ts +2 -2
  72. package/dist/components/list-item/index.vue +45 -40
  73. package/dist/components/loading-bar/index.vue +9 -8
  74. package/dist/components/material/index.vue +24 -46
  75. package/dist/components/menu/index.d.vue.ts +6 -8
  76. package/dist/components/menu/index.vue +18 -24
  77. package/dist/components/menu/types.d.ts +1 -2
  78. package/dist/components/message/composables/use-group-expand.d.ts +13 -0
  79. package/dist/components/message/composables/use-group-expand.js +50 -0
  80. package/dist/components/message/composables/use-message-timer.d.ts +9 -0
  81. package/dist/components/message/composables/use-message-timer.js +61 -0
  82. package/dist/components/message/composables/use-promise-message.d.ts +4 -0
  83. package/dist/components/message/composables/use-promise-message.js +49 -0
  84. package/dist/components/message/index.d.vue.ts +6 -33
  85. package/dist/components/message/index.vue +33 -185
  86. package/dist/components/message/types.d.ts +2 -2
  87. package/dist/components/message-item/index.vue +26 -2
  88. package/dist/components/modal/index.d.vue.ts +7 -7
  89. package/dist/components/modal/index.vue +7 -3
  90. package/dist/components/modal/types.d.ts +7 -3
  91. package/dist/components/note/index.vue +3 -3
  92. package/dist/components/number-input/index.d.vue.ts +5 -4
  93. package/dist/components/number-input/index.vue +3 -0
  94. package/dist/components/number-input/types.d.ts +1 -0
  95. package/dist/components/overlay/index.d.vue.ts +6 -3
  96. package/dist/components/overlay/index.vue +63 -68
  97. package/dist/components/overlay/types.d.ts +5 -4
  98. package/dist/components/pagination/index.vue +2 -2
  99. package/dist/components/pin-input/index.d.vue.ts +2 -2
  100. package/dist/components/pin-input/index.vue +9 -8
  101. package/dist/components/placeholder/index.vue +14 -12
  102. package/dist/components/popover/index.d.vue.ts +8 -9
  103. package/dist/components/popover/index.vue +150 -240
  104. package/dist/components/popover/types.d.ts +6 -7
  105. package/dist/components/progress/index.vue +3 -3
  106. package/dist/components/project-banner/index.vue +1 -1
  107. package/dist/components/radio/index.vue +3 -3
  108. package/dist/components/radio-group/index.vue +1 -1
  109. package/dist/components/resizable/index.vue +43 -51
  110. package/dist/components/resizable/types.d.ts +1 -1
  111. package/dist/components/resizable-handle/index.d.vue.ts +4 -1
  112. package/dist/components/resizable-handle/index.vue +29 -3
  113. package/dist/components/resizable-panel/index.vue +3 -7
  114. package/dist/components/scalable-text/index.d.vue.ts +9 -0
  115. package/dist/components/scalable-text/index.vue +147 -0
  116. package/dist/components/scalable-text/types.d.ts +12 -0
  117. package/dist/components/scrollable/index.d.vue.ts +2 -2
  118. package/dist/components/scrollable/index.vue +4 -3
  119. package/dist/components/scrollable/types.d.ts +1 -2
  120. package/dist/components/separator/index.d.vue.ts +6 -0
  121. package/dist/components/separator/index.vue +18 -0
  122. package/dist/components/separator/types.d.ts +5 -0
  123. package/dist/components/skeleton/index.d.vue.ts +1 -1
  124. package/dist/components/skeleton/index.vue +1 -1
  125. package/dist/components/slider/index.d.vue.ts +1 -1
  126. package/dist/components/slider/index.vue +41 -9
  127. package/dist/components/snippet/index.vue +18 -15
  128. package/dist/components/spinner/index.vue +3 -1
  129. package/dist/components/stack/index.d.vue.ts +1 -1
  130. package/dist/components/stack/index.vue +2 -2
  131. package/dist/components/switch/index.d.vue.ts +1 -1
  132. package/dist/components/switch/index.vue +5 -4
  133. package/dist/components/switch-item/index.vue +3 -3
  134. package/dist/components/tabs/index.d.vue.ts +12 -0
  135. package/dist/components/tabs/index.vue +270 -0
  136. package/dist/components/tabs/types.d.ts +12 -0
  137. package/dist/components/tabs-item/index.d.vue.ts +4 -0
  138. package/dist/components/tabs-item/index.vue +16 -0
  139. package/dist/components/tabs-item/types.d.ts +10 -0
  140. package/dist/components/text/index.vue +2 -2
  141. package/dist/components/textarea/index.d.vue.ts +2 -2
  142. package/dist/components/textarea/index.vue +3 -3
  143. package/dist/components/time-picker/index.d.vue.ts +3 -5
  144. package/dist/components/time-picker/index.vue +54 -46
  145. package/dist/components/time-picker/types.d.ts +1 -2
  146. package/dist/components/toggle/index.d.vue.ts +0 -2
  147. package/dist/components/toggle/index.vue +7 -7
  148. package/dist/components/toggle-button/index.vue +11 -9
  149. package/dist/components/toggle-button-group/index.vue +3 -3
  150. package/dist/components/tooltip/index.d.vue.ts +1 -1
  151. package/dist/components/tooltip/index.vue +19 -11
  152. package/dist/components/tooltip/types.d.ts +2 -3
  153. package/dist/components/virtual-list/index.d.vue.ts +8 -8
  154. package/dist/components/virtual-list/index.vue +29 -7
  155. package/dist/components/virtual-list/types.d.ts +3 -0
  156. package/dist/composables/index.d.ts +4 -1
  157. package/dist/composables/index.js +4 -1
  158. package/dist/composables/use-browser-observer.d.ts +1 -1
  159. package/dist/composables/use-browser-observer.js +2 -2
  160. package/dist/composables/use-client-online.js +2 -2
  161. package/dist/composables/use-color-scheme.js +2 -2
  162. package/dist/composables/use-countdown.js +3 -2
  163. package/dist/composables/use-deferred-value.js +2 -2
  164. package/dist/composables/use-delay-destroy.d.ts +1 -1
  165. package/dist/composables/use-delay-destroy.js +11 -6
  166. package/dist/composables/use-document-hidden.js +2 -2
  167. package/dist/composables/use-focus-trap.d.ts +1 -1
  168. package/dist/composables/use-focus-trap.js +2 -2
  169. package/dist/composables/use-list-filter.d.ts +11 -0
  170. package/dist/composables/use-list-filter.js +56 -0
  171. package/dist/composables/use-list-navigation.d.ts +27 -0
  172. package/dist/composables/use-list-navigation.js +159 -0
  173. package/dist/composables/use-lock-scroll.js +12 -12
  174. package/dist/composables/use-media-query.js +2 -2
  175. package/dist/composables/use-message.d.ts +1 -1
  176. package/dist/composables/use-outside-click.d.ts +1 -1
  177. package/dist/composables/use-outside-click.js +8 -11
  178. package/dist/composables/use-overlay-manager.d.ts +18 -0
  179. package/dist/composables/use-overlay-manager.js +80 -0
  180. package/dist/composables/use-popover-responsive.d.ts +6 -8
  181. package/dist/composables/use-popover-responsive.js +9 -12
  182. package/dist/composables/use-repeat-action.d.ts +1 -1
  183. package/dist/composables/use-repeat-action.js +2 -2
  184. package/dist/composables/use-swipe-gesture.d.ts +65 -0
  185. package/dist/composables/use-swipe-gesture.js +99 -0
  186. package/dist/composables/use-virtual-list.d.ts +6 -4
  187. package/dist/composables/use-virtual-list.js +25 -14
  188. package/dist/composables/use-window-size.js +2 -2
  189. package/dist/constants/size.d.ts +12 -0
  190. package/dist/constants/size.js +12 -0
  191. package/dist/contexts/button.d.ts +5 -0
  192. package/dist/contexts/button.js +5 -0
  193. package/dist/contexts/carousel.d.ts +3 -2
  194. package/dist/contexts/checkbox.d.ts +1 -1
  195. package/dist/contexts/choicebox.d.ts +1 -1
  196. package/dist/contexts/collapse.d.ts +1 -1
  197. package/dist/contexts/list.d.ts +23 -3
  198. package/dist/contexts/list.js +6 -2
  199. package/dist/contexts/radio.d.ts +1 -1
  200. package/dist/contexts/resizable.d.ts +3 -11
  201. package/dist/contexts/switch.d.ts +1 -1
  202. package/dist/contexts/tabs.d.ts +15 -0
  203. package/dist/contexts/tabs.js +2 -0
  204. package/dist/contexts/toggle-button.d.ts +1 -1
  205. package/dist/locales/en-us.d.ts +4 -4
  206. package/dist/locales/en-us.js +4 -4
  207. package/dist/locales/zh-cn.d.ts +4 -4
  208. package/dist/locales/zh-cn.js +4 -4
  209. package/dist/plugins/dayjs-millisecond-token.js +1 -1
  210. package/dist/styles/source.css +133 -128
  211. package/dist/styles/styles.css +2 -2
  212. package/dist/styles/tw.css +133 -128
  213. package/dist/types/shared/props.d.ts +1 -0
  214. package/dist/types/shared/utils.d.ts +1 -4
  215. package/dist/utils/date.d.ts +3 -3
  216. package/dist/utils/dom.d.ts +1 -0
  217. package/dist/utils/dom.js +4 -0
  218. package/dist/utils/event.d.ts +2 -1
  219. package/dist/utils/event.js +7 -1
  220. package/dist/utils/format.d.ts +3 -3
  221. package/dist/utils/format.js +5 -4
  222. package/dist/utils/fuzzy-search.d.ts +7 -0
  223. package/dist/utils/fuzzy-search.js +61 -0
  224. package/dist/utils/get.d.ts +2 -0
  225. package/dist/utils/get.js +15 -1
  226. package/dist/utils/index.d.ts +10 -11
  227. package/dist/utils/index.js +2 -3
  228. package/dist/utils/ref.d.ts +2 -2
  229. package/dist/utils/{throttle.d.ts → timing.d.ts} +1 -0
  230. package/dist/utils/{throttle.js → timing.js} +4 -2
  231. package/package.json +67 -63
  232. package/volar.d.ts +7 -0
  233. package/dist/components/overlay/overlay-stack.d.ts +0 -3
  234. package/dist/components/overlay/overlay-stack.js +0 -17
  235. package/dist/composables/use-pointer-gesture.d.ts +0 -180
  236. package/dist/composables/use-pointer-gesture.js +0 -406
  237. package/dist/utils/debounce.d.ts +0 -1
  238. package/dist/utils/debounce.js +0 -1
  239. package/dist/utils/regexp.d.ts +0 -8
  240. package/dist/utils/regexp.js +0 -8
  241. package/dist/utils/responsive.d.ts +0 -3
  242. package/dist/utils/responsive.js +0 -14
@@ -1,5 +1,5 @@
1
- import type { MaybeRefOrGetter, Ref } from 'vue';
2
1
  import type { Nullable } from '../types/shared/utils';
2
+ import type { MaybeRefOrGetter, Ref } from 'vue';
3
3
  export declare const useIntersectionObserver: (target: TargetRef, callback: IntersectionObserverCallback, options?: IntersectionObserverInit) => ObserverResults<IntersectionObserver>;
4
4
  export declare const useMutationObserver: (target: TargetRef, callback: MutationCallback, options?: MutationObserverInit) => ObserverResults<MutationObserver>;
5
5
  export declare const useResizeObserver: (target: TargetRef, callback: ResizeObserverCallback, options?: ResizeObserverOptions) => ObserverResults<ResizeObserver>;
@@ -1,5 +1,5 @@
1
1
  import { isNotNil } from "es-toolkit";
2
- import { computed, onBeforeUnmount, watch, shallowRef } from "vue";
2
+ import { computed, onScopeDispose, watch, shallowRef } from "vue";
3
3
  import { toArray } from "../utils/format.js";
4
4
  import { toValue, unrefElement } from "../utils/ref.js";
5
5
  export const useIntersectionObserver = createObserver(
@@ -62,7 +62,7 @@ function createObserver(ObserverConstructor, type) {
62
62
  cleanup();
63
63
  unwatch();
64
64
  }
65
- onBeforeUnmount(() => {
65
+ onScopeDispose(() => {
66
66
  stop();
67
67
  });
68
68
  return {
@@ -1,4 +1,4 @@
1
- import { onBeforeUnmount, onMounted, shallowRef } from "vue";
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 useClientOnline() {
@@ -12,7 +12,7 @@ export function useClientOnline() {
12
12
  cleanOnline = cachedOn(window, "online", toggle);
13
13
  cleanOffline = cachedOn(window, "offline", toggle);
14
14
  });
15
- onBeforeUnmount(() => {
15
+ onScopeDispose(() => {
16
16
  cleanOnline?.();
17
17
  cleanOffline?.();
18
18
  });
@@ -1,4 +1,4 @@
1
- import { computed, onBeforeUnmount, shallowRef, watchEffect } from "vue";
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
- onBeforeUnmount(() => {
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
- requestAnimationFrame(frame);
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
- requestAnimationFrame(frame);
97
+ raf(frame);
97
98
  }
98
99
  const unwatchActive = watch(
99
100
  () => props.active,
@@ -1,4 +1,4 @@
1
- import { onBeforeUnmount, ref, watch } from "vue";
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
- onBeforeUnmount(() => {
19
+ onScopeDispose(() => {
20
20
  unwatch();
21
21
  clearTimeout(syncTimeoutId);
22
22
  });
@@ -1,5 +1,5 @@
1
- import type { MaybeRefOrGetter, Ref } from 'vue';
2
1
  import type { Nullable } from '../types/shared';
2
+ import type { MaybeRefOrGetter, Ref } from 'vue';
3
3
  interface Options {
4
4
  delay?: number;
5
5
  renderChange?: (v: boolean) => void;
@@ -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 visibleTimeoutId;
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 (!visible.value) {
17
- clearTimeout(visibleTimeoutId);
18
- visibleTimeoutId = setTimeout(() => {
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
- }, 0);
26
+ });
23
27
  }
24
28
  });
25
29
  }
26
30
  function hide() {
27
31
  return new Promise((resolve) => {
28
- clearTimeout(visibleTimeoutId);
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 { onBeforeUnmount, onMounted, shallowRef } from "vue";
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
- onBeforeUnmount(() => {
14
+ onScopeDispose(() => {
15
15
  cleanHidden?.();
16
16
  });
17
17
  return isHidden;
@@ -1,6 +1,6 @@
1
+ import type { MaybeElementRef } from '../types/shared/utils';
1
2
  import type { Options as FocusTrapOptions } from 'focus-trap';
2
3
  import { type MaybeRefOrGetter } from 'vue';
3
- import type { MaybeElementRef } from '../types/shared/utils';
4
4
  export interface UseFocusTrapOptions extends FocusTrapOptions {
5
5
  autoFocusElement?: string | boolean;
6
6
  }
@@ -1,5 +1,5 @@
1
1
  import { createFocusTrap } from "focus-trap";
2
- import { onBeforeUnmount, watch } from "vue";
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
- onBeforeUnmount(() => {
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 documentTouchMoveLocks = 0;
3
+ let rootTouchMoveLocks = 0;
4
4
  export function useLockScroll() {
5
- const rootEl = document.documentElement;
5
+ const classList = ["pointer-events-none"];
6
6
  function isLocked() {
7
- return documentTouchMoveLocks > 0;
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 classList = ["pointer-events-none!"];
13
- const { y: yScrollbar } = hasScrollbar(rootEl);
14
- const { y: yScrollable } = isScrollable(rootEl);
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
- documentTouchMoveLocks++;
20
+ rootTouchMoveLocks++;
21
21
  }
22
22
  function unlockScroll() {
23
- if (documentTouchMoveLocks <= 0) {
23
+ if (rootTouchMoveLocks <= 0) {
24
24
  return;
25
25
  }
26
- documentTouchMoveLocks = Math.max(documentTouchMoveLocks - 1, 0);
27
- if (!documentTouchMoveLocks) {
26
+ rootTouchMoveLocks = Math.max(rootTouchMoveLocks - 1, 0);
27
+ if (!rootTouchMoveLocks) {
28
28
  cachedOff(document, "touchmove", preventDefaultScroll);
29
- rootEl.classList.remove("pointer-events-none!", "scrollbar-stable", "scrollbar-disabled");
29
+ document.documentElement.classList.remove(...classList);
30
30
  }
31
31
  }
32
32
  return {
@@ -1,4 +1,4 @@
1
- import { customRef, onBeforeUnmount } from "vue";
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
- onBeforeUnmount(() => {
72
+ onScopeDispose(() => {
73
73
  stop();
74
74
  });
75
75
  return matches;
@@ -1,6 +1,6 @@
1
- import type { VNode } from 'vue';
2
1
  import type { ButtonProps } from '../components/button/types';
3
2
  import type { ComponentClass } from '../types/shared/props';
3
+ import type { VNode } from 'vue';
4
4
  type MessageContent = string | VNode;
5
5
  type PromiseMessageHandler = MessageContent | ((data: unknown) => MessageContent);
6
6
  interface Action {
@@ -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 { onBeforeUnmount, watch } from "vue";
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, isOutside, onTrigger } = options;
6
+ const { isEnabled } = options;
7
7
  if (typeof isEnabled === "function" && !isEnabled(ev)) {
8
8
  return;
9
9
  }
10
- if (typeof isOutside === "function") {
11
- if (!isOutside(ev)) {
12
- return;
13
- }
14
- } else {
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
- onBeforeUnmount(() => {
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
+ }