@fangxinyan/lumina 0.6.13 → 0.6.15

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 (239) hide show
  1. package/dist/Alert.cjs +3 -3
  2. package/dist/Alert.js +2 -2
  3. package/dist/AppShell.cjs +5 -5
  4. package/dist/AppShell.js +1 -1
  5. package/dist/AutoComplete.cjs +5 -5
  6. package/dist/AutoComplete.js +4 -4
  7. package/dist/Avatar.cjs +2 -2
  8. package/dist/Avatar.js +1 -1
  9. package/dist/Badge.cjs +2 -2
  10. package/dist/Badge.js +1 -1
  11. package/dist/Button.cjs +4 -4
  12. package/dist/Button.js +2 -2
  13. package/dist/{Calendar-RUTPKREW.css → Calendar-I6NHCXIB.css} +65 -0
  14. package/dist/Calendar.cjs +3 -3
  15. package/dist/Calendar.d.cts +2 -0
  16. package/dist/Calendar.d.ts +2 -0
  17. package/dist/Calendar.js +2 -2
  18. package/dist/Card.cjs +3 -3
  19. package/dist/Card.js +2 -2
  20. package/dist/Cascader.cjs +5 -5
  21. package/dist/Cascader.js +4 -4
  22. package/dist/Checkbox.cjs +3 -3
  23. package/dist/Checkbox.js +2 -2
  24. package/dist/Collapse.cjs +3 -3
  25. package/dist/Collapse.js +2 -2
  26. package/dist/ColorPicker.cjs +2 -2
  27. package/dist/ColorPicker.js +1 -1
  28. package/dist/CommandPalette.cjs +5 -5
  29. package/dist/CommandPalette.js +4 -4
  30. package/dist/ContextMenu.cjs +2 -2
  31. package/dist/ContextMenu.js +1 -1
  32. package/dist/DatePicker-VDVSIARF.css +60 -0
  33. package/dist/DatePicker.cjs +16 -0
  34. package/dist/DatePicker.d.cts +49 -0
  35. package/dist/DatePicker.d.ts +49 -0
  36. package/dist/DatePicker.js +7 -0
  37. package/dist/DateTimePicker-77ZLZIWO.css +224 -0
  38. package/dist/DateTimePicker.cjs +16 -0
  39. package/dist/DateTimePicker.d.cts +61 -0
  40. package/dist/DateTimePicker.d.ts +61 -0
  41. package/dist/DateTimePicker.js +7 -0
  42. package/dist/Divider.cjs +2 -2
  43. package/dist/Divider.js +1 -1
  44. package/dist/{Drawer-7N3URAJ6.css → Drawer-7KICRM4L.css} +1 -1
  45. package/dist/Drawer.cjs +3 -3
  46. package/dist/Drawer.d.cts +4 -0
  47. package/dist/Drawer.d.ts +4 -0
  48. package/dist/Drawer.js +2 -2
  49. package/dist/Empty.cjs +2 -2
  50. package/dist/Empty.js +1 -1
  51. package/dist/Form.cjs +4 -4
  52. package/dist/Form.js +1 -1
  53. package/dist/Icon.cjs +49 -49
  54. package/dist/Icon.js +1 -1
  55. package/dist/{Image-SGSRTHQX.css → Image-TDCXJISG.css} +1 -1
  56. package/dist/Image.cjs +6 -6
  57. package/dist/Image.d.cts +4 -0
  58. package/dist/Image.d.ts +4 -0
  59. package/dist/Image.js +2 -2
  60. package/dist/Input.cjs +5 -5
  61. package/dist/Input.js +3 -3
  62. package/dist/InputNumber.cjs +5 -5
  63. package/dist/InputNumber.js +4 -4
  64. package/dist/List.cjs +2 -2
  65. package/dist/List.js +1 -1
  66. package/dist/Message.cjs +6 -6
  67. package/dist/Message.js +2 -2
  68. package/dist/{Modal-MCFDYVUQ.css → Modal-ZFWNFEA5.css} +1 -1
  69. package/dist/Modal.cjs +4 -4
  70. package/dist/Modal.d.cts +4 -0
  71. package/dist/Modal.d.ts +4 -0
  72. package/dist/Modal.js +3 -3
  73. package/dist/Pagination.cjs +7 -7
  74. package/dist/Pagination.js +6 -6
  75. package/dist/Popover.cjs +2 -2
  76. package/dist/Popover.js +1 -1
  77. package/dist/Progress.cjs +2 -2
  78. package/dist/Progress.js +1 -1
  79. package/dist/Radio.cjs +3 -3
  80. package/dist/Radio.js +1 -1
  81. package/dist/Select.cjs +6 -6
  82. package/dist/Select.js +5 -5
  83. package/dist/Skeleton.cjs +2 -2
  84. package/dist/Skeleton.js +1 -1
  85. package/dist/Slider.cjs +2 -2
  86. package/dist/Slider.js +1 -1
  87. package/dist/Spin.cjs +2 -2
  88. package/dist/Spin.js +1 -1
  89. package/dist/Splitter.cjs +2 -2
  90. package/dist/Splitter.js +1 -1
  91. package/dist/StatusBar.cjs +3 -3
  92. package/dist/StatusBar.js +1 -1
  93. package/dist/Surface.cjs +4 -4
  94. package/dist/Surface.js +2 -2
  95. package/dist/Switch.cjs +2 -2
  96. package/dist/Switch.js +1 -1
  97. package/dist/Table.cjs +9 -9
  98. package/dist/Table.js +8 -8
  99. package/dist/TablePro.cjs +10 -10
  100. package/dist/TablePro.js +9 -9
  101. package/dist/Tabs.cjs +2 -2
  102. package/dist/Tabs.js +1 -1
  103. package/dist/Tag.cjs +3 -3
  104. package/dist/Tag.js +2 -2
  105. package/dist/Textarea.cjs +4 -4
  106. package/dist/Textarea.js +2 -2
  107. package/dist/Theme.cjs +11 -11
  108. package/dist/Theme.js +1 -1
  109. package/dist/ThemePanel.cjs +13 -13
  110. package/dist/ThemePanel.js +10 -10
  111. package/dist/TimePicker-6URACYEH.css +151 -0
  112. package/dist/TimePicker.cjs +15 -0
  113. package/dist/TimePicker.d.cts +63 -0
  114. package/dist/TimePicker.d.ts +63 -0
  115. package/dist/TimePicker.js +6 -0
  116. package/dist/Timeline.cjs +3 -3
  117. package/dist/Timeline.js +2 -2
  118. package/dist/Tooltip.cjs +2 -2
  119. package/dist/Tooltip.js +1 -1
  120. package/dist/Typography.cjs +7 -7
  121. package/dist/Typography.js +2 -2
  122. package/dist/{chunk-J7VYTDFN.cjs → chunk-262ED6WQ.cjs} +3 -3
  123. package/dist/chunk-26AJ7OY3.cjs +505 -0
  124. package/dist/{chunk-BX45WJRT.js → chunk-3VSHGM54.js} +9 -9
  125. package/dist/{chunk-KRVWQKTZ.js → chunk-3VXGZ3SJ.js} +3 -3
  126. package/dist/{chunk-VJVXXCNL.js → chunk-4HJBF4GY.js} +3 -3
  127. package/dist/chunk-4KDABJSY.cjs +241 -0
  128. package/dist/{chunk-ONHYDQFP.cjs → chunk-4TTRHEGM.cjs} +3 -3
  129. package/dist/{chunk-GVULVTWO.js → chunk-4YSGGZDB.js} +4 -4
  130. package/dist/{chunk-HNP7KEQP.cjs → chunk-5A6KSYWA.cjs} +1 -1
  131. package/dist/{chunk-RFFP6J6O.cjs → chunk-5ERD3W24.cjs} +4 -4
  132. package/dist/{chunk-TTXYZDQ3.js → chunk-5MOYKVB7.js} +2 -2
  133. package/dist/{chunk-X2NY3YQS.cjs → chunk-5QEI7GGA.cjs} +6 -6
  134. package/dist/{chunk-O7OPFKAM.js → chunk-6HF6UF73.js} +2 -2
  135. package/dist/{chunk-DCATZUT3.js → chunk-6K5YI4ZE.js} +2 -2
  136. package/dist/{chunk-EVKLGNVR.js → chunk-6LC4QROE.js} +3 -3
  137. package/dist/{chunk-6Z4PZWND.js → chunk-6LN4VVX7.js} +2 -2
  138. package/dist/{chunk-7RNT6KN4.js → chunk-6MEOLYNQ.js} +1 -1
  139. package/dist/{chunk-UMLRSKBE.js → chunk-6PHPRZTT.js} +4 -4
  140. package/dist/{chunk-4VPRY4EM.cjs → chunk-6Q76VLCE.cjs} +3 -3
  141. package/dist/{chunk-SWMQ2GKT.cjs → chunk-7IO3EOHN.cjs} +3 -3
  142. package/dist/{chunk-B55XILNY.cjs → chunk-7QXP6DXC.cjs} +4 -4
  143. package/dist/{chunk-56GNNOOT.cjs → chunk-7YJV45U6.cjs} +11 -11
  144. package/dist/{chunk-AJ44ZLJY.cjs → chunk-A4Z7PLHV.cjs} +59 -59
  145. package/dist/{chunk-RUE3QE6T.js → chunk-A6O25EP2.js} +2 -2
  146. package/dist/{chunk-ZNR6LWTQ.js → chunk-AAPZLBHQ.js} +1 -1
  147. package/dist/{chunk-Q4IAUKAW.js → chunk-ARUPS7JH.js} +2 -2
  148. package/dist/{chunk-VAOAAWGI.cjs → chunk-ATUPFAPZ.cjs} +3 -3
  149. package/dist/{chunk-GKBCXYDF.cjs → chunk-BNY2NVTL.cjs} +3 -3
  150. package/dist/{chunk-7J26GI3T.cjs → chunk-BT2RXFT4.cjs} +15 -13
  151. package/dist/{chunk-WY6AEPFW.js → chunk-BVQOJKRX.js} +8 -6
  152. package/dist/{chunk-QPZCDZWI.cjs → chunk-BW76ENTW.cjs} +1 -1
  153. package/dist/{chunk-EKNDL2XB.js → chunk-CFZVWY5N.js} +2 -2
  154. package/dist/chunk-CUBKHQ63.js +483 -0
  155. package/dist/chunk-CYBBUXUK.cjs +415 -0
  156. package/dist/{chunk-JST4HJ3I.js → chunk-D7GK6H6V.js} +1 -1
  157. package/dist/{chunk-T7RV2UMU.js → chunk-DSLYWX4O.js} +1 -1
  158. package/dist/{chunk-JKFGLYMM.js → chunk-EQ4FPOQQ.js} +14 -4
  159. package/dist/{chunk-ZZH4UIPN.cjs → chunk-ES7AWMNH.cjs} +1 -1
  160. package/dist/{chunk-ZLMJVSBO.cjs → chunk-FDUQPAQE.cjs} +1 -1
  161. package/dist/{chunk-HHBXCBZP.js → chunk-FDZG27IG.js} +1 -1
  162. package/dist/chunk-FKP5D5IS.js +271 -0
  163. package/dist/{chunk-EEHZRPPF.cjs → chunk-FQJY4D3T.cjs} +1 -1
  164. package/dist/{chunk-LA62SD2F.js → chunk-FYSXJXNW.js} +1 -1
  165. package/dist/{chunk-DEXYWDHF.js → chunk-GNV6W4BN.js} +1 -1
  166. package/dist/{chunk-NZBOHEQA.js → chunk-HBO7ZDEQ.js} +1 -1
  167. package/dist/{chunk-BAWP2QVY.js → chunk-I777JTTG.js} +1 -1
  168. package/dist/chunk-I7TOBKJO.js +219 -0
  169. package/dist/{chunk-IZGHMMX7.js → chunk-IOAOG5L7.js} +3 -3
  170. package/dist/{chunk-QQROR2RU.cjs → chunk-IOUAZYK2.cjs} +1 -1
  171. package/dist/{chunk-CQKQ7KS2.js → chunk-IPSNC5VZ.js} +2 -2
  172. package/dist/{chunk-7X7FXV5E.cjs → chunk-IVFVLRWJ.cjs} +14 -14
  173. package/dist/{chunk-LM5XXSGE.js → chunk-IZHH6CVY.js} +1 -1
  174. package/dist/{chunk-GGNBMIZ2.js → chunk-JFL2WMJZ.js} +2 -2
  175. package/dist/{chunk-XRIXQM3Z.cjs → chunk-JMFHL7GN.cjs} +1 -1
  176. package/dist/chunk-KHRYPNUV.cjs +293 -0
  177. package/dist/{chunk-LFPFFSN2.js → chunk-KMPFESEV.js} +1 -1
  178. package/dist/{chunk-TAHZH6DJ.js → chunk-KYV75JPQ.js} +1 -1
  179. package/dist/{chunk-2A2XM7D5.cjs → chunk-LEMMFFEY.cjs} +4 -4
  180. package/dist/{chunk-MZIZGYA4.cjs → chunk-M4NJTJKV.cjs} +1 -1
  181. package/dist/{chunk-HYXA7S43.js → chunk-MOZ52KN6.js} +1 -1
  182. package/dist/{chunk-E5MSFY5H.cjs → chunk-MPOO5VPW.cjs} +1 -1
  183. package/dist/{chunk-MPJLGYFV.cjs → chunk-MYW7LNB2.cjs} +1 -1
  184. package/dist/chunk-N7CHFKRS.js +393 -0
  185. package/dist/{chunk-VBTASJ3Y.cjs → chunk-N7OQNSII.cjs} +1 -1
  186. package/dist/{chunk-VGERRI4S.js → chunk-OTSDPQPV.js} +2 -2
  187. package/dist/{chunk-7NAN7OVX.cjs → chunk-P2OQTJZP.cjs} +1 -1
  188. package/dist/{chunk-HAA5C5YW.js → chunk-P64NPZBG.js} +2 -2
  189. package/dist/{chunk-QP6RNHGR.cjs → chunk-PBT4UKPL.cjs} +3 -3
  190. package/dist/{chunk-FUR5SDP7.cjs → chunk-PKNRTFNE.cjs} +1 -1
  191. package/dist/{chunk-FPXBY2MY.cjs → chunk-POU3W5J3.cjs} +1 -1
  192. package/dist/{chunk-SOY3LB7W.cjs → chunk-PSQ3HNZP.cjs} +1 -1
  193. package/dist/{chunk-BK4XKZUO.js → chunk-PU7VXDAS.js} +1 -1
  194. package/dist/{chunk-OCQC2ZSV.cjs → chunk-QMX67CVT.cjs} +1 -1
  195. package/dist/{chunk-R3JCW3ES.js → chunk-QNN3YV2P.js} +2 -2
  196. package/dist/{chunk-V5HMQGFD.js → chunk-R3DTXVP2.js} +1 -1
  197. package/dist/{chunk-EQGNKCBY.cjs → chunk-RFI5R42I.cjs} +4 -4
  198. package/dist/{chunk-FROWMHDP.cjs → chunk-RMFSX7DO.cjs} +18 -8
  199. package/dist/{chunk-TCWGIRAW.js → chunk-RR2BKV65.js} +1 -1
  200. package/dist/{chunk-YHFGMI7T.cjs → chunk-RSSOX4RQ.cjs} +8 -8
  201. package/dist/{chunk-3XV4LGQ7.cjs → chunk-RZEFKXL3.cjs} +3 -3
  202. package/dist/{chunk-GDWAQGOH.cjs → chunk-S2ZGXBUH.cjs} +1 -1
  203. package/dist/{chunk-M63HWVOS.js → chunk-S7IHWY24.js} +2 -2
  204. package/dist/{chunk-NLX2RB4L.cjs → chunk-SOQ56ZI2.cjs} +1 -1
  205. package/dist/{chunk-RV37BGW3.cjs → chunk-SW2HMNCA.cjs} +4 -4
  206. package/dist/{chunk-UVL5SIAQ.cjs → chunk-TBNPJPYG.cjs} +1 -1
  207. package/dist/{chunk-QVWCUKEY.js → chunk-TJECLLN4.js} +1 -1
  208. package/dist/{chunk-E2OC4CUE.js → chunk-TYLDISRK.js} +1 -1
  209. package/dist/{chunk-23HN42SP.cjs → chunk-ULUD3FED.cjs} +9 -6
  210. package/dist/{chunk-LINUXKS7.cjs → chunk-V5KUC5VH.cjs} +1 -1
  211. package/dist/{chunk-U2543OZS.cjs → chunk-VA2I7ZAL.cjs} +1 -1
  212. package/dist/{chunk-7TWL3SJ5.cjs → chunk-VS3I5OKA.cjs} +8 -8
  213. package/dist/{chunk-A7BI7YWZ.js → chunk-WMGMIE2D.js} +8 -5
  214. package/dist/{chunk-CCBEHIRU.cjs → chunk-X5MYHDEQ.cjs} +6 -6
  215. package/dist/{chunk-QSGH4FCS.cjs → chunk-X7XP6GEI.cjs} +1 -1
  216. package/dist/{chunk-UROQO2HR.js → chunk-XCXUGHDF.js} +1 -1
  217. package/dist/{chunk-2M5WJENK.js → chunk-YAFDVNXT.js} +1 -1
  218. package/dist/{chunk-PDYM26IC.cjs → chunk-ZBWUIR2J.cjs} +6 -6
  219. package/dist/{chunk-5GKALAMP.js → chunk-ZD3L4V3H.js} +2 -2
  220. package/dist/{chunk-XJTDCWKP.js → chunk-ZR4IMROK.js} +1 -1
  221. package/dist/{chunk-5MCFW2HC.js → chunk-ZTCRD2FL.js} +1 -1
  222. package/dist/index.cjs +214 -199
  223. package/dist/index.d.cts +4 -1
  224. package/dist/index.d.ts +4 -1
  225. package/dist/index.js +51 -48
  226. package/dist/styles.css +445 -3
  227. package/dist/{tokens-OJLK3XMZ.css → tokens-RYJ3DFTU.css} +3 -0
  228. package/dist/tokens.css +3 -0
  229. package/docs/llms/calendar.md +2 -1
  230. package/docs/llms/datepicker.md +69 -0
  231. package/docs/llms/datetimepicker.md +83 -0
  232. package/docs/llms/drawer.md +13 -0
  233. package/docs/llms/image.md +14 -0
  234. package/docs/llms/modal.md +13 -0
  235. package/docs/llms/timepicker.md +81 -0
  236. package/docs/llms.md +5 -2
  237. package/package.json +7 -3
  238. package/dist/chunk-56U4P7QA.cjs +0 -112
  239. package/dist/chunk-J3LUTXVO.js +0 -90
@@ -0,0 +1,483 @@
1
+ import { useFloating } from './chunk-DUFRASGO.js';
2
+ import { Input } from './chunk-IOAOG5L7.js';
3
+ import { Button } from './chunk-IPSNC5VZ.js';
4
+ import { Calendar } from './chunk-I7TOBKJO.js';
5
+ import './tokens-RYJ3DFTU.css';
6
+ import './shared-NJHRNLRH.css';
7
+ import './DateTimePicker-77ZLZIWO.css';
8
+ import * as React from 'react';
9
+ import { createPortal } from 'react-dom';
10
+ import { jsxs, jsx } from 'react/jsx-runtime';
11
+
12
+ var pad = (value) => String(value).padStart(2, "0");
13
+ var clampStep = (value) => {
14
+ if (!Number.isFinite(value) || !value || value < 1) return 1;
15
+ return Math.floor(value);
16
+ };
17
+ var isValidDate = (date) => date instanceof Date && !Number.isNaN(date.getTime());
18
+ var startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate());
19
+ var isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
20
+ var normalizeDateTime = (date, includeSecond) => {
21
+ const normalized = new Date(date);
22
+ if (!includeSecond) normalized.setSeconds(0);
23
+ normalized.setMilliseconds(0);
24
+ return normalized;
25
+ };
26
+ var getTimeParts = (date) => ({
27
+ hour: date.getHours(),
28
+ minute: date.getMinutes(),
29
+ second: date.getSeconds()
30
+ });
31
+ var composeDateTime = (date, time, includeSecond) => {
32
+ const next = new Date(date);
33
+ next.setHours(time.hour, time.minute, includeSecond ? time.second : 0, 0);
34
+ return next;
35
+ };
36
+ var composeTime = (base, key, value) => ({
37
+ hour: key === "hour" ? value : base.hour,
38
+ minute: key === "minute" ? value : base.minute,
39
+ second: key === "second" ? value : base.second
40
+ });
41
+ var byDistanceFrom = (preferred) => (a, b) => Math.abs(a - preferred) - Math.abs(b - preferred) || a - b;
42
+ var buildOptions = (max, step, selected) => {
43
+ const safeStep = clampStep(step);
44
+ const values = [];
45
+ for (let value = 0; value <= max; value += safeStep) {
46
+ values.push(value);
47
+ }
48
+ if (selected != null && !values.includes(selected)) {
49
+ values.push(selected);
50
+ values.sort((a, b) => a - b);
51
+ }
52
+ return values;
53
+ };
54
+ var formatDateTime = (date, format, includeSecond) => {
55
+ if (!isValidDate(date)) return "";
56
+ if (typeof format === "function") return format(date);
57
+ const year = String(date.getFullYear());
58
+ const month = pad(date.getMonth() + 1);
59
+ const day = pad(date.getDate());
60
+ const base = `${year}-${month}-${day} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
61
+ return includeSecond ? `${base}:${pad(date.getSeconds())}` : base;
62
+ };
63
+ var parseDateTimeInput = (input, includeSecond) => {
64
+ const text = input.trim();
65
+ if (!text) return null;
66
+ const match = text.match(
67
+ /^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?(?:\s+|T)(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?$/
68
+ );
69
+ if (!match) return null;
70
+ const year = Number(match[1]);
71
+ const month = Number(match[2]);
72
+ const day = Number(match[3]);
73
+ const hour = Number(match[4]);
74
+ const minute = Number(match[5]);
75
+ const second = match[6] == null || !includeSecond ? 0 : Number(match[6]);
76
+ if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) {
77
+ return null;
78
+ }
79
+ const date = new Date(year, month - 1, day, hour, minute, second, 0);
80
+ if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
81
+ return null;
82
+ }
83
+ return date;
84
+ };
85
+ var getNow = (includeSecond) => normalizeDateTime(/* @__PURE__ */ new Date(), includeSecond);
86
+ var DateTimePicker = React.forwardRef(
87
+ ({
88
+ value,
89
+ defaultValue = null,
90
+ onChange,
91
+ format = "YYYY-MM-DD HH:mm",
92
+ showSecond,
93
+ placeholder = "\u8BF7\u9009\u62E9\u65E5\u671F\u65F6\u95F4",
94
+ disabled,
95
+ readOnly,
96
+ invalid,
97
+ size = "md",
98
+ allowClear,
99
+ hourStep = 1,
100
+ minuteStep = 1,
101
+ secondStep = 1,
102
+ min,
103
+ max,
104
+ disabledDate,
105
+ disabledTime,
106
+ placement = "bottom",
107
+ open: openProp,
108
+ defaultOpen = false,
109
+ onOpenChange,
110
+ popupClassName = "",
111
+ dropdownClassName = "",
112
+ className = "",
113
+ onKeyDown,
114
+ ...rest
115
+ }, ref) => {
116
+ const includeSecond = showSecond ?? format === "YYYY-MM-DD HH:mm:ss";
117
+ const controlled = value !== void 0;
118
+ const initial = isValidDate(defaultValue) ? normalizeDateTime(defaultValue, includeSecond) : null;
119
+ const [inner, setInner] = React.useState(initial);
120
+ const current = controlled ? isValidDate(value) ? normalizeDateTime(value, includeSecond) : null : inner;
121
+ const currentTime = current?.getTime() ?? null;
122
+ const formattedCurrent = React.useMemo(
123
+ () => currentTime == null ? "" : formatDateTime(new Date(currentTime), format, includeSecond),
124
+ [currentTime, format, includeSecond]
125
+ );
126
+ const scrollSignature = currentTime == null ? "" : String(currentTime);
127
+ const [draft, setDraft] = React.useState(formattedCurrent);
128
+ React.useEffect(() => {
129
+ setDraft(formattedCurrent);
130
+ }, [formattedCurrent]);
131
+ const openControlled = openProp !== void 0;
132
+ const [innerOpen, setInnerOpen] = React.useState(defaultOpen);
133
+ const open = openControlled ? !!openProp : innerOpen;
134
+ const [compactPanel, setCompactPanel] = React.useState(false);
135
+ const [calendarViewDate, setCalendarViewDate] = React.useState(null);
136
+ const wasOpenRef = React.useRef(false);
137
+ const scrollSignatureRef = React.useRef(null);
138
+ const scrollFramesRef = React.useRef(/* @__PURE__ */ new Map());
139
+ const setOpen = React.useCallback(
140
+ (next) => {
141
+ if (disabled || readOnly) return;
142
+ if (!openControlled) setInnerOpen(next);
143
+ onOpenChange?.(next);
144
+ },
145
+ [disabled, onOpenChange, openControlled, readOnly]
146
+ );
147
+ const rootRef = React.useRef(null);
148
+ const panelRef = React.useRef(null);
149
+ const { triggerRef, floatingStyle } = useFloating({
150
+ open,
151
+ placement,
152
+ panelWidth: compactPanel ? 332 : 476,
153
+ panelHeight: compactPanel ? includeSecond ? 492 : 468 : 328
154
+ });
155
+ const setRootRef = React.useCallback(
156
+ (node) => {
157
+ rootRef.current = node;
158
+ triggerRef.current = node;
159
+ if (typeof ref === "function") ref(node);
160
+ else if (ref) ref.current = node;
161
+ },
162
+ [ref, triggerRef]
163
+ );
164
+ React.useEffect(() => {
165
+ if (typeof window === "undefined") return;
166
+ const media = window.matchMedia("(max-width: 640px)");
167
+ const update = () => setCompactPanel(media.matches);
168
+ update();
169
+ media.addEventListener?.("change", update);
170
+ return () => media.removeEventListener?.("change", update);
171
+ }, []);
172
+ const normalizedMin = React.useMemo(
173
+ () => isValidDate(min) ? normalizeDateTime(min, includeSecond) : void 0,
174
+ [includeSecond, min]
175
+ );
176
+ const normalizedMax = React.useMemo(
177
+ () => isValidDate(max) ? normalizeDateTime(max, includeSecond) : void 0,
178
+ [includeSecond, max]
179
+ );
180
+ const isDisabledDay = React.useCallback(
181
+ (date) => {
182
+ const day = startOfDay(date);
183
+ if (normalizedMin && day < startOfDay(normalizedMin)) return true;
184
+ if (normalizedMax && day > startOfDay(normalizedMax)) return true;
185
+ return disabledDate?.(day) ?? false;
186
+ },
187
+ [disabledDate, normalizedMax, normalizedMin]
188
+ );
189
+ const isDisabledDateTime = React.useCallback(
190
+ (date) => {
191
+ const normalized = normalizeDateTime(date, includeSecond);
192
+ if (isDisabledDay(normalized)) return true;
193
+ if (normalizedMin && normalized < normalizedMin) return true;
194
+ if (normalizedMax && normalized > normalizedMax) return true;
195
+ return disabledTime?.(getTimeParts(normalized), startOfDay(normalized)) ?? false;
196
+ },
197
+ [disabledTime, includeSecond, isDisabledDay, normalizedMax, normalizedMin]
198
+ );
199
+ const commit = React.useCallback(
200
+ (next, close = false) => {
201
+ if (!next) {
202
+ if (!controlled) setInner(null);
203
+ setDraft("");
204
+ onChange?.(null, "");
205
+ if (close) setOpen(false);
206
+ return;
207
+ }
208
+ const normalized = normalizeDateTime(next, includeSecond);
209
+ if (isDisabledDateTime(normalized)) return;
210
+ if (!controlled) setInner(normalized);
211
+ const nextString = formatDateTime(normalized, format, includeSecond);
212
+ setDraft(nextString);
213
+ onChange?.(normalized, nextString);
214
+ if (close) setOpen(false);
215
+ },
216
+ [controlled, format, includeSecond, isDisabledDateTime, onChange, setOpen]
217
+ );
218
+ React.useEffect(() => {
219
+ if (!open) return;
220
+ const onDown = (event) => {
221
+ const target = event.target;
222
+ if (rootRef.current?.contains(target)) return;
223
+ if (panelRef.current?.contains(target)) return;
224
+ setOpen(false);
225
+ };
226
+ const onDocKey = (event) => {
227
+ if (event.key === "Escape") setOpen(false);
228
+ };
229
+ document.addEventListener("mousedown", onDown);
230
+ document.addEventListener("keydown", onDocKey);
231
+ return () => {
232
+ document.removeEventListener("mousedown", onDown);
233
+ document.removeEventListener("keydown", onDocKey);
234
+ };
235
+ }, [open, setOpen]);
236
+ const scrollListTo = React.useCallback(
237
+ (list, top, animate) => {
238
+ const frame = scrollFramesRef.current.get(list);
239
+ if (frame != null) cancelAnimationFrame(frame);
240
+ if (!animate) {
241
+ list.scrollTop = top;
242
+ return;
243
+ }
244
+ const start = list.scrollTop;
245
+ const distance = top - start;
246
+ if (Math.abs(distance) < 1) {
247
+ list.scrollTop = top;
248
+ return;
249
+ }
250
+ const startedAt = performance.now();
251
+ const duration = 180;
252
+ const tick = (now) => {
253
+ const progress = Math.min((now - startedAt) / duration, 1);
254
+ const eased = 1 - Math.pow(1 - progress, 3);
255
+ list.scrollTop = start + distance * eased;
256
+ if (progress < 1) {
257
+ scrollFramesRef.current.set(list, requestAnimationFrame(tick));
258
+ return;
259
+ }
260
+ scrollFramesRef.current.delete(list);
261
+ list.scrollTop = top;
262
+ };
263
+ scrollFramesRef.current.set(list, requestAnimationFrame(tick));
264
+ },
265
+ []
266
+ );
267
+ React.useEffect(() => {
268
+ if (!open) return;
269
+ const shouldAnimate = wasOpenRef.current && scrollSignatureRef.current != null && scrollSignatureRef.current !== scrollSignature;
270
+ requestAnimationFrame(() => {
271
+ panelRef.current?.querySelectorAll(".date-time-picker-time-list").forEach((list) => {
272
+ const selected = list.querySelector(".date-time-picker-time-option.selected");
273
+ if (!selected) return;
274
+ const top = selected.offsetTop - list.offsetTop - list.clientHeight / 2 + selected.offsetHeight / 2;
275
+ scrollListTo(list, top, shouldAnimate);
276
+ });
277
+ });
278
+ wasOpenRef.current = open;
279
+ scrollSignatureRef.current = scrollSignature;
280
+ }, [open, scrollListTo, scrollSignature]);
281
+ React.useEffect(() => {
282
+ if (open) return;
283
+ wasOpenRef.current = false;
284
+ scrollSignatureRef.current = null;
285
+ setCalendarViewDate(null);
286
+ }, [open]);
287
+ React.useEffect(
288
+ () => () => {
289
+ scrollFramesRef.current.forEach((frame) => cancelAnimationFrame(frame));
290
+ scrollFramesRef.current.clear();
291
+ },
292
+ []
293
+ );
294
+ const panelBase = current ?? getNow(includeSecond);
295
+ const selectedDay = startOfDay(panelBase);
296
+ const timeParts = getTimeParts(panelBase);
297
+ const hourOptions = buildOptions(23, hourStep, timeParts.hour);
298
+ const minuteOptions = buildOptions(59, minuteStep, timeParts.minute);
299
+ const secondOptions = buildOptions(59, secondStep, timeParts.second);
300
+ const findAvailableTime = (key, value2) => {
301
+ const preferred = composeTime(timeParts, key, value2);
302
+ if (!isDisabledDateTime(composeDateTime(selectedDay, preferred, includeSecond))) {
303
+ return preferred;
304
+ }
305
+ const hours = key === "hour" ? [value2] : [...hourOptions].sort(byDistanceFrom(timeParts.hour));
306
+ const minutes = key === "minute" ? [value2] : [...minuteOptions].sort(byDistanceFrom(timeParts.minute));
307
+ const seconds = key === "second" ? [value2] : includeSecond ? [...secondOptions].sort(byDistanceFrom(timeParts.second)) : [0];
308
+ for (const hour of hours) {
309
+ for (const minute of minutes) {
310
+ for (const second of seconds) {
311
+ const candidate = { hour, minute, second };
312
+ if (!isDisabledDateTime(composeDateTime(selectedDay, candidate, includeSecond))) {
313
+ return candidate;
314
+ }
315
+ }
316
+ }
317
+ }
318
+ return null;
319
+ };
320
+ const handleDatePick = (date) => {
321
+ const next = composeDateTime(date, timeParts, includeSecond);
322
+ if (normalizedMin && isSameDay(next, normalizedMin) && next < normalizedMin) {
323
+ commit(normalizedMin);
324
+ return;
325
+ }
326
+ if (normalizedMax && isSameDay(next, normalizedMax) && next > normalizedMax) {
327
+ commit(normalizedMax);
328
+ return;
329
+ }
330
+ commit(next);
331
+ };
332
+ const pickTime = (key, nextValue) => {
333
+ const nextTime = findAvailableTime(key, nextValue);
334
+ if (nextTime) commit(composeDateTime(selectedDay, nextTime, includeSecond));
335
+ };
336
+ const handleInputChange = (next) => {
337
+ setDraft(next);
338
+ if (next.trim() === "") commit(null);
339
+ };
340
+ const handleInputBlur = () => {
341
+ if (!draft.trim()) {
342
+ setDraft(formatDateTime(current, format, includeSecond));
343
+ return;
344
+ }
345
+ if (typeof format === "function") {
346
+ setDraft(formatDateTime(current, format, includeSecond));
347
+ return;
348
+ }
349
+ const parsed = parseDateTimeInput(draft, includeSecond);
350
+ if (!parsed || isDisabledDateTime(parsed)) {
351
+ setDraft(formatDateTime(current, format, includeSecond));
352
+ return;
353
+ }
354
+ commit(parsed);
355
+ };
356
+ const handleRootKeyDown = (event) => {
357
+ onKeyDown?.(event);
358
+ if (event.defaultPrevented) return;
359
+ if ((event.key === "ArrowDown" || event.key === "Enter") && !open) {
360
+ event.preventDefault();
361
+ setOpen(true);
362
+ }
363
+ if (event.key === "Escape" && open) {
364
+ event.preventDefault();
365
+ setOpen(false);
366
+ }
367
+ };
368
+ const renderTimeColumn = (label, key, options) => /* @__PURE__ */ jsxs("div", { className: "date-time-picker-time-column", children: [
369
+ /* @__PURE__ */ jsx("div", { className: "date-time-picker-time-label", children: label }),
370
+ /* @__PURE__ */ jsx("div", { className: "date-time-picker-time-list", role: "listbox", "aria-label": label, children: options.map((option) => {
371
+ const selected = timeParts[key] === option;
372
+ const optionDisabled = findAvailableTime(key, option) == null;
373
+ return /* @__PURE__ */ jsx(
374
+ "button",
375
+ {
376
+ type: "button",
377
+ role: "option",
378
+ "aria-selected": selected,
379
+ disabled: optionDisabled,
380
+ className: `date-time-picker-time-option ${selected ? "selected" : ""}`,
381
+ onClick: () => pickTime(key, option),
382
+ children: pad(option)
383
+ },
384
+ option
385
+ );
386
+ }) })
387
+ ] });
388
+ const today = getNow(includeSecond);
389
+ const mergedPanelClassName = [popupClassName, dropdownClassName].filter(Boolean).join(" ");
390
+ const rootClassName = [
391
+ "date-time-picker",
392
+ size,
393
+ open && "open",
394
+ disabled && "disabled",
395
+ readOnly && "readonly",
396
+ invalid && "invalid",
397
+ className
398
+ ].filter(Boolean).join(" ");
399
+ return /* @__PURE__ */ jsxs("div", { ref: setRootRef, className: rootClassName, onKeyDown: handleRootKeyDown, ...rest, children: [
400
+ /* @__PURE__ */ jsx(
401
+ Input,
402
+ {
403
+ value: draft,
404
+ size,
405
+ placeholder,
406
+ disabled,
407
+ readOnly,
408
+ invalid,
409
+ allowClear,
410
+ leadingIcon: "calendar",
411
+ onFocus: () => setOpen(true),
412
+ onClick: () => setOpen(true),
413
+ onValueChange: handleInputChange,
414
+ onBlur: handleInputBlur,
415
+ inputMode: "numeric",
416
+ "aria-expanded": open,
417
+ "aria-haspopup": "dialog"
418
+ }
419
+ ),
420
+ open && !disabled && !readOnly && typeof document !== "undefined" && createPortal(
421
+ /* @__PURE__ */ jsxs(
422
+ "div",
423
+ {
424
+ ref: panelRef,
425
+ className: `date-time-picker-panel ${includeSecond ? "with-second" : "without-second"} ${mergedPanelClassName}`,
426
+ role: "dialog",
427
+ style: floatingStyle,
428
+ children: [
429
+ /* @__PURE__ */ jsxs("div", { className: "date-time-picker-body", children: [
430
+ /* @__PURE__ */ jsx(
431
+ Calendar,
432
+ {
433
+ value: selectedDay,
434
+ viewDate: calendarViewDate ?? void 0,
435
+ min: normalizedMin ? startOfDay(normalizedMin) : void 0,
436
+ max: normalizedMax ? startOfDay(normalizedMax) : void 0,
437
+ disabledDate: isDisabledDay,
438
+ onChange: handleDatePick
439
+ }
440
+ ),
441
+ /* @__PURE__ */ jsx("div", { className: "date-time-picker-time", children: /* @__PURE__ */ jsxs("div", { className: "date-time-picker-time-columns", children: [
442
+ renderTimeColumn("\u65F6", "hour", hourOptions),
443
+ renderTimeColumn("\u5206", "minute", minuteOptions),
444
+ includeSecond && renderTimeColumn("\u79D2", "second", secondOptions)
445
+ ] }) })
446
+ ] }),
447
+ /* @__PURE__ */ jsxs("div", { className: "date-time-picker-footer", children: [
448
+ /* @__PURE__ */ jsx(
449
+ Button,
450
+ {
451
+ size: "sm",
452
+ variant: "ghost",
453
+ disabled: isDisabledDateTime(today),
454
+ onClick: () => {
455
+ setCalendarViewDate(today);
456
+ commit(today);
457
+ },
458
+ children: "\u73B0\u5728"
459
+ }
460
+ ),
461
+ /* @__PURE__ */ jsx("span", { className: "date-time-picker-footer-spacer" }),
462
+ allowClear && /* @__PURE__ */ jsx(
463
+ Button,
464
+ {
465
+ size: "sm",
466
+ variant: "ghost",
467
+ onClick: () => commit(null, true),
468
+ children: "\u6E05\u7A7A"
469
+ }
470
+ ),
471
+ /* @__PURE__ */ jsx(Button, { size: "sm", variant: "primary", onClick: () => setOpen(false), children: "\u786E\u5B9A" })
472
+ ] })
473
+ ]
474
+ }
475
+ ),
476
+ document.body
477
+ )
478
+ ] });
479
+ }
480
+ );
481
+ DateTimePicker.displayName = "DateTimePicker";
482
+
483
+ export { DateTimePicker };