@expcat/tigercat-react 1.3.3 → 1.4.0

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 (248) hide show
  1. package/dist/{chunk-3SV6J7I5.mjs → chunk-2L7QEOFD.mjs} +34 -25
  2. package/dist/{chunk-FNJDBFKM.mjs → chunk-2LYV6NBJ.mjs} +6 -1
  3. package/dist/{chunk-EEWHWEYO.js → chunk-2RBHQBSG.js} +2 -2
  4. package/dist/{chunk-Y5RQN5BO.mjs → chunk-376X7SDZ.mjs} +2 -2
  5. package/dist/{chunk-UXUYCWQC.js → chunk-3EDASNTG.js} +5 -5
  6. package/dist/{chunk-NPTXXUXF.mjs → chunk-3RBRWBUG.mjs} +9 -7
  7. package/dist/{chunk-PUZDW7NR.js → chunk-4AMSYFYC.js} +134 -20
  8. package/dist/{chunk-IG75YSX3.mjs → chunk-4MONGWU5.mjs} +4 -6
  9. package/dist/{chunk-3CJFNG54.mjs → chunk-56CTXEJS.mjs} +1 -1
  10. package/dist/{chunk-TMON4MPO.js → chunk-5ALMTE35.js} +9 -7
  11. package/dist/{chunk-MSHCPJIJ.mjs → chunk-6BOSSZM3.mjs} +8 -9
  12. package/dist/{chunk-SIY6FDKJ.js → chunk-7CHTTM6D.js} +339 -314
  13. package/dist/{chunk-RF2BA2N6.js → chunk-7PXALKLM.js} +4 -4
  14. package/dist/{chunk-DLKUDB2R.js → chunk-AF2AEZKM.js} +15 -3
  15. package/dist/{chunk-FB34UWF7.mjs → chunk-AVLIUHOS.mjs} +101 -40
  16. package/dist/{chunk-TSJYAEFZ.js → chunk-B63GEB2Y.js} +358 -305
  17. package/dist/{chunk-CFPKK5WW.js → chunk-BA6TJQZL.js} +12 -12
  18. package/dist/{chunk-LMTUM3J3.js → chunk-BEM7XG2L.js} +2 -4
  19. package/dist/{chunk-MB6U72CI.js → chunk-BEZO5IE4.js} +2 -2
  20. package/dist/{chunk-5OHVTGHS.mjs → chunk-BN4ZKCAI.mjs} +368 -315
  21. package/dist/{chunk-UHFHOTNI.js → chunk-BRA3PO53.js} +6 -7
  22. package/dist/{chunk-M7HBWFQO.js → chunk-BROIZ266.js} +11 -1
  23. package/dist/{chunk-SDZOVRVR.mjs → chunk-CAQPYJFA.mjs} +350 -325
  24. package/dist/{chunk-BFAZZUD6.js → chunk-CC5GFX6F.js} +5 -22
  25. package/dist/{chunk-LQT6ZGME.mjs → chunk-CME2IFUT.mjs} +15 -3
  26. package/dist/{chunk-KQ5I7PRM.js → chunk-CNNEUJR2.js} +28 -14
  27. package/dist/{chunk-EF5ZTNHX.js → chunk-D5MQBUP2.js} +16 -4
  28. package/dist/{chunk-RQXY2MGX.mjs → chunk-D7UR526A.mjs} +231 -184
  29. package/dist/{chunk-CBYJXDW4.js → chunk-DBMC6FPU.js} +16 -4
  30. package/dist/{chunk-WQ4FOHOU.mjs → chunk-DEIVWO2D.mjs} +3 -5
  31. package/dist/{chunk-7QZ4XT2P.mjs → chunk-DVEK5SO6.mjs} +3 -8
  32. package/dist/{chunk-TC6JLEGZ.js → chunk-EJKOUI26.js} +24 -7
  33. package/dist/{chunk-4GITZKAH.mjs → chunk-EPJ6W4VI.mjs} +14 -2
  34. package/dist/{chunk-KYP7U6FK.js → chunk-FZHBVHQ6.js} +34 -25
  35. package/dist/{chunk-WVVXZKNI.js → chunk-GDPU5MYA.js} +3 -8
  36. package/dist/{chunk-2GQCFTD7.mjs → chunk-H4MPPCTB.mjs} +23 -4
  37. package/dist/{chunk-YOAYDEWW.mjs → chunk-HHMYERHY.mjs} +3 -20
  38. package/dist/{chunk-LRPPXU74.mjs → chunk-I7FEGKX2.mjs} +19 -5
  39. package/dist/{chunk-F6IXIH6B.mjs → chunk-IZGXDHPB.mjs} +24 -5
  40. package/dist/{chunk-GQFVVAEF.js → chunk-J6OZWT3P.js} +5 -5
  41. package/dist/{chunk-IGAMV6ML.mjs → chunk-KDXKF6B2.mjs} +1 -1
  42. package/dist/{chunk-A42OLED6.mjs → chunk-KED5S2WG.mjs} +13 -2
  43. package/dist/{chunk-BJQIYELW.mjs → chunk-KGMVRIYC.mjs} +5 -5
  44. package/dist/{chunk-6GYT3EZD.mjs → chunk-KXT2TP6A.mjs} +3 -4
  45. package/dist/{chunk-BBLVRLXT.js → chunk-KYNWNTGO.js} +230 -146
  46. package/dist/{chunk-M73NMNZX.js → chunk-L24PPXLV.js} +17 -5
  47. package/dist/chunk-L3WPA2RP.js +25 -0
  48. package/dist/{chunk-V4JIZN3E.mjs → chunk-L6KSO66F.mjs} +4 -12
  49. package/dist/{chunk-4LX5UGPQ.js → chunk-LJRCEB7F.js} +168 -121
  50. package/dist/{chunk-F7H4ALKN.js → chunk-LZG24TDB.js} +8 -9
  51. package/dist/{chunk-ZYJTHGQW.js → chunk-M3FVPPMM.js} +9 -13
  52. package/dist/{chunk-GN3TSQWW.mjs → chunk-M6YXUNOU.mjs} +2 -2
  53. package/dist/{chunk-I373B74W.js → chunk-MC26ORSN.js} +102 -41
  54. package/dist/{chunk-5HFHHFQS.mjs → chunk-MTIGGMHG.mjs} +17 -5
  55. package/dist/{chunk-DKT2EYVM.mjs → chunk-MV2JQ6XQ.mjs} +3 -6
  56. package/dist/{chunk-HR5GBE3P.js → chunk-NDGA3N6H.js} +19 -7
  57. package/dist/{chunk-BO6QGXMN.mjs → chunk-NEZ445D4.mjs} +9 -9
  58. package/dist/{chunk-4U5HSR2H.js → chunk-NVI2P7VH.js} +3 -4
  59. package/dist/{chunk-NVEIVIAW.mjs → chunk-OFRKYQOZ.mjs} +133 -19
  60. package/dist/{chunk-AW5M3EL4.js → chunk-OS6M3IZF.js} +62 -12
  61. package/dist/{chunk-3ZNZLGQO.mjs → chunk-OXQOKKTP.mjs} +6 -7
  62. package/dist/{chunk-NMEVQPOD.js → chunk-PHAJXRGE.js} +2 -4
  63. package/dist/{chunk-WG3YS2QV.js → chunk-PT5T5F4H.js} +13 -2
  64. package/dist/{chunk-WNLUUD5N.mjs → chunk-QIL24WZD.mjs} +8 -12
  65. package/dist/{chunk-ZFMMAYSX.js → chunk-QLATA4UB.js} +4 -6
  66. package/dist/{chunk-KIYNHQGW.mjs → chunk-RVLV63SI.mjs} +41 -20
  67. package/dist/{chunk-3QPCQH62.mjs → chunk-RYNLPRUM.mjs} +1 -1
  68. package/dist/{chunk-6GIJ7NFV.mjs → chunk-SDZKL3IB.mjs} +3 -5
  69. package/dist/{chunk-G5USITWF.js → chunk-SH4BZYXO.js} +27 -8
  70. package/dist/{chunk-L5AMVEQL.mjs → chunk-SLEXEH7R.mjs} +60 -10
  71. package/dist/{chunk-JLRRXRZO.js → chunk-SQONS5PH.js} +4 -7
  72. package/dist/chunk-SQTOVSDU.mjs +692 -0
  73. package/dist/{chunk-3ZQMHXRY.js → chunk-TEYL5X56.js} +39 -18
  74. package/dist/{chunk-KGSDDVRC.mjs → chunk-TNTOSFGN.mjs} +4 -4
  75. package/dist/{chunk-CY5GRTAX.js → chunk-UAM3RQY4.js} +24 -5
  76. package/dist/{chunk-XRNKHQTL.js → chunk-UEAXYZSE.js} +3 -2
  77. package/dist/{chunk-7ISEWLA3.js → chunk-UKQMF3JV.js} +21 -6
  78. package/dist/{chunk-ITVLIR7T.mjs → chunk-ULWT6W6M.mjs} +13 -20
  79. package/dist/{chunk-M5GSLKUX.mjs → chunk-VAIWWELW.mjs} +15 -3
  80. package/dist/{chunk-4SO4LANY.js → chunk-VC26SAXB.js} +340 -274
  81. package/dist/{chunk-SKMZTW3K.js → chunk-WCTNQYXO.js} +16 -23
  82. package/dist/{chunk-KXNWY2Q7.mjs → chunk-WFWEMXO7.mjs} +241 -157
  83. package/dist/chunk-WHYHLUXG.mjs +25 -0
  84. package/dist/{chunk-ONTRGV5T.js → chunk-WZUADPYB.js} +6 -14
  85. package/dist/{chunk-N4PP3ENO.js → chunk-XTQUPDRI.js} +2 -2
  86. package/dist/{chunk-XATXFVKR.mjs → chunk-Y7K27DVV.mjs} +4 -3
  87. package/dist/{chunk-WI4N5DD3.mjs → chunk-YH57D4AV.mjs} +16 -4
  88. package/dist/{chunk-3MRP3XYI.js → chunk-YRVAF2ID.js} +7 -2
  89. package/dist/{chunk-5XE5VBDS.mjs → chunk-YSGM22AH.mjs} +11 -1
  90. package/dist/{chunk-6TR7JB6C.js → chunk-ZDNQGS4O.js} +4 -4
  91. package/dist/{chunk-CHBUNQIJ.mjs → chunk-ZQSMJS2Q.mjs} +23 -6
  92. package/dist/{chunk-QQFLRNI3.mjs → chunk-ZRZB3C5J.mjs} +18 -3
  93. package/dist/components/ActivityFeed.js +4 -3
  94. package/dist/components/ActivityFeed.mjs +3 -2
  95. package/dist/components/Cascader.d.mts +3 -1
  96. package/dist/components/Cascader.d.ts +3 -1
  97. package/dist/components/Cascader.js +3 -2
  98. package/dist/components/Cascader.mjs +2 -1
  99. package/dist/components/ChatWindow.js +5 -5
  100. package/dist/components/ChatWindow.mjs +4 -4
  101. package/dist/components/Checkbox.js +4 -4
  102. package/dist/components/Checkbox.mjs +3 -3
  103. package/dist/components/CheckboxGroup.js +3 -3
  104. package/dist/components/CheckboxGroup.mjs +2 -2
  105. package/dist/components/CommentThread.js +4 -4
  106. package/dist/components/CommentThread.mjs +3 -3
  107. package/dist/components/CropUpload.js +4 -4
  108. package/dist/components/CropUpload.mjs +3 -3
  109. package/dist/components/DataTableWithToolbar.d.mts +2 -2
  110. package/dist/components/DataTableWithToolbar.d.ts +2 -2
  111. package/dist/components/DataTableWithToolbar.js +11 -11
  112. package/dist/components/DataTableWithToolbar.mjs +10 -10
  113. package/dist/components/DatePicker.d.mts +1 -0
  114. package/dist/components/DatePicker.d.ts +1 -0
  115. package/dist/components/DatePicker.js +3 -2
  116. package/dist/components/DatePicker.mjs +2 -1
  117. package/dist/components/Drawer.js +3 -3
  118. package/dist/components/Drawer.mjs +2 -2
  119. package/dist/components/FileManager.d.mts +2 -1
  120. package/dist/components/FileManager.d.ts +2 -1
  121. package/dist/components/FileManager.js +3 -2
  122. package/dist/components/FileManager.mjs +2 -1
  123. package/dist/components/Form.js +3 -2
  124. package/dist/components/Form.mjs +2 -1
  125. package/dist/components/FormItem.js +4 -3
  126. package/dist/components/FormItem.mjs +3 -2
  127. package/dist/components/FormWizard.js +4 -4
  128. package/dist/components/FormWizard.mjs +3 -3
  129. package/dist/components/Image.js +4 -4
  130. package/dist/components/Image.mjs +3 -3
  131. package/dist/components/ImageGroup.js +3 -3
  132. package/dist/components/ImageGroup.mjs +2 -2
  133. package/dist/components/ImagePreview.js +2 -2
  134. package/dist/components/ImagePreview.mjs +1 -1
  135. package/dist/components/ImageViewer.d.mts +1 -1
  136. package/dist/components/ImageViewer.d.ts +1 -1
  137. package/dist/components/ImageViewer.js +2 -2
  138. package/dist/components/ImageViewer.mjs +1 -1
  139. package/dist/components/InfiniteScroll.d.mts +2 -0
  140. package/dist/components/InfiniteScroll.d.ts +2 -0
  141. package/dist/components/InfiniteScroll.js +3 -2
  142. package/dist/components/InfiniteScroll.mjs +2 -1
  143. package/dist/components/Input.js +3 -2
  144. package/dist/components/Input.mjs +2 -1
  145. package/dist/components/InputNumber.js +3 -2
  146. package/dist/components/InputNumber.mjs +2 -1
  147. package/dist/components/List.d.mts +6 -2
  148. package/dist/components/List.d.ts +6 -2
  149. package/dist/components/List.js +3 -2
  150. package/dist/components/List.mjs +2 -1
  151. package/dist/components/Loading.js +3 -2
  152. package/dist/components/Loading.mjs +2 -1
  153. package/dist/components/MarkdownEditor.js +3 -3
  154. package/dist/components/MarkdownEditor.mjs +2 -2
  155. package/dist/components/Mentions.js +2 -2
  156. package/dist/components/Mentions.mjs +1 -1
  157. package/dist/components/Menu.d.mts +8 -80
  158. package/dist/components/Menu.d.ts +8 -80
  159. package/dist/components/Menu.js +2 -2
  160. package/dist/components/Menu.mjs +1 -1
  161. package/dist/components/MenuItem.d.mts +6 -2
  162. package/dist/components/MenuItem.d.ts +6 -2
  163. package/dist/components/MenuItem.js +2 -2
  164. package/dist/components/MenuItem.mjs +1 -1
  165. package/dist/components/MenuItemGroup.d.mts +6 -2
  166. package/dist/components/MenuItemGroup.d.ts +6 -2
  167. package/dist/components/MenuItemGroup.js +2 -2
  168. package/dist/components/MenuItemGroup.mjs +1 -1
  169. package/dist/components/Message.js +2 -2
  170. package/dist/components/Message.mjs +1 -1
  171. package/dist/components/Modal.js +3 -3
  172. package/dist/components/Modal.mjs +2 -2
  173. package/dist/components/Notification.js +2 -2
  174. package/dist/components/Notification.mjs +1 -1
  175. package/dist/components/NotificationCenter.js +5 -4
  176. package/dist/components/NotificationCenter.mjs +4 -3
  177. package/dist/components/NumberKeyboard.js +3 -2
  178. package/dist/components/NumberKeyboard.mjs +2 -1
  179. package/dist/components/Radio.js +4 -4
  180. package/dist/components/Radio.mjs +3 -3
  181. package/dist/components/RadioGroup.js +3 -3
  182. package/dist/components/RadioGroup.mjs +2 -2
  183. package/dist/components/RichTextEditor.js +3 -3
  184. package/dist/components/RichTextEditor.mjs +2 -2
  185. package/dist/components/Select.d.mts +3 -1
  186. package/dist/components/Select.d.ts +3 -1
  187. package/dist/components/Select.js +3 -2
  188. package/dist/components/Select.mjs +2 -1
  189. package/dist/components/Signature.d.mts +1 -0
  190. package/dist/components/Signature.d.ts +1 -0
  191. package/dist/components/Signature.js +3 -2
  192. package/dist/components/Signature.mjs +2 -1
  193. package/dist/components/Spotlight.js +4 -2
  194. package/dist/components/Spotlight.mjs +3 -1
  195. package/dist/components/Steps.js +2 -2
  196. package/dist/components/Steps.mjs +1 -1
  197. package/dist/components/StepsItem.js +2 -2
  198. package/dist/components/StepsItem.mjs +1 -1
  199. package/dist/components/SubMenu.d.mts +6 -2
  200. package/dist/components/SubMenu.d.ts +6 -2
  201. package/dist/components/SubMenu.js +2 -2
  202. package/dist/components/SubMenu.mjs +1 -1
  203. package/dist/components/Table.d.mts +2 -2
  204. package/dist/components/Table.d.ts +2 -2
  205. package/dist/components/Table.js +9 -9
  206. package/dist/components/Table.mjs +8 -8
  207. package/dist/components/Textarea.js +3 -3
  208. package/dist/components/Textarea.mjs +2 -2
  209. package/dist/components/TimePicker.d.mts +1 -0
  210. package/dist/components/TimePicker.d.ts +1 -0
  211. package/dist/components/TimePicker.js +4 -2
  212. package/dist/components/TimePicker.mjs +3 -1
  213. package/dist/components/Tour.js +3 -2
  214. package/dist/components/Tour.mjs +2 -1
  215. package/dist/components/Transfer.d.mts +3 -1
  216. package/dist/components/Transfer.d.ts +3 -1
  217. package/dist/components/Transfer.js +3 -2
  218. package/dist/components/Transfer.mjs +2 -1
  219. package/dist/components/Tree.d.mts +3 -1
  220. package/dist/components/Tree.d.ts +3 -1
  221. package/dist/components/Tree.js +3 -2
  222. package/dist/components/Tree.mjs +2 -1
  223. package/dist/components/TreeSelect.d.mts +3 -1
  224. package/dist/components/TreeSelect.d.ts +3 -1
  225. package/dist/components/TreeSelect.js +3 -2
  226. package/dist/components/TreeSelect.mjs +2 -1
  227. package/dist/components/Upload.js +3 -2
  228. package/dist/components/Upload.mjs +2 -1
  229. package/dist/components/VirtualTable.d.mts +3 -2
  230. package/dist/components/VirtualTable.d.ts +3 -2
  231. package/dist/components/VirtualTable.js +3 -2
  232. package/dist/components/VirtualTable.mjs +2 -1
  233. package/dist/index.d.mts +33 -7
  234. package/dist/index.d.ts +33 -7
  235. package/dist/index.js +54 -54
  236. package/dist/index.mjs +53 -53
  237. package/dist/{types-CHmCMNEM.d.ts → types-0oVwMXtR.d.mts} +1 -1
  238. package/dist/{types-CHmCMNEM.d.mts → types-0oVwMXtR.d.ts} +1 -1
  239. package/dist/types-DaC4a0Ny.d.mts +80 -0
  240. package/dist/types-DaC4a0Ny.d.ts +80 -0
  241. package/package.json +2 -2
  242. package/dist/chunk-UKGQ7256.js +0 -12
  243. package/dist/chunk-UQMPEMY7.mjs +0 -12
  244. package/dist/chunk-VNVGSPBI.mjs +0 -626
  245. package/dist/{chunk-OZD75CLT.js → chunk-ANBNSUSR.js} +3 -3
  246. package/dist/{chunk-I2AUOICV.mjs → chunk-M3MOSUZO.mjs} +3 -3
  247. package/dist/{chunk-UMZ3PMUJ.js → chunk-SXHCMZ6U.js} +2 -2
  248. package/dist/{chunk-BWDQZSAB.mjs → chunk-WTSG7QXK.mjs} +3 -3
@@ -0,0 +1,692 @@
1
+ import {
2
+ useControlledState
3
+ } from "./chunk-WHYHLUXG.mjs";
4
+ import {
5
+ useTigerConfig
6
+ } from "./chunk-QAIBQHIO.mjs";
7
+
8
+ // src/components/TimePicker.tsx
9
+ import {
10
+ timePickerInputWrapperClasses,
11
+ timePickerClearButtonClasses,
12
+ timePickerPanelClasses,
13
+ timePickerRangeHeaderClasses,
14
+ getTimePickerRangeTabButtonClasses,
15
+ timePickerFooterClasses,
16
+ timePickerFooterButtonClasses,
17
+ ClockIconPath,
18
+ TimePickerCloseIconPath
19
+ } from "@expcat/tigercat-core";
20
+
21
+ // src/components/TimePicker/state.ts
22
+ import { useState, useMemo, useRef, useEffect, useCallback } from "react";
23
+ import {
24
+ classNames,
25
+ parseTime,
26
+ formatTime,
27
+ formatTimeDisplayWithLocale,
28
+ getTimePeriodLabels,
29
+ getTimePickerLabels,
30
+ mergeTigerLocale,
31
+ to12HourFormat,
32
+ to24HourFormat,
33
+ isTimeInRange,
34
+ generateHours,
35
+ generateMinutes,
36
+ generateSeconds,
37
+ getCurrentTime,
38
+ timePickerBaseClasses,
39
+ getTimePickerInputClasses,
40
+ getTimePickerIconButtonClasses,
41
+ focusTimePickerOption
42
+ } from "@expcat/tigercat-core";
43
+ function useTimePickerState(allProps) {
44
+ const config = useTigerConfig();
45
+ const {
46
+ size = "md",
47
+ format = "24",
48
+ showSeconds = false,
49
+ hourStep = 1,
50
+ minuteStep = 1,
51
+ secondStep = 1,
52
+ disabled = false,
53
+ readonly = false,
54
+ required = false,
55
+ minTime,
56
+ maxTime,
57
+ clearable = true,
58
+ name,
59
+ id,
60
+ className,
61
+ onClear,
62
+ locale,
63
+ labels: labelsOverrides,
64
+ value,
65
+ defaultValue,
66
+ range,
67
+ ...restProps
68
+ } = allProps;
69
+ const divProps = (({ onChange: _omitOnChange, ...rest }) => rest)(restProps);
70
+ const isRangeMode = range === true;
71
+ const [isOpen, setIsOpen] = useState(false);
72
+ const normalizeRangeValue = (input) => {
73
+ if (Array.isArray(input)) return [input[0] ?? null, input[1] ?? null];
74
+ return [null, null];
75
+ };
76
+ const singleControlled = !isRangeMode && value !== void 0 && (typeof value === "string" || value === null) ? value : void 0;
77
+ const singleDefault = (() => {
78
+ const dv = defaultValue;
79
+ if (typeof dv === "string" || dv === null || dv === void 0) return dv ?? null;
80
+ return null;
81
+ })();
82
+ const [singleValue, setSingleValue] = useControlledState(
83
+ singleControlled,
84
+ singleDefault,
85
+ allProps.onChange
86
+ );
87
+ const [rangeValue, setRangeValue] = useControlledState(
88
+ isRangeMode && value !== void 0 ? normalizeRangeValue(value) : void 0,
89
+ normalizeRangeValue(defaultValue),
90
+ allProps.onChange
91
+ );
92
+ const [activePart, setActivePart] = useState("start");
93
+ const panelRef = useRef(null);
94
+ const inputWrapperRef = useRef(null);
95
+ const inputRef = useRef(null);
96
+ const currentSingleValue = isRangeMode ? null : singleValue;
97
+ const currentRangeValue = isRangeMode ? rangeValue : [null, null];
98
+ const activeValue = isRangeMode ? currentRangeValue[activePart === "start" ? 0 : 1] : currentSingleValue;
99
+ const parsedTime = parseTime(activeValue);
100
+ const [selectedHours, setSelectedHours] = useState(parsedTime?.hours ?? 0);
101
+ const [selectedMinutes, setSelectedMinutes] = useState(parsedTime?.minutes ?? 0);
102
+ const [selectedSeconds, setSelectedSeconds] = useState(parsedTime?.seconds ?? 0);
103
+ const [selectedPeriod, setSelectedPeriod] = useState("AM");
104
+ const localeOverride = useMemo(() => typeof locale === "string" ? { locale } : locale, [locale]);
105
+ const mergedLocale = useMemo(
106
+ () => mergeTigerLocale(config.locale, localeOverride),
107
+ [config.locale, localeOverride]
108
+ );
109
+ const localeCode = mergedLocale?.locale;
110
+ const syncFromActiveValue = useCallback(() => {
111
+ const parsed = parseTime(activeValue);
112
+ if (!parsed) return;
113
+ setSelectedHours(parsed.hours);
114
+ setSelectedMinutes(parsed.minutes);
115
+ setSelectedSeconds(parsed.seconds);
116
+ if (format === "12") {
117
+ const { period } = to12HourFormat(parsed.hours);
118
+ setSelectedPeriod(period);
119
+ }
120
+ }, [activeValue, format]);
121
+ useEffect(() => {
122
+ syncFromActiveValue();
123
+ }, [syncFromActiveValue]);
124
+ const labels = useMemo(
125
+ () => getTimePickerLabels(mergedLocale, labelsOverrides),
126
+ [mergedLocale, labelsOverrides]
127
+ );
128
+ const placeholder = allProps.placeholder ?? (isRangeMode ? labels.selectTimeRange : labels.selectTime);
129
+ const periodLabels = useMemo(() => getTimePeriodLabels(localeCode), [localeCode]);
130
+ const displayValue = (() => {
131
+ if (!isRangeMode) {
132
+ return parsedTime ? formatTimeDisplayWithLocale(
133
+ parsedTime.hours,
134
+ parsedTime.minutes,
135
+ parsedTime.seconds,
136
+ format,
137
+ showSeconds,
138
+ localeCode
139
+ ) : "";
140
+ }
141
+ const toDisplay = (timeStr) => {
142
+ const parsed = parseTime(timeStr);
143
+ if (!parsed) return "";
144
+ return formatTimeDisplayWithLocale(
145
+ parsed.hours,
146
+ parsed.minutes,
147
+ parsed.seconds,
148
+ format,
149
+ showSeconds,
150
+ localeCode
151
+ );
152
+ };
153
+ const start = toDisplay(currentRangeValue[0]);
154
+ const end = toDisplay(currentRangeValue[1]);
155
+ if (!start && !end) return "";
156
+ return `${start} - ${end}`;
157
+ })();
158
+ const showClearButton = (() => {
159
+ if (!clearable || disabled || readonly) return false;
160
+ if (!isRangeMode) return currentSingleValue !== null;
161
+ return currentRangeValue[0] !== null || currentRangeValue[1] !== null;
162
+ })();
163
+ const hoursList = useMemo(() => generateHours(hourStep, format), [hourStep, format]);
164
+ const minutesList = useMemo(() => generateMinutes(minuteStep), [minuteStep]);
165
+ const secondsList = useMemo(() => generateSeconds(secondStep), [secondStep]);
166
+ const togglePanel = () => {
167
+ if (!disabled && !readonly) {
168
+ if (isOpen) {
169
+ closePanel();
170
+ return;
171
+ }
172
+ setIsOpen(true);
173
+ syncFromActiveValue();
174
+ }
175
+ };
176
+ const closePanel = () => {
177
+ setIsOpen(false);
178
+ inputRef.current?.focus();
179
+ };
180
+ const focusOptionInUnit = (unit, action) => {
181
+ focusTimePickerOption(panelRef.current, unit, action);
182
+ };
183
+ const handlePanelKeyDown = (event) => {
184
+ if (event.key === "Escape") {
185
+ event.preventDefault();
186
+ closePanel();
187
+ return;
188
+ }
189
+ const active = document.activeElement;
190
+ const unit = active?.getAttribute("data-tiger-timepicker-unit");
191
+ if (!unit) return;
192
+ if (event.key === "ArrowUp") {
193
+ event.preventDefault();
194
+ focusOptionInUnit(unit, "prev");
195
+ return;
196
+ }
197
+ if (event.key === "ArrowDown") {
198
+ event.preventDefault();
199
+ focusOptionInUnit(unit, "next");
200
+ return;
201
+ }
202
+ if (event.key === "Home") {
203
+ event.preventDefault();
204
+ focusOptionInUnit(unit, "first");
205
+ return;
206
+ }
207
+ if (event.key === "End") {
208
+ event.preventDefault();
209
+ focusOptionInUnit(unit, "last");
210
+ return;
211
+ }
212
+ if (event.key === "Enter" || event.key === " ") {
213
+ const el = document.activeElement;
214
+ if (el && el.tagName === "BUTTON" && !el.disabled) {
215
+ event.preventDefault();
216
+ el.click();
217
+ }
218
+ }
219
+ };
220
+ const selectHour = (hour) => {
221
+ const hours24 = format === "12" ? to24HourFormat(hour, selectedPeriod) : hour;
222
+ setSelectedHours(hours24);
223
+ updateTime(hours24, selectedMinutes, selectedSeconds);
224
+ };
225
+ const selectMinute = (minute) => {
226
+ setSelectedMinutes(minute);
227
+ updateTime(selectedHours, minute, selectedSeconds);
228
+ };
229
+ const selectSecond = (second) => {
230
+ setSelectedSeconds(second);
231
+ updateTime(selectedHours, selectedMinutes, second);
232
+ };
233
+ const selectPeriod = (period) => {
234
+ setSelectedPeriod(period);
235
+ const { hours: hours12 } = to12HourFormat(selectedHours);
236
+ const hours24 = to24HourFormat(hours12, period);
237
+ setSelectedHours(hours24);
238
+ updateTime(hours24, selectedMinutes, selectedSeconds);
239
+ };
240
+ const updateTime = (hours, minutes, seconds) => {
241
+ if (!isTimeInRange(hours, minutes, minTime, maxTime)) {
242
+ return;
243
+ }
244
+ let timeString = formatTime(hours, minutes, seconds, showSeconds);
245
+ if (!isRangeMode) {
246
+ setSingleValue(timeString);
247
+ return;
248
+ }
249
+ const index = activePart === "start" ? 0 : 1;
250
+ const parsedStart = parseTime(currentRangeValue[0]);
251
+ const parsedEnd = parseTime(currentRangeValue[1]);
252
+ const candidateSeconds = hours * 3600 + minutes * 60 + seconds;
253
+ const startSeconds = parsedStart ? parsedStart.hours * 3600 + parsedStart.minutes * 60 + parsedStart.seconds : null;
254
+ const endSeconds = parsedEnd ? parsedEnd.hours * 3600 + parsedEnd.minutes * 60 + parsedEnd.seconds : null;
255
+ if (activePart === "end" && parsedStart && startSeconds !== null) {
256
+ if (candidateSeconds < startSeconds) {
257
+ timeString = formatTime(
258
+ parsedStart.hours,
259
+ parsedStart.minutes,
260
+ parsedStart.seconds,
261
+ showSeconds
262
+ );
263
+ setSelectedHours(parsedStart.hours);
264
+ setSelectedMinutes(parsedStart.minutes);
265
+ setSelectedSeconds(parsedStart.seconds);
266
+ if (format === "12") {
267
+ const { period } = to12HourFormat(parsedStart.hours);
268
+ setSelectedPeriod(period);
269
+ }
270
+ }
271
+ }
272
+ const nextRange = [currentRangeValue[0], currentRangeValue[1]];
273
+ nextRange[index] = timeString;
274
+ if (activePart === "start" && endSeconds !== null && candidateSeconds > endSeconds) {
275
+ nextRange[1] = timeString;
276
+ }
277
+ setRangeValue(nextRange);
278
+ if (activePart === "start" && nextRange[1] === null) {
279
+ setActivePart("end");
280
+ }
281
+ };
282
+ const clearTime = (event) => {
283
+ event.stopPropagation();
284
+ if (!isRangeMode) {
285
+ setSingleValue(null);
286
+ onClear?.();
287
+ return;
288
+ }
289
+ setRangeValue([null, null]);
290
+ onClear?.();
291
+ };
292
+ const setNow = () => {
293
+ const now = getCurrentTime(showSeconds);
294
+ const parsed = parseTime(now);
295
+ if (parsed) {
296
+ setSelectedHours(parsed.hours);
297
+ setSelectedMinutes(parsed.minutes);
298
+ setSelectedSeconds(parsed.seconds);
299
+ if (format === "12") {
300
+ const { period } = to12HourFormat(parsed.hours);
301
+ setSelectedPeriod(period);
302
+ }
303
+ updateTime(parsed.hours, parsed.minutes, parsed.seconds);
304
+ }
305
+ };
306
+ const isHourDisabled = (hour) => {
307
+ const hours24 = format === "12" ? to24HourFormat(hour, selectedPeriod) : hour;
308
+ return !isTimeInRange(hours24, selectedMinutes, minTime, maxTime);
309
+ };
310
+ const isMinuteDisabled = (minute) => {
311
+ return !isTimeInRange(selectedHours, minute, minTime, maxTime);
312
+ };
313
+ const handleInputClick = () => {
314
+ togglePanel();
315
+ };
316
+ useEffect(() => {
317
+ const handleClickOutside = (event) => {
318
+ if (panelRef.current && inputWrapperRef.current && !panelRef.current.contains(event.target) && !inputWrapperRef.current.contains(event.target)) {
319
+ closePanel();
320
+ }
321
+ };
322
+ if (isOpen) {
323
+ document.addEventListener("click", handleClickOutside);
324
+ return () => {
325
+ document.removeEventListener("click", handleClickOutside);
326
+ };
327
+ }
328
+ }, [isOpen]);
329
+ useEffect(() => {
330
+ if (!isOpen) return;
331
+ const panel = panelRef.current;
332
+ if (!panel) return;
333
+ const focusTimer = window.setTimeout(() => {
334
+ const selectedHour = panel.querySelector(
335
+ 'button[data-tiger-timepicker-unit="hour"][aria-selected="true"]:not([disabled])'
336
+ );
337
+ if (selectedHour) {
338
+ selectedHour.focus();
339
+ return;
340
+ }
341
+ const firstHour = panel.querySelector(
342
+ 'button[data-tiger-timepicker-unit="hour"]:not([disabled])'
343
+ );
344
+ firstHour?.focus();
345
+ }, 0);
346
+ return () => window.clearTimeout(focusTimer);
347
+ }, [isOpen, activePart]);
348
+ const inputClasses = getTimePickerInputClasses(size, disabled || readonly);
349
+ const iconButtonClasses = getTimePickerIconButtonClasses(size);
350
+ return {
351
+ panelRef,
352
+ inputWrapperRef,
353
+ inputRef,
354
+ isOpen,
355
+ activePart,
356
+ setActivePart,
357
+ isRangeMode,
358
+ placeholder,
359
+ disabled,
360
+ readonly,
361
+ required,
362
+ name,
363
+ id,
364
+ format,
365
+ showSeconds,
366
+ locale: mergedLocale,
367
+ labelsOverrides,
368
+ containerClasses: classNames(timePickerBaseClasses, className),
369
+ divProps,
370
+ displayValue,
371
+ showClearButton,
372
+ inputClasses,
373
+ iconButtonClasses,
374
+ labels,
375
+ periodLabels,
376
+ hoursList,
377
+ minutesList,
378
+ secondsList,
379
+ selectedHours,
380
+ selectedMinutes,
381
+ selectedSeconds,
382
+ selectedPeriod,
383
+ togglePanel,
384
+ closePanel,
385
+ handleInputClick,
386
+ clearTime,
387
+ setNow,
388
+ handlePanelKeyDown,
389
+ selectHour,
390
+ selectMinute,
391
+ selectSecond,
392
+ selectPeriod,
393
+ isHourDisabled,
394
+ isMinuteDisabled
395
+ };
396
+ }
397
+
398
+ // src/components/TimePicker/render-mobile.tsx
399
+ import {
400
+ timePickerMobileWheelClasses,
401
+ timePickerMobileWheelSelectClasses,
402
+ to12HourFormat as to12HourFormat2,
403
+ padTwo
404
+ } from "@expcat/tigercat-core";
405
+ import { jsx, jsxs } from "react/jsx-runtime";
406
+ function renderTimePickerMobile(ctx) {
407
+ return /* @__PURE__ */ jsxs("div", { className: timePickerMobileWheelClasses, children: [
408
+ /* @__PURE__ */ jsx(
409
+ "select",
410
+ {
411
+ className: timePickerMobileWheelSelectClasses,
412
+ value: ctx.format === "12" ? to12HourFormat2(ctx.selectedHours).hours : ctx.selectedHours,
413
+ "aria-label": ctx.labels.hour,
414
+ onChange: (event) => ctx.selectHour(Number(event.target.value)),
415
+ children: ctx.hoursList.map((hour) => /* @__PURE__ */ jsx("option", { value: hour, disabled: ctx.isHourDisabled(hour), children: padTwo(hour) }, hour))
416
+ }
417
+ ),
418
+ /* @__PURE__ */ jsx(
419
+ "select",
420
+ {
421
+ className: timePickerMobileWheelSelectClasses,
422
+ value: ctx.selectedMinutes,
423
+ "aria-label": ctx.labels.minute,
424
+ onChange: (event) => ctx.selectMinute(Number(event.target.value)),
425
+ children: ctx.minutesList.map((minute) => /* @__PURE__ */ jsx("option", { value: minute, disabled: ctx.isMinuteDisabled(minute), children: padTwo(minute) }, minute))
426
+ }
427
+ ),
428
+ ctx.showSeconds && /* @__PURE__ */ jsx(
429
+ "select",
430
+ {
431
+ className: timePickerMobileWheelSelectClasses,
432
+ value: ctx.selectedSeconds,
433
+ "aria-label": ctx.labels.second,
434
+ onChange: (event) => ctx.selectSecond(Number(event.target.value)),
435
+ children: ctx.secondsList.map((second) => /* @__PURE__ */ jsx("option", { value: second, children: padTwo(second) }, second))
436
+ }
437
+ ),
438
+ ctx.format === "12" && /* @__PURE__ */ jsxs(
439
+ "select",
440
+ {
441
+ className: timePickerMobileWheelSelectClasses,
442
+ value: ctx.selectedPeriod,
443
+ "aria-label": "Period",
444
+ onChange: (event) => ctx.selectPeriod(event.target.value),
445
+ children: [
446
+ /* @__PURE__ */ jsx("option", { value: "AM", children: ctx.periodLabels.am }),
447
+ /* @__PURE__ */ jsx("option", { value: "PM", children: ctx.periodLabels.pm })
448
+ ]
449
+ }
450
+ )
451
+ ] });
452
+ }
453
+
454
+ // src/components/TimePicker/render-desktop.tsx
455
+ import {
456
+ timePickerDesktopPanelContentClasses,
457
+ timePickerColumnClasses,
458
+ timePickerColumnHeaderClasses,
459
+ timePickerColumnListClasses,
460
+ getTimePickerItemClasses,
461
+ getTimePickerPeriodButtonClasses,
462
+ getTimePickerOptionAriaLabel,
463
+ to24HourFormat as to24HourFormat2,
464
+ padTwo as padTwo2
465
+ } from "@expcat/tigercat-core";
466
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
467
+ function renderTimePickerDesktop(ctx) {
468
+ return /* @__PURE__ */ jsxs2("div", { className: timePickerDesktopPanelContentClasses, children: [
469
+ /* @__PURE__ */ jsxs2("div", { className: timePickerColumnClasses, children: [
470
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnHeaderClasses, children: ctx.labels.hour }),
471
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnListClasses, children: ctx.hoursList.map((hour) => {
472
+ const hours24 = ctx.format === "12" ? to24HourFormat2(hour, ctx.selectedPeriod) : hour;
473
+ const isSelected = ctx.selectedHours === hours24;
474
+ const isDisabled = ctx.isHourDisabled(hour);
475
+ return /* @__PURE__ */ jsx2(
476
+ "button",
477
+ {
478
+ type: "button",
479
+ className: getTimePickerItemClasses(isSelected, isDisabled),
480
+ disabled: isDisabled,
481
+ onClick: () => ctx.selectHour(hour),
482
+ "data-tiger-timepicker-unit": "hour",
483
+ "aria-label": getTimePickerOptionAriaLabel(
484
+ hour,
485
+ "hour",
486
+ ctx.locale,
487
+ ctx.labelsOverrides
488
+ ),
489
+ "aria-selected": isSelected,
490
+ children: padTwo2(hour)
491
+ },
492
+ hour
493
+ );
494
+ }) })
495
+ ] }),
496
+ /* @__PURE__ */ jsxs2("div", { className: timePickerColumnClasses, children: [
497
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnHeaderClasses, children: ctx.labels.minute }),
498
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnListClasses, children: ctx.minutesList.map((minute) => {
499
+ const isSelected = ctx.selectedMinutes === minute;
500
+ const isDisabled = ctx.isMinuteDisabled(minute);
501
+ return /* @__PURE__ */ jsx2(
502
+ "button",
503
+ {
504
+ type: "button",
505
+ className: getTimePickerItemClasses(isSelected, isDisabled),
506
+ disabled: isDisabled,
507
+ onClick: () => ctx.selectMinute(minute),
508
+ "data-tiger-timepicker-unit": "minute",
509
+ "aria-label": getTimePickerOptionAriaLabel(
510
+ minute,
511
+ "minute",
512
+ ctx.locale,
513
+ ctx.labelsOverrides
514
+ ),
515
+ "aria-selected": isSelected,
516
+ children: padTwo2(minute)
517
+ },
518
+ minute
519
+ );
520
+ }) })
521
+ ] }),
522
+ ctx.showSeconds && /* @__PURE__ */ jsxs2("div", { className: timePickerColumnClasses, children: [
523
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnHeaderClasses, children: ctx.labels.second }),
524
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnListClasses, children: ctx.secondsList.map((second) => {
525
+ const isSelected = ctx.selectedSeconds === second;
526
+ return /* @__PURE__ */ jsx2(
527
+ "button",
528
+ {
529
+ type: "button",
530
+ className: getTimePickerItemClasses(isSelected, false),
531
+ onClick: () => ctx.selectSecond(second),
532
+ "data-tiger-timepicker-unit": "second",
533
+ "aria-label": getTimePickerOptionAriaLabel(
534
+ second,
535
+ "second",
536
+ ctx.locale,
537
+ ctx.labelsOverrides
538
+ ),
539
+ "aria-selected": isSelected,
540
+ children: padTwo2(second)
541
+ },
542
+ second
543
+ );
544
+ }) })
545
+ ] }),
546
+ ctx.format === "12" && /* @__PURE__ */ jsxs2("div", { className: timePickerColumnClasses, children: [
547
+ /* @__PURE__ */ jsx2("div", { className: timePickerColumnHeaderClasses, children: " " }),
548
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-col", children: [
549
+ /* @__PURE__ */ jsx2(
550
+ "button",
551
+ {
552
+ type: "button",
553
+ className: getTimePickerPeriodButtonClasses(ctx.selectedPeriod === "AM"),
554
+ onClick: () => ctx.selectPeriod("AM"),
555
+ "data-tiger-timepicker-unit": "period",
556
+ "aria-label": ctx.periodLabels.am,
557
+ "aria-selected": ctx.selectedPeriod === "AM",
558
+ children: ctx.periodLabels.am
559
+ }
560
+ ),
561
+ /* @__PURE__ */ jsx2(
562
+ "button",
563
+ {
564
+ type: "button",
565
+ className: getTimePickerPeriodButtonClasses(ctx.selectedPeriod === "PM"),
566
+ onClick: () => ctx.selectPeriod("PM"),
567
+ "data-tiger-timepicker-unit": "period",
568
+ "aria-label": ctx.periodLabels.pm,
569
+ "aria-selected": ctx.selectedPeriod === "PM",
570
+ children: ctx.periodLabels.pm
571
+ }
572
+ )
573
+ ] })
574
+ ] })
575
+ ] });
576
+ }
577
+
578
+ // src/components/TimePicker/icons.tsx
579
+ import { icon20ViewBox } from "@expcat/tigercat-core";
580
+ import { jsx as jsx3 } from "react/jsx-runtime";
581
+ var Icon = ({ path, className }) => /* @__PURE__ */ jsx3(
582
+ "svg",
583
+ {
584
+ className,
585
+ xmlns: "http://www.w3.org/2000/svg",
586
+ viewBox: icon20ViewBox,
587
+ fill: "currentColor",
588
+ children: /* @__PURE__ */ jsx3("path", { fillRule: "evenodd", d: path, clipRule: "evenodd" })
589
+ }
590
+ );
591
+
592
+ // src/components/TimePicker.tsx
593
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
594
+ var TimePicker = (allProps) => {
595
+ const ctx = useTimePickerState(allProps);
596
+ return /* @__PURE__ */ jsxs3("div", { className: ctx.containerClasses, ...ctx.divProps, children: [
597
+ /* @__PURE__ */ jsxs3("div", { ref: ctx.inputWrapperRef, className: timePickerInputWrapperClasses, children: [
598
+ /* @__PURE__ */ jsx4(
599
+ "input",
600
+ {
601
+ ref: ctx.inputRef,
602
+ type: "text",
603
+ className: ctx.inputClasses,
604
+ value: ctx.displayValue,
605
+ placeholder: ctx.placeholder,
606
+ disabled: ctx.disabled,
607
+ readOnly: true,
608
+ required: ctx.required,
609
+ name: ctx.name,
610
+ id: ctx.id,
611
+ onClick: ctx.handleInputClick,
612
+ "aria-label": ctx.placeholder || ctx.labels.selectTime
613
+ }
614
+ ),
615
+ ctx.showClearButton && /* @__PURE__ */ jsx4(
616
+ "button",
617
+ {
618
+ type: "button",
619
+ className: timePickerClearButtonClasses,
620
+ onClick: ctx.clearTime,
621
+ "aria-label": ctx.labels.clear,
622
+ children: /* @__PURE__ */ jsx4(Icon, { path: TimePickerCloseIconPath, className: "w-4 h-4" })
623
+ }
624
+ ),
625
+ /* @__PURE__ */ jsx4(
626
+ "button",
627
+ {
628
+ type: "button",
629
+ className: ctx.iconButtonClasses,
630
+ disabled: ctx.disabled || ctx.readonly,
631
+ onClick: ctx.togglePanel,
632
+ "aria-label": ctx.labels.toggle,
633
+ children: /* @__PURE__ */ jsx4(Icon, { path: ClockIconPath, className: "w-5 h-5" })
634
+ }
635
+ )
636
+ ] }),
637
+ ctx.isOpen && /* @__PURE__ */ jsxs3(
638
+ "div",
639
+ {
640
+ ref: ctx.panelRef,
641
+ className: timePickerPanelClasses,
642
+ role: "dialog",
643
+ "aria-label": ctx.labels.dialog,
644
+ onKeyDown: ctx.handlePanelKeyDown,
645
+ children: [
646
+ ctx.isRangeMode && /* @__PURE__ */ jsxs3("div", { className: timePickerRangeHeaderClasses, children: [
647
+ /* @__PURE__ */ jsx4(
648
+ "button",
649
+ {
650
+ type: "button",
651
+ className: getTimePickerRangeTabButtonClasses(ctx.activePart === "start"),
652
+ onClick: () => ctx.setActivePart("start"),
653
+ "aria-label": ctx.labels.start,
654
+ "aria-selected": ctx.activePart === "start",
655
+ children: ctx.labels.start
656
+ }
657
+ ),
658
+ /* @__PURE__ */ jsx4(
659
+ "button",
660
+ {
661
+ type: "button",
662
+ className: getTimePickerRangeTabButtonClasses(ctx.activePart === "end"),
663
+ onClick: () => ctx.setActivePart("end"),
664
+ "aria-label": ctx.labels.end,
665
+ "aria-selected": ctx.activePart === "end",
666
+ children: ctx.labels.end
667
+ }
668
+ )
669
+ ] }),
670
+ renderTimePickerMobile(ctx),
671
+ renderTimePickerDesktop(ctx),
672
+ /* @__PURE__ */ jsxs3("div", { className: timePickerFooterClasses, children: [
673
+ /* @__PURE__ */ jsx4("button", { type: "button", className: timePickerFooterButtonClasses, onClick: ctx.setNow, children: ctx.labels.now }),
674
+ /* @__PURE__ */ jsx4(
675
+ "button",
676
+ {
677
+ type: "button",
678
+ className: timePickerFooterButtonClasses,
679
+ onClick: ctx.closePanel,
680
+ children: ctx.labels.ok
681
+ }
682
+ )
683
+ ] })
684
+ ]
685
+ }
686
+ )
687
+ ] });
688
+ };
689
+
690
+ export {
691
+ TimePicker
692
+ };