pxd 0.0.39 → 0.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +9 -3
  2. package/dist/components/active-graph/index.vue +10 -5
  3. package/dist/components/backtop/index.vue +75 -0
  4. package/dist/components/badge/index.vue +9 -7
  5. package/dist/components/book/index.vue +3 -3
  6. package/dist/components/browser/index.vue +2 -2
  7. package/dist/components/checkbox/index.vue +4 -3
  8. package/dist/components/checkbox-group/index.vue +1 -1
  9. package/dist/components/choicebox-group/index.vue +1 -1
  10. package/dist/components/command-menu/index.vue +124 -0
  11. package/dist/components/command-menu-group/index.vue +18 -0
  12. package/dist/components/command-menu-item/index.vue +13 -0
  13. package/dist/components/countdown/index.vue +2 -1
  14. package/dist/components/drawer/index.vue +26 -26
  15. package/dist/components/error/index.vue +2 -2
  16. package/dist/components/fader/index.vue +31 -17
  17. package/dist/components/grid/index.vue +2 -2
  18. package/dist/components/grid-item/index.vue +2 -2
  19. package/dist/components/hold-button/index.vue +1 -1
  20. package/dist/components/index.d.ts +7 -0
  21. package/dist/components/index.js +7 -0
  22. package/dist/components/input/index.vue +18 -10
  23. package/dist/components/intersection-observer/index.vue +5 -5
  24. package/dist/components/kbd/index.vue +21 -8
  25. package/dist/components/{intersection-observer/content.vue → keep-alive-container/index.vue} +3 -1
  26. package/dist/components/list/index.vue +100 -92
  27. package/dist/components/list-item/index.vue +35 -33
  28. package/dist/components/loading-bar/index.vue +149 -0
  29. package/dist/components/material/index.vue +8 -8
  30. package/dist/components/menu/index.vue +26 -16
  31. package/dist/components/message/index.vue +28 -18
  32. package/dist/components/modal/index.vue +32 -36
  33. package/dist/components/note/index.vue +1 -1
  34. package/dist/components/overlay/index.vue +77 -24
  35. package/dist/components/pagination/index.vue +2 -2
  36. package/dist/components/placeholder/index.vue +13 -6
  37. package/dist/components/popover/index.vue +97 -87
  38. package/dist/components/progress/index.vue +1 -1
  39. package/dist/components/radio/index.vue +4 -3
  40. package/dist/components/radio-group/index.vue +1 -1
  41. package/dist/components/scrollable/index.vue +161 -94
  42. package/dist/components/slider/index.vue +7 -7
  43. package/dist/components/stack/index.vue +4 -4
  44. package/dist/components/switch/index.vue +1 -1
  45. package/dist/components/text/index.vue +1 -1
  46. package/dist/components/theme-switcher/index.vue +6 -2
  47. package/dist/components/time-picker/index.vue +281 -0
  48. package/dist/components/tooltip/index.vue +7 -7
  49. package/dist/composables/index.d.ts +1 -0
  50. package/dist/composables/index.js +1 -0
  51. package/dist/composables/use-browser-observer.d.ts +5 -5
  52. package/dist/composables/use-color-scheme.d.ts +5 -1
  53. package/dist/composables/use-color-scheme.js +20 -1
  54. package/dist/composables/use-config-provider-context.d.ts +1 -1
  55. package/dist/composables/use-countdown.d.ts +6 -0
  56. package/dist/composables/use-countdown.js +21 -7
  57. package/dist/composables/use-delay-destroy.d.ts +4 -4
  58. package/dist/composables/use-delay-destroy.js +15 -11
  59. package/dist/composables/use-focus-trap.d.ts +2 -2
  60. package/dist/composables/use-focus-trap.js +6 -6
  61. package/dist/composables/use-loading-bar.d.ts +25 -0
  62. package/dist/composables/use-loading-bar.js +27 -0
  63. package/dist/composables/use-media-query.js +1 -1
  64. package/dist/composables/use-message.d.ts +4 -1
  65. package/dist/composables/use-message.js +18 -0
  66. package/dist/composables/use-pointer-gesture.d.ts +2 -2
  67. package/dist/composables/use-pointer-gesture.js +3 -3
  68. package/dist/composables/use-repeat-action.d.ts +2 -2
  69. package/dist/composables/use-repeat-action.js +5 -5
  70. package/dist/composables/use-virtual-list.d.ts +1 -1
  71. package/dist/contexts/avatar.d.ts +1 -1
  72. package/dist/contexts/carousel.d.ts +1 -1
  73. package/dist/contexts/checkbox.d.ts +1 -1
  74. package/dist/contexts/choicebox.d.ts +2 -2
  75. package/dist/contexts/collapse.d.ts +1 -1
  76. package/dist/contexts/list.d.ts +5 -6
  77. package/dist/contexts/list.js +3 -3
  78. package/dist/contexts/radio.d.ts +1 -1
  79. package/dist/contexts/resizable.d.ts +1 -1
  80. package/dist/contexts/switch.d.ts +2 -2
  81. package/dist/{components/carousel → dist/components/keep-alive-container}/index.vue.d.ts +1 -1
  82. package/dist/index.d.ts +1 -1
  83. package/dist/index.js +1 -1
  84. package/dist/locales/en-us.d.ts +15 -7
  85. package/dist/locales/en-us.js +17 -9
  86. package/dist/locales/zh-cn.d.ts +15 -7
  87. package/dist/locales/zh-cn.js +17 -9
  88. package/dist/{components → src/components}/active-graph/index.vue.d.ts +7 -5
  89. package/dist/{components → src/components}/avatar-group/index.vue.d.ts +1 -1
  90. package/dist/src/components/backtop/index.vue.d.ts +20 -0
  91. package/dist/{components → src/components}/badge/index.vue.d.ts +2 -1
  92. package/dist/{components → src/components}/book/index.vue.d.ts +1 -1
  93. package/dist/{components → src/components}/browser/index.vue.d.ts +1 -1
  94. package/dist/{components → src/components}/button/index.vue.d.ts +1 -1
  95. package/dist/{components/intersection-observer/content.vue.d.ts → src/components/carousel/index.vue.d.ts} +1 -1
  96. package/dist/{components → src/components}/carousel-group/index.vue.d.ts +1 -1
  97. package/dist/{components → src/components}/chip/index.vue.d.ts +1 -1
  98. package/dist/{components → src/components}/choicebox/index.vue.d.ts +1 -1
  99. package/dist/{components → src/components}/choicebox-group/index.vue.d.ts +1 -1
  100. package/dist/{components → src/components}/collapse/index.vue.d.ts +1 -1
  101. package/dist/{components → src/components}/collapse-group/index.vue.d.ts +1 -1
  102. package/dist/src/components/command-menu/index.vue.d.ts +39 -0
  103. package/dist/src/components/command-menu-group/index.vue.d.ts +16 -0
  104. package/dist/src/components/command-menu-item/index.vue.d.ts +12 -0
  105. package/dist/{components → src/components}/config-provider/index.vue.d.ts +1 -1
  106. package/dist/{components → src/components}/description/index.vue.d.ts +1 -1
  107. package/dist/{components → src/components}/drawer/index.vue.d.ts +19 -14
  108. package/dist/{components → src/components}/empty-state/index.vue.d.ts +1 -1
  109. package/dist/{components → src/components}/error/index.vue.d.ts +1 -1
  110. package/dist/src/components/fader/index.vue.d.ts +11 -0
  111. package/dist/{components → src/components}/gauge/index.vue.d.ts +1 -1
  112. package/dist/{components → src/components}/grid/index.vue.d.ts +1 -1
  113. package/dist/{components → src/components}/grid-item/index.vue.d.ts +1 -1
  114. package/dist/{components → src/components}/hold-button/index.vue.d.ts +1 -1
  115. package/dist/{components → src/components}/input/index.vue.d.ts +9 -4
  116. package/dist/{components → src/components}/intersection-observer/index.vue.d.ts +3 -3
  117. package/dist/{components → src/components}/kbd/index.vue.d.ts +8 -5
  118. package/dist/src/components/keep-alive-container/index.vue.d.ts +12 -0
  119. package/dist/{components → src/components}/link-button/index.vue.d.ts +1 -1
  120. package/dist/src/components/list/index.vue.d.ts +40 -0
  121. package/dist/{components → src/components}/list-item/index.vue.d.ts +4 -4
  122. package/dist/src/components/loading-bar/index.vue.d.ts +14 -0
  123. package/dist/{components → src/components}/loading-dots/index.vue.d.ts +1 -1
  124. package/dist/{components → src/components}/material/index.vue.d.ts +1 -1
  125. package/dist/{components → src/components}/menu/index.vue.d.ts +11 -7
  126. package/dist/{components → src/components}/message/index.vue.d.ts +13 -13
  127. package/dist/{components → src/components}/modal/index.vue.d.ts +19 -14
  128. package/dist/{components → src/components}/more-button/index.vue.d.ts +1 -1
  129. package/dist/{components → src/components}/note/index.vue.d.ts +1 -1
  130. package/dist/{components → src/components}/number-input/index.vue.d.ts +1 -1
  131. package/dist/{components → src/components}/overlay/index.vue.d.ts +3 -4
  132. package/dist/{components → src/components}/pagination/index.vue.d.ts +1 -1
  133. package/dist/{components → src/components}/pin-input/index.vue.d.ts +1 -1
  134. package/dist/src/components/placeholder/index.vue.d.ts +9 -0
  135. package/dist/{components → src/components}/popover/index.vue.d.ts +10 -8
  136. package/dist/{components → src/components}/progress/index.vue.d.ts +1 -1
  137. package/dist/{components → src/components}/radio/index.vue.d.ts +1 -1
  138. package/dist/{components → src/components}/radio-group/index.vue.d.ts +1 -1
  139. package/dist/{components → src/components}/resizable/index.vue.d.ts +1 -1
  140. package/dist/src/components/resizable-handle/index.vue.d.ts +2 -0
  141. package/dist/{components → src/components}/resizable-panel/index.vue.d.ts +1 -1
  142. package/dist/{components → src/components}/skeleton/index.vue.d.ts +1 -1
  143. package/dist/{components → src/components}/slider/index.vue.d.ts +1 -1
  144. package/dist/{components → src/components}/snippet/index.vue.d.ts +1 -1
  145. package/dist/src/components/spinner/index.vue.d.ts +2 -0
  146. package/dist/{components → src/components}/stack/index.vue.d.ts +1 -1
  147. package/dist/{components → src/components}/status-dot/index.vue.d.ts +1 -1
  148. package/dist/{components → src/components}/switch/index.vue.d.ts +1 -1
  149. package/dist/{components → src/components}/switch-group/index.vue.d.ts +1 -1
  150. package/dist/{components → src/components}/teleport/index.vue.d.ts +1 -1
  151. package/dist/{components → src/components}/text/index.vue.d.ts +1 -1
  152. package/dist/{components → src/components}/textarea/index.vue.d.ts +1 -1
  153. package/dist/{components → src/components}/theme-switcher/index.vue.d.ts +1 -1
  154. package/dist/src/components/time-picker/index.vue.d.ts +25 -0
  155. package/dist/{components → src/components}/toggle/index.vue.d.ts +1 -1
  156. package/dist/{components → src/components}/tooltip/index.vue.d.ts +3 -5
  157. package/dist/{components → src/components}/virtual-list/index.vue.d.ts +1 -1
  158. package/dist/src/composables/use-browser-observer.d.ts +12 -0
  159. package/dist/src/composables/use-color-scheme.d.ts +11 -0
  160. package/dist/src/composables/use-config-provider-context.d.ts +7 -0
  161. package/dist/src/composables/use-copy-click.d.ts +4 -0
  162. package/dist/src/composables/use-countdown.d.ts +60 -0
  163. package/dist/src/composables/use-delay-change.d.ts +7 -0
  164. package/dist/src/composables/use-delay-destroy.d.ts +13 -0
  165. package/dist/src/composables/use-focus-trap.d.ts +4 -0
  166. package/dist/src/composables/use-loading-bar.d.ts +25 -0
  167. package/dist/src/composables/use-media-query.d.ts +15 -0
  168. package/dist/src/composables/use-message.d.ts +33 -0
  169. package/dist/src/composables/use-model-value.d.ts +11 -0
  170. package/dist/src/composables/use-pointer-gesture.d.ts +180 -0
  171. package/dist/src/composables/use-repeat-action.d.ts +16 -0
  172. package/dist/src/composables/use-unique-id-context.d.ts +2 -0
  173. package/dist/src/composables/use-virtual-list.d.ts +16 -0
  174. package/dist/src/contexts/avatar.d.ts +2 -0
  175. package/dist/src/contexts/carousel.d.ts +13 -0
  176. package/dist/src/contexts/checkbox.d.ts +2 -0
  177. package/dist/src/contexts/choicebox.d.ts +4 -0
  178. package/dist/src/contexts/collapse.d.ts +8 -0
  179. package/dist/src/contexts/list.d.ts +8 -0
  180. package/dist/src/contexts/radio.d.ts +2 -0
  181. package/dist/src/contexts/resizable.d.ts +35 -0
  182. package/dist/src/contexts/switch.d.ts +4 -0
  183. package/dist/src/locales/en-us.d.ts +42 -0
  184. package/dist/src/plugins/dayjs-millisecond-token.d.ts +3 -0
  185. package/dist/src/types/components/time-picker.d.ts +4 -0
  186. package/dist/src/utils/context.d.ts +17 -0
  187. package/dist/src/utils/date.d.ts +26 -0
  188. package/dist/src/utils/debounce/index.d.ts +73 -0
  189. package/dist/src/utils/debounce.d.ts +1 -0
  190. package/dist/src/utils/dom.d.ts +40 -0
  191. package/dist/{utils/events.d.ts → src/utils/event.d.ts} +1 -0
  192. package/dist/src/utils/format.d.ts +25 -0
  193. package/dist/src/utils/get.d.ts +11 -0
  194. package/dist/src/utils/is.d.ts +4 -0
  195. package/dist/src/utils/ref.d.ts +5 -0
  196. package/dist/src/utils/regexp.d.ts +8 -0
  197. package/dist/src/utils/responsive.d.ts +3 -0
  198. package/dist/src/utils/throttle/index.d.ts +53 -0
  199. package/dist/src/utils/throttle.d.ts +1 -0
  200. package/dist/src/utils/uid.d.ts +1 -0
  201. package/dist/styles/styles.css +2 -2
  202. package/dist/styles/tw.css +18 -1
  203. package/dist/types/components/list.d.ts +4 -3
  204. package/dist/types/components/time-picker.d.ts +4 -0
  205. package/dist/types/components/time-picker.js +0 -0
  206. package/dist/types/shared/utils.d.ts +5 -2
  207. package/dist/utils/date.d.ts +3 -3
  208. package/dist/utils/debounce/compat.d.ts +143 -0
  209. package/dist/utils/debounce/compat.js +47 -0
  210. package/dist/utils/debounce/index.d.ts +73 -0
  211. package/dist/utils/debounce/index.js +60 -0
  212. package/dist/utils/debounce.d.ts +1 -73
  213. package/dist/utils/debounce.js +1 -60
  214. package/dist/utils/event.d.ts +9 -0
  215. package/dist/utils/{events.js → event.js} +3 -0
  216. package/dist/utils/format.d.ts +4 -1
  217. package/dist/utils/format.js +6 -0
  218. package/dist/utils/ref.d.ts +2 -5
  219. package/dist/utils/regexp.d.ts +4 -0
  220. package/dist/utils/regexp.js +4 -0
  221. package/dist/utils/responsive.d.ts +2 -1
  222. package/dist/utils/responsive.js +4 -1
  223. package/dist/utils/throttle/compat.d.ts +79 -0
  224. package/dist/utils/throttle/compat.js +9 -0
  225. package/dist/utils/throttle/index.d.ts +53 -0
  226. package/dist/utils/throttle/index.js +34 -0
  227. package/dist/utils/throttle.d.ts +1 -53
  228. package/dist/utils/throttle.js +1 -34
  229. package/dist/utils/uid.js +1 -1
  230. package/package.json +11 -11
  231. package/volar.d.ts +7 -0
  232. package/dist/components/fader/index.vue.d.ts +0 -11
  233. package/dist/components/list/index.vue.d.ts +0 -29
  234. package/dist/components/placeholder/index.vue.d.ts +0 -8
  235. package/dist/components/resizable-handle/index.vue.d.ts +0 -2
  236. package/dist/components/spinner/index.vue.d.ts +0 -2
  237. /package/dist/{components → src/components}/avatar/index.vue.d.ts +0 -0
  238. /package/dist/{components → src/components}/checkbox/index.vue.d.ts +0 -0
  239. /package/dist/{components → src/components}/checkbox-group/index.vue.d.ts +0 -0
  240. /package/dist/{components → src/components}/countdown/index.vue.d.ts +0 -0
@@ -0,0 +1,281 @@
1
+ <script setup>
2
+ import CalendarIcon from "@gdsicon/vue/calendar";
3
+ import { computed, ref, shallowRef, watch } from "vue";
4
+ import { useConfigProvider } from "../../composables/use-config-provider-context";
5
+ import { dayjs } from "../../utils/date";
6
+ import { sleep } from "../../utils/event";
7
+ import { clampValue } from "../../utils/format";
8
+ import { throttle } from "../../utils/throttle";
9
+ import PInput from "../input/index.vue";
10
+ import PPopover from "../popover/index.vue";
11
+ defineOptions({
12
+ name: "PTimePicker",
13
+ inheritAttrs: false,
14
+ model: {
15
+ prop: "modelValue",
16
+ event: "update:modelValue"
17
+ }
18
+ });
19
+ const props = defineProps({
20
+ allowClear: { type: Boolean, required: false },
21
+ presets: { type: Array, required: false, default: () => [] },
22
+ disabled: { type: Boolean, required: false },
23
+ modelValue: { type: [Date, String, Number], required: false, default: "" },
24
+ prefixIcon: { type: Boolean, required: false, default: true },
25
+ placeholder: { type: String, required: false },
26
+ closeOnPressEscape: { type: Boolean, required: false, default: true }
27
+ });
28
+ const emits = defineEmits(["change", "select", "update:modelValue"]);
29
+ const HEIGHT = 32;
30
+ const VALUE_POSITION_MAP = {
31
+ hours: 0,
32
+ minutes: 1,
33
+ seconds: 2
34
+ };
35
+ const config = useConfigProvider();
36
+ const inputRef = shallowRef();
37
+ const timeHoursRef = shallowRef();
38
+ const timeMinutesRef = shallowRef();
39
+ const timeSecondsRef = shallowRef();
40
+ const popoverVisible = shallowRef(false);
41
+ const modelValueList = ref([]);
42
+ const modelValue = computed({
43
+ get() {
44
+ return modelValueList.value.join(":");
45
+ },
46
+ set(value) {
47
+ emits("update:modelValue", value);
48
+ }
49
+ });
50
+ const onTimeListScroll = throttle((ev) => {
51
+ const target = ev.target;
52
+ const type = target.dataset.type;
53
+ const value = Math.ceil(target.scrollTop / HEIGHT);
54
+ const index = VALUE_POSITION_MAP[type];
55
+ modelValueList.value[index] = padStringZero(value);
56
+ }, 150, { edges: ["leading", "trailing"] });
57
+ function padStringZero(value) {
58
+ return String(value).padStart(2, "0");
59
+ }
60
+ function showPopover() {
61
+ popoverVisible.value = true;
62
+ setTimesScrollTop();
63
+ }
64
+ function hidePopover() {
65
+ popoverVisible.value = false;
66
+ }
67
+ function parseTimeValue(value, max) {
68
+ const numberValue = value ? Number.parseInt(value.slice(0, 2)) : 0;
69
+ if (!numberValue) {
70
+ return "00";
71
+ }
72
+ return clampValue(numberValue, 0, max).toString();
73
+ }
74
+ function updateValueList(value) {
75
+ modelValueList.value = getFormattedValue(value).split(":");
76
+ }
77
+ function getFormattedValue(value) {
78
+ if (value == null || value === "") {
79
+ return "";
80
+ }
81
+ let _value;
82
+ if (typeof value === "string") {
83
+ const formatDate = dayjs(/* @__PURE__ */ new Date()).format("YYYY-MM-DD");
84
+ _value = `${formatDate} ${value}`;
85
+ } else if (value instanceof Date) {
86
+ _value = value;
87
+ } else {
88
+ _value = new Date(value);
89
+ }
90
+ return dayjs(_value).format("HH:mm:ss");
91
+ }
92
+ async function setTimesScrollTop() {
93
+ await sleep(10);
94
+ const elList = [timeHoursRef.value, timeMinutesRef.value, timeSecondsRef.value];
95
+ elList.forEach((el, i) => {
96
+ const scrollTop = Number(modelValueList.value[i] || 0) * HEIGHT;
97
+ el?.scrollTo({ top: scrollTop });
98
+ });
99
+ }
100
+ function onTimesContainerClick(ev) {
101
+ const target = ev.target;
102
+ if (target.tagName !== "LI") {
103
+ return;
104
+ }
105
+ const scrollContainer = target.parentNode;
106
+ if (!scrollContainer) {
107
+ return;
108
+ }
109
+ const containerRect = scrollContainer.getBoundingClientRect();
110
+ const targetRect = target.getBoundingClientRect();
111
+ const containerCenter = containerRect.height / 2;
112
+ const targetCenter = targetRect.height / 2;
113
+ const targetOffsetFromTop = targetRect.top - containerRect.top + scrollContainer.scrollTop;
114
+ const newScrollTop = targetOffsetFromTop - containerCenter + targetCenter;
115
+ scrollContainer.scrollTo({
116
+ top: Math.max(0, newScrollTop),
117
+ behavior: "smooth"
118
+ });
119
+ }
120
+ function onCancelClick() {
121
+ updateValueList(props.modelValue);
122
+ hidePopover();
123
+ }
124
+ function onConfirmClick() {
125
+ updateValueList(modelValueList.value.join(":"));
126
+ modelValue.value = modelValueList.value.join(":");
127
+ hidePopover();
128
+ }
129
+ function onNowBtnClick(date) {
130
+ const newValue = getFormattedValue(date ?? /* @__PURE__ */ new Date());
131
+ modelValue.value = newValue;
132
+ modelValueList.value = newValue.split(":");
133
+ hidePopover();
134
+ }
135
+ function onInputValueChange(value) {
136
+ if (!value) {
137
+ modelValue.value = "";
138
+ modelValueList.value = [];
139
+ return;
140
+ }
141
+ const [h, m, s] = value.split(":");
142
+ const hh = parseTimeValue(h, 23);
143
+ const mm = parseTimeValue(m, 59);
144
+ const ss = parseTimeValue(s, 59);
145
+ modelValue.value = getFormattedValue(`${hh}:${mm}:${ss}`);
146
+ modelValueList.value = [padStringZero(hh), padStringZero(mm), padStringZero(ss)];
147
+ }
148
+ function onUpdateModelValue(value) {
149
+ if (value) {
150
+ return;
151
+ }
152
+ modelValue.value = "";
153
+ modelValueList.value = [];
154
+ }
155
+ function onPresetClick(ev) {
156
+ const target = ev.target;
157
+ if (target.tagName !== "BUTTON") {
158
+ return;
159
+ }
160
+ const index = Number(target.dataset.index);
161
+ if (Number.isNaN(index)) {
162
+ return;
163
+ }
164
+ const presetValue = props.presets[index].getDate();
165
+ if (!presetValue) {
166
+ return;
167
+ }
168
+ onNowBtnClick(presetValue);
169
+ }
170
+ watch(() => props.modelValue, updateValueList, { immediate: true });
171
+ </script>
172
+
173
+ <template>
174
+ <PPopover
175
+ enterable
176
+ scroll-hidden
177
+ trigger="manual"
178
+ :show-delay="0"
179
+ :hide-delay="100"
180
+ disabled-show-transition
181
+ :visible="popoverVisible"
182
+ :close-on-press-escape="closeOnPressEscape"
183
+ class="pxd-time-picker"
184
+ trigger-class="w-full"
185
+ v-bind="$attrs"
186
+ @trigger-click="showPopover"
187
+ @outside-click="onConfirmClick"
188
+ >
189
+ <PInput
190
+ ref="inputRef"
191
+ :disabled="disabled"
192
+ :allow-clear="allowClear"
193
+ :model-value="modelValue"
194
+ :placeholder="placeholder"
195
+ :prefix-style="false"
196
+ @change="onInputValueChange"
197
+ @update:model-value="onUpdateModelValue"
198
+ >
199
+ <template v-if="prefixIcon" #prefix>
200
+ <CalendarIcon class="ml-3 pointer-events-none" />
201
+ </template>
202
+ </PInput>
203
+
204
+ <template #content>
205
+ <div class="rounded-xl bg-background-100 shadow-border-menu">
206
+ <div class="text-sm flex max-w-full transform-gpu tabular-nums outline-none select-none" @click.stop="onTimesContainerClick">
207
+ <div class="p-2 gap-1 relative flex items-center">
208
+ <div class="pxd-time-picker--list relative">
209
+ <ul ref="timeHoursRef" data-type="hours" class="w-8 h-40 py-16 scrollbar-hidden snap-y snap-mandatory list-none overflow-x-hidden overflow-y-scroll overscroll-contain text-center outline-none" @scroll.stop="onTimeListScroll">
210
+ <li v-for="_, i of 24" :key="i" class="h-8 leading-8 cursor-pointer snap-center">
211
+ {{ padStringZero(i) }}
212
+ </li>
213
+ </ul>
214
+ </div>
215
+ <div class="pxd-time-picker--list relative">
216
+ <ul ref="timeMinutesRef" data-type="minutes" class="w-8 h-40 py-16 scrollbar-hidden snap-y snap-mandatory list-none overflow-x-hidden overflow-y-scroll overscroll-contain text-center outline-none" @scroll.stop="onTimeListScroll">
217
+ <li v-for="_, i of 60" :key="i" class="h-8 leading-8 cursor-pointer snap-center">
218
+ {{ padStringZero(i) }}
219
+ </li>
220
+ </ul>
221
+ </div>
222
+ <div class="pxd-time-picker--list relative">
223
+ <ul ref="timeSecondsRef" data-type="seconds" class="w-8 h-40 py-16 scrollbar-hidden snap-y snap-mandatory list-none overflow-x-hidden overflow-y-scroll overscroll-contain text-center outline-none" @scroll.stop="onTimeListScroll">
224
+ <li v-for="_, i of 60" :key="i" class="h-8 leading-8 cursor-pointer snap-center">
225
+ {{ padStringZero(i) }}
226
+ </li>
227
+ </ul>
228
+ </div>
229
+ </div>
230
+
231
+ <div v-if="presets?.length" class="w-26 p-2 h-44 gap-1 scrollbar-hidden flex flex-wrap content-start overflow-auto border-l outline-none" @click="onPresetClick">
232
+ <button
233
+ v-for="preset, i in presets"
234
+ :key="preset.label"
235
+ :data-index="i"
236
+ class="h-5 px-1.5 cursor-pointer appearance-none rounded-sm bg-gray-300 text-13px whitespace-nowrap text-foreground self-focus-ring outline-none motion-safe:transition-all"
237
+ >
238
+ {{ preset.label }}
239
+ </button>
240
+ </div>
241
+ </div>
242
+
243
+ <div class="p-2 gap-1 flex items-center justify-between border-t" @click.stop>
244
+ <PButton size="xs" variant="ghost" class="!px-0 text-13px" @click="onNowBtnClick()">
245
+ {{ config.locale.date.now }}
246
+ </PButton>
247
+
248
+ <PButton size="xs" variant="ghost" class="!px-0 text-13px" @click="onCancelClick">
249
+ {{ config.locale.confirm.cancel }}
250
+ </PButton>
251
+ </div>
252
+ </div>
253
+ </template>
254
+ </PPopover>
255
+ </template>
256
+
257
+ <style>
258
+ .pxd-time-picker--list::before {
259
+ content: '';
260
+ position: fixed;
261
+ top: 72px;
262
+ width: 32px;
263
+ height: 32px;
264
+ z-index: -1;
265
+ border-radius: var(--radius-md);
266
+ background: var(--color-gray-alpha-200);
267
+ pointer-events: none;
268
+ }
269
+
270
+ .pxd-time-picker--list:nth-child(1)::before {
271
+ left: 8px;
272
+ }
273
+
274
+ .pxd-time-picker--list:nth-child(2)::before {
275
+ left: 44px;
276
+ }
277
+
278
+ .pxd-time-picker--list:nth-child(3)::before {
279
+ left: 80px;
280
+ }
281
+ </style>
@@ -16,9 +16,9 @@ const props = defineProps({
16
16
  showArrow: { type: Boolean, required: false, default: true },
17
17
  desktopOnly: { type: Boolean, required: false },
18
18
  triggerClass: { type: [String, Array, Object], required: false },
19
- popoverClass: { type: [String, Array, Object], required: false, default: "" },
19
+ contentClass: { type: [String, Array, Object], required: false },
20
20
  triggerStyle: { type: [Object, String], required: false },
21
- popoverStyle: { type: [Object, String], required: false, default: "" }
21
+ contentStyle: { type: [Object, String], required: false }
22
22
  });
23
23
  const VARIANTS = {
24
24
  primary: {
@@ -42,11 +42,11 @@ const computedVariant = computed(() => getFallbackValue(props.variant, VARIANTS,
42
42
  const computedDisabled = computed(() => {
43
43
  return props.disabled || props.desktopOnly && isTouchDevice();
44
44
  });
45
- const computedPopoverClass = computed(() => {
45
+ const mergedClasses = computed(() => {
46
46
  return [
47
- "px-3 py-2 rounded-md text-[13px] break-words whitespace-pre-line shadow-border-tooltip bg-(--c)",
47
+ "px-3 py-2 rounded-md text-13px break-words whitespace-pre-line shadow-border-tooltip bg-(--popover-bg)",
48
48
  computedVariant.value.text,
49
- props.popoverClass
49
+ props.contentClass
50
50
  ].join(" ");
51
51
  });
52
52
  </script>
@@ -60,8 +60,8 @@ const computedPopoverClass = computed(() => {
60
60
  :arrow-color="computedVariant.bg"
61
61
  :trigger-class="triggerClass"
62
62
  :trigger-style="triggerStyle"
63
- :popover-class="computedPopoverClass"
64
- :popover-style="popoverStyle"
63
+ :content-style="contentStyle"
64
+ :content-class="mergedClasses"
65
65
  v-bind="$attrs"
66
66
  >
67
67
  <slot />
@@ -6,6 +6,7 @@ export * from './use-countdown.js';
6
6
  export * from './use-delay-change.js';
7
7
  export * from './use-delay-destroy.js';
8
8
  export * from './use-focus-trap.js';
9
+ export * from './use-loading-bar.js';
9
10
  export * from './use-media-query.js';
10
11
  export * from './use-message.js';
11
12
  export * from './use-model-value.js';
@@ -6,6 +6,7 @@ export * from "./use-countdown.js";
6
6
  export * from "./use-delay-change.js";
7
7
  export * from "./use-delay-destroy.js";
8
8
  export * from "./use-focus-trap.js";
9
+ export * from "./use-loading-bar.js";
9
10
  export * from "./use-media-query.js";
10
11
  export * from "./use-message.js";
11
12
  export * from "./use-model-value.js";
@@ -1,10 +1,10 @@
1
- import type { MaybeRef } from 'vue';
1
+ import type { MaybeRefOrGetter } from 'vue';
2
2
  import type { Nullable } from '../types/shared/utils';
3
- export declare const useIntersectionObserver: (target: TargetRef, callback: IntersectionObserverCallback, options?: MaybeRef<IntersectionObserverInit>) => ObserverReturnType<IntersectionObserver>;
4
- export declare const useMutationObserver: (target: TargetRef, callback: MutationCallback, options?: MaybeRef<MutationObserverInit>) => ObserverReturnType<MutationObserver>;
5
- export declare const useResizeObserver: (target: TargetRef, callback: ResizeObserverCallback, options?: MaybeRef<ResizeObserverOptions>) => ObserverReturnType<ResizeObserver>;
3
+ export declare const useIntersectionObserver: (target: TargetRef, callback: IntersectionObserverCallback, options?: MaybeRefOrGetter<IntersectionObserverInit>) => ObserverReturnType<IntersectionObserver>;
4
+ export declare const useMutationObserver: (target: TargetRef, callback: MutationCallback, options?: MaybeRefOrGetter<MutationObserverInit>) => ObserverReturnType<MutationObserver>;
5
+ export declare const useResizeObserver: (target: TargetRef, callback: ResizeObserverCallback, options?: MaybeRefOrGetter<ResizeObserverOptions>) => ObserverReturnType<ResizeObserver>;
6
6
  type Observers = IntersectionObserver | ResizeObserver | MutationObserver;
7
- type TargetRef = MaybeRef<Nullable<HTMLElement>> | MaybeRef<Nullable<HTMLElement>>[];
7
+ type TargetRef = MaybeRefOrGetter<Nullable<HTMLElement>> | MaybeRefOrGetter<Nullable<HTMLElement>>[];
8
8
  interface ObserverReturnType<T extends Observers> {
9
9
  observer: T | undefined;
10
10
  stop: () => void;
@@ -1,7 +1,11 @@
1
1
  export type ColorScheme = 'light' | 'dark';
2
2
  export type ColorPreference = ColorScheme | 'auto';
3
- export declare function useColorScheme(): {
3
+ interface Options {
4
+ syncStatus?: boolean;
5
+ }
6
+ export declare function useColorScheme(options?: Options): {
4
7
  isDark: import("vue").ComputedRef<boolean>;
5
8
  colorScheme: import("vue").ShallowRef<ColorPreference, ColorPreference>;
6
9
  toggleDarkMode: () => void;
7
10
  };
11
+ export {};
@@ -1,7 +1,10 @@
1
1
  import { computed, onBeforeUnmount, shallowRef, watchEffect } from "vue";
2
+ import { on } from "../utils/event.js";
2
3
  import { isServer } from "../utils/is.js";
3
4
  import { PRESET_MEDIA_QUERIES, useMediaQuery } from "./use-media-query.js";
4
- export function useColorScheme() {
5
+ export function useColorScheme(options = {}) {
6
+ const RANDOM_KEY = Math.random();
7
+ const EVENT_NAME = "#toggle-color-scheme";
5
8
  const STORAGE_KEY = "fe.system.color-scheme";
6
9
  const colorScheme = shallowRef("auto");
7
10
  const preferredDark = useMediaQuery(PRESET_MEDIA_QUERIES.COLOR_SCHEME_DARK);
@@ -47,6 +50,16 @@ export function useColorScheme() {
47
50
  }
48
51
  updateStorages();
49
52
  removeDisableTransitionStyle();
53
+ if (options.syncStatus) {
54
+ const payload = { id: RANDOM_KEY, mode: colorScheme.value };
55
+ window.dispatchEvent(new CustomEvent(EVENT_NAME, { detail: payload }));
56
+ }
57
+ }
58
+ function onToggleModeType({ detail }) {
59
+ if (detail.id === RANDOM_KEY) {
60
+ return;
61
+ }
62
+ colorScheme.value = detail.mode;
50
63
  }
51
64
  if (!isServer) {
52
65
  const stored = localStorage.getItem(STORAGE_KEY);
@@ -62,8 +75,14 @@ export function useColorScheme() {
62
75
  htmlEl.classList.remove("dark");
63
76
  }
64
77
  });
78
+ let unbindSubscriber = () => {
79
+ };
80
+ if (options.syncStatus) {
81
+ unbindSubscriber = on(window, EVENT_NAME, onToggleModeType);
82
+ }
65
83
  onBeforeUnmount(() => {
66
84
  stopEffect();
85
+ unbindSubscriber();
67
86
  });
68
87
  }
69
88
  return {
@@ -4,4 +4,4 @@ export interface ConfigProviderProps {
4
4
  size?: ComponentSize;
5
5
  locale?: Record<string, any>;
6
6
  }
7
- export declare const provideConfigProvider: (contextValue: Required<ConfigProviderProps>) => Required<ConfigProviderProps>, useConfigProvider: ((fallback?: Required<ConfigProviderProps>) => Required<ConfigProviderProps>) & ((fallback: null) => Required<ConfigProviderProps>);
7
+ export declare const provideConfigProvider: (contextValue: Required<ConfigProviderProps>) => Required<ConfigProviderProps>, useConfigProvider: ((fallback?: Required<ConfigProviderProps> | undefined) => Required<ConfigProviderProps>) & ((fallback: null) => Required<ConfigProviderProps> | null);
@@ -46,6 +46,12 @@ export interface Options {
46
46
  * @default true
47
47
  */
48
48
  millisecond?: boolean;
49
+ /**
50
+ * 是否启用人性化时间显示(向上取整到秒)
51
+ * Whether to enable human-friendly time display (ceil to seconds).
52
+ * @default false
53
+ */
54
+ intuitive?: boolean;
49
55
  }
50
56
  export declare function useCountdown<T extends Record<string, any>>(props: Options, emits: EmitFn<T>): {
51
57
  stop: () => void;
@@ -1,5 +1,5 @@
1
1
  import { computed, shallowRef, watch } from "vue";
2
- const UPDATE_INTERVAL = Math.ceil(1e3 / 25);
2
+ const UPDATE_INTERVAL = 100;
3
3
  export function useCountdown(props, emits) {
4
4
  let startTimestamp = -1;
5
5
  let isFinished = false;
@@ -24,22 +24,36 @@ export function useCountdown(props, emits) {
24
24
  return props.millisecond ? Math.round(time) : Math.round(time * 1e3);
25
25
  }
26
26
  function getCurrent(now) {
27
- return props.invert ? now - startTimestamp : totalDuration.value + startTimestamp - now;
27
+ const rawCurrent = props.invert ? now - startTimestamp : totalDuration.value + startTimestamp - now;
28
+ if (props.intuitive && !props.invert && rawCurrent > 0) {
29
+ const seconds = Math.ceil(rawCurrent / 1e3);
30
+ return Math.max(0, seconds * 1e3);
31
+ }
32
+ return rawCurrent;
28
33
  }
29
34
  function setCurrent() {
30
35
  const startAtValue = formatTime(props.startAt);
31
36
  if (props.invert) {
32
37
  timeRef.value = isInfiniteCountup.value ? startAtValue : Math.min(startAtValue, totalDuration.value);
33
38
  } else {
34
- timeRef.value = Math.max(0, totalDuration.value - startAtValue);
39
+ const rawTime = Math.max(0, totalDuration.value - startAtValue);
40
+ if (props.intuitive && rawTime > 0) {
41
+ const seconds = Math.ceil(rawTime / 1e3);
42
+ timeRef.value = Math.max(0, seconds * 1e3);
43
+ } else {
44
+ timeRef.value = rawTime;
45
+ }
35
46
  }
36
47
  }
37
48
  function shouldFinish(current) {
38
49
  if (!props.invert) {
50
+ if (props.intuitive) {
51
+ const actualCurrent = totalDuration.value + startTimestamp - performance.now();
52
+ return actualCurrent <= 0;
53
+ }
39
54
  return current <= 0;
40
- } else {
41
- return !isInfiniteCountup.value && current >= totalDuration.value;
42
55
  }
56
+ return !isInfiniteCountup.value && current >= totalDuration.value;
43
57
  }
44
58
  function finish() {
45
59
  timeRef.value = props.invert ? totalDuration.value : 0;
@@ -56,7 +70,7 @@ export function useCountdown(props, emits) {
56
70
  frame();
57
71
  }
58
72
  }
59
- function frame(timestamp) {
73
+ function frame() {
60
74
  const now = performance.now();
61
75
  const current = getCurrent(now);
62
76
  let isLastFrame = false;
@@ -71,7 +85,7 @@ export function useCountdown(props, emits) {
71
85
  requestAnimationFrame(frame);
72
86
  return;
73
87
  }
74
- previousFrameTime = timestamp;
88
+ previousFrameTime = now;
75
89
  if (shouldFinish(current)) {
76
90
  finish();
77
91
  return;
@@ -3,11 +3,11 @@ interface Options {
3
3
  default?: boolean;
4
4
  delay?: number;
5
5
  }
6
- interface ReturnType {
6
+ interface UseDelayDestroyReturnType {
7
7
  render: Ref<boolean>;
8
8
  visible: Ref<boolean>;
9
- open: () => void;
10
- close: () => void;
9
+ open: () => Promise<boolean>;
10
+ close: () => Promise<boolean>;
11
11
  }
12
- export declare function useDelayDestroy(valueOrOptions?: boolean | Options): ReturnType;
12
+ export declare function useDelayDestroy(valueOrOptions?: boolean | Options): UseDelayDestroyReturnType;
13
13
  export {};
@@ -1,4 +1,4 @@
1
- import { shallowRef } from "vue";
1
+ import { nextTick, shallowRef } from "vue";
2
2
  export function useDelayDestroy(valueOrOptions = {}) {
3
3
  const {
4
4
  delay = 300,
@@ -6,19 +6,23 @@ export function useDelayDestroy(valueOrOptions = {}) {
6
6
  } = typeof valueOrOptions === "boolean" ? { default: valueOrOptions, delay: 300 } : valueOrOptions;
7
7
  const render = shallowRef(value);
8
8
  const visible = shallowRef(value);
9
- let delayTimeoutId = -1;
10
- const open = () => {
11
- clearTimeout(delayTimeoutId);
12
- render.value = true;
13
- Promise.resolve().then(() => {
14
- visible.value = true;
9
+ let delayTimeoutId;
10
+ const open = async () => {
11
+ return new Promise((resolve) => {
12
+ clearTimeout(delayTimeoutId);
13
+ render.value = true;
14
+ nextTick().then(() => {
15
+ resolve(visible.value = true);
16
+ });
15
17
  });
16
18
  };
17
19
  const close = () => {
18
- visible.value = false;
19
- delayTimeoutId = window.setTimeout(() => {
20
- render.value = false;
21
- }, delay);
20
+ return new Promise((resolve) => {
21
+ visible.value = false;
22
+ delayTimeoutId = setTimeout(() => {
23
+ resolve(render.value = false);
24
+ }, delay);
25
+ });
22
26
  };
23
27
  return {
24
28
  open,
@@ -1,4 +1,4 @@
1
- import type { DOMRef } from '../types/shared/utils';
2
- export declare function useFocusTrap(container: DOMRef): {
1
+ import type { MaybeElementRef } from '../types/shared/utils';
2
+ export declare function useFocusTrap(container: MaybeElementRef<HTMLElement>): {
3
3
  stop: import("vue").WatchHandle;
4
4
  };
@@ -1,5 +1,5 @@
1
1
  import { nextTick, onBeforeUnmount, watch } from "vue";
2
- import { on } from "../utils/events.js";
2
+ import { on } from "../utils/event.js";
3
3
  import { toValue } from "../utils/ref.js";
4
4
  export function useFocusTrap(container) {
5
5
  const FOCUSABLE_SELECTORS = [
@@ -34,19 +34,19 @@ export function useFocusTrap(container) {
34
34
  const nextFocusIndex = (focusIndex + offset + elements.length) % elements.length;
35
35
  elements[nextFocusIndex]?.focus();
36
36
  }
37
- const unwatch = watch(() => toValue(container), (container2, _, onCleanup) => {
38
- if (!container2) {
37
+ const unwatch = watch(() => toValue(container), (target, _, onCleanup) => {
38
+ if (!target) {
39
39
  previousFocusedElement?.focus();
40
40
  return;
41
41
  }
42
42
  previousFocusedElement = document.activeElement;
43
43
  nextTick(() => {
44
- const unbindEvent = on(container2, "keydown", onContainerKeydown);
45
- elements = Array.from(container2.querySelectorAll(FOCUSABLE_SELECTORS));
44
+ const unbindEvent = on(target, "keydown", onContainerKeydown);
45
+ elements = Array.from(target.querySelectorAll(FOCUSABLE_SELECTORS));
46
46
  if (elements.length) {
47
47
  elements[0].focus();
48
48
  } else {
49
- container2.focus({ preventScroll: true });
49
+ target.focus({ preventScroll: true });
50
50
  }
51
51
  onCleanup(() => {
52
52
  unbindEvent();
@@ -0,0 +1,25 @@
1
+ export declare const START_LOADING_BAR_EVENT_NAME = "#start-loading-bar";
2
+ export declare const ERROR_LOADING_BAR_EVENT_NAME = "#error-loading-bar";
3
+ export declare const FINISH_LOADING_BAR_EVENT_NAME = "#finish-loading-bar";
4
+ export declare const INCREASE_LOADING_BAR_EVENT_NAME = "#increase-loading-bar";
5
+ declare const LOADING_BAR_EVENTS: {
6
+ readonly start: "#start-loading-bar";
7
+ readonly error: "#error-loading-bar";
8
+ readonly finish: "#finish-loading-bar";
9
+ readonly increase: "#increase-loading-bar";
10
+ };
11
+ interface Options extends Record<string, any> {
12
+ type?: keyof typeof LOADING_BAR_EVENTS;
13
+ }
14
+ export interface LoadingBarEventParams {
15
+ group: string;
16
+ value?: number;
17
+ }
18
+ export declare function useLoadingBar(options?: Options): void;
19
+ export declare namespace useLoadingBar {
20
+ var start: (group?: string) => void;
21
+ var error: (group?: string) => void;
22
+ var finish: (group?: string) => void;
23
+ var increase: (group?: string, value?: number) => void;
24
+ }
25
+ export {};
@@ -0,0 +1,27 @@
1
+ export const START_LOADING_BAR_EVENT_NAME = "#start-loading-bar";
2
+ export const ERROR_LOADING_BAR_EVENT_NAME = "#error-loading-bar";
3
+ export const FINISH_LOADING_BAR_EVENT_NAME = "#finish-loading-bar";
4
+ export const INCREASE_LOADING_BAR_EVENT_NAME = "#increase-loading-bar";
5
+ const LOADING_BAR_EVENTS = {
6
+ start: START_LOADING_BAR_EVENT_NAME,
7
+ error: ERROR_LOADING_BAR_EVENT_NAME,
8
+ finish: FINISH_LOADING_BAR_EVENT_NAME,
9
+ increase: INCREASE_LOADING_BAR_EVENT_NAME
10
+ };
11
+ export function useLoadingBar(options = {}) {
12
+ const { type = "start", ...data } = options;
13
+ const event = LOADING_BAR_EVENTS[type];
14
+ window.dispatchEvent(new CustomEvent(event, { detail: data }));
15
+ }
16
+ useLoadingBar.start = function(group = "default") {
17
+ useLoadingBar({ type: "start", group });
18
+ };
19
+ useLoadingBar.error = function(group = "default") {
20
+ useLoadingBar({ type: "error", group });
21
+ };
22
+ useLoadingBar.finish = function(group = "default") {
23
+ useLoadingBar({ type: "finish", group });
24
+ };
25
+ useLoadingBar.increase = function(group = "default", value) {
26
+ useLoadingBar({ type: "increase", group, value });
27
+ };
@@ -1,5 +1,5 @@
1
1
  import { onBeforeUnmount, shallowRef } from "vue";
2
- import { on } from "../utils/events.js";
2
+ import { on } from "../utils/event.js";
3
3
  import { isServer } from "../utils/is.js";
4
4
  const CACHED_QUERIES = {};
5
5
  export const PRESET_MEDIA_QUERIES = {