pxd 0.0.61 → 0.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) 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 +4 -4
  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 +5 -1
  12. package/dist/components/badge/index.vue +18 -4
  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 +30 -21
  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 +6 -6
  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 +4 -4
  33. package/dist/components/color-selector/index.d.vue.ts +12 -0
  34. package/dist/components/color-selector/index.vue +64 -0
  35. package/dist/components/color-selector/types.d.ts +12 -0
  36. package/dist/components/command-menu/index.d.vue.ts +6 -6
  37. package/dist/components/command-menu/index.vue +23 -32
  38. package/dist/components/command-menu/types.d.ts +1 -1
  39. package/dist/components/command-menu-group/index.vue +15 -6
  40. package/dist/components/command-menu-group/types.d.ts +1 -1
  41. package/dist/components/countdown/index.d.vue.ts +11 -11
  42. package/dist/components/drawer/index.d.vue.ts +8 -8
  43. package/dist/components/drawer/index.vue +13 -10
  44. package/dist/components/drawer/types.d.ts +4 -3
  45. package/dist/components/ellipsis-text/index.d.vue.ts +4 -1
  46. package/dist/components/ellipsis-text/index.vue +84 -107
  47. package/dist/components/ellipsis-text/types.d.ts +2 -1
  48. package/dist/components/error/index.vue +1 -1
  49. package/dist/components/fader/index.vue +5 -9
  50. package/dist/components/gauge/index.vue +34 -29
  51. package/dist/components/grid/index.vue +1 -1
  52. package/dist/components/grid-item/index.vue +1 -1
  53. package/dist/components/hold-button/index.d.vue.ts +8 -10
  54. package/dist/components/hold-button/index.vue +20 -29
  55. package/dist/components/hold-button/types.d.ts +5 -6
  56. package/dist/components/index.d.ts +7 -0
  57. package/dist/components/index.js +7 -0
  58. package/dist/components/input/index.d.vue.ts +8 -8
  59. package/dist/components/input/index.vue +5 -4
  60. package/dist/components/intersection-observer/index.vue +4 -4
  61. package/dist/components/kbd/index.vue +1 -1
  62. package/dist/components/link-button/index.d.vue.ts +4 -4
  63. package/dist/components/link-button/index.vue +9 -8
  64. package/dist/components/link-button/types.d.ts +0 -3
  65. package/dist/components/list/index.d.vue.ts +10 -15
  66. package/dist/components/list/index.vue +58 -131
  67. package/dist/components/list/types.d.ts +4 -4
  68. package/dist/components/list-item/index.d.vue.ts +2 -2
  69. package/dist/components/list-item/index.vue +44 -39
  70. package/dist/components/loading-bar/index.vue +8 -7
  71. package/dist/components/material/index.vue +24 -46
  72. package/dist/components/menu/index.d.vue.ts +6 -8
  73. package/dist/components/menu/index.vue +18 -24
  74. package/dist/components/menu/types.d.ts +1 -2
  75. package/dist/components/message/composables/use-group-expand.d.ts +13 -0
  76. package/dist/components/message/composables/use-group-expand.js +50 -0
  77. package/dist/components/message/composables/use-message-timer.d.ts +9 -0
  78. package/dist/components/message/composables/use-message-timer.js +61 -0
  79. package/dist/components/message/composables/use-promise-message.d.ts +4 -0
  80. package/dist/components/message/composables/use-promise-message.js +49 -0
  81. package/dist/components/message/index.d.vue.ts +6 -33
  82. package/dist/components/message/index.vue +33 -185
  83. package/dist/components/message/types.d.ts +2 -2
  84. package/dist/components/message-item/index.vue +26 -2
  85. package/dist/components/modal/index.d.vue.ts +7 -7
  86. package/dist/components/modal/index.vue +7 -3
  87. package/dist/components/modal/types.d.ts +7 -3
  88. package/dist/components/note/index.vue +2 -2
  89. package/dist/components/number-input/index.d.vue.ts +5 -4
  90. package/dist/components/number-input/index.vue +3 -0
  91. package/dist/components/number-input/types.d.ts +1 -0
  92. package/dist/components/overlay/index.d.vue.ts +6 -3
  93. package/dist/components/overlay/index.vue +63 -68
  94. package/dist/components/overlay/types.d.ts +5 -4
  95. package/dist/components/pagination/index.vue +2 -2
  96. package/dist/components/pin-input/index.d.vue.ts +1 -1
  97. package/dist/components/pin-input/index.vue +7 -6
  98. package/dist/components/placeholder/index.vue +1 -1
  99. package/dist/components/popover/index.d.vue.ts +7 -8
  100. package/dist/components/popover/index.vue +149 -239
  101. package/dist/components/popover/types.d.ts +5 -5
  102. package/dist/components/progress/index.vue +1 -1
  103. package/dist/components/radio/index.vue +2 -2
  104. package/dist/components/resizable/index.vue +43 -51
  105. package/dist/components/resizable/types.d.ts +1 -1
  106. package/dist/components/resizable-handle/index.d.vue.ts +4 -1
  107. package/dist/components/resizable-handle/index.vue +29 -3
  108. package/dist/components/resizable-panel/index.vue +3 -7
  109. package/dist/components/scalable-text/index.d.vue.ts +9 -0
  110. package/dist/components/scalable-text/index.vue +147 -0
  111. package/dist/components/scalable-text/types.d.ts +12 -0
  112. package/dist/components/scrollable/index.d.vue.ts +2 -2
  113. package/dist/components/scrollable/index.vue +4 -3
  114. package/dist/components/separator/index.d.vue.ts +6 -0
  115. package/dist/components/separator/index.vue +18 -0
  116. package/dist/components/separator/types.d.ts +5 -0
  117. package/dist/components/skeleton/index.d.vue.ts +1 -1
  118. package/dist/components/slider/index.d.vue.ts +1 -1
  119. package/dist/components/slider/index.vue +39 -7
  120. package/dist/components/snippet/index.vue +16 -13
  121. package/dist/components/spinner/index.vue +3 -1
  122. package/dist/components/stack/index.d.vue.ts +1 -1
  123. package/dist/components/stack/index.vue +1 -1
  124. package/dist/components/switch/index.d.vue.ts +1 -1
  125. package/dist/components/switch/index.vue +4 -3
  126. package/dist/components/switch-item/index.vue +1 -1
  127. package/dist/components/tabs/index.d.vue.ts +12 -0
  128. package/dist/components/tabs/index.vue +270 -0
  129. package/dist/components/tabs/types.d.ts +12 -0
  130. package/dist/components/tabs-item/index.d.vue.ts +4 -0
  131. package/dist/components/tabs-item/index.vue +16 -0
  132. package/dist/components/tabs-item/types.d.ts +10 -0
  133. package/dist/components/text/index.vue +1 -1
  134. package/dist/components/textarea/index.d.vue.ts +2 -2
  135. package/dist/components/textarea/index.vue +1 -1
  136. package/dist/components/time-picker/index.d.vue.ts +3 -5
  137. package/dist/components/time-picker/index.vue +53 -45
  138. package/dist/components/time-picker/types.d.ts +1 -2
  139. package/dist/components/toggle/index.d.vue.ts +0 -2
  140. package/dist/components/toggle/index.vue +6 -6
  141. package/dist/components/toggle-button/index.vue +8 -6
  142. package/dist/components/tooltip/index.d.vue.ts +1 -1
  143. package/dist/components/tooltip/index.vue +19 -11
  144. package/dist/components/tooltip/types.d.ts +2 -2
  145. package/dist/components/virtual-list/index.d.vue.ts +8 -8
  146. package/dist/components/virtual-list/index.vue +27 -5
  147. package/dist/components/virtual-list/types.d.ts +3 -0
  148. package/dist/composables/index.d.ts +4 -1
  149. package/dist/composables/index.js +4 -1
  150. package/dist/composables/use-browser-observer.js +2 -2
  151. package/dist/composables/use-client-online.js +2 -2
  152. package/dist/composables/use-color-scheme.js +2 -2
  153. package/dist/composables/use-countdown.js +3 -2
  154. package/dist/composables/use-deferred-value.js +2 -2
  155. package/dist/composables/use-delay-destroy.js +11 -6
  156. package/dist/composables/use-document-hidden.js +2 -2
  157. package/dist/composables/use-focus-trap.js +2 -2
  158. package/dist/composables/use-list-filter.d.ts +11 -0
  159. package/dist/composables/use-list-filter.js +56 -0
  160. package/dist/composables/use-list-navigation.d.ts +27 -0
  161. package/dist/composables/use-list-navigation.js +159 -0
  162. package/dist/composables/use-lock-scroll.js +12 -12
  163. package/dist/composables/use-media-query.js +2 -2
  164. package/dist/composables/use-outside-click.d.ts +1 -1
  165. package/dist/composables/use-outside-click.js +8 -11
  166. package/dist/composables/use-overlay-manager.d.ts +18 -0
  167. package/dist/composables/use-overlay-manager.js +80 -0
  168. package/dist/composables/use-popover-responsive.d.ts +6 -8
  169. package/dist/composables/use-popover-responsive.js +9 -12
  170. package/dist/composables/use-repeat-action.js +2 -2
  171. package/dist/composables/use-swipe-gesture.d.ts +65 -0
  172. package/dist/composables/use-swipe-gesture.js +99 -0
  173. package/dist/composables/use-virtual-list.d.ts +5 -3
  174. package/dist/composables/use-virtual-list.js +25 -14
  175. package/dist/composables/use-window-size.js +2 -2
  176. package/dist/constants/size.d.ts +12 -0
  177. package/dist/constants/size.js +12 -0
  178. package/dist/contexts/button.d.ts +5 -0
  179. package/dist/contexts/button.js +5 -0
  180. package/dist/contexts/carousel.d.ts +2 -1
  181. package/dist/contexts/list.d.ts +23 -3
  182. package/dist/contexts/list.js +6 -2
  183. package/dist/contexts/resizable.d.ts +3 -11
  184. package/dist/contexts/tabs.d.ts +15 -0
  185. package/dist/contexts/tabs.js +2 -0
  186. package/dist/locales/en-us.d.ts +4 -4
  187. package/dist/locales/en-us.js +4 -4
  188. package/dist/locales/zh-cn.d.ts +4 -4
  189. package/dist/locales/zh-cn.js +4 -4
  190. package/dist/plugins/dayjs-millisecond-token.js +1 -1
  191. package/dist/styles/source.css +133 -128
  192. package/dist/styles/styles.css +2 -2
  193. package/dist/styles/tw.css +133 -128
  194. package/dist/types/shared/props.d.ts +1 -0
  195. package/dist/types/shared/utils.d.ts +1 -4
  196. package/dist/utils/date.d.ts +3 -3
  197. package/dist/utils/dom.d.ts +1 -0
  198. package/dist/utils/dom.js +4 -0
  199. package/dist/utils/event.d.ts +2 -1
  200. package/dist/utils/event.js +7 -1
  201. package/dist/utils/format.d.ts +3 -3
  202. package/dist/utils/format.js +5 -4
  203. package/dist/utils/fuzzy-search.d.ts +7 -0
  204. package/dist/utils/fuzzy-search.js +61 -0
  205. package/dist/utils/get.d.ts +2 -0
  206. package/dist/utils/get.js +15 -1
  207. package/dist/utils/index.d.ts +10 -11
  208. package/dist/utils/index.js +2 -3
  209. package/dist/utils/ref.d.ts +2 -2
  210. package/dist/utils/{throttle.d.ts → timing.d.ts} +1 -0
  211. package/dist/utils/{throttle.js → timing.js} +4 -2
  212. package/package.json +40 -37
  213. package/volar.d.ts +7 -0
  214. package/dist/components/overlay/overlay-stack.d.ts +0 -3
  215. package/dist/components/overlay/overlay-stack.js +0 -17
  216. package/dist/composables/use-pointer-gesture.d.ts +0 -180
  217. package/dist/composables/use-pointer-gesture.js +0 -406
  218. package/dist/utils/debounce.d.ts +0 -1
  219. package/dist/utils/debounce.js +0 -1
  220. package/dist/utils/regexp.d.ts +0 -8
  221. package/dist/utils/regexp.js +0 -8
  222. package/dist/utils/responsive.d.ts +0 -3
  223. package/dist/utils/responsive.js +0 -14
@@ -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,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,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,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
+ }
@@ -1,12 +1,10 @@
1
1
  export declare function usePopoverResponsive(): {
2
- isXs: import("vue").Ref<boolean, boolean>;
3
- attrs: import("vue").ComputedRef<{
4
- readonly contentClass: "bg-background-100 border w-full rounded-tl-xl rounded-tr-xl";
5
- readonly wrapperClass: "fixed w-screen h-screen items-end pointer-events-none pxd-container-mask";
6
- readonly transitionType: "fade-slide";
2
+ isAdaptive: import("vue").Ref<boolean, boolean>;
3
+ responsiveClasses: import("vue").ComputedRef<{
4
+ readonly content: "bg-background-100 shadow-border-menu w-full rounded-tl-xl rounded-tr-xl";
5
+ readonly wrapper: "fixed w-full h-full items-end pointer-events-none";
7
6
  } | {
8
- readonly contentClass: "bg-background-100 border rounded-xl";
9
- readonly wrapperClass: "";
10
- readonly transitionType: "fade-scale";
7
+ readonly content: "bg-background-100 shadow-border-menu rounded-xl";
8
+ readonly wrapper: "";
11
9
  }>;
12
10
  };
@@ -1,24 +1,21 @@
1
1
  import { computed } from "vue";
2
2
  import { PRESET_MEDIA_QUERIES, useMediaQuery } from "./use-media-query.js";
3
3
  export function usePopoverResponsive() {
4
- const isXs = useMediaQuery(PRESET_MEDIA_QUERIES.IS_XS);
5
- const attrs = computed(() => {
6
- const basicContentClass = "bg-background-100 border";
7
- if (isXs.value) {
4
+ const isAdaptive = useMediaQuery(PRESET_MEDIA_QUERIES.IS_XS);
5
+ const responsiveClasses = computed(() => {
6
+ if (isAdaptive.value) {
8
7
  return {
9
- contentClass: `${basicContentClass} w-full rounded-tl-xl rounded-tr-xl`,
10
- wrapperClass: "fixed w-screen h-screen items-end pointer-events-none pxd-container-mask",
11
- transitionType: "fade-slide"
8
+ content: `bg-background-100 shadow-border-menu w-full rounded-tl-xl rounded-tr-xl`,
9
+ wrapper: "fixed w-full h-full items-end pointer-events-none"
12
10
  };
13
11
  }
14
12
  return {
15
- contentClass: `${basicContentClass} rounded-xl`,
16
- wrapperClass: "",
17
- transitionType: "fade-scale"
13
+ content: `bg-background-100 shadow-border-menu rounded-xl`,
14
+ wrapper: ""
18
15
  };
19
16
  });
20
17
  return {
21
- isXs,
22
- attrs
18
+ isAdaptive,
19
+ responsiveClasses
23
20
  };
24
21
  }
@@ -1,4 +1,4 @@
1
- import { onBeforeUnmount } from "vue";
1
+ import { onScopeDispose } from "vue";
2
2
  import { off, once } from "../utils/event.js";
3
3
  import { toValue } from "../utils/ref.js";
4
4
  export function useRepeatAction(actionOrOptions) {
@@ -40,7 +40,7 @@ export function useRepeatAction(actionOrOptions) {
40
40
  once(document, "pointerup", stop);
41
41
  once(document, "pointercancel", stop);
42
42
  }
43
- onBeforeUnmount(() => {
43
+ onScopeDispose(() => {
44
44
  off(document, "pointerup", stop);
45
45
  off(document, "pointercancel", stop);
46
46
  });