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
@@ -5,7 +5,9 @@ export { default as Backtop } from "./backtop/index.vue";
5
5
  export { default as Badge } from "./badge/index.vue";
6
6
  export { default as Book } from "./book/index.vue";
7
7
  export { default as Browser } from "./browser/index.vue";
8
+ export { default as Bubble } from "./bubble/index.vue";
8
9
  export { default as Button } from "./button/index.vue";
10
+ export { default as ButtonGroup } from "./button-group/index.vue";
9
11
  export { default as Carousel } from "./carousel/index.vue";
10
12
  export { default as CarouselItem } from "./carousel-item/index.vue";
11
13
  export { default as Checkbox } from "./checkbox/index.vue";
@@ -15,6 +17,7 @@ export { default as Choicebox } from "./choicebox/index.vue";
15
17
  export { default as ChoiceboxItem } from "./choicebox-item/index.vue";
16
18
  export { default as Collapse } from "./collapse/index.vue";
17
19
  export { default as CollapseGroup } from "./collapse-group/index.vue";
20
+ export { default as ColorSelector } from "./color-selector/index.vue";
18
21
  export { default as CommandMenu } from "./command-menu/index.vue";
19
22
  export { default as CommandMenuGroup } from "./command-menu-group/index.vue";
20
23
  export { default as ConfigProvider } from "./config-provider/index.vue";
@@ -60,7 +63,9 @@ export { default as RadioGroup } from "./radio-group/index.vue";
60
63
  export { default as Resizable } from "./resizable/index.vue";
61
64
  export { default as ResizableHandle } from "./resizable-handle/index.vue";
62
65
  export { default as ResizablePanel } from "./resizable-panel/index.vue";
66
+ export { default as ScalableText } from "./scalable-text/index.vue";
63
67
  export { default as Scrollable } from "./scrollable/index.vue";
68
+ export { default as Separator } from "./separator/index.vue";
64
69
  export { default as Skeleton } from "./skeleton/index.vue";
65
70
  export { default as Slider } from "./slider/index.vue";
66
71
  export { default as Snippet } from "./snippet/index.vue";
@@ -69,6 +74,8 @@ export { default as Stack } from "./stack/index.vue";
69
74
  export { default as StatusDot } from "./status-dot/index.vue";
70
75
  export { default as Switch } from "./switch/index.vue";
71
76
  export { default as SwitchItem } from "./switch-item/index.vue";
77
+ export { default as Tabs } from "./tabs/index.vue";
78
+ export { default as TabsItem } from "./tabs-item/index.vue";
72
79
  export { default as Teleport } from "./teleport/index.vue";
73
80
  export { default as Text } from "./text/index.vue";
74
81
  export { default as Textarea } from "./textarea/index.vue";
@@ -15,27 +15,27 @@ declare const __VLS_base: import("vue").DefineComponent<InputProps, {
15
15
  focus: typeof focus;
16
16
  select: typeof select;
17
17
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
18
- input: (args_0: string) => any;
19
- click: (args_0: MouseEvent) => any;
20
18
  change: (args_0: string, args_1: Event) => any;
21
19
  "update:modelValue": (args_0: string) => any;
20
+ input: (args_0: string) => any;
21
+ click: (args_0: MouseEvent) => any;
22
22
  keydown: (args_0: KeyboardEvent) => any;
23
+ focus: (args_0: FocusEvent) => any;
23
24
  blur: (args_0: FocusEvent) => any;
24
- compositionend: (args_0: CompositionEvent) => any;
25
25
  compositionstart: (args_0: CompositionEvent) => any;
26
26
  compositionupdate: (args_0: CompositionEvent) => any;
27
- focus: (args_0: FocusEvent) => any;
27
+ compositionend: (args_0: CompositionEvent) => any;
28
28
  }, string, import("vue").PublicProps, Readonly<InputProps> & Readonly<{
29
- onInput?: ((args_0: string) => any) | undefined;
30
- onClick?: ((args_0: MouseEvent) => any) | undefined;
31
29
  onChange?: ((args_0: string, args_1: Event) => any) | undefined;
32
30
  "onUpdate:modelValue"?: ((args_0: string) => any) | undefined;
31
+ onInput?: ((args_0: string) => any) | undefined;
32
+ onClick?: ((args_0: MouseEvent) => any) | undefined;
33
33
  onKeydown?: ((args_0: KeyboardEvent) => any) | undefined;
34
+ onFocus?: ((args_0: FocusEvent) => any) | undefined;
34
35
  onBlur?: ((args_0: FocusEvent) => any) | undefined;
35
- onCompositionend?: ((args_0: CompositionEvent) => any) | undefined;
36
36
  onCompositionstart?: ((args_0: CompositionEvent) => any) | undefined;
37
37
  onCompositionupdate?: ((args_0: CompositionEvent) => any) | undefined;
38
- onFocus?: ((args_0: FocusEvent) => any) | undefined;
38
+ onCompositionend?: ((args_0: CompositionEvent) => any) | undefined;
39
39
  }>, {
40
40
  align: "left" | "center" | "right";
41
41
  defaultPrefixStyle: boolean;
@@ -5,6 +5,7 @@ import EyeOffIcon from "@gdsicon/vue/eye-off";
5
5
  import { tv } from "tailwind-variants";
6
6
  import { computed, shallowRef } from "vue";
7
7
  import { useModelValue } from "../../composables/use-model-value";
8
+ import { BASIC_HEIGHTS } from "../../constants/size";
8
9
  import { useConfigProvider } from "../../contexts/config-provider";
9
10
  import { NOOP } from "../../utils/event";
10
11
  import { isTruthyProp } from "../../utils/format";
@@ -46,10 +47,10 @@ const inputVariant = tv({
46
47
  base: "pxd-input pxd-input--border group relative flex w-full max-w-full items-center overflow-hidden bg-background-100 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:bg-gray-100 motion-safe:transition-all",
47
48
  variants: {
48
49
  size: {
49
- xs: "h-6 text-xs rounded-sm",
50
- sm: "h-7.5 text-sm rounded-md",
51
- md: "h-9 text-sm rounded-md",
52
- lg: "h-10 text-base rounded-lg"
50
+ xs: `${BASIC_HEIGHTS.xs} text-sm rounded-sm`,
51
+ sm: `${BASIC_HEIGHTS.sm} text-sm rounded-md`,
52
+ md: `${BASIC_HEIGHTS.md} text-sm rounded-md`,
53
+ lg: `${BASIC_HEIGHTS.lg} text-base rounded-lg`
53
54
  },
54
55
  align: {
55
56
  left: "text-left",
@@ -24,11 +24,11 @@ const containerSize = shallowRef({
24
24
  "--slot-estimated-height": getCssUnitValue(props.height)
25
25
  });
26
26
  function getRenderedSlotSize() {
27
- const rect = containerRef.value.getBoundingClientRect();
27
+ const { offsetWidth, offsetHeight } = containerRef.value;
28
28
  containerSize.value = {
29
- "contain-intrinsic-size": `auto ${rect.height}px`,
30
- "--slot-estimated-width": `${rect.width}px`,
31
- "--slot-estimated-height": `${rect.height}px`
29
+ "contain-intrinsic-size": `auto ${offsetHeight}px`,
30
+ "--slot-estimated-width": `${offsetWidth}px`,
31
+ "--slot-estimated-height": `${offsetHeight}px`
32
32
  };
33
33
  }
34
34
  function onVisibleChange(isIntersecting) {
@@ -38,7 +38,7 @@ const internalKey = computed(() => {
38
38
 
39
39
  <template>
40
40
  <kbd
41
- class="pxd-keyboard px-1.5 ml-1 inline-flex items-center rounded-md border border-input bg-background-100 text-center font-sans text-nowrap whitespace-nowrap text-gray-1000"
41
+ class="pxd-keyboard px-1.5 ml-1 inline-flex items-center rounded-md border bg-background-100 text-center font-sans leading-none text-nowrap whitespace-nowrap text-gray-1000"
42
42
  :class="computedSize"
43
43
  v-bind="$attrs"
44
44
  >
@@ -1,11 +1,11 @@
1
1
  import type { LinkButtonProps } from './types';
2
- declare var __VLS_9: {}, __VLS_11: {}, __VLS_14: {};
2
+ declare var __VLS_11: {}, __VLS_13: {}, __VLS_16: {};
3
3
  type __VLS_Slots = {} & {
4
- prefix?: (props: typeof __VLS_9) => any;
4
+ prefix?: (props: typeof __VLS_11) => any;
5
5
  } & {
6
- default?: (props: typeof __VLS_11) => any;
6
+ default?: (props: typeof __VLS_13) => any;
7
7
  } & {
8
- suffix?: (props: typeof __VLS_14) => any;
8
+ suffix?: (props: typeof __VLS_16) => any;
9
9
  };
10
10
  declare const __VLS_base: import("vue").DefineComponent<LinkButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
11
  click: (args_0: MouseEvent) => any;
@@ -1,27 +1,28 @@
1
1
  <script setup>
2
2
  import ExternalIcon from "@gdsicon/vue/external";
3
- import { computed } from "vue";
3
+ import { computed, useAttrs } from "vue";
4
4
  import { isExternalLink } from "../../utils/format";
5
5
  import PButton from "../button/index.vue";
6
6
  defineOptions({
7
- name: "PLinkButton"
7
+ name: "PLinkButton",
8
+ inheritAttrs: false
8
9
  });
9
10
  const props = defineProps({
10
11
  href: { type: String, required: true },
11
12
  text: { type: String, required: false },
12
13
  align: { type: String, required: false, default: "left" },
13
14
  target: { type: String, required: false, default: "_self" },
14
- variant: { type: String, required: false },
15
15
  externalIcon: { type: Boolean, required: false }
16
16
  });
17
17
  const emits = defineEmits(["click"]);
18
+ const attrs = useAttrs();
18
19
  const computedAttrs = computed(() => {
19
- const { externalIcon, text, href, ...restProps } = props;
20
+ const { align, target, href } = props;
20
21
  const baseAttrs = {
21
- ...restProps,
22
- class: "pxd-link-button",
22
+ align,
23
+ target,
23
24
  rel: "noopener noreferrer",
24
- onClick: onLinkClick
25
+ ...attrs
25
26
  };
26
27
  if (!href) {
27
28
  return baseAttrs;
@@ -45,7 +46,7 @@ function onLinkClick(ev) {
45
46
  </script>
46
47
 
47
48
  <template>
48
- <PButton v-bind="computedAttrs">
49
+ <PButton class="pxd-link-button" v-bind="computedAttrs" @click="onLinkClick">
49
50
  <template #prefix>
50
51
  <slot name="prefix" />
51
52
  </template>
@@ -1,11 +1,8 @@
1
- import type { ButtonVariant } from '../button/types'
2
-
3
1
  export interface LinkButtonProps {
4
2
  href: string
5
3
  text?: string
6
4
  align?: 'left' | 'center' | 'right'
7
5
  target?: '_blank' | '_self' | '_parent' | '_top'
8
- variant?: ButtonVariant
9
6
  externalIcon?: boolean
10
7
  }
11
8
 
@@ -1,33 +1,28 @@
1
1
  import type { ListProps, ListOptionSelected } from './types';
2
- declare function updateListItem(): void;
3
- declare function isNoVisibleItem(): boolean;
4
- declare function setActiveValue(newValue?: string): void;
5
- declare function setFirstAsActive(): void;
6
- declare var __VLS_7: {}, __VLS_15: {
2
+ declare var __VLS_1: {}, __VLS_9: {
7
3
  item: import("./types").ListOption;
8
4
  };
9
5
  type __VLS_Slots = {} & {
10
- default?: (props: typeof __VLS_7) => any;
6
+ default?: (props: typeof __VLS_1) => any;
11
7
  } & {
12
- item?: (props: typeof __VLS_15) => any;
8
+ item?: (props: typeof __VLS_9) => any;
13
9
  };
14
10
  declare const __VLS_base: import("vue").DefineComponent<ListProps, {
15
- setActiveValue: typeof setActiveValue;
16
- updateListItem: typeof updateListItem;
17
- isNoVisibleItem: typeof isNoVisibleItem;
18
- setFirstAsActive: typeof setFirstAsActive;
11
+ isEmpty: () => boolean;
12
+ refreshItems: () => Promise<void>;
13
+ setActiveIndex: (index: number) => void;
14
+ setFirstAsActive: () => void;
19
15
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
- select: (args_0: MouseEvent, args_1: ListOptionSelected) => any;
16
+ select: (args_0: ListOptionSelected, args_1: MouseEvent) => any;
21
17
  toggle: () => any;
22
- escape: (args_0: KeyboardEvent) => any;
23
18
  }, string, import("vue").PublicProps, Readonly<ListProps> & Readonly<{
24
- onSelect?: ((args_0: MouseEvent, args_1: ListOptionSelected) => any) | undefined;
19
+ onSelect?: ((args_0: ListOptionSelected, args_1: MouseEvent) => any) | undefined;
25
20
  onToggle?: (() => any) | undefined;
26
- onEscape?: ((args_0: KeyboardEvent) => any) | undefined;
27
21
  }>, {
28
22
  options: import("./types").ListOption[];
29
23
  loop: boolean;
30
24
  toggleOnKeyPress: boolean;
25
+ defaultActiveIndex: number;
31
26
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
27
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
33
28
  declare const _default: typeof __VLS_export;
@@ -1,151 +1,84 @@
1
1
  <script setup>
2
- import { nextTick, onBeforeUnmount, onMounted, shallowRef } from "vue";
3
- import { provideListContext } from "../../contexts/list";
2
+ import { onBeforeUnmount, onMounted, shallowRef, watch } from "vue";
3
+ import { useListNavigation } from "../../composables/use-list-navigation";
4
+ import { provideListContext, useListFilterContext } from "../../contexts/list";
4
5
  import { cachedOff, cachedOn } from "../../utils/event";
5
6
  import { isServer } from "../../utils/is";
6
- import { throttle } from "../../utils/throttle";
7
7
  import PListItem from "../list-item/index.vue";
8
- import PScrollable from "../scrollable/index.vue";
9
8
  defineOptions({
10
9
  name: "PList",
11
10
  inheritAttrs: false
12
11
  });
13
12
  const props = defineProps({
14
13
  loop: { type: Boolean, required: false, default: true },
14
+ visible: { type: Boolean, required: false },
15
15
  options: { type: Array, required: false, default: () => [] },
16
16
  toggleOnKeyPress: { type: Boolean, required: false, default: true },
17
- closeOnPressEscape: { type: Boolean, required: false }
17
+ defaultActiveIndex: { type: Number, required: false, default: -1 }
18
18
  });
19
- const emits = defineEmits(["toggle", "escape", "select"]);
20
- const activeValue = shallowRef("");
19
+ const emits = defineEmits(["toggle", "select"]);
21
20
  const containerRef = shallowRef();
22
- const ITEM_CLASS = "pxd-list-item";
23
- const itemSelector = `.${ITEM_CLASS}:not([data-disabled="true"])`;
24
- const PREV_KEYS = ["ArrowUp", "ArrowLeft"];
25
- const NEXT_KEYS = ["ArrowDown", "ArrowRight"];
26
- const FUNCTION_KEYS = ["Enter", "Tab", "Home", "End"];
27
- const PREVENT_DEFAULT_KEYS = [...FUNCTION_KEYS, ...PREV_KEYS, ...NEXT_KEYS];
28
- const listItemKeys = [];
29
- const listItemsMap = /* @__PURE__ */ new Map();
30
- function resolveNavigationTarget(key) {
31
- const len = listItemKeys.length;
32
- if (key === "Home") {
33
- return listItemKeys[0];
34
- }
35
- if (key === "End") {
36
- return listItemKeys[len - 1];
37
- }
38
- const dir = PREV_KEYS.includes(key) ? -1 : NEXT_KEYS.includes(key) ? 1 : void 0;
39
- if (dir === void 0) {
40
- return void 0;
41
- }
42
- if (!activeValue.value) {
43
- return dir === -1 ? listItemKeys[len - 1] : listItemKeys[0];
44
- }
45
- const index = listItemKeys.indexOf(activeValue.value);
46
- if (index === -1) {
47
- return dir === -1 ? listItemKeys[len - 1] : listItemKeys[0];
48
- }
49
- if (props.loop) {
50
- return listItemKeys[(index + dir + len) % len];
51
- }
52
- const nextIndex = index + dir;
53
- return nextIndex >= 0 && nextIndex < len ? listItemKeys[nextIndex] : void 0;
21
+ function onOptionClick(item, ev) {
22
+ emits("select", item, ev);
54
23
  }
55
- const containerKeydownThrottled = throttle(
56
- (ev) => {
57
- if (ev.ctrlKey || ev.metaKey || ev.altKey || ev.shiftKey) {
58
- return;
59
- }
60
- const { key } = ev;
61
- if (key === "Enter") {
62
- listItemsMap.get(activeValue.value)?.click();
63
- return;
64
- }
65
- if (key === "Escape" && props.closeOnPressEscape) {
66
- emits("escape", ev);
67
- return;
68
- }
69
- const newActiveValue = resolveNavigationTarget(key);
70
- if (newActiveValue === void 0) {
71
- return;
72
- }
73
- if (activeValue.value !== newActiveValue) {
74
- emits("toggle");
75
- activeValue.value = newActiveValue;
24
+ const {
25
+ activeIndex,
26
+ isEmpty,
27
+ onKeydown,
28
+ setActiveIndex,
29
+ registerItem,
30
+ unregisterItem,
31
+ onPointerOver,
32
+ refreshItems,
33
+ setFirstAsActive
34
+ } = useListNavigation(containerRef, {
35
+ loop: props.loop,
36
+ itemSelector: `[data-list-item]:not([data-disabled="true"],[hidden])`,
37
+ toggleOnKeyPress: props.toggleOnKeyPress,
38
+ defaultActiveIndex: props.defaultActiveIndex,
39
+ onToggle: () => emits("toggle")
40
+ });
41
+ const filterCtx = useListFilterContext(null);
42
+ if (filterCtx) {
43
+ watch(
44
+ () => filterCtx.searchValue.value.trim(),
45
+ async () => {
46
+ await refreshItems();
47
+ setFirstAsActive();
76
48
  }
77
- listItemsMap.get(activeValue.value)?.scrollIntoView({ block: "nearest" });
78
- },
79
- 100,
80
- { edges: ["leading"] }
81
- );
82
- function onContainerKeydown(ev) {
83
- if (!props.toggleOnKeyPress || listItemKeys.length === 0) {
84
- return;
85
- }
86
- if (PREVENT_DEFAULT_KEYS.includes(ev.key)) {
87
- ev.preventDefault();
88
- }
89
- ev.stopPropagation();
90
- containerKeydownThrottled(ev);
91
- }
92
- function onPointerOver(ev) {
93
- const target = ev.target;
94
- const listItem = target.closest(`.${ITEM_CLASS}`);
95
- const itemValue = listItem?.dataset.value;
96
- if (!listItem || itemValue === void 0) {
97
- return;
98
- }
99
- activeValue.value = itemValue;
100
- }
101
- function onOptionClick(item, ev) {
102
- activeValue.value = "";
103
- emits("select", ev, item);
49
+ );
104
50
  }
105
- function updateListItem() {
106
- cleanupListItem();
107
- if (!containerRef.value) {
108
- return;
51
+ watch(
52
+ () => props.visible,
53
+ (visible) => {
54
+ if (visible) {
55
+ cachedOff(document, "keydown", onKeydown);
56
+ cachedOn(document, "keydown", onKeydown);
57
+ } else {
58
+ setActiveIndex(-1);
59
+ cachedOff(document, "keydown", onKeydown);
60
+ }
109
61
  }
110
- Array.from(containerRef.value.querySelectorAll(itemSelector)).forEach((el) => {
111
- const key = el.dataset.value;
112
- listItemsMap.set(key, el);
113
- listItemKeys.push(key);
114
- });
115
- }
116
- function cleanupListItem() {
117
- listItemsMap.clear();
118
- listItemKeys.splice(0);
119
- }
120
- function isNoVisibleItem() {
121
- return listItemsMap.size === 0;
122
- }
123
- function setActiveValue(newValue = "") {
124
- activeValue.value = newValue;
125
- }
126
- function setFirstAsActive() {
127
- setActiveValue(listItemKeys[0]);
128
- }
62
+ );
129
63
  provideListContext({
130
- activeValue,
64
+ activeIndex,
65
+ registerItem,
66
+ unregisterItem,
131
67
  onOptionClick
132
68
  });
133
69
  onMounted(async () => {
134
70
  if (isServer()) {
135
71
  return;
136
72
  }
137
- await nextTick();
138
- updateListItem();
139
- cachedOn(document, "keydown", onContainerKeydown);
73
+ cachedOn(document, "keydown", onKeydown);
140
74
  });
141
75
  onBeforeUnmount(() => {
142
- cleanupListItem();
143
- cachedOff(document, "keydown", onContainerKeydown);
76
+ cachedOff(document, "keydown", onKeydown);
144
77
  });
145
78
  defineExpose({
146
- setActiveValue,
147
- updateListItem,
148
- isNoVisibleItem,
79
+ isEmpty,
80
+ refreshItems,
81
+ setActiveIndex,
149
82
  setFirstAsActive
150
83
  });
151
84
  </script>
@@ -155,20 +88,14 @@ defineExpose({
155
88
  ref="containerRef"
156
89
  role="list"
157
90
  tabindex="-1"
158
- class="pxd-list m-0 p-0 max-w-full list-none bg-background-100 outline-none"
91
+ class="pxd-list m-0 p-2 max-w-full list-none overflow-auto bg-background-100 outline-none"
159
92
  v-bind="$attrs"
160
93
  @pointerover="onPointerOver"
161
94
  >
162
- <PScrollable
163
- class="h-full max-h-inherit rounded-inherit"
164
- content-class="p-2"
165
- fader-direction="vertical"
166
- >
167
- <slot>
168
- <PListItem v-for="(option, index) in options" :key="option.value ?? index" v-bind="option">
169
- <slot name="item" :item="option" />
170
- </PListItem>
171
- </slot>
172
- </PScrollable>
95
+ <slot>
96
+ <PListItem v-for="(option, index) in options" :key="option.value ?? index" v-bind="option">
97
+ <slot name="item" :item="option" />
98
+ </PListItem>
99
+ </slot>
173
100
  </ul>
174
101
  </template>
@@ -2,7 +2,7 @@ import type { ComponentAs, ComponentLabel, ComponentOption } from '../../types/s
2
2
 
3
3
  export interface ListOption extends Partial<ComponentOption> {
4
4
  as?: ComponentAs
5
- type?: 'default' | 'error' | 'warning' | 'separator'
5
+ type?: 'default' | 'error' | 'warning'
6
6
  description?: ComponentLabel
7
7
  onClick?: (item: ListOptionSelected, ev: MouseEvent) => void
8
8
  }
@@ -11,13 +11,13 @@ export type ListOptionSelected = Omit<ListOption, 'as' | 'onClick'>
11
11
 
12
12
  export interface ListProps {
13
13
  loop?: boolean
14
+ visible?: boolean
14
15
  options?: ListOption[]
15
16
  toggleOnKeyPress?: boolean
16
- closeOnPressEscape?: boolean
17
+ defaultActiveIndex?: number
17
18
  }
18
19
 
19
20
  export interface ListEmits {
20
21
  toggle: []
21
- escape: [KeyboardEvent]
22
- select: [MouseEvent, ListOptionSelected]
22
+ select: [ListOptionSelected, MouseEvent]
23
23
  }
@@ -8,9 +8,9 @@ declare const __VLS_base: import("vue").DefineComponent<ListItemProps, {}, {}, {
8
8
  }, string, import("vue").PublicProps, Readonly<ListItemProps> & Readonly<{
9
9
  onClick?: ((args_0: import("../list/types").ListOptionSelected, args_1: MouseEvent) => any) | undefined;
10
10
  }>, {
11
- type: "default" | "error" | "warning" | "separator";
12
- as: import("../../types/shared").ComponentAs;
13
11
  disabled: boolean;
12
+ type: "default" | "error" | "warning";
13
+ as: import("../../types/shared").ComponentAs;
14
14
  keywords: string[];
15
15
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
16
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1,7 +1,7 @@
1
1
  <script setup>
2
2
  import { tv } from "tailwind-variants";
3
- import { computed, shallowRef } from "vue";
4
- import { useListContext, useListFilterValue } from "../../contexts/list";
3
+ import { computed, onBeforeUnmount, onMounted, shallowRef } from "vue";
4
+ import { useListContext, useListFilterContext, useListFilterGroupId } from "../../contexts/list";
5
5
  import { unrefElement } from "../../utils/ref";
6
6
  import { getUniqueId } from "../../utils/uid";
7
7
  defineOptions({
@@ -19,73 +19,78 @@ const props = defineProps({
19
19
  });
20
20
  const emits = defineEmits(["click"]);
21
21
  const listItemVariant = tv({
22
- base: "pxd-list-item h-10 gap-3 px-2 text-sm flex w-full cursor-pointer items-center rounded-md outline-none [contain-intrinsic-size:auto_2.5rem] content-visibility-auto data-[disabled=true]:pointer-events-none data-[disabled=true]:text-gray-700 motion-safe:transition-colors",
22
+ base: "pxd-list-item sm:h-10 h-11 gap-3 px-2 scroll-m-2 text-sm flex w-full cursor-pointer items-center rounded-md outline-none [contain-intrinsic-size:auto_2.5rem] content-visibility-auto data-[disabled=true]:pointer-events-none data-[disabled=true]:text-gray-700",
23
23
  variants: {
24
24
  type: {
25
- error: "text-red-900 pointer-coarse:active:bg-red-100 pointer-fine:data-[selected=true]:bg-red-100",
26
- warning: "text-amber-900 pointer-coarse:active:bg-amber-100 pointer-fine:data-[selected=true]:bg-amber-100",
27
- default: "text-foreground pointer-coarse:active:bg-gray-alpha-100 pointer-fine:data-[selected=true]:bg-gray-alpha-100",
28
- separator: "h-0! px-0 m-1.5 w-auto! border-b"
25
+ error: "text-red-900 active:bg-red-100 pointer-fine:aria-selected:bg-red-100",
26
+ warning: "text-amber-900 active:bg-amber-100 pointer-fine:aria-selected:bg-amber-100",
27
+ default: "text-foreground active:bg-gray-alpha-100 pointer-fine:aria-selected:bg-gray-alpha-100"
29
28
  }
30
- },
31
- defaultVariants: {
32
- type: "default"
33
29
  }
34
30
  });
35
- const { activeValue, onOptionClick } = useListContext();
36
- const uniqueId = getUniqueId();
37
- const filterValue = useListFilterValue();
31
+ const { activeIndex, registerItem, unregisterItem, onOptionClick } = useListContext();
32
+ const groupId = useListFilterGroupId(null);
33
+ const filterCtx = useListFilterContext(null);
34
+ const itemId = getUniqueId("list-item");
38
35
  const itemRef = shallowRef();
39
- const searchableText = computed(() => {
40
- const keywordsText = props.keywords.length > 0 ? props.keywords.join("").toLowerCase().replace(/\s/g, "") : "";
41
- if (props.label) {
42
- const propsText = `${String(props.label || "")}${props.description || ""}`.toLowerCase().replace(/\s/g, "");
43
- return propsText + keywordsText;
36
+ const itemIndex = shallowRef(-1);
37
+ const isVisible = computed(() => {
38
+ if (!filterCtx || !filterCtx.searchValue.value.trim()) {
39
+ return true;
44
40
  }
45
- if (keywordsText) {
46
- return keywordsText;
47
- }
48
- return getCachedTextContent();
41
+ return filterCtx.isItemVisible(itemId);
49
42
  });
50
- const isVisible = computed(
51
- () => filterValue?.value ? searchableText.value.includes(filterValue.value.toLowerCase()) : true
52
- );
53
- const isSelected = computed(() => activeValue.value === uniqueId);
54
- const isDisabled = computed(() => props.disabled || props.type === "separator");
43
+ const isSelected = computed(() => itemIndex.value !== -1 && itemIndex.value === activeIndex.value);
55
44
  const computedClasses = computed(() => {
56
45
  return listItemVariant({ type: props.type });
57
46
  });
58
- let cachedTextContent = "";
59
- function getCachedTextContent() {
60
- const text = unrefElement(itemRef.value)?.textContent || "";
61
- if (text) {
62
- cachedTextContent = text.toLowerCase().replace(/\s/g, "");
63
- }
64
- return cachedTextContent;
47
+ function getValue() {
48
+ return `${String(props.label ?? "")}${String(props.description ?? "")}`.trim();
49
+ }
50
+ function getKeywords() {
51
+ return props.keywords;
65
52
  }
66
53
  function onItemClick(ev) {
67
54
  const { as, keywords, ...restProps } = props;
68
55
  emits("click", restProps, ev);
69
56
  onOptionClick?.(restProps, ev);
70
57
  }
58
+ onMounted(() => {
59
+ const el = unrefElement(itemRef.value);
60
+ if (el) {
61
+ registerItem(el, itemIndex);
62
+ }
63
+ filterCtx?.registerItem(itemId, {
64
+ groupId,
65
+ getValue,
66
+ getKeywords
67
+ });
68
+ });
69
+ onBeforeUnmount(() => {
70
+ const el = unrefElement(itemRef.value);
71
+ if (el) {
72
+ unregisterItem(el);
73
+ }
74
+ filterCtx?.unregisterItem(itemId);
75
+ });
71
76
  </script>
72
77
 
73
78
  <template>
74
79
  <Component
75
80
  :is="as"
76
- v-if="isVisible"
77
81
  ref="itemRef"
78
82
  tabindex="-1"
79
83
  role="listitem"
84
+ data-list-item
80
85
  :data-type="type"
81
- :data-value="uniqueId"
82
- :data-selected="isSelected"
83
- :data-disabled="isDisabled"
86
+ :data-disabled="disabled"
87
+ :aria-selected="isSelected"
88
+ :hidden="!isVisible"
84
89
  :class="computedClasses"
85
90
  v-bind="$attrs"
86
91
  @click.prevent.stop="onItemClick"
87
92
  >
88
- <slot v-if="type !== 'separator'">
93
+ <slot>
89
94
  <span>{{ label }}</span>
90
95
  <span v-if="description" class="text-foreground-secondary">{{ description }}</span>
91
96
  </slot>