@nori-ui/core 0.0.5 → 1.0.2

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 (387) hide show
  1. package/dist/animation/animated-view.cjs +13 -0
  2. package/dist/animation/animated-view.cjs.map +1 -0
  3. package/dist/animation/animated-view.d.cts +6 -0
  4. package/dist/animation/animated-view.d.ts +6 -0
  5. package/dist/animation/animated-view.js +4 -0
  6. package/dist/animation/animated-view.js.map +1 -0
  7. package/dist/animation/animated-view.web.cjs +9 -0
  8. package/dist/animation/animated-view.web.cjs.map +1 -0
  9. package/dist/animation/animated-view.web.d.cts +5 -0
  10. package/dist/animation/animated-view.web.d.ts +5 -0
  11. package/dist/animation/animated-view.web.js +8 -0
  12. package/dist/animation/animated-view.web.js.map +1 -0
  13. package/dist/animation/use-animated-number.cjs +80 -0
  14. package/dist/animation/use-animated-number.cjs.map +1 -0
  15. package/dist/animation/use-animated-number.d.cts +8 -0
  16. package/dist/animation/use-animated-number.d.ts +8 -0
  17. package/dist/animation/use-animated-number.js +4 -0
  18. package/dist/animation/use-animated-number.js.map +1 -0
  19. package/dist/animation/use-animated-number.web.cjs +28 -0
  20. package/dist/animation/use-animated-number.web.cjs.map +1 -0
  21. package/dist/animation/use-animated-number.web.d.cts +8 -0
  22. package/dist/animation/use-animated-number.web.d.ts +8 -0
  23. package/dist/animation/use-animated-number.web.js +25 -0
  24. package/dist/animation/use-animated-number.web.js.map +1 -0
  25. package/dist/{chunk-RX7UULY3.js → chunk-33S7ADWM.js} +3 -3
  26. package/dist/{chunk-RX7UULY3.js.map → chunk-33S7ADWM.js.map} +1 -1
  27. package/dist/chunk-3BDDPFCI.js +108 -0
  28. package/dist/chunk-3BDDPFCI.js.map +1 -0
  29. package/dist/chunk-3F4TXKDY.js +314 -0
  30. package/dist/chunk-3F4TXKDY.js.map +1 -0
  31. package/dist/chunk-5A2QOOVN.js +15 -0
  32. package/dist/chunk-5A2QOOVN.js.map +1 -0
  33. package/dist/chunk-5XEGZFG5.js +208 -0
  34. package/dist/chunk-5XEGZFG5.js.map +1 -0
  35. package/dist/chunk-6AD6KCVB.js +178 -0
  36. package/dist/chunk-6AD6KCVB.js.map +1 -0
  37. package/dist/chunk-7GPDNQSX.js +967 -0
  38. package/dist/chunk-7GPDNQSX.js.map +1 -0
  39. package/dist/chunk-7UKRN73P.js +42 -0
  40. package/dist/chunk-7UKRN73P.js.map +1 -0
  41. package/dist/chunk-7Z4NMNX6.js +64 -0
  42. package/dist/chunk-7Z4NMNX6.js.map +1 -0
  43. package/dist/chunk-ACLHDHX3.js +29 -0
  44. package/dist/chunk-ACLHDHX3.js.map +1 -0
  45. package/dist/chunk-BZLT6R62.js +80 -0
  46. package/dist/chunk-BZLT6R62.js.map +1 -0
  47. package/dist/chunk-CCUXO2HN.js +450 -0
  48. package/dist/chunk-CCUXO2HN.js.map +1 -0
  49. package/dist/chunk-CHXHRJNZ.js +43 -0
  50. package/dist/chunk-CHXHRJNZ.js.map +1 -0
  51. package/dist/chunk-DDGMLLS3.js +188 -0
  52. package/dist/chunk-DDGMLLS3.js.map +1 -0
  53. package/dist/chunk-EWWQQ5DB.js +654 -0
  54. package/dist/chunk-EWWQQ5DB.js.map +1 -0
  55. package/dist/chunk-FEPTH5RV.js +169 -0
  56. package/dist/chunk-FEPTH5RV.js.map +1 -0
  57. package/dist/{chunk-SSTXLK5I.js → chunk-FT2XBBQJ.js} +42 -6
  58. package/dist/chunk-FT2XBBQJ.js.map +1 -0
  59. package/dist/chunk-IKLA2CVQ.js +260 -0
  60. package/dist/chunk-IKLA2CVQ.js.map +1 -0
  61. package/dist/chunk-JQQ3FBN7.js +18 -0
  62. package/dist/chunk-JQQ3FBN7.js.map +1 -0
  63. package/dist/chunk-JSAG5YO7.js +69 -0
  64. package/dist/chunk-JSAG5YO7.js.map +1 -0
  65. package/dist/chunk-JZ774T7U.js +76 -0
  66. package/dist/chunk-JZ774T7U.js.map +1 -0
  67. package/dist/chunk-KWRDJPP3.js +10 -0
  68. package/dist/chunk-KWRDJPP3.js.map +1 -0
  69. package/dist/chunk-LVWNMQGR.js +1106 -0
  70. package/dist/chunk-LVWNMQGR.js.map +1 -0
  71. package/dist/chunk-LWLK6HSW.js +143 -0
  72. package/dist/chunk-LWLK6HSW.js.map +1 -0
  73. package/dist/chunk-MDOZGILD.js +134 -0
  74. package/dist/chunk-MDOZGILD.js.map +1 -0
  75. package/dist/chunk-MKSDYRWQ.js +446 -0
  76. package/dist/chunk-MKSDYRWQ.js.map +1 -0
  77. package/dist/chunk-MRJWPRCX.js +80 -0
  78. package/dist/chunk-MRJWPRCX.js.map +1 -0
  79. package/dist/chunk-NRYWNOG5.js +410 -0
  80. package/dist/chunk-NRYWNOG5.js.map +1 -0
  81. package/dist/chunk-OMU4R4Y5.js +144 -0
  82. package/dist/chunk-OMU4R4Y5.js.map +1 -0
  83. package/dist/chunk-PNP7L4TA.js +103 -0
  84. package/dist/chunk-PNP7L4TA.js.map +1 -0
  85. package/dist/chunk-QI6646JZ.js +3 -0
  86. package/dist/{chunk-UAKFCMWK.js.map → chunk-QI6646JZ.js.map} +1 -1
  87. package/dist/chunk-QJNV7YQP.js +138 -0
  88. package/dist/chunk-QJNV7YQP.js.map +1 -0
  89. package/dist/chunk-R5JMDDCB.js +292 -0
  90. package/dist/chunk-R5JMDDCB.js.map +1 -0
  91. package/dist/chunk-RB3YBWQ4.js +77 -0
  92. package/dist/chunk-RB3YBWQ4.js.map +1 -0
  93. package/dist/chunk-RFW5SRZA.js +23 -0
  94. package/dist/chunk-RFW5SRZA.js.map +1 -0
  95. package/dist/chunk-RGJ3NBKE.js +8 -0
  96. package/dist/chunk-RGJ3NBKE.js.map +1 -0
  97. package/dist/chunk-SFNDR6DI.js +485 -0
  98. package/dist/chunk-SFNDR6DI.js.map +1 -0
  99. package/dist/chunk-SWC5CNKE.js +13 -0
  100. package/dist/chunk-SWC5CNKE.js.map +1 -0
  101. package/dist/chunk-TLS54G6Y.js +15 -0
  102. package/dist/chunk-TLS54G6Y.js.map +1 -0
  103. package/dist/chunk-WCQVDF3K.js +12 -0
  104. package/dist/{chunk-7QVYU63E.js.map → chunk-WCQVDF3K.js.map} +1 -1
  105. package/dist/chunk-WGT345SV.js +427 -0
  106. package/dist/chunk-WGT345SV.js.map +1 -0
  107. package/dist/chunk-X7APG7G2.js +1566 -0
  108. package/dist/chunk-X7APG7G2.js.map +1 -0
  109. package/dist/chunk-XALU6LOT.js +306 -0
  110. package/dist/chunk-XALU6LOT.js.map +1 -0
  111. package/dist/chunk-YNKKEO2A.js +336 -0
  112. package/dist/chunk-YNKKEO2A.js.map +1 -0
  113. package/dist/chunk-ZBW3BA5R.js +148 -0
  114. package/dist/chunk-ZBW3BA5R.js.map +1 -0
  115. package/dist/{chunk-FXKIWONG.js → chunk-ZIBNLXIV.js} +12 -6
  116. package/dist/chunk-ZIBNLXIV.js.map +1 -0
  117. package/dist/chunk-ZMSIYLSI.js +563 -0
  118. package/dist/chunk-ZMSIYLSI.js.map +1 -0
  119. package/dist/chunk-ZQMNGPLE.js +981 -0
  120. package/dist/chunk-ZQMNGPLE.js.map +1 -0
  121. package/dist/chunk-ZRD4FQBT.js +153 -0
  122. package/dist/chunk-ZRD4FQBT.js.map +1 -0
  123. package/dist/client.cjs +11289 -439
  124. package/dist/client.cjs.map +1 -1
  125. package/dist/client.d.cts +68 -117
  126. package/dist/client.d.ts +68 -117
  127. package/dist/client.js +58 -40
  128. package/dist/client.js.map +1 -1
  129. package/dist/components/Accordion/index.cjs +900 -0
  130. package/dist/components/Accordion/index.cjs.map +1 -0
  131. package/dist/components/Accordion/index.d.cts +72 -0
  132. package/dist/components/Accordion/index.d.ts +72 -0
  133. package/dist/components/Accordion/index.js +10 -0
  134. package/dist/components/Accordion/index.js.map +1 -0
  135. package/dist/components/Alert/index.cjs +567 -0
  136. package/dist/components/Alert/index.cjs.map +1 -0
  137. package/dist/components/Alert/index.d.cts +41 -0
  138. package/dist/components/Alert/index.d.ts +41 -0
  139. package/dist/components/Alert/index.js +8 -0
  140. package/dist/components/Alert/index.js.map +1 -0
  141. package/dist/components/AlertDialog/index.cjs +892 -0
  142. package/dist/components/AlertDialog/index.cjs.map +1 -0
  143. package/dist/components/AlertDialog/index.d.cts +68 -0
  144. package/dist/components/AlertDialog/index.d.ts +68 -0
  145. package/dist/components/AlertDialog/index.js +9 -0
  146. package/dist/components/AlertDialog/index.js.map +1 -0
  147. package/dist/components/Avatar/index.cjs +427 -0
  148. package/dist/components/Avatar/index.cjs.map +1 -0
  149. package/dist/components/Avatar/index.d.cts +40 -0
  150. package/dist/components/Avatar/index.d.ts +40 -0
  151. package/dist/components/Avatar/index.js +7 -0
  152. package/dist/components/Avatar/index.js.map +1 -0
  153. package/dist/components/Badge/index.cjs +433 -0
  154. package/dist/components/Badge/index.cjs.map +1 -0
  155. package/dist/components/Badge/index.d.cts +35 -0
  156. package/dist/components/Badge/index.d.ts +35 -0
  157. package/dist/components/Badge/index.js +7 -0
  158. package/dist/components/Badge/index.js.map +1 -0
  159. package/dist/components/Box/index.cjs +415 -0
  160. package/dist/components/Box/index.cjs.map +1 -0
  161. package/dist/components/Box/index.d.cts +24 -0
  162. package/dist/components/Box/index.d.ts +24 -0
  163. package/dist/components/Box/index.js +9 -0
  164. package/dist/components/Box/index.js.map +1 -0
  165. package/dist/components/Breadcrumb/index.cjs +1939 -0
  166. package/dist/components/Breadcrumb/index.cjs.map +1 -0
  167. package/dist/components/Breadcrumb/index.d.cts +186 -0
  168. package/dist/components/Breadcrumb/index.d.ts +186 -0
  169. package/dist/components/Breadcrumb/index.js +11 -0
  170. package/dist/components/Breadcrumb/index.js.map +1 -0
  171. package/dist/components/Button/index.cjs +631 -0
  172. package/dist/components/Button/index.cjs.map +1 -0
  173. package/dist/components/Button/index.d.cts +27 -0
  174. package/dist/components/Button/index.d.ts +27 -0
  175. package/dist/components/Button/index.js +9 -0
  176. package/dist/components/Button/index.js.map +1 -0
  177. package/dist/components/Calendar/index.cjs +3017 -0
  178. package/dist/components/Calendar/index.cjs.map +1 -0
  179. package/dist/components/Calendar/index.d.cts +169 -0
  180. package/dist/components/Calendar/index.d.ts +169 -0
  181. package/dist/components/Calendar/index.js +11 -0
  182. package/dist/components/Calendar/index.js.map +1 -0
  183. package/dist/components/Card/index.cjs +469 -0
  184. package/dist/components/Card/index.cjs.map +1 -0
  185. package/dist/components/Card/index.d.cts +33 -0
  186. package/dist/components/Card/index.d.ts +33 -0
  187. package/dist/components/Card/index.js +7 -0
  188. package/dist/components/Card/index.js.map +1 -0
  189. package/dist/components/Checkbox/index.cjs +590 -0
  190. package/dist/components/Checkbox/index.cjs.map +1 -0
  191. package/dist/components/Checkbox/index.d.cts +22 -0
  192. package/dist/components/Checkbox/index.d.ts +22 -0
  193. package/dist/components/Checkbox/index.js +9 -0
  194. package/dist/components/Checkbox/index.js.map +1 -0
  195. package/dist/components/Dialog/index.cjs +888 -0
  196. package/dist/components/Dialog/index.cjs.map +1 -0
  197. package/dist/components/Dialog/index.d.cts +56 -0
  198. package/dist/components/Dialog/index.d.ts +56 -0
  199. package/dist/components/Dialog/index.js +10 -0
  200. package/dist/components/Dialog/index.js.map +1 -0
  201. package/dist/components/FloatButton/index.cjs +1254 -0
  202. package/dist/components/FloatButton/index.cjs.map +1 -0
  203. package/dist/components/FloatButton/index.d.cts +133 -0
  204. package/dist/components/FloatButton/index.d.ts +133 -0
  205. package/dist/components/FloatButton/index.js +11 -0
  206. package/dist/components/FloatButton/index.js.map +1 -0
  207. package/dist/components/HStack/index.cjs +480 -0
  208. package/dist/components/HStack/index.cjs.map +1 -0
  209. package/dist/components/HStack/index.d.cts +24 -0
  210. package/dist/components/HStack/index.d.ts +24 -0
  211. package/dist/components/HStack/index.js +9 -0
  212. package/dist/components/HStack/index.js.map +1 -0
  213. package/dist/components/InputGroup/index.cjs +638 -0
  214. package/dist/components/InputGroup/index.cjs.map +1 -0
  215. package/dist/components/InputGroup/index.d.cts +33 -0
  216. package/dist/components/InputGroup/index.d.ts +33 -0
  217. package/dist/components/InputGroup/index.js +7 -0
  218. package/dist/components/InputGroup/index.js.map +1 -0
  219. package/dist/components/Pagination/index.cjs +2501 -0
  220. package/dist/components/Pagination/index.cjs.map +1 -0
  221. package/dist/components/Pagination/index.d.cts +164 -0
  222. package/dist/components/Pagination/index.d.ts +164 -0
  223. package/dist/components/Pagination/index.js +12 -0
  224. package/dist/components/Pagination/index.js.map +1 -0
  225. package/dist/components/Popover/index.cjs +739 -0
  226. package/dist/components/Popover/index.cjs.map +1 -0
  227. package/dist/components/Popover/index.d.cts +44 -0
  228. package/dist/components/Popover/index.d.ts +44 -0
  229. package/dist/components/Popover/index.js +8 -0
  230. package/dist/components/Popover/index.js.map +1 -0
  231. package/dist/components/Progress/index.cjs +493 -0
  232. package/dist/components/Progress/index.cjs.map +1 -0
  233. package/dist/components/Progress/index.d.cts +63 -0
  234. package/dist/components/Progress/index.d.ts +63 -0
  235. package/dist/components/Progress/index.js +7 -0
  236. package/dist/components/Progress/index.js.map +1 -0
  237. package/dist/components/Radio/index.cjs +584 -0
  238. package/dist/components/Radio/index.cjs.map +1 -0
  239. package/dist/components/Radio/index.d.cts +51 -0
  240. package/dist/components/Radio/index.d.ts +51 -0
  241. package/dist/components/Radio/index.js +7 -0
  242. package/dist/components/Radio/index.js.map +1 -0
  243. package/dist/components/SegmentedControl/index.cjs +502 -0
  244. package/dist/components/SegmentedControl/index.cjs.map +1 -0
  245. package/dist/components/SegmentedControl/index.d.cts +45 -0
  246. package/dist/components/SegmentedControl/index.d.ts +45 -0
  247. package/dist/components/SegmentedControl/index.js +7 -0
  248. package/dist/components/SegmentedControl/index.js.map +1 -0
  249. package/dist/components/Select/index.cjs +1359 -0
  250. package/dist/components/Select/index.cjs.map +1 -0
  251. package/dist/components/Select/index.d.cts +140 -0
  252. package/dist/components/Select/index.d.ts +140 -0
  253. package/dist/components/Select/index.js +8 -0
  254. package/dist/components/Select/index.js.map +1 -0
  255. package/dist/components/Separator/index.cjs +358 -0
  256. package/dist/components/Separator/index.cjs.map +1 -0
  257. package/dist/components/Separator/index.d.cts +28 -0
  258. package/dist/components/Separator/index.d.ts +28 -0
  259. package/dist/components/Separator/index.js +6 -0
  260. package/dist/components/Separator/index.js.map +1 -0
  261. package/dist/components/Skeleton/index.cjs +384 -0
  262. package/dist/components/Skeleton/index.cjs.map +1 -0
  263. package/dist/components/Skeleton/index.d.cts +30 -0
  264. package/dist/components/Skeleton/index.d.ts +30 -0
  265. package/dist/components/Skeleton/index.js +6 -0
  266. package/dist/components/Skeleton/index.js.map +1 -0
  267. package/dist/components/Slider/index.cjs +880 -0
  268. package/dist/components/Slider/index.cjs.map +1 -0
  269. package/dist/components/Slider/index.d.cts +84 -0
  270. package/dist/components/Slider/index.d.ts +84 -0
  271. package/dist/components/Slider/index.js +6 -0
  272. package/dist/components/Slider/index.js.map +1 -0
  273. package/dist/components/Spinner/index.cjs +32 -0
  274. package/dist/components/Spinner/index.cjs.map +1 -0
  275. package/dist/components/Spinner/index.d.cts +25 -0
  276. package/dist/components/Spinner/index.d.ts +25 -0
  277. package/dist/components/Spinner/index.js +4 -0
  278. package/dist/components/Spinner/index.js.map +1 -0
  279. package/dist/components/Switch/index.cjs +623 -0
  280. package/dist/components/Switch/index.cjs.map +1 -0
  281. package/dist/components/Switch/index.d.cts +22 -0
  282. package/dist/components/Switch/index.d.ts +22 -0
  283. package/dist/components/Switch/index.js +10 -0
  284. package/dist/components/Switch/index.js.map +1 -0
  285. package/dist/components/Tabs/index.cjs +630 -0
  286. package/dist/components/Tabs/index.cjs.map +1 -0
  287. package/dist/components/Tabs/index.d.cts +63 -0
  288. package/dist/components/Tabs/index.d.ts +63 -0
  289. package/dist/components/Tabs/index.js +7 -0
  290. package/dist/components/Tabs/index.js.map +1 -0
  291. package/dist/components/Text/index.cjs +401 -0
  292. package/dist/components/Text/index.cjs.map +1 -0
  293. package/dist/components/Text/index.d.cts +24 -0
  294. package/dist/components/Text/index.d.ts +24 -0
  295. package/dist/components/Text/index.js +7 -0
  296. package/dist/components/Text/index.js.map +1 -0
  297. package/dist/components/TextArea/index.cjs +482 -0
  298. package/dist/components/TextArea/index.cjs.map +1 -0
  299. package/dist/components/TextArea/index.d.cts +25 -0
  300. package/dist/components/TextArea/index.d.ts +25 -0
  301. package/dist/components/TextArea/index.js +8 -0
  302. package/dist/components/TextArea/index.js.map +1 -0
  303. package/dist/components/TextInput/index.cjs +477 -0
  304. package/dist/components/TextInput/index.cjs.map +1 -0
  305. package/dist/components/TextInput/index.d.cts +33 -0
  306. package/dist/components/TextInput/index.d.ts +33 -0
  307. package/dist/components/TextInput/index.js +7 -0
  308. package/dist/components/TextInput/index.js.map +1 -0
  309. package/dist/components/Toast/index.cjs +167 -0
  310. package/dist/components/Toast/index.cjs.map +1 -0
  311. package/dist/components/Toast/index.d.cts +143 -0
  312. package/dist/components/Toast/index.d.ts +143 -0
  313. package/dist/components/Toast/index.js +4 -0
  314. package/dist/components/Toast/index.js.map +1 -0
  315. package/dist/components/Toggle/index.cjs +770 -0
  316. package/dist/components/Toggle/index.cjs.map +1 -0
  317. package/dist/components/Toggle/index.d.cts +83 -0
  318. package/dist/components/Toggle/index.d.ts +83 -0
  319. package/dist/components/Toggle/index.js +7 -0
  320. package/dist/components/Toggle/index.js.map +1 -0
  321. package/dist/components/Tooltip/index.cjs +813 -0
  322. package/dist/components/Tooltip/index.cjs.map +1 -0
  323. package/dist/components/Tooltip/index.d.cts +55 -0
  324. package/dist/components/Tooltip/index.d.ts +55 -0
  325. package/dist/components/Tooltip/index.js +8 -0
  326. package/dist/components/Tooltip/index.js.map +1 -0
  327. package/dist/components/VStack/index.cjs +480 -0
  328. package/dist/components/VStack/index.cjs.map +1 -0
  329. package/dist/components/VStack/index.d.cts +19 -0
  330. package/dist/components/VStack/index.d.ts +19 -0
  331. package/dist/components/VStack/index.js +9 -0
  332. package/dist/components/VStack/index.js.map +1 -0
  333. package/dist/i18n/index.cjs +39 -3
  334. package/dist/i18n/index.cjs.map +1 -1
  335. package/dist/i18n/index.d.cts +4 -60
  336. package/dist/i18n/index.d.ts +4 -60
  337. package/dist/i18n/index.js +3 -2
  338. package/dist/icons/index.cjs +326 -26
  339. package/dist/icons/index.cjs.map +1 -1
  340. package/dist/icons/index.js +4 -3
  341. package/dist/index-D3_M3G6U.d.ts +19 -0
  342. package/dist/index-uXPK_Rg8.d.cts +19 -0
  343. package/dist/index.cjs +11176 -463
  344. package/dist/index.cjs.map +1 -1
  345. package/dist/index.d.cts +39 -183
  346. package/dist/index.d.ts +39 -183
  347. package/dist/index.js +49 -9
  348. package/dist/resolve-D-GOaxZy.d.cts +60 -0
  349. package/dist/resolve-D-GOaxZy.d.ts +60 -0
  350. package/dist/slot/index.cjs +9 -3
  351. package/dist/slot/index.cjs.map +1 -1
  352. package/dist/slot/index.js +2 -2
  353. package/dist/stories/index.cjs +108 -0
  354. package/dist/stories/index.cjs.map +1 -0
  355. package/dist/stories/index.d.cts +46 -0
  356. package/dist/stories/index.d.ts +46 -0
  357. package/dist/stories/index.js +94 -0
  358. package/dist/stories/index.js.map +1 -0
  359. package/dist/theme/index.cjs +259 -26
  360. package/dist/theme/index.cjs.map +1 -1
  361. package/dist/theme/index.d.cts +26 -0
  362. package/dist/theme/index.d.ts +26 -0
  363. package/dist/theme/index.js +4 -3
  364. package/dist/use-theme-CoqfnvRs.d.cts +112 -0
  365. package/dist/use-theme-CoqfnvRs.d.ts +112 -0
  366. package/dist/utils/cn.cjs +18 -6
  367. package/dist/utils/cn.cjs.map +1 -1
  368. package/dist/utils/cn.js +2 -2
  369. package/package.json +41 -10
  370. package/dist/chunk-6OABNXBY.js +0 -213
  371. package/dist/chunk-6OABNXBY.js.map +0 -1
  372. package/dist/chunk-7QVYU63E.js +0 -6
  373. package/dist/chunk-FXKIWONG.js.map +0 -1
  374. package/dist/chunk-NDEDMCHT.js +0 -40
  375. package/dist/chunk-NDEDMCHT.js.map +0 -1
  376. package/dist/chunk-SSTXLK5I.js.map +0 -1
  377. package/dist/chunk-UAKFCMWK.js +0 -3
  378. package/dist/chunk-X3AJNNF6.js +0 -539
  379. package/dist/chunk-X3AJNNF6.js.map +0 -1
  380. package/dist/chunk-XGM2K4TT.js +0 -31
  381. package/dist/chunk-XGM2K4TT.js.map +0 -1
  382. package/dist/stories/story-registry.cjs +0 -776
  383. package/dist/stories/story-registry.cjs.map +0 -1
  384. package/dist/stories/story-registry.d.cts +0 -13
  385. package/dist/stories/story-registry.d.ts +0 -13
  386. package/dist/stories/story-registry.js +0 -106
  387. package/dist/stories/story-registry.js.map +0 -1
@@ -0,0 +1,3017 @@
1
+ 'use strict';
2
+
3
+ var date = require('@internationalized/date');
4
+ var react = require('react');
5
+ var reactNative = require('react-native');
6
+ var jsxRuntime = require('nativewind/jsx-runtime');
7
+ var reactDom = require('react-dom');
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
11
+ var detectLocale = /* @__PURE__ */ __name(() => {
12
+ try {
13
+ return new Intl.DateTimeFormat().resolvedOptions().locale;
14
+ } catch {
15
+ return "en-US";
16
+ }
17
+ }, "detectLocale");
18
+ var LocaleContext = react.createContext(null);
19
+ LocaleContext.displayName = "LocaleContext";
20
+ var useLocale = /* @__PURE__ */ __name(() => {
21
+ const ctx = react.useContext(LocaleContext);
22
+ return ctx ?? detectLocale();
23
+ }, "useLocale");
24
+
25
+ // ../tokens/build/theme.ts
26
+ var theme = {
27
+ color: {
28
+ danger: "#ef4444",
29
+ info: "#3b82f6",
30
+ neutral: {
31
+ "100": "#f4f4f5",
32
+ "200": "#e4e4e7",
33
+ "300": "#d4d4d8",
34
+ "400": "#a1a1aa",
35
+ "50": "#fafafa",
36
+ "500": "#71717a",
37
+ "600": "#52525b",
38
+ "700": "#3f3f46",
39
+ "800": "#27272a",
40
+ "900": "#18181b"
41
+ },
42
+ primary: {
43
+ "100": "#ccfbf1",
44
+ "200": "#99f6e4",
45
+ "300": "#5eead4",
46
+ "400": "#2dd4bf",
47
+ "50": "#f0fdfa",
48
+ "500": "#14b8a6",
49
+ "600": "#0d9488",
50
+ "700": "#0f766e",
51
+ "800": "#115e59",
52
+ "900": "#134e4a"
53
+ },
54
+ success: "#22c55e",
55
+ warning: "#f59e0b"
56
+ },
57
+ fontFamily: {
58
+ body: "system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
59
+ display: "ui-serif, Georgia, 'Times New Roman', serif",
60
+ mono: "ui-monospace, 'SF Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace"
61
+ },
62
+ fontSize: {
63
+ "2xl": "24px",
64
+ "3xl": "30px",
65
+ "4xl": "36px",
66
+ lg: "18px",
67
+ md: "16px",
68
+ sm: "14px",
69
+ xl: "20px",
70
+ xs: "12px"
71
+ },
72
+ fontWeight: {
73
+ bold: "700",
74
+ medium: "500",
75
+ regular: "400",
76
+ semibold: "600"
77
+ },
78
+ lineHeight: {
79
+ normal: "1.4",
80
+ relaxed: "1.6",
81
+ tight: "1.2"
82
+ },
83
+ radius: {
84
+ "2xl": "16px",
85
+ full: "9999px",
86
+ lg: "8px",
87
+ md: "6px",
88
+ none: "0px",
89
+ sm: "4px",
90
+ xl: "12px"
91
+ },
92
+ semantic: {
93
+ background: {
94
+ default: "#fafafa",
95
+ elevated: "#ffffff",
96
+ subtle: "#f4f4f5"
97
+ },
98
+ border: {
99
+ default: "#e4e4e7",
100
+ strong: "#d4d4d8"
101
+ },
102
+ interactive: {
103
+ destructive: "#ef4444",
104
+ primary: "#0d9488",
105
+ primaryHover: "#0f766e",
106
+ primaryPressed: "#115e59"
107
+ },
108
+ text: {
109
+ default: "#18181b",
110
+ inverted: "#fafafa",
111
+ muted: "#52525b"
112
+ }
113
+ },
114
+ shadow: {
115
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
116
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
117
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
118
+ },
119
+ spacing: {
120
+ "0": "0px",
121
+ "1": "4px",
122
+ "10": "40px",
123
+ "12": "48px",
124
+ "16": "64px",
125
+ "2": "8px",
126
+ "20": "80px",
127
+ "24": "96px",
128
+ "3": "12px",
129
+ "4": "16px",
130
+ "5": "20px",
131
+ "6": "24px",
132
+ "8": "32px"
133
+ }
134
+ };
135
+ var themeDark = {
136
+ color: {
137
+ danger: "#ef4444",
138
+ info: "#3b82f6",
139
+ neutral: {
140
+ "100": "#f4f4f5",
141
+ "200": "#e4e4e7",
142
+ "300": "#d4d4d8",
143
+ "400": "#a1a1aa",
144
+ "50": "#fafafa",
145
+ "500": "#71717a",
146
+ "600": "#52525b",
147
+ "700": "#3f3f46",
148
+ "800": "#27272a",
149
+ "900": "#18181b"
150
+ },
151
+ primary: {
152
+ "100": "#ccfbf1",
153
+ "200": "#99f6e4",
154
+ "300": "#5eead4",
155
+ "400": "#2dd4bf",
156
+ "50": "#f0fdfa",
157
+ "500": "#14b8a6",
158
+ "600": "#0d9488",
159
+ "700": "#0f766e",
160
+ "800": "#115e59",
161
+ "900": "#134e4a"
162
+ },
163
+ success: "#22c55e",
164
+ warning: "#f59e0b"
165
+ },
166
+ fontFamily: {
167
+ body: "system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
168
+ display: "ui-serif, Georgia, 'Times New Roman', serif",
169
+ mono: "ui-monospace, 'SF Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace"
170
+ },
171
+ fontSize: {
172
+ "2xl": "24px",
173
+ "3xl": "30px",
174
+ "4xl": "36px",
175
+ lg: "18px",
176
+ md: "16px",
177
+ sm: "14px",
178
+ xl: "20px",
179
+ xs: "12px"
180
+ },
181
+ fontWeight: {
182
+ bold: "700",
183
+ medium: "500",
184
+ regular: "400",
185
+ semibold: "600"
186
+ },
187
+ lineHeight: {
188
+ normal: "1.4",
189
+ relaxed: "1.6",
190
+ tight: "1.2"
191
+ },
192
+ radius: {
193
+ "2xl": "16px",
194
+ full: "9999px",
195
+ lg: "8px",
196
+ md: "6px",
197
+ none: "0px",
198
+ sm: "4px",
199
+ xl: "12px"
200
+ },
201
+ semantic: {
202
+ background: {
203
+ default: "#18181b",
204
+ elevated: "#3f3f46",
205
+ subtle: "#27272a"
206
+ },
207
+ border: {
208
+ default: "#3f3f46",
209
+ strong: "#52525b"
210
+ },
211
+ interactive: {
212
+ destructive: "#ef4444",
213
+ primary: "#2dd4bf",
214
+ primaryHover: "#5eead4",
215
+ primaryPressed: "#99f6e4"
216
+ },
217
+ text: {
218
+ default: "#fafafa",
219
+ inverted: "#18181b",
220
+ muted: "#a1a1aa"
221
+ }
222
+ },
223
+ shadow: {
224
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
225
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
226
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
227
+ },
228
+ spacing: {
229
+ "0": "0px",
230
+ "1": "4px",
231
+ "10": "40px",
232
+ "12": "48px",
233
+ "16": "64px",
234
+ "2": "8px",
235
+ "20": "80px",
236
+ "24": "96px",
237
+ "3": "12px",
238
+ "4": "16px",
239
+ "5": "20px",
240
+ "6": "24px",
241
+ "8": "32px"
242
+ }
243
+ };
244
+ var defaultTheme = {
245
+ light: theme,
246
+ dark: themeDark
247
+ };
248
+ var ThemeContext = react.createContext(defaultTheme);
249
+ ThemeContext.displayName = "ThemeContext";
250
+ var ColorSchemeOverrideContext = react.createContext(null);
251
+ ColorSchemeOverrideContext.displayName = "ColorSchemeOverrideContext";
252
+ var isWeb = reactNative.Platform.OS === "web";
253
+ function readWebScheme() {
254
+ if (typeof document === "undefined") {
255
+ return "light";
256
+ }
257
+ const root = document.documentElement;
258
+ if (root.classList.contains("dark")) {
259
+ return "dark";
260
+ }
261
+ if (root.getAttribute("data-theme") === "dark") {
262
+ return "dark";
263
+ }
264
+ return "light";
265
+ }
266
+ __name(readWebScheme, "readWebScheme");
267
+ function useColorScheme() {
268
+ const override = react.useContext(ColorSchemeOverrideContext);
269
+ const [scheme, setScheme] = react.useState(() => {
270
+ if (isWeb) {
271
+ return readWebScheme();
272
+ }
273
+ return reactNative.Appearance.getColorScheme() ?? "light";
274
+ });
275
+ react.useEffect(() => {
276
+ if (isWeb) {
277
+ const root = document.documentElement;
278
+ const update = /* @__PURE__ */ __name(() => setScheme(readWebScheme()), "update");
279
+ const observer = new MutationObserver(update);
280
+ observer.observe(root, { attributes: true, attributeFilter: ["class", "data-theme"] });
281
+ update();
282
+ return () => observer.disconnect();
283
+ }
284
+ const sub = reactNative.Appearance.addChangeListener(({ colorScheme }) => {
285
+ setScheme(colorScheme ?? "light");
286
+ });
287
+ return () => sub.remove();
288
+ }, []);
289
+ return override ?? scheme;
290
+ }
291
+ __name(useColorScheme, "useColorScheme");
292
+
293
+ // src/theme/use-theme-colors.ts
294
+ function useThemeColors() {
295
+ const scheme = useColorScheme();
296
+ const themePair = react.useContext(ThemeContext);
297
+ return scheme === "dark" ? themePair.dark : themePair.light;
298
+ }
299
+ __name(useThemeColors, "useThemeColors");
300
+
301
+ // src/components/Calendar/state/locale-utils.ts
302
+ var getFirstDayOfWeek = /* @__PURE__ */ __name((locale) => {
303
+ try {
304
+ const loc = new Intl.Locale(locale);
305
+ const info = loc.getWeekInfo?.() ?? loc.weekInfo;
306
+ if (typeof info?.firstDay === "number") {
307
+ return info.firstDay === 7 ? 0 : info.firstDay;
308
+ }
309
+ } catch {
310
+ }
311
+ return FIRST_DAY_FALLBACK[locale] ?? FIRST_DAY_FALLBACK[locale.split("-")[0] ?? ""] ?? 1;
312
+ }, "getFirstDayOfWeek");
313
+ var FIRST_DAY_FALLBACK = {
314
+ en: 0,
315
+ "en-US": 0,
316
+ "en-CA": 0,
317
+ "en-GB": 1,
318
+ "en-AU": 1,
319
+ de: 1,
320
+ fr: 1,
321
+ ja: 0,
322
+ ar: 0,
323
+ he: 0,
324
+ fa: 6
325
+ };
326
+ var getWeekendDays = /* @__PURE__ */ __name((locale) => {
327
+ try {
328
+ const loc = new Intl.Locale(locale);
329
+ const info = loc.getWeekInfo?.() ?? loc.weekInfo;
330
+ if (info?.weekend && Array.isArray(info.weekend) && info.weekend.length === 2) {
331
+ const [a, b] = info.weekend.map((d) => d === 7 ? 0 : d);
332
+ return [a, b];
333
+ }
334
+ } catch {
335
+ }
336
+ return WEEKEND_FALLBACK[locale] ?? WEEKEND_FALLBACK[locale.split("-")[0] ?? ""] ?? [6, 0];
337
+ }, "getWeekendDays");
338
+ var WEEKEND_FALLBACK = {
339
+ "en-US": [6, 0],
340
+ "de-DE": [6, 0],
341
+ "fr-FR": [6, 0],
342
+ "ja-JP": [6, 0],
343
+ "ar-SA": [5, 6],
344
+ "ar-AE": [5, 6],
345
+ "he-IL": [5, 6],
346
+ "fa-IR": [4, 5],
347
+ en: [6, 0],
348
+ de: [6, 0],
349
+ fr: [6, 0],
350
+ ar: [5, 6],
351
+ he: [5, 6]
352
+ };
353
+ var formatWeekdayNames = /* @__PURE__ */ __name((locale, format = "short") => {
354
+ const fmt = new Intl.DateTimeFormat(locale, { weekday: format });
355
+ const start = getFirstDayOfWeek(locale);
356
+ return Array.from({ length: 7 }, (_, i) => {
357
+ const d = new Date(Date.UTC(2026, 0, 4 + (start + i) % 7));
358
+ return fmt.format(d);
359
+ });
360
+ }, "formatWeekdayNames");
361
+ var formatMonthYearTitle = /* @__PURE__ */ __name((date, locale) => {
362
+ const fmt = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" });
363
+ return fmt.format(date.toDate("UTC"));
364
+ }, "formatMonthYearTitle");
365
+ var formatMonthNames = /* @__PURE__ */ __name((locale) => {
366
+ const fmt = new Intl.DateTimeFormat(locale, { month: "long" });
367
+ return Array.from({ length: 12 }, (_, m) => fmt.format(new Date(Date.UTC(2026, m, 15))));
368
+ }, "formatMonthNames");
369
+ var useCalendarKeyboard = /* @__PURE__ */ __name((props) => {
370
+ const { focusedDate, moveFocus, selectDate, firstDayOfWeek = 0 } = props;
371
+ const onKeyDown = react.useCallback(
372
+ (event) => {
373
+ const focusedDow = focusedDate.toDate("UTC").getUTCDay();
374
+ switch (event.key) {
375
+ case "ArrowLeft":
376
+ event.preventDefault();
377
+ moveFocus({ days: -1 });
378
+ return;
379
+ case "ArrowRight":
380
+ event.preventDefault();
381
+ moveFocus({ days: 1 });
382
+ return;
383
+ case "ArrowUp":
384
+ event.preventDefault();
385
+ moveFocus({ weeks: -1 });
386
+ return;
387
+ case "ArrowDown":
388
+ event.preventDefault();
389
+ moveFocus({ weeks: 1 });
390
+ return;
391
+ case "PageUp":
392
+ event.preventDefault();
393
+ moveFocus(event.shiftKey ? { years: -1 } : { months: -1 });
394
+ return;
395
+ case "PageDown":
396
+ event.preventDefault();
397
+ moveFocus(event.shiftKey ? { years: 1 } : { months: 1 });
398
+ return;
399
+ case "Home": {
400
+ event.preventDefault();
401
+ const back = (focusedDow - firstDayOfWeek + 7) % 7;
402
+ moveFocus({ days: -back });
403
+ return;
404
+ }
405
+ case "End": {
406
+ event.preventDefault();
407
+ const back = (focusedDow - firstDayOfWeek + 7) % 7;
408
+ const forward = 6 - back;
409
+ moveFocus({ days: forward });
410
+ return;
411
+ }
412
+ case "Enter":
413
+ case " ":
414
+ event.preventDefault();
415
+ selectDate(focusedDate, "keyboard");
416
+ return;
417
+ default:
418
+ return;
419
+ }
420
+ },
421
+ [focusedDate, firstDayOfWeek, moveFocus, selectDate]
422
+ );
423
+ return { onKeyDown };
424
+ }, "useCalendarKeyboard");
425
+
426
+ // src/components/Calendar/state/constraints.ts
427
+ var cmp = /* @__PURE__ */ __name((a, b) => a.compare(b), "cmp");
428
+ var isOutOfRange = /* @__PURE__ */ __name((date, bounds = {}) => {
429
+ if (bounds.minValue && cmp(date, bounds.minValue) < 0) {
430
+ return true;
431
+ }
432
+ if (bounds.maxValue && cmp(date, bounds.maxValue) > 0) {
433
+ return true;
434
+ }
435
+ return false;
436
+ }, "isOutOfRange");
437
+ var composeUnavailable = /* @__PURE__ */ __name((c) => (date) => {
438
+ if (isOutOfRange(date, c)) {
439
+ return true;
440
+ }
441
+ if (c.isDateUnavailable?.(date)) {
442
+ return true;
443
+ }
444
+ return false;
445
+ }, "composeUnavailable");
446
+
447
+ // src/components/Calendar/state/use-calendar-state.ts
448
+ var initialFocus = /* @__PURE__ */ __name((mode, value, fallback) => {
449
+ if (!value) {
450
+ return fallback;
451
+ }
452
+ if (mode === "single") {
453
+ return value ?? fallback;
454
+ }
455
+ if (mode === "range") {
456
+ const r = value;
457
+ return r?.start ?? fallback;
458
+ }
459
+ const arr = value;
460
+ return arr[0] ?? fallback;
461
+ }, "initialFocus");
462
+ var useCalendarState = /* @__PURE__ */ __name((props) => {
463
+ const mode = props.mode ?? "single";
464
+ const fallback = date.today(date.getLocalTimeZone());
465
+ const [internalValue, setInternalValue] = react.useState(() => {
466
+ if (props.value !== void 0) {
467
+ return props.value;
468
+ }
469
+ if (props.defaultValue !== void 0) {
470
+ return props.defaultValue;
471
+ }
472
+ return mode === "multiple" ? [] : null;
473
+ });
474
+ const isControlled = props.value !== void 0;
475
+ const value = isControlled ? props.value : internalValue;
476
+ const [internalView, setInternalView] = react.useState(props.defaultView ?? "day");
477
+ const isViewControlled = props.view !== void 0;
478
+ const view = isViewControlled ? props.view : internalView;
479
+ const [focusedDate, setFocusedDate] = react.useState(() => initialFocus(mode, value, fallback));
480
+ const isUnavailable = react.useMemo(
481
+ () => composeUnavailable({
482
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
483
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
484
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {}
485
+ }),
486
+ [props.minValue, props.maxValue, props.isDateUnavailable]
487
+ );
488
+ const setView = react.useCallback(
489
+ (next) => {
490
+ if (!isViewControlled) {
491
+ setInternalView(next);
492
+ }
493
+ props.onViewChange?.(next);
494
+ },
495
+ [isViewControlled, props.onViewChange]
496
+ );
497
+ const moveFocus = react.useCallback(
498
+ (delta) => {
499
+ setFocusedDate((cur) => {
500
+ let next = cur;
501
+ if (delta.days) {
502
+ next = next.add({ days: delta.days });
503
+ }
504
+ if (delta.weeks) {
505
+ next = next.add({ weeks: delta.weeks });
506
+ }
507
+ if (delta.months) {
508
+ next = next.add({ months: delta.months });
509
+ }
510
+ if (delta.years) {
511
+ next = next.add({ years: delta.years });
512
+ }
513
+ if (!isUnavailable(next)) {
514
+ return next;
515
+ }
516
+ const totalDelta = (delta.days ?? 0) + (delta.weeks ?? 0) * 7 + (delta.months ?? 0) * 30 + (delta.years ?? 0) * 365;
517
+ const sign = totalDelta >= 0 ? 1 : -1;
518
+ for (let i = 1; i <= 100; i++) {
519
+ const candidate = next.add({ days: sign * i });
520
+ if (!isUnavailable(candidate)) {
521
+ return candidate;
522
+ }
523
+ }
524
+ return cur;
525
+ });
526
+ },
527
+ [isUnavailable]
528
+ );
529
+ const selectDate = react.useCallback(
530
+ (date, source) => {
531
+ if (isUnavailable(date)) {
532
+ return;
533
+ }
534
+ const meta = { view, source };
535
+ let next;
536
+ if (mode === "single") {
537
+ next = date;
538
+ } else if (mode === "multiple") {
539
+ const arr = value ?? [];
540
+ const exists = arr.some((d) => d.compare(date) === 0);
541
+ next = exists ? arr.filter((d) => d.compare(date) !== 0) : [...arr, date];
542
+ } else {
543
+ return;
544
+ }
545
+ if (!isControlled) {
546
+ setInternalValue(next);
547
+ }
548
+ props.onChange?.(next, meta);
549
+ setFocusedDate(date);
550
+ },
551
+ [isControlled, isUnavailable, mode, props.onChange, value, view]
552
+ );
553
+ return {
554
+ value,
555
+ view,
556
+ focusedDate,
557
+ setView,
558
+ moveFocus,
559
+ setFocusedDate,
560
+ selectDate,
561
+ isUnavailable
562
+ };
563
+ }, "useCalendarState");
564
+ var order = /* @__PURE__ */ __name((a, b) => a.compare(b) <= 0 ? [a, b] : [b, a], "order");
565
+ var nightsBetween = /* @__PURE__ */ __name((a, b) => {
566
+ const [first, last] = order(a, b);
567
+ return Math.round((last.toDate("UTC").getTime() - first.toDate("UTC").getTime()) / 864e5);
568
+ }, "nightsBetween");
569
+ var useRangeState = /* @__PURE__ */ __name((props) => {
570
+ const [internal, setInternal] = react.useState(props.defaultValue ?? null);
571
+ const isControlled = props.value !== void 0;
572
+ const value = isControlled ? props.value ?? null : internal;
573
+ const [hoveredDate, setHoveredDate] = react.useState(null);
574
+ const isUnavailable = react.useMemo(
575
+ () => composeUnavailable({
576
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
577
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
578
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {}
579
+ }),
580
+ [props.minValue, props.maxValue, props.isDateUnavailable]
581
+ );
582
+ const commit = react.useCallback(
583
+ (next, source) => {
584
+ if (!isControlled) {
585
+ setInternal(next);
586
+ }
587
+ props.onChange?.(next, { view: "day", source });
588
+ },
589
+ [isControlled, props.onChange]
590
+ );
591
+ const selectDate = react.useCallback(
592
+ (date, source = "click") => {
593
+ if (isUnavailable(date)) {
594
+ return;
595
+ }
596
+ if (!value || value.end !== null) {
597
+ commit({ start: date, end: null }, source);
598
+ setHoveredDate(null);
599
+ return;
600
+ }
601
+ const nights = nightsBetween(value.start, date);
602
+ if (props.minNights !== void 0 && nights < props.minNights) {
603
+ return;
604
+ }
605
+ if (props.maxNights !== void 0 && nights > props.maxNights) {
606
+ return;
607
+ }
608
+ const [start, end] = order(value.start, date);
609
+ commit({ start, end }, source);
610
+ setHoveredDate(null);
611
+ },
612
+ [commit, isUnavailable, props.maxNights, props.minNights, value]
613
+ );
614
+ const previewRange = react.useMemo(() => {
615
+ if (!value || value.end !== null || !hoveredDate) {
616
+ return null;
617
+ }
618
+ const [start, end] = order(value.start, hoveredDate);
619
+ return { start, end };
620
+ }, [hoveredDate, value]);
621
+ return {
622
+ value,
623
+ previewRange,
624
+ hoveredDate,
625
+ selectDate,
626
+ setHoveredDate,
627
+ isUnavailable
628
+ };
629
+ }, "useRangeState");
630
+
631
+ // src/i18n/default-dictionary.ts
632
+ var defaultDictionary = {
633
+ // generic / shared
634
+ "common.cancel": "Cancel",
635
+ "common.confirm": "Confirm",
636
+ "common.close": "Close",
637
+ "common.back": "Back",
638
+ "common.loading": "Loading",
639
+ "common.error": "Something went wrong",
640
+ "common.retry": "Try again",
641
+ // breadcrumb
642
+ "breadcrumb.ariaLabel": "Breadcrumb",
643
+ "breadcrumb.expandLabel": "Show full path",
644
+ "breadcrumb.ellipsisLabel": "More",
645
+ "breadcrumb.currentPageLabel": "Current page",
646
+ "breadcrumb.siblingMenuLabel": "Open sibling pages",
647
+ // pagination
648
+ "pagination.ariaLabel": "Pagination",
649
+ "pagination.previous": "Previous page",
650
+ "pagination.next": "Next page",
651
+ "pagination.first": "First page",
652
+ "pagination.last": "Last page",
653
+ "pagination.ellipsis": "More pages",
654
+ "pagination.currentPage": "Current page",
655
+ "pagination.gotoPage": "Go to page {{page}}",
656
+ "pagination.range": "Showing {{from}}\u2013{{to}} of {{total}}",
657
+ "pagination.pageOf": "Page {{page}} of {{total}}",
658
+ "pagination.pageSizeLabel": "Items per page",
659
+ "pagination.jumperLabel": "Go to page",
660
+ "pagination.jumperPlaceholder": "#",
661
+ // floatButton
662
+ "floatButton.backToTop": "Back to top",
663
+ // calendar
664
+ "calendar.header.previous": "Previous",
665
+ "calendar.header.next": "Next",
666
+ "calendar.header.openMonthView": "Open month picker",
667
+ "calendar.header.openYearView": "Open year picker",
668
+ "calendar.header.openDayView": "Open day picker",
669
+ "calendar.today": "Today",
670
+ "calendar.clear": "Clear",
671
+ // button
672
+ "button.loadingLabel": "Loading",
673
+ // input
674
+ "input.clear": "Clear",
675
+ "input.passwordShow": "Show password",
676
+ "input.passwordHide": "Hide password",
677
+ // checkbox / switch
678
+ "checkbox.checked": "Checked",
679
+ "checkbox.unchecked": "Unchecked",
680
+ "switch.on": "On",
681
+ "switch.off": "Off"
682
+ };
683
+
684
+ // src/i18n/resolve.ts
685
+ function resolveI18n(input, defaults) {
686
+ if (typeof input === "function") {
687
+ return (keyOrKeys, options) => input(keyOrKeys, options);
688
+ }
689
+ const dict = input ?? {};
690
+ return (keyOrKeys, options) => {
691
+ const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
692
+ for (const rawKey of keys) {
693
+ const key = pluralize(rawKey, options?.count);
694
+ const template = dict[key] ?? defaults[key];
695
+ if (template !== void 0) {
696
+ return interpolate(template, options);
697
+ }
698
+ }
699
+ const lastKey = keys[keys.length - 1];
700
+ if (options?.defaultValue !== void 0) {
701
+ return interpolate(options.defaultValue, options);
702
+ }
703
+ return lastKey ?? "";
704
+ };
705
+ }
706
+ __name(resolveI18n, "resolveI18n");
707
+ function pluralize(key, count) {
708
+ if (count === void 0) {
709
+ return key;
710
+ }
711
+ if (count === 1) {
712
+ return `${key}_one`;
713
+ }
714
+ return `${key}_other`;
715
+ }
716
+ __name(pluralize, "pluralize");
717
+ function interpolate(template, options) {
718
+ if (!options) {
719
+ return template;
720
+ }
721
+ return template.replace(/\{\{\s*([A-Za-z0-9_.-]+)\s*\}\}/g, (_match, name) => {
722
+ const value = options[name];
723
+ return value === void 0 || value === null ? "" : String(value);
724
+ });
725
+ }
726
+ __name(interpolate, "interpolate");
727
+ var defaultValue = {
728
+ t: resolveI18n(void 0, defaultDictionary)
729
+ };
730
+ var I18nContext = react.createContext(defaultValue);
731
+ I18nContext.displayName = "I18nContext";
732
+
733
+ // src/i18n/use-translation.ts
734
+ function useTranslation() {
735
+ return react.useContext(I18nContext);
736
+ }
737
+ __name(useTranslation, "useTranslation");
738
+ var isWeb2 = reactNative.Platform.OS === "web";
739
+ var make = /* @__PURE__ */ __name(({ path, glyph }) => /* @__PURE__ */ __name(function PlaceholderIcon({ size = 20, color = "currentColor" }) {
740
+ const colors = useThemeColors();
741
+ if (isWeb2) {
742
+ return /* @__PURE__ */ jsxRuntime.jsx(
743
+ "svg",
744
+ {
745
+ width: size,
746
+ height: size,
747
+ viewBox: "0 0 24 24",
748
+ fill: "none",
749
+ stroke: color,
750
+ strokeWidth: "2",
751
+ strokeLinecap: "round",
752
+ strokeLinejoin: "round",
753
+ "aria-hidden": "true",
754
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: path })
755
+ }
756
+ );
757
+ }
758
+ const resolvedColor = color === "currentColor" ? colors.semantic.text.default : color;
759
+ return /* @__PURE__ */ jsxRuntime.jsx(
760
+ reactNative.Text,
761
+ {
762
+ accessibilityElementsHidden: true,
763
+ importantForAccessibility: "no-hide-descendants",
764
+ style: { fontSize: size, lineHeight: size, color: resolvedColor },
765
+ children: glyph
766
+ }
767
+ );
768
+ }, "PlaceholderIcon"), "make");
769
+ var defaultSemanticIcons = {
770
+ checkmark: make({ path: "M20 6 9 17l-5-5", glyph: "\u2713" }),
771
+ close: make({ path: "M18 6 6 18 M6 6l12 12", glyph: "\u2715" }),
772
+ eye: make({
773
+ path: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z",
774
+ glyph: "\u{1F441}"
775
+ }),
776
+ eyeOff: make({
777
+ path: "M17.94 17.94A10 10 0 0 1 2 12s3.5-7 10-7c2 0 3.8.6 5.4 1.5 M1 1l22 22",
778
+ glyph: "\u{1F648}"
779
+ }),
780
+ chevronDown: make({ path: "m6 9 6 6 6-6", glyph: "\u2304" }),
781
+ chevronUp: make({ path: "m18 15-6-6-6 6", glyph: "\u2303" }),
782
+ alertTriangle: make({
783
+ path: "M12 9v4 M12 17h.01 M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z",
784
+ glyph: "\u26A0"
785
+ }),
786
+ info: make({
787
+ path: "M12 8h.01 M11 12h1v4h1 M12 22C6.48 22 2 17.52 2 12 2 6.48 6.48 2 12 2c5.52 0 10 4.48 10 10 0 5.52-4.48 10-10 10z",
788
+ glyph: "\u24D8"
789
+ }),
790
+ check: make({ path: "M20 6 9 17l-5-5", glyph: "\u2713" }),
791
+ x: make({ path: "M18 6 6 18 M6 6l12 12", glyph: "\u2715" })
792
+ };
793
+
794
+ // src/theme/px.ts
795
+ function px(value) {
796
+ if (typeof value === "number") {
797
+ return value;
798
+ }
799
+ const n = Number.parseFloat(value);
800
+ return Number.isFinite(n) ? n : 0;
801
+ }
802
+ __name(px, "px");
803
+
804
+ // src/utils/cn.ts
805
+ function cn(...inputs) {
806
+ const out = [];
807
+ for (const input of inputs) {
808
+ append(out, input);
809
+ }
810
+ return out.join(" ");
811
+ }
812
+ __name(cn, "cn");
813
+ function append(out, input) {
814
+ if (!input) {
815
+ return;
816
+ }
817
+ if (typeof input === "string") {
818
+ if (input.length > 0) {
819
+ out.push(input);
820
+ }
821
+ return;
822
+ }
823
+ if (typeof input === "number") {
824
+ return;
825
+ }
826
+ if (Array.isArray(input)) {
827
+ for (const inner of input) {
828
+ append(out, inner);
829
+ }
830
+ return;
831
+ }
832
+ if (typeof input === "object") {
833
+ for (const key of Object.keys(input)) {
834
+ if (input[key]) {
835
+ out.push(key);
836
+ }
837
+ }
838
+ }
839
+ }
840
+ __name(append, "append");
841
+ var DEFAULT_PAGE_SIZE = 50;
842
+ var DEFAULT_ITEM_HEIGHT = 36;
843
+ var DEFAULT_MAX_MENU = 320;
844
+ var SEARCH_DEBOUNCE_MS = 150;
845
+ var VIRTUAL_OVERSCAN = 4;
846
+ var TYPE_AHEAD_RESET_MS = 500;
847
+ var defaultFilter = /* @__PURE__ */ __name((option, search) => {
848
+ if (!search) {
849
+ return true;
850
+ }
851
+ return option.label.toLowerCase().includes(search.toLowerCase());
852
+ }, "defaultFilter");
853
+ var Select = /* @__PURE__ */ __name((props) => {
854
+ const {
855
+ options: staticOptions,
856
+ loadOptions,
857
+ pageSize = DEFAULT_PAGE_SIZE,
858
+ searchable: searchableProp,
859
+ searchPlaceholder = "Search\u2026",
860
+ filterOption,
861
+ renderOption,
862
+ placeholder = "Select\u2026",
863
+ locale,
864
+ sortByLocale = true,
865
+ noOptionsMessage = "No options",
866
+ loadingMessage = "Loading\u2026",
867
+ disabled = false,
868
+ dir = "ltr",
869
+ virtualized: virtualizedProp,
870
+ itemHeight = DEFAULT_ITEM_HEIGHT,
871
+ maxMenuHeight = DEFAULT_MAX_MENU,
872
+ className,
873
+ testID
874
+ } = props;
875
+ const ariaLabel = props["aria-label"];
876
+ const multiple = props.multiple === true;
877
+ const maxSelected = multiple ? props.maxSelected : void 0;
878
+ const maxChips = multiple ? props.maxChips ?? 3 : void 0;
879
+ const baseId = react.useId();
880
+ const colors = useThemeColors();
881
+ const [open, setOpen] = react.useState(false);
882
+ const controlledValues = multiple ? props.value : props.value !== void 0 ? [props.value] : void 0;
883
+ const defaultValues = multiple ? props.defaultValue ?? [] : props.defaultValue !== void 0 ? [props.defaultValue] : [];
884
+ const [innerValues, setInnerValues] = react.useState(defaultValues);
885
+ const isControlled = controlledValues !== void 0;
886
+ const currentValues = isControlled ? controlledValues : innerValues;
887
+ const current = currentValues[0];
888
+ const [searchInput, setSearchInput] = react.useState("");
889
+ const [debouncedSearch, setDebouncedSearch] = react.useState("");
890
+ const [activeIndex, setActiveIndex] = react.useState(0);
891
+ react.useEffect(() => {
892
+ const t = setTimeout(() => setDebouncedSearch(searchInput), SEARCH_DEBOUNCE_MS);
893
+ return () => clearTimeout(t);
894
+ }, [searchInput]);
895
+ const [asyncItems, setAsyncItems] = react.useState([]);
896
+ const [asyncLoading, setAsyncLoading] = react.useState(false);
897
+ const [asyncTotal, setAsyncTotal] = react.useState(void 0);
898
+ const asyncRequestId = react.useRef(0);
899
+ const isAsync = loadOptions !== void 0;
900
+ react.useEffect(() => {
901
+ if (!isAsync || !loadOptions || !open) {
902
+ return;
903
+ }
904
+ const requestId = ++asyncRequestId.current;
905
+ setAsyncLoading(true);
906
+ setAsyncItems([]);
907
+ setAsyncTotal(void 0);
908
+ loadOptions({ search: debouncedSearch, offset: 0, limit: pageSize }).then((result) => {
909
+ if (requestId !== asyncRequestId.current) {
910
+ return;
911
+ }
912
+ setAsyncItems(result.items.slice());
913
+ setAsyncTotal(result.total);
914
+ }).catch(() => {
915
+ }).finally(() => {
916
+ if (requestId === asyncRequestId.current) {
917
+ setAsyncLoading(false);
918
+ }
919
+ });
920
+ }, [debouncedSearch, isAsync, loadOptions, pageSize, open]);
921
+ const loadMore = react.useCallback(() => {
922
+ if (!isAsync || !loadOptions || asyncLoading) {
923
+ return;
924
+ }
925
+ const haveAll = asyncTotal !== void 0 && asyncItems.length >= asyncTotal;
926
+ if (haveAll) {
927
+ return;
928
+ }
929
+ const requestId = ++asyncRequestId.current;
930
+ setAsyncLoading(true);
931
+ loadOptions({ search: debouncedSearch, offset: asyncItems.length, limit: pageSize }).then((result) => {
932
+ if (requestId !== asyncRequestId.current) {
933
+ return;
934
+ }
935
+ setAsyncItems((prev) => prev.concat(result.items));
936
+ if (result.total !== void 0) {
937
+ setAsyncTotal(result.total);
938
+ }
939
+ }).catch(() => void 0).finally(() => {
940
+ if (requestId === asyncRequestId.current) {
941
+ setAsyncLoading(false);
942
+ }
943
+ });
944
+ }, [asyncItems.length, asyncLoading, asyncTotal, debouncedSearch, isAsync, loadOptions, pageSize]);
945
+ const visibleOptions = react.useMemo(() => {
946
+ const source = isAsync ? asyncItems : staticOptions ?? [];
947
+ const filtered = isAsync ? source.slice() : source.filter((opt) => (filterOption ?? defaultFilter)(opt, debouncedSearch));
948
+ if (locale && sortByLocale) {
949
+ const collator = new Intl.Collator(locale, { sensitivity: "base", numeric: true });
950
+ return filtered.slice().sort((a, b) => {
951
+ const ga = a.group ?? "";
952
+ const gb = b.group ?? "";
953
+ const groupDelta = collator.compare(ga, gb);
954
+ if (groupDelta !== 0) {
955
+ return groupDelta;
956
+ }
957
+ return collator.compare(a.label, b.label);
958
+ });
959
+ }
960
+ return filtered;
961
+ }, [isAsync, asyncItems, staticOptions, filterOption, debouncedSearch, locale, sortByLocale]);
962
+ const selectedOption = react.useMemo(() => {
963
+ const all = isAsync ? asyncItems : staticOptions ?? [];
964
+ return all.find((o) => o.value === current);
965
+ }, [asyncItems, isAsync, staticOptions, current]);
966
+ const selectedOptions = react.useMemo(() => {
967
+ if (!multiple) {
968
+ return [];
969
+ }
970
+ const all = isAsync ? asyncItems : staticOptions ?? [];
971
+ const map = new Map(all.map((o) => [o.value, o]));
972
+ return currentValues.map((v) => map.get(v)).filter((o) => o !== void 0);
973
+ }, [multiple, currentValues, asyncItems, isAsync, staticOptions]);
974
+ const searchable = searchableProp ?? (isAsync || staticOptions !== void 0 && staticOptions.length >= 10);
975
+ const virtualized = virtualizedProp ?? visibleOptions.length > 100;
976
+ react.useEffect(() => {
977
+ setActiveIndex((idx) => Math.min(Math.max(0, idx), Math.max(0, visibleOptions.length - 1)));
978
+ }, [visibleOptions.length]);
979
+ const onSelect = react.useCallback(
980
+ (option) => {
981
+ if (option.disabled) {
982
+ return;
983
+ }
984
+ if (multiple) {
985
+ const has = currentValues.includes(option.value);
986
+ let nextValues;
987
+ if (has) {
988
+ nextValues = currentValues.filter((v) => v !== option.value);
989
+ } else {
990
+ if (maxSelected !== void 0 && currentValues.length >= maxSelected) {
991
+ return;
992
+ }
993
+ nextValues = [...currentValues, option.value];
994
+ }
995
+ if (!isControlled) {
996
+ setInnerValues(nextValues);
997
+ }
998
+ const allOpts = [
999
+ ...staticOptions ?? [],
1000
+ ...asyncItems
1001
+ ];
1002
+ const optMap = new Map(allOpts.map((o) => [o.value, o]));
1003
+ const selectedOpts = nextValues.map((v) => optMap.get(v)).filter((o) => o !== void 0);
1004
+ props.onChange?.(nextValues, selectedOpts);
1005
+ return;
1006
+ }
1007
+ if (!isControlled) {
1008
+ setInnerValues([option.value]);
1009
+ }
1010
+ props.onChange?.(option.value, option);
1011
+ setOpen(false);
1012
+ setSearchInput("");
1013
+ },
1014
+ // biome-ignore lint/correctness/useExhaustiveDependencies: `props` is the discriminated union — destructuring it would defeat the narrowing; the asyncItems / staticOptions captures intentionally re-trigger the callback when the option pool changes
1015
+ [multiple, isControlled, currentValues, maxSelected, staticOptions, asyncItems, props]
1016
+ );
1017
+ const clearAll = react.useCallback(() => {
1018
+ if (!isControlled) {
1019
+ setInnerValues([]);
1020
+ }
1021
+ props.onChange?.([], []);
1022
+ }, [isControlled, props]);
1023
+ const moveActive = react.useCallback(
1024
+ (delta) => {
1025
+ setActiveIndex((idx) => {
1026
+ if (visibleOptions.length === 0) {
1027
+ return 0;
1028
+ }
1029
+ let next = (idx + delta + visibleOptions.length) % visibleOptions.length;
1030
+ for (let attempts = 0; attempts < visibleOptions.length; attempts += 1) {
1031
+ if (!visibleOptions[next]?.disabled) {
1032
+ return next;
1033
+ }
1034
+ next = (next + delta + visibleOptions.length) % visibleOptions.length;
1035
+ }
1036
+ return idx;
1037
+ });
1038
+ },
1039
+ [visibleOptions]
1040
+ );
1041
+ const typeAheadRef = react.useRef({
1042
+ buffer: "",
1043
+ timer: null
1044
+ });
1045
+ react.useEffect(() => {
1046
+ return () => {
1047
+ if (typeAheadRef.current.timer) {
1048
+ clearTimeout(typeAheadRef.current.timer);
1049
+ typeAheadRef.current.timer = null;
1050
+ }
1051
+ };
1052
+ }, []);
1053
+ const handleTypeAhead = react.useCallback(
1054
+ (char) => {
1055
+ if (visibleOptions.length === 0) {
1056
+ return;
1057
+ }
1058
+ if (typeAheadRef.current.timer) {
1059
+ clearTimeout(typeAheadRef.current.timer);
1060
+ }
1061
+ const nextBuffer = typeAheadRef.current.buffer + char.toLowerCase();
1062
+ typeAheadRef.current.buffer = nextBuffer;
1063
+ typeAheadRef.current.timer = setTimeout(() => {
1064
+ typeAheadRef.current.buffer = "";
1065
+ typeAheadRef.current.timer = null;
1066
+ }, TYPE_AHEAD_RESET_MS);
1067
+ const allSame = nextBuffer.length > 1 && nextBuffer.split("").every((c) => c === nextBuffer[0]);
1068
+ const cycleMode = nextBuffer.length === 1 || allSame;
1069
+ const needle = cycleMode ? nextBuffer.charAt(0) : nextBuffer;
1070
+ const len = visibleOptions.length;
1071
+ const startFrom = cycleMode ? (activeIndex + 1) % len : 0;
1072
+ for (let i = 0; i < len; i += 1) {
1073
+ const idx = (startFrom + i) % len;
1074
+ const opt = visibleOptions[idx];
1075
+ if (!opt || opt.disabled) {
1076
+ continue;
1077
+ }
1078
+ if (opt.label.toLowerCase().startsWith(needle)) {
1079
+ setActiveIndex(idx);
1080
+ return;
1081
+ }
1082
+ }
1083
+ },
1084
+ [visibleOptions, activeIndex]
1085
+ );
1086
+ const handleListKeyDown = react.useCallback(
1087
+ (event) => {
1088
+ switch (event.key) {
1089
+ case "ArrowDown":
1090
+ event.preventDefault();
1091
+ moveActive(1);
1092
+ return true;
1093
+ case "ArrowUp":
1094
+ event.preventDefault();
1095
+ moveActive(-1);
1096
+ return true;
1097
+ case "Home": {
1098
+ event.preventDefault();
1099
+ const idx = visibleOptions.findIndex((o) => !o.disabled);
1100
+ if (idx >= 0) {
1101
+ setActiveIndex(idx);
1102
+ }
1103
+ return true;
1104
+ }
1105
+ case "End": {
1106
+ event.preventDefault();
1107
+ for (let i = visibleOptions.length - 1; i >= 0; i -= 1) {
1108
+ if (!visibleOptions[i]?.disabled) {
1109
+ setActiveIndex(i);
1110
+ break;
1111
+ }
1112
+ }
1113
+ return true;
1114
+ }
1115
+ case "Enter": {
1116
+ const opt = visibleOptions[activeIndex];
1117
+ if (opt) {
1118
+ event.preventDefault();
1119
+ onSelect(opt);
1120
+ }
1121
+ return true;
1122
+ }
1123
+ case "Escape":
1124
+ event.preventDefault();
1125
+ setOpen(false);
1126
+ if (reactNative.Platform.OS === "web") {
1127
+ const trigger = triggerRef.current;
1128
+ trigger?.focus?.();
1129
+ }
1130
+ return true;
1131
+ case "Tab":
1132
+ setOpen(false);
1133
+ return true;
1134
+ }
1135
+ return false;
1136
+ },
1137
+ [moveActive, activeIndex, visibleOptions, onSelect]
1138
+ );
1139
+ const handleSearchKeyDown = react.useCallback(
1140
+ (event) => {
1141
+ handleListKeyDown(event);
1142
+ },
1143
+ [handleListKeyDown]
1144
+ );
1145
+ const handlePopupKeyDown = react.useCallback(
1146
+ (event) => {
1147
+ if (handleListKeyDown(event)) {
1148
+ return;
1149
+ }
1150
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey && event.key !== " ") {
1151
+ event.preventDefault();
1152
+ handleTypeAhead(event.key);
1153
+ }
1154
+ },
1155
+ [handleListKeyDown, handleTypeAhead]
1156
+ );
1157
+ const handleTriggerKeyDown = react.useCallback(
1158
+ (event) => {
1159
+ switch (event.key) {
1160
+ case " ":
1161
+ case "Enter":
1162
+ case "ArrowDown":
1163
+ case "ArrowUp":
1164
+ event.preventDefault();
1165
+ setOpen(true);
1166
+ return;
1167
+ }
1168
+ if (!disabled && event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
1169
+ event.preventDefault();
1170
+ setOpen(true);
1171
+ handleTypeAhead(event.key);
1172
+ }
1173
+ },
1174
+ [disabled, handleTypeAhead]
1175
+ );
1176
+ const containerRef = react.useRef(null);
1177
+ const triggerRef = react.useRef(null);
1178
+ const popupRef = react.useRef(null);
1179
+ react.useEffect(() => {
1180
+ if (reactNative.Platform.OS !== "web" || typeof document === "undefined" || typeof document.addEventListener !== "function") {
1181
+ return;
1182
+ }
1183
+ if (!open) {
1184
+ return;
1185
+ }
1186
+ const onDocClick = /* @__PURE__ */ __name((event) => {
1187
+ const node = containerRef.current;
1188
+ const popup = popupRef.current;
1189
+ const target = event.target;
1190
+ if (node?.contains(target)) {
1191
+ return;
1192
+ }
1193
+ if (popup?.contains(target)) {
1194
+ return;
1195
+ }
1196
+ setOpen(false);
1197
+ }, "onDocClick");
1198
+ document.addEventListener("mousedown", onDocClick);
1199
+ return () => document.removeEventListener("mousedown", onDocClick);
1200
+ }, [open]);
1201
+ const [triggerRect, setTriggerRect] = react.useState(
1202
+ null
1203
+ );
1204
+ const measureTrigger = react.useCallback(() => {
1205
+ const node = triggerRef.current;
1206
+ if (!node) {
1207
+ return;
1208
+ }
1209
+ if (reactNative.Platform.OS === "web" && typeof node.getBoundingClientRect === "function") {
1210
+ const rect = node.getBoundingClientRect();
1211
+ setTriggerRect({ top: rect.top, left: rect.left, width: rect.width, height: rect.height });
1212
+ return;
1213
+ }
1214
+ if (typeof node.measure === "function") {
1215
+ node.measure((_x, _y, w, h, pageX, pageY) => {
1216
+ setTriggerRect({ top: pageY, left: pageX, width: w, height: h });
1217
+ });
1218
+ }
1219
+ }, []);
1220
+ react.useEffect(() => {
1221
+ if (!open) {
1222
+ return;
1223
+ }
1224
+ if (reactNative.Platform.OS !== "web" || typeof window === "undefined" || typeof window.addEventListener !== "function") {
1225
+ return;
1226
+ }
1227
+ measureTrigger();
1228
+ window.addEventListener("scroll", measureTrigger, true);
1229
+ window.addEventListener("resize", measureTrigger);
1230
+ return () => {
1231
+ window.removeEventListener("scroll", measureTrigger, true);
1232
+ window.removeEventListener("resize", measureTrigger);
1233
+ };
1234
+ }, [open, measureTrigger]);
1235
+ react.useEffect(() => {
1236
+ if (!open || searchable || reactNative.Platform.OS !== "web") {
1237
+ return;
1238
+ }
1239
+ const id = requestAnimationFrame(() => {
1240
+ const node = popupRef.current;
1241
+ node?.focus?.();
1242
+ });
1243
+ return () => cancelAnimationFrame(id);
1244
+ }, [open, searchable]);
1245
+ const onListScroll = react.useCallback(
1246
+ (event) => {
1247
+ if (!isAsync) {
1248
+ return;
1249
+ }
1250
+ const { contentOffset, contentSize, layoutMeasurement } = event.nativeEvent;
1251
+ const remaining = contentSize.height - contentOffset.y - layoutMeasurement.height;
1252
+ if (remaining < itemHeight * 4) {
1253
+ loadMore();
1254
+ }
1255
+ },
1256
+ [isAsync, itemHeight, loadMore]
1257
+ );
1258
+ const triggerStyle = {
1259
+ flexDirection: "row",
1260
+ alignItems: "center",
1261
+ justifyContent: "space-between",
1262
+ gap: px(colors.spacing["2"]),
1263
+ paddingHorizontal: px(colors.spacing["3"]),
1264
+ paddingVertical: px(colors.spacing["2"]),
1265
+ minHeight: 36,
1266
+ // component-density literal — not from theme
1267
+ borderWidth: 1,
1268
+ borderColor: colors.semantic.border.default,
1269
+ borderRadius: px(colors.radius.md),
1270
+ backgroundColor: colors.semantic.background.elevated,
1271
+ opacity: disabled ? 0.6 : 1
1272
+ };
1273
+ const winDims = reactNative.useWindowDimensions();
1274
+ const popupStyle = triggerRect ? {
1275
+ position: reactNative.Platform.OS === "web" ? "fixed" : "absolute",
1276
+ top: triggerRect.top + triggerRect.height + px(colors.spacing["1"]),
1277
+ left: dir === "rtl" ? void 0 : triggerRect.left,
1278
+ right: dir === "rtl" ? reactNative.Platform.OS === "web" && typeof window !== "undefined" ? window.innerWidth - (triggerRect.left + triggerRect.width) : winDims.width - (triggerRect.left + triggerRect.width) : void 0,
1279
+ minWidth: Math.max(200, triggerRect.width),
1280
+ backgroundColor: colors.semantic.background.elevated,
1281
+ borderRadius: px(colors.radius.lg),
1282
+ borderWidth: 1,
1283
+ borderColor: colors.semantic.border.default,
1284
+ // 2147483646 (max int32 - 1) so we sit above any third-party
1285
+ // chrome (toasts, modals, dev banners) without picking a fight
1286
+ // for the very top slot. Combined with portaling to body below,
1287
+ // this also dodges any ancestor stacking context that would
1288
+ // otherwise trap our z-index inside a sibling preview frame.
1289
+ zIndex: 2147483646,
1290
+ ...{ boxShadow: "0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)" }
1291
+ } : {
1292
+ // Trigger not yet measured — render off-screen until the
1293
+ // first measurement lands. Avoids a one-frame flash at (0,0).
1294
+ position: reactNative.Platform.OS === "web" ? "fixed" : "absolute",
1295
+ top: -9999,
1296
+ left: -9999
1297
+ };
1298
+ const containerProps = {
1299
+ ref: /* @__PURE__ */ __name((node) => {
1300
+ containerRef.current = node;
1301
+ }, "ref"),
1302
+ ...testID !== void 0 ? { testID } : {},
1303
+ dir
1304
+ };
1305
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { ...containerProps, className: cn("relative", className), style: { position: "relative" }, children: [
1306
+ /* @__PURE__ */ jsxRuntime.jsxs(
1307
+ reactNative.Pressable,
1308
+ {
1309
+ ref: (node) => {
1310
+ triggerRef.current = node;
1311
+ },
1312
+ ...{
1313
+ onKeyDown: handleTriggerKeyDown,
1314
+ role: "combobox",
1315
+ accessibilityRole: "combobox",
1316
+ "aria-expanded": open,
1317
+ "aria-controls": `${baseId}-listbox`,
1318
+ "aria-haspopup": "listbox",
1319
+ tabIndex: disabled ? -1 : 0,
1320
+ ...ariaLabel !== void 0 ? { "aria-label": ariaLabel, accessibilityLabel: ariaLabel } : {},
1321
+ ...disabled ? { "aria-disabled": true, disabled: true } : {}
1322
+ },
1323
+ onPress: () => {
1324
+ if (disabled) {
1325
+ return;
1326
+ }
1327
+ measureTrigger();
1328
+ setOpen((v) => !v);
1329
+ },
1330
+ style: triggerStyle,
1331
+ children: [
1332
+ multiple ? /* @__PURE__ */ jsxRuntime.jsx(MultiTriggerLabel, { options: selectedOptions, placeholder, maxChips: maxChips ?? 3 }) : /* @__PURE__ */ jsxRuntime.jsx(
1333
+ reactNative.Text,
1334
+ {
1335
+ style: {
1336
+ color: selectedOption ? colors.semantic.text.default : colors.semantic.text.muted,
1337
+ fontFamily: colors.fontFamily.body,
1338
+ fontSize: px(colors.fontSize.sm),
1339
+ flex: 1
1340
+ },
1341
+ numberOfLines: 1,
1342
+ children: selectedOption?.label ?? placeholder
1343
+ }
1344
+ ),
1345
+ /* @__PURE__ */ jsxRuntime.jsx(defaultSemanticIcons.chevronDown, { size: 16, color: colors.semantic.text.muted })
1346
+ ]
1347
+ }
1348
+ ),
1349
+ open ? renderPopup() : null
1350
+ ] });
1351
+ function renderPopup() {
1352
+ const popup = /* @__PURE__ */ jsxRuntime.jsxs(
1353
+ reactNative.View,
1354
+ {
1355
+ ref: (node) => {
1356
+ popupRef.current = node;
1357
+ },
1358
+ ...{
1359
+ role: "listbox",
1360
+ id: `${baseId}-listbox`,
1361
+ ...multiple ? { "aria-multiselectable": true } : {},
1362
+ // Without a search field there's no input to capture
1363
+ // keystrokes — make the popup itself focusable and own
1364
+ // arrow / Enter / Escape / type-ahead. With a search
1365
+ // field these belong to the input below.
1366
+ ...searchable ? {} : { tabIndex: -1, onKeyDown: handlePopupKeyDown }
1367
+ },
1368
+ style: popupStyle,
1369
+ children: [
1370
+ searchable ? /* @__PURE__ */ jsxRuntime.jsx(
1371
+ SearchInput,
1372
+ {
1373
+ value: searchInput,
1374
+ onChange: setSearchInput,
1375
+ onKeyDown: handleSearchKeyDown,
1376
+ placeholder: searchPlaceholder,
1377
+ dir
1378
+ }
1379
+ ) : null,
1380
+ multiple && currentValues.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(MultiSelectionHeader, { count: currentValues.length, onClearAll: clearAll }) : null,
1381
+ /* @__PURE__ */ jsxRuntime.jsx(
1382
+ SelectList,
1383
+ {
1384
+ options: visibleOptions,
1385
+ activeIndex,
1386
+ currentValue: current,
1387
+ selectedValues: currentValues,
1388
+ multiple,
1389
+ onSelect,
1390
+ onActiveChange: setActiveIndex,
1391
+ ...renderOption !== void 0 ? { renderOption } : {},
1392
+ itemHeight,
1393
+ maxHeight: maxMenuHeight,
1394
+ virtualized,
1395
+ loading: isAsync && asyncLoading,
1396
+ loadingMessage,
1397
+ noOptionsMessage,
1398
+ listboxId: `${baseId}-listbox`,
1399
+ onScroll: onListScroll
1400
+ }
1401
+ )
1402
+ ]
1403
+ }
1404
+ );
1405
+ if (reactNative.Platform.OS === "web" && typeof document !== "undefined") {
1406
+ return reactDom.createPortal(popup, document.body);
1407
+ }
1408
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Modal, { transparent: true, visible: true, animationType: "fade", onRequestClose: () => setOpen(false), statusBarTranslucent: true, children: [
1409
+ /* @__PURE__ */ jsxRuntime.jsx(
1410
+ reactNative.Pressable,
1411
+ {
1412
+ onPress: () => setOpen(false),
1413
+ style: {
1414
+ position: "absolute",
1415
+ top: 0,
1416
+ left: 0,
1417
+ right: 0,
1418
+ bottom: 0
1419
+ }
1420
+ }
1421
+ ),
1422
+ popup
1423
+ ] });
1424
+ }
1425
+ }, "Select");
1426
+ var SearchInput = /* @__PURE__ */ __name(({ value, onChange, onKeyDown, placeholder, dir }) => {
1427
+ const colors = useThemeColors();
1428
+ const inputRef = react.useRef(null);
1429
+ react.useEffect(() => {
1430
+ inputRef.current?.focus?.();
1431
+ }, []);
1432
+ return /* @__PURE__ */ jsxRuntime.jsx(
1433
+ reactNative.View,
1434
+ {
1435
+ style: {
1436
+ paddingHorizontal: px(colors.spacing["2"]),
1437
+ paddingVertical: px(colors.spacing["2"]),
1438
+ borderBottomWidth: 1,
1439
+ borderBottomColor: colors.semantic.border.default
1440
+ },
1441
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1442
+ "input",
1443
+ {
1444
+ ref: inputRef,
1445
+ type: "text",
1446
+ value,
1447
+ onChange: (event) => onChange(event.target.value),
1448
+ onKeyDown,
1449
+ placeholder,
1450
+ dir,
1451
+ "aria-label": "Search options",
1452
+ style: {
1453
+ width: "100%",
1454
+ // Inline `padding: '6px 8px'` shorthand intentionally kept as a
1455
+ // string for the native HTML <input> — it's not an RN style prop.
1456
+ padding: `${px(colors.spacing["2"]) - 2}px ${px(colors.spacing["2"])}px`,
1457
+ fontFamily: colors.fontFamily.body,
1458
+ fontSize: px(colors.fontSize.sm),
1459
+ color: colors.semantic.text.default,
1460
+ backgroundColor: colors.semantic.background.elevated,
1461
+ border: `1px solid ${colors.semantic.border.default}`,
1462
+ borderRadius: px(colors.radius.sm),
1463
+ outline: "none"
1464
+ }
1465
+ }
1466
+ )
1467
+ }
1468
+ );
1469
+ }, "SearchInput");
1470
+ var SelectList = /* @__PURE__ */ __name(({
1471
+ options,
1472
+ activeIndex,
1473
+ currentValue,
1474
+ selectedValues,
1475
+ multiple,
1476
+ onSelect,
1477
+ onActiveChange,
1478
+ renderOption,
1479
+ itemHeight,
1480
+ maxHeight,
1481
+ virtualized,
1482
+ loading,
1483
+ loadingMessage,
1484
+ noOptionsMessage,
1485
+ listboxId,
1486
+ onScroll
1487
+ }) => {
1488
+ const colors = useThemeColors();
1489
+ const [scrollTop, setScrollTop] = react.useState(0);
1490
+ const totalHeight = options.length * itemHeight;
1491
+ const visibleStart = virtualized ? Math.max(0, Math.floor(scrollTop / itemHeight) - VIRTUAL_OVERSCAN) : 0;
1492
+ const visibleEnd = virtualized ? Math.min(options.length, Math.ceil((scrollTop + maxHeight) / itemHeight) + VIRTUAL_OVERSCAN) : options.length;
1493
+ const handleScroll = /* @__PURE__ */ __name((event) => {
1494
+ if (virtualized) {
1495
+ setScrollTop(event.nativeEvent.contentOffset.y);
1496
+ }
1497
+ onScroll(event);
1498
+ }, "handleScroll");
1499
+ if (loading && options.length === 0) {
1500
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { padding: px(colors.spacing["4"]), alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1501
+ reactNative.Text,
1502
+ {
1503
+ style: {
1504
+ color: colors.semantic.text.muted,
1505
+ fontFamily: colors.fontFamily.body,
1506
+ fontSize: px(colors.fontSize.sm)
1507
+ },
1508
+ children: loadingMessage
1509
+ }
1510
+ ) });
1511
+ }
1512
+ if (options.length === 0) {
1513
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { padding: px(colors.spacing["4"]), alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1514
+ reactNative.Text,
1515
+ {
1516
+ style: {
1517
+ color: colors.semantic.text.muted,
1518
+ fontFamily: colors.fontFamily.body,
1519
+ fontSize: px(colors.fontSize.sm)
1520
+ },
1521
+ children: noOptionsMessage
1522
+ }
1523
+ ) });
1524
+ }
1525
+ const items = [];
1526
+ let lastGroup;
1527
+ for (let i = visibleStart; i < visibleEnd; i += 1) {
1528
+ const opt = options[i];
1529
+ if (!opt) {
1530
+ continue;
1531
+ }
1532
+ if (opt.group !== lastGroup && opt.group !== void 0) {
1533
+ items.push(
1534
+ /* @__PURE__ */ jsxRuntime.jsx(
1535
+ reactNative.View,
1536
+ {
1537
+ style: {
1538
+ paddingHorizontal: px(colors.spacing["3"]),
1539
+ paddingTop: px(colors.spacing["2"]),
1540
+ paddingBottom: px(colors.spacing["1"]),
1541
+ position: virtualized ? "absolute" : "relative",
1542
+ top: virtualized ? i * itemHeight - px(colors.spacing["4"]) : void 0,
1543
+ left: 0,
1544
+ right: 0
1545
+ },
1546
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1547
+ reactNative.Text,
1548
+ {
1549
+ style: {
1550
+ color: colors.semantic.text.muted,
1551
+ fontFamily: colors.fontFamily.body,
1552
+ fontSize: 11,
1553
+ // group header — component-density literal — not from theme (smaller than xs)
1554
+ fontWeight: colors.fontWeight.semibold,
1555
+ textTransform: "uppercase",
1556
+ letterSpacing: 0.5
1557
+ },
1558
+ children: opt.group
1559
+ }
1560
+ )
1561
+ },
1562
+ `grp-${i}-${opt.group}`
1563
+ )
1564
+ );
1565
+ lastGroup = opt.group;
1566
+ }
1567
+ const selected = multiple ? selectedValues.includes(opt.value) : opt.value === currentValue;
1568
+ const active = i === activeIndex;
1569
+ const itemNode = renderOption ? renderOption(opt, { selected, active }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultOptionRow, { option: opt, selected, active, multiple });
1570
+ items.push(
1571
+ /* @__PURE__ */ jsxRuntime.jsx(
1572
+ reactNative.Pressable,
1573
+ {
1574
+ ...{
1575
+ role: "option",
1576
+ accessibilityRole: "none",
1577
+ "aria-selected": selected,
1578
+ onMouseEnter: /* @__PURE__ */ __name(() => onActiveChange(i), "onMouseEnter"),
1579
+ ...opt.disabled ? { "aria-disabled": true, disabled: true } : {}
1580
+ },
1581
+ onPress: () => onSelect(opt),
1582
+ style: {
1583
+ position: virtualized ? "absolute" : "relative",
1584
+ top: virtualized ? i * itemHeight : void 0,
1585
+ left: 0,
1586
+ right: 0,
1587
+ height: itemHeight,
1588
+ flexDirection: "row",
1589
+ alignItems: "center",
1590
+ paddingHorizontal: px(colors.spacing["3"]),
1591
+ backgroundColor: active ? colors.semantic.background.subtle : "transparent",
1592
+ opacity: opt.disabled ? 0.5 : 1
1593
+ },
1594
+ children: itemNode
1595
+ },
1596
+ `opt-${i}-${opt.value}`
1597
+ )
1598
+ );
1599
+ }
1600
+ return /* @__PURE__ */ jsxRuntime.jsx(
1601
+ reactNative.ScrollView,
1602
+ {
1603
+ nativeID: listboxId,
1604
+ onScroll: handleScroll,
1605
+ scrollEventThrottle: 16,
1606
+ style: { maxHeight },
1607
+ contentContainerStyle: virtualized ? { height: totalHeight, position: "relative" } : void 0,
1608
+ children: items
1609
+ }
1610
+ );
1611
+ }, "SelectList");
1612
+ var DefaultOptionRow = /* @__PURE__ */ __name(({
1613
+ option,
1614
+ selected,
1615
+ active,
1616
+ multiple = false
1617
+ }) => {
1618
+ const colors = useThemeColors();
1619
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, gap: px(colors.spacing["2"]) }, children: [
1620
+ multiple ? (
1621
+ // Inline checkbox-style indicator. We don't reuse <Checkbox>
1622
+ // here because the row is already a Pressable — nesting two
1623
+ // pressable surfaces breaks tap handling on native; this
1624
+ // is purely visual (the Pressable parent owns the toggle).
1625
+ /* @__PURE__ */ jsxRuntime.jsx(
1626
+ reactNative.View,
1627
+ {
1628
+ "aria-hidden": true,
1629
+ accessibilityElementsHidden: true,
1630
+ importantForAccessibility: "no-hide-descendants",
1631
+ style: {
1632
+ width: 18,
1633
+ height: 18,
1634
+ borderWidth: 1,
1635
+ borderRadius: px(colors.radius.sm),
1636
+ borderColor: selected ? colors.semantic.interactive.primary : colors.semantic.border.strong,
1637
+ backgroundColor: selected ? colors.semantic.interactive.primary : "transparent",
1638
+ alignItems: "center",
1639
+ justifyContent: "center"
1640
+ },
1641
+ children: selected ? /* @__PURE__ */ jsxRuntime.jsx(defaultSemanticIcons.check, { size: 12, color: colors.semantic.text.inverted }) : null
1642
+ }
1643
+ )
1644
+ ) : null,
1645
+ /* @__PURE__ */ jsxRuntime.jsx(
1646
+ reactNative.Text,
1647
+ {
1648
+ style: {
1649
+ color: colors.semantic.text.default,
1650
+ fontFamily: colors.fontFamily.body,
1651
+ fontSize: px(colors.fontSize.sm),
1652
+ fontWeight: selected ? colors.fontWeight.semibold : colors.fontWeight.regular,
1653
+ flex: 1
1654
+ },
1655
+ numberOfLines: 1,
1656
+ children: option.label
1657
+ }
1658
+ ),
1659
+ selected && !multiple ? /* @__PURE__ */ jsxRuntime.jsx(defaultSemanticIcons.check, { size: 16, color: colors.semantic.interactive.primary }) : null,
1660
+ active ? null : null
1661
+ ] });
1662
+ }, "DefaultOptionRow");
1663
+ var MultiTriggerLabel = /* @__PURE__ */ __name(({
1664
+ options,
1665
+ placeholder,
1666
+ maxChips
1667
+ }) => {
1668
+ const colors = useThemeColors();
1669
+ if (options.length === 0) {
1670
+ return /* @__PURE__ */ jsxRuntime.jsx(
1671
+ reactNative.Text,
1672
+ {
1673
+ style: {
1674
+ color: colors.semantic.text.muted,
1675
+ fontFamily: colors.fontFamily.body,
1676
+ fontSize: px(colors.fontSize.sm),
1677
+ flex: 1
1678
+ },
1679
+ numberOfLines: 1,
1680
+ children: placeholder
1681
+ }
1682
+ );
1683
+ }
1684
+ if (options.length > maxChips) {
1685
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1686
+ reactNative.Text,
1687
+ {
1688
+ style: {
1689
+ color: colors.semantic.text.default,
1690
+ fontFamily: colors.fontFamily.body,
1691
+ fontSize: px(colors.fontSize.sm),
1692
+ fontWeight: colors.fontWeight.medium,
1693
+ fontVariant: ["tabular-nums"],
1694
+ flex: 1
1695
+ },
1696
+ numberOfLines: 1,
1697
+ children: [
1698
+ options.length,
1699
+ " selected"
1700
+ ]
1701
+ }
1702
+ );
1703
+ }
1704
+ return /* @__PURE__ */ jsxRuntime.jsx(
1705
+ reactNative.View,
1706
+ {
1707
+ style: {
1708
+ flexDirection: "row",
1709
+ alignItems: "center",
1710
+ flexWrap: "wrap",
1711
+ rowGap: px(colors.spacing["1"]),
1712
+ columnGap: px(colors.spacing["1"]),
1713
+ flex: 1
1714
+ },
1715
+ children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
1716
+ reactNative.View,
1717
+ {
1718
+ style: {
1719
+ flexDirection: "row",
1720
+ alignItems: "center",
1721
+ paddingHorizontal: px(colors.spacing["2"]),
1722
+ paddingVertical: 2,
1723
+ borderRadius: px(colors.radius.sm),
1724
+ backgroundColor: colors.semantic.background.subtle,
1725
+ borderWidth: 1,
1726
+ borderColor: colors.semantic.border.default
1727
+ },
1728
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1729
+ reactNative.Text,
1730
+ {
1731
+ style: {
1732
+ color: colors.semantic.text.default,
1733
+ fontFamily: colors.fontFamily.body,
1734
+ fontSize: px(colors.fontSize.sm)
1735
+ },
1736
+ numberOfLines: 1,
1737
+ children: opt.label
1738
+ }
1739
+ )
1740
+ },
1741
+ `chip-${opt.value}`
1742
+ ))
1743
+ }
1744
+ );
1745
+ }, "MultiTriggerLabel");
1746
+ var MultiSelectionHeader = /* @__PURE__ */ __name(({ count, onClearAll }) => {
1747
+ const colors = useThemeColors();
1748
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1749
+ reactNative.View,
1750
+ {
1751
+ style: {
1752
+ flexDirection: "row",
1753
+ alignItems: "center",
1754
+ justifyContent: "space-between",
1755
+ paddingHorizontal: px(colors.spacing["3"]),
1756
+ paddingVertical: px(colors.spacing["2"]),
1757
+ borderBottomWidth: 1,
1758
+ borderBottomColor: colors.semantic.border.default
1759
+ },
1760
+ children: [
1761
+ /* @__PURE__ */ jsxRuntime.jsxs(
1762
+ reactNative.Text,
1763
+ {
1764
+ style: {
1765
+ color: colors.semantic.text.muted,
1766
+ fontFamily: colors.fontFamily.body,
1767
+ fontSize: px(colors.fontSize.sm),
1768
+ fontVariant: ["tabular-nums"]
1769
+ },
1770
+ children: [
1771
+ count,
1772
+ " selected"
1773
+ ]
1774
+ }
1775
+ ),
1776
+ /* @__PURE__ */ jsxRuntime.jsx(
1777
+ reactNative.Pressable,
1778
+ {
1779
+ role: "button",
1780
+ accessibilityRole: "button",
1781
+ "aria-label": "Clear all",
1782
+ accessibilityLabel: "Clear all",
1783
+ onPress: onClearAll,
1784
+ style: ({ pressed }) => ({
1785
+ paddingHorizontal: px(colors.spacing["2"]),
1786
+ paddingVertical: 2,
1787
+ borderRadius: px(colors.radius.sm),
1788
+ opacity: pressed ? 0.6 : 1
1789
+ }),
1790
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1791
+ reactNative.Text,
1792
+ {
1793
+ style: {
1794
+ color: colors.semantic.interactive.primary,
1795
+ fontFamily: colors.fontFamily.body,
1796
+ fontSize: px(colors.fontSize.sm),
1797
+ fontWeight: colors.fontWeight.medium
1798
+ },
1799
+ children: "Clear all"
1800
+ }
1801
+ )
1802
+ }
1803
+ )
1804
+ ]
1805
+ }
1806
+ );
1807
+ }, "MultiSelectionHeader");
1808
+ var CaptionContext = react.createContext(null);
1809
+ CaptionContext.displayName = "CalendarCaptionContext";
1810
+ var CaptionProvider = /* @__PURE__ */ __name(({ value, children }) => /* @__PURE__ */ jsxRuntime.jsx(CaptionContext.Provider, { value, children }), "CaptionProvider");
1811
+ var useCalendarCaption = /* @__PURE__ */ __name(() => {
1812
+ const ctx = react.useContext(CaptionContext);
1813
+ if (!ctx) {
1814
+ throw new Error('useCalendarCaption must be called inside a <Calendar caption="custom"> subtree.');
1815
+ }
1816
+ return ctx;
1817
+ }, "useCalendarCaption");
1818
+ var ARROW_BUTTON_GAP = 8;
1819
+ var NavButton = /* @__PURE__ */ __name(({ label, onPress, children }) => {
1820
+ const colors = useThemeColors();
1821
+ return /* @__PURE__ */ jsxRuntime.jsx(
1822
+ reactNative.Pressable,
1823
+ {
1824
+ accessibilityRole: "button",
1825
+ accessibilityLabel: label,
1826
+ onPress,
1827
+ style: ({ pressed, hovered, focused }) => {
1828
+ const base = {
1829
+ width: 32,
1830
+ height: 32,
1831
+ alignItems: "center",
1832
+ justifyContent: "center",
1833
+ borderRadius: 8
1834
+ };
1835
+ const transition = {
1836
+ transitionProperty: "background-color, border-color, transform",
1837
+ transitionDuration: "140ms",
1838
+ transitionTimingFunction: "cubic-bezier(0.2, 0, 0, 1)",
1839
+ outlineStyle: "none"
1840
+ };
1841
+ const bg = pressed ? colors.color.primary["200"] : hovered ? colors.color.primary["100"] : "transparent";
1842
+ const border = focused ? { borderWidth: 2, borderColor: colors.semantic.interactive.primary } : { borderWidth: 0 };
1843
+ return [base, transition, { backgroundColor: bg, transform: [{ scale: pressed ? 0.94 : 1 }] }, border];
1844
+ },
1845
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: { color: colors.semantic.text.default, fontSize: 16, lineHeight: 16, fontWeight: "500" }, children })
1846
+ }
1847
+ );
1848
+ }, "NavButton");
1849
+ var TitleButton = /* @__PURE__ */ __name(({
1850
+ text,
1851
+ ariaLabel,
1852
+ onPress,
1853
+ drilldown
1854
+ }) => {
1855
+ const colors = useThemeColors();
1856
+ if (!onPress) {
1857
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { paddingHorizontal: 12, paddingVertical: 6, alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1858
+ reactNative.Text,
1859
+ {
1860
+ style: {
1861
+ color: colors.semantic.text.default,
1862
+ fontSize: 15,
1863
+ fontWeight: "600",
1864
+ letterSpacing: -0.1
1865
+ },
1866
+ children: text
1867
+ }
1868
+ ) });
1869
+ }
1870
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1871
+ reactNative.Pressable,
1872
+ {
1873
+ accessibilityRole: "button",
1874
+ accessibilityLabel: ariaLabel,
1875
+ onPress,
1876
+ style: ({ pressed, hovered, focused }) => {
1877
+ const base = {
1878
+ flexDirection: "row",
1879
+ alignItems: "center",
1880
+ gap: 6,
1881
+ paddingHorizontal: 12,
1882
+ paddingVertical: 6,
1883
+ borderRadius: 8
1884
+ };
1885
+ const transition = {
1886
+ transitionProperty: "background-color, transform",
1887
+ transitionDuration: "140ms",
1888
+ transitionTimingFunction: "cubic-bezier(0.2, 0, 0, 1)",
1889
+ outlineStyle: "none"
1890
+ };
1891
+ const bg = pressed ? colors.color.primary["200"] : hovered ? colors.color.primary["100"] : "transparent";
1892
+ const border = focused ? { borderWidth: 2, borderColor: colors.semantic.interactive.primary } : { borderWidth: 0 };
1893
+ return [base, transition, { backgroundColor: bg, transform: [{ scale: pressed ? 0.97 : 1 }] }, border];
1894
+ },
1895
+ children: [
1896
+ /* @__PURE__ */ jsxRuntime.jsx(
1897
+ reactNative.Text,
1898
+ {
1899
+ style: {
1900
+ color: colors.semantic.text.default,
1901
+ fontSize: 15,
1902
+ fontWeight: "600",
1903
+ letterSpacing: -0.1
1904
+ },
1905
+ children: text
1906
+ }
1907
+ ),
1908
+ drilldown ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { "aria-hidden": true, style: { color: colors.semantic.text.muted, fontSize: 10, opacity: 0.7 }, children: "\u25BE" }) : null
1909
+ ]
1910
+ }
1911
+ );
1912
+ }, "TitleButton");
1913
+ var Caption = /* @__PURE__ */ __name(({
1914
+ months,
1915
+ locale,
1916
+ view,
1917
+ caption,
1918
+ gridWidth,
1919
+ monthGap,
1920
+ yearRange,
1921
+ isMonthDisabled,
1922
+ isYearDisabled,
1923
+ onPrev,
1924
+ onNext,
1925
+ onTitlePress,
1926
+ onSetMonth,
1927
+ onSetYear,
1928
+ children
1929
+ }) => {
1930
+ const { t } = useTranslation();
1931
+ const titleText = /* @__PURE__ */ __name((m) => {
1932
+ if (view === "day") {
1933
+ return formatMonthYearTitle(m, locale);
1934
+ }
1935
+ if (view === "month") {
1936
+ return String(m.year);
1937
+ }
1938
+ const start = m.year - m.year % 10;
1939
+ return `${start} \u2013 ${start + 11}`;
1940
+ }, "titleText");
1941
+ const titleAriaKey = view === "day" ? "calendar.header.openMonthView" : view === "month" ? "calendar.header.openYearView" : "calendar.header.openDayView";
1942
+ const showMultiTitles = view === "day" && months.length > 1;
1943
+ const titleRowWidth = showMultiTitles ? months.length * gridWidth + (months.length - 1) * monthGap : gridWidth;
1944
+ const monthNames = react.useMemo(() => formatMonthNames(locale), [locale]);
1945
+ const focused = months[0] ?? void 0;
1946
+ if (!focused) {
1947
+ return null;
1948
+ }
1949
+ const ctxValue = {
1950
+ month: focused.month,
1951
+ year: focused.year,
1952
+ visibleMonth: focused,
1953
+ monthOptions: monthNames.map((label, i) => ({
1954
+ value: i + 1,
1955
+ label,
1956
+ disabled: isMonthDisabled?.(focused.year, i + 1) ?? false
1957
+ })),
1958
+ yearOptions: Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, i) => ({
1959
+ value: yearRange[0] + i,
1960
+ label: String(yearRange[0] + i),
1961
+ disabled: isYearDisabled?.(yearRange[0] + i) ?? false
1962
+ })),
1963
+ setMonth: /* @__PURE__ */ __name((m) => onSetMonth(0, m), "setMonth"),
1964
+ setYear: /* @__PURE__ */ __name((y) => onSetYear(0, y), "setYear"),
1965
+ goPrev: onPrev,
1966
+ goNext: onNext
1967
+ };
1968
+ if (caption === "custom") {
1969
+ return /* @__PURE__ */ jsxRuntime.jsx(
1970
+ reactNative.View,
1971
+ {
1972
+ style: {
1973
+ flexDirection: "row",
1974
+ alignItems: "center",
1975
+ paddingBottom: 10,
1976
+ gap: ARROW_BUTTON_GAP,
1977
+ alignSelf: "center"
1978
+ },
1979
+ children: /* @__PURE__ */ jsxRuntime.jsx(CaptionProvider, { value: ctxValue, children })
1980
+ }
1981
+ );
1982
+ }
1983
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1984
+ reactNative.View,
1985
+ {
1986
+ style: {
1987
+ flexDirection: "row",
1988
+ alignItems: "center",
1989
+ paddingBottom: 10,
1990
+ gap: ARROW_BUTTON_GAP,
1991
+ alignSelf: "center"
1992
+ },
1993
+ children: [
1994
+ /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.previous", { defaultValue: "Previous" }), onPress: onPrev, children: "\u2039" }),
1995
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: monthGap, width: titleRowWidth }, children: showMultiTitles ? months.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { width: gridWidth, alignItems: "center" }, children: caption === "dropdown" && view === "day" ? /* @__PURE__ */ jsxRuntime.jsx(
1996
+ DropdownPair,
1997
+ {
1998
+ month: m.month,
1999
+ year: m.year,
2000
+ monthOptions: monthNames.map((label, j) => ({
2001
+ value: j + 1,
2002
+ label,
2003
+ disabled: isMonthDisabled?.(m.year, j + 1) ?? false
2004
+ })),
2005
+ yearOptions: makeYearOptions(yearRange, isYearDisabled),
2006
+ onMonthChange: (next) => onSetMonth(i, next),
2007
+ onYearChange: (next) => onSetYear(i, next)
2008
+ }
2009
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2010
+ TitleButton,
2011
+ {
2012
+ text: titleText(m),
2013
+ ariaLabel: t(titleAriaKey, { defaultValue: "Change view" }),
2014
+ onPress: () => onTitlePress(m),
2015
+ drilldown: true
2016
+ }
2017
+ ) }, `${m.year}-${m.month}`)) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { width: gridWidth, alignItems: "center" }, children: caption === "dropdown" && view === "day" ? /* @__PURE__ */ jsxRuntime.jsx(
2018
+ DropdownPair,
2019
+ {
2020
+ month: focused.month,
2021
+ year: focused.year,
2022
+ monthOptions: monthNames.map((label, j) => ({
2023
+ value: j + 1,
2024
+ label,
2025
+ disabled: isMonthDisabled?.(focused.year, j + 1) ?? false
2026
+ })),
2027
+ yearOptions: makeYearOptions(yearRange, isYearDisabled),
2028
+ onMonthChange: (next) => onSetMonth(0, next),
2029
+ onYearChange: (next) => onSetYear(0, next)
2030
+ }
2031
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2032
+ TitleButton,
2033
+ {
2034
+ text: titleText(focused),
2035
+ ariaLabel: t(titleAriaKey, { defaultValue: "Change view" }),
2036
+ onPress: () => onTitlePress(focused),
2037
+ drilldown: true
2038
+ }
2039
+ ) }) }),
2040
+ /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.next", { defaultValue: "Next" }), onPress: onNext, children: "\u203A" })
2041
+ ]
2042
+ }
2043
+ );
2044
+ }, "Caption");
2045
+ var makeYearOptions = /* @__PURE__ */ __name((yearRange, isYearDisabled) => Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, i) => ({
2046
+ value: yearRange[0] + i,
2047
+ label: String(yearRange[0] + i),
2048
+ disabled: isYearDisabled?.(yearRange[0] + i) ?? false
2049
+ })), "makeYearOptions");
2050
+ var DropdownPair = /* @__PURE__ */ __name(({ month, year, monthOptions, yearOptions, onMonthChange, onYearChange }) => {
2051
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flexDirection: "row", gap: 6 }, children: [
2052
+ /* @__PURE__ */ jsxRuntime.jsx(
2053
+ Select,
2054
+ {
2055
+ value: String(month),
2056
+ onChange: (v) => onMonthChange(Number(v)),
2057
+ options: monthOptions.map((o) => ({
2058
+ value: String(o.value),
2059
+ label: o.label,
2060
+ disabled: o.disabled
2061
+ })),
2062
+ "aria-label": "Month",
2063
+ searchable: false
2064
+ }
2065
+ ),
2066
+ /* @__PURE__ */ jsxRuntime.jsx(
2067
+ Select,
2068
+ {
2069
+ value: String(year),
2070
+ onChange: (v) => onYearChange(Number(v)),
2071
+ options: yearOptions.map((o) => ({
2072
+ value: String(o.value),
2073
+ label: o.label,
2074
+ disabled: o.disabled
2075
+ })),
2076
+ "aria-label": "Year",
2077
+ searchable: false
2078
+ }
2079
+ )
2080
+ ] });
2081
+ }, "DropdownPair");
2082
+ var CELL_SIZE = 40;
2083
+ var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, renderDay }) => {
2084
+ const colors = useThemeColors();
2085
+ const isSelectedLike = ctx.isSelected || ctx.isRangeStart || ctx.isRangeEnd;
2086
+ const isInsideRange = ctx.isInRange || ctx.isInPreviewRange;
2087
+ const isRangeMiddle = isInsideRange && !isSelectedLike;
2088
+ const dataState = ctx.isSelected ? "selected" : ctx.isRangeStart ? "range-start" : ctx.isRangeEnd ? "range-end" : ctx.isInPreviewRange ? "preview" : ctx.isInRange ? "in-range" : void 0;
2089
+ return /* @__PURE__ */ jsxRuntime.jsx(
2090
+ reactNative.Pressable,
2091
+ {
2092
+ accessibilityRole: "button",
2093
+ accessibilityState: { disabled: ctx.isUnavailable },
2094
+ disabled: ctx.isUnavailable,
2095
+ onPress,
2096
+ ...onHoverIn ? { onHoverIn } : {},
2097
+ ...onHoverOut ? { onHoverOut } : {},
2098
+ style: ({ pressed, hovered, focused }) => {
2099
+ const base = {
2100
+ width: CELL_SIZE,
2101
+ height: CELL_SIZE,
2102
+ alignItems: "center",
2103
+ justifyContent: "center",
2104
+ borderRadius: 999,
2105
+ // perfect circle for endpoints/selected
2106
+ position: "relative"
2107
+ };
2108
+ if (ctx.isUnavailable) {
2109
+ return [base, { opacity: 0.28 }];
2110
+ }
2111
+ let backgroundColor;
2112
+ let transform;
2113
+ let borderWidth;
2114
+ let borderColor;
2115
+ if (isSelectedLike) {
2116
+ backgroundColor = colors.semantic.interactive.primary;
2117
+ if (pressed) {
2118
+ backgroundColor = colors.semantic.interactive.primaryPressed;
2119
+ } else if (hovered) {
2120
+ backgroundColor = colors.semantic.interactive.primaryHover;
2121
+ }
2122
+ transform = [{ scale: pressed ? 0.94 : 1 }];
2123
+ } else if (isRangeMiddle) {
2124
+ backgroundColor = hovered ? colors.color.primary["200"] : "transparent";
2125
+ transform = [{ scale: pressed ? 0.94 : 1 }];
2126
+ } else {
2127
+ if (pressed) {
2128
+ backgroundColor = colors.color.primary["200"];
2129
+ } else if (hovered) {
2130
+ backgroundColor = colors.color.primary["100"];
2131
+ } else {
2132
+ backgroundColor = "transparent";
2133
+ }
2134
+ transform = [{ scale: pressed ? 0.94 : 1 }];
2135
+ }
2136
+ if ((ctx.isFocused || focused) && !isSelectedLike) {
2137
+ borderWidth = 2;
2138
+ borderColor = colors.semantic.interactive.primary;
2139
+ }
2140
+ const transition = {
2141
+ transitionProperty: "background-color, transform, border-color, opacity",
2142
+ transitionDuration: "140ms",
2143
+ transitionTimingFunction: "cubic-bezier(0.2, 0, 0, 1)",
2144
+ outlineStyle: "none"
2145
+ };
2146
+ return [
2147
+ base,
2148
+ transition,
2149
+ {
2150
+ backgroundColor,
2151
+ ...transform ? { transform } : {},
2152
+ ...borderWidth ? { borderWidth, borderColor } : {}
2153
+ }
2154
+ ];
2155
+ },
2156
+ ...{
2157
+ dataSet: {
2158
+ dayKey: `${ctx.date.year}-${ctx.date.month}-${ctx.date.day}`,
2159
+ ...dataState ? { state: dataState } : {}
2160
+ }
2161
+ },
2162
+ children: renderDay ? renderDay(ctx) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2163
+ /* @__PURE__ */ jsxRuntime.jsx(
2164
+ reactNative.Text,
2165
+ {
2166
+ style: {
2167
+ color: isSelectedLike ? colors.semantic.text.inverted : ctx.isOutsideMonth ? colors.semantic.text.muted : colors.semantic.text.default,
2168
+ fontSize: 14,
2169
+ fontWeight: ctx.isToday ? "600" : "400",
2170
+ opacity: ctx.isOutsideMonth ? 0.55 : 1,
2171
+ transitionProperty: "color",
2172
+ transitionDuration: "140ms"
2173
+ },
2174
+ children: ctx.date.day
2175
+ }
2176
+ ),
2177
+ ctx.isToday ? /* @__PURE__ */ jsxRuntime.jsx(
2178
+ reactNative.View,
2179
+ {
2180
+ style: {
2181
+ position: "absolute",
2182
+ bottom: 5,
2183
+ width: 4,
2184
+ height: 4,
2185
+ borderRadius: 999,
2186
+ backgroundColor: isSelectedLike ? colors.semantic.text.inverted : colors.semantic.interactive.primary
2187
+ }
2188
+ }
2189
+ ) : null
2190
+ ] })
2191
+ }
2192
+ );
2193
+ }, "DayCell");
2194
+ var isInRange = /* @__PURE__ */ __name((date, range) => {
2195
+ if (!range?.end) {
2196
+ return false;
2197
+ }
2198
+ return date.compare(range.start) >= 0 && date.compare(range.end) <= 0;
2199
+ }, "isInRange");
2200
+ var buildContext = /* @__PURE__ */ __name((date, args) => {
2201
+ const isOutsideMonth = date.month !== args.visibleMonth.month;
2202
+ const isToday = date.compare(args.todayDate) === 0;
2203
+ const dow = date.toDate("UTC").getUTCDay();
2204
+ const isWeekend = args.weekendDays.includes(dow);
2205
+ let isSelected = false;
2206
+ let isRangeStart = false;
2207
+ let isRangeEnd = false;
2208
+ let inRange = false;
2209
+ if (args.mode === "single") {
2210
+ const v = args.value;
2211
+ isSelected = !!v && v.compare(date) === 0;
2212
+ } else if (args.mode === "range") {
2213
+ const r = args.value;
2214
+ if (r) {
2215
+ isRangeStart = r.start.compare(date) === 0;
2216
+ isRangeEnd = r.end !== null && r.end.compare(date) === 0;
2217
+ inRange = isInRange(date, r);
2218
+ }
2219
+ } else {
2220
+ const arr = args.value;
2221
+ isSelected = arr.some((x) => x.compare(date) === 0);
2222
+ }
2223
+ return {
2224
+ date,
2225
+ isOutsideMonth,
2226
+ isToday,
2227
+ isSelected,
2228
+ isRangeStart,
2229
+ isRangeEnd,
2230
+ isInRange: inRange,
2231
+ isInPreviewRange: isInRange(date, args.previewRange ?? null),
2232
+ isUnavailable: args.isUnavailable(date),
2233
+ isFocused: args.focusedDate.compare(date) === 0,
2234
+ isWeekend
2235
+ };
2236
+ }, "buildContext");
2237
+ var ROW_KEYS = ["row-0", "row-1", "row-2", "row-3", "row-4", "row-5"];
2238
+ var DayGrid = /* @__PURE__ */ __name((props) => {
2239
+ const {
2240
+ visibleMonth,
2241
+ locale,
2242
+ mode,
2243
+ value,
2244
+ previewRange,
2245
+ focusedDate,
2246
+ isUnavailable,
2247
+ weekendDays,
2248
+ firstDayOfWeek,
2249
+ onDayPress,
2250
+ onDayHover,
2251
+ renderDay
2252
+ } = props;
2253
+ const colors = useThemeColors();
2254
+ const fdow = firstDayOfWeek ?? getFirstDayOfWeek(locale);
2255
+ const cells = react.useMemo(() => {
2256
+ const start = date.startOfMonth(visibleMonth);
2257
+ const startDow = start.toDate("UTC").getUTCDay();
2258
+ const back = (startDow - fdow + 7) % 7;
2259
+ const first = start.subtract({ days: back });
2260
+ const total = 42;
2261
+ return Array.from({ length: total }, (_, i) => first.add({ days: i }));
2262
+ }, [visibleMonth, fdow]);
2263
+ const weekdayNames = react.useMemo(() => formatWeekdayNames(locale), [locale]);
2264
+ const todayDate = react.useMemo(() => date.today(date.getLocalTimeZone()), []);
2265
+ const gridWidth = 7 * CELL_SIZE;
2266
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { role: "grid", style: { width: gridWidth }, children: [
2267
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { role: "row", style: { flexDirection: "row", marginBottom: 4 }, children: weekdayNames.map((name) => /* @__PURE__ */ jsxRuntime.jsx(
2268
+ reactNative.View,
2269
+ {
2270
+ role: "columnheader",
2271
+ style: { width: CELL_SIZE, alignItems: "center", paddingVertical: 6 },
2272
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2273
+ reactNative.Text,
2274
+ {
2275
+ style: {
2276
+ fontSize: 11,
2277
+ fontWeight: "500",
2278
+ letterSpacing: 0.6,
2279
+ color: colors.semantic.text.muted,
2280
+ textTransform: "uppercase"
2281
+ },
2282
+ children: name
2283
+ }
2284
+ )
2285
+ },
2286
+ name
2287
+ )) }),
2288
+ ROW_KEYS.map((rowKey, row) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { role: "row", style: { flexDirection: "row" }, children: cells.slice(row * 7, row * 7 + 7).map((date) => {
2289
+ const ctx = buildContext(date, {
2290
+ visibleMonth,
2291
+ mode,
2292
+ value,
2293
+ ...previewRange !== void 0 ? { previewRange } : {},
2294
+ focusedDate,
2295
+ isUnavailable,
2296
+ weekendDays,
2297
+ todayDate
2298
+ });
2299
+ const isSelectedLike = ctx.isSelected || ctx.isRangeStart || ctx.isRangeEnd;
2300
+ const isInsideRange = ctx.isInRange || ctx.isInPreviewRange;
2301
+ const wrapperStyle = {
2302
+ width: CELL_SIZE,
2303
+ height: CELL_SIZE,
2304
+ position: "relative"
2305
+ };
2306
+ const rangeFillTint = colors.color.primary["100"];
2307
+ let rangeFillStyle = null;
2308
+ if (ctx.isRangeStart && !ctx.isRangeEnd) {
2309
+ rangeFillStyle = {
2310
+ position: "absolute",
2311
+ top: 0,
2312
+ bottom: 0,
2313
+ left: "50%",
2314
+ right: 0,
2315
+ backgroundColor: rangeFillTint
2316
+ };
2317
+ } else if (ctx.isRangeEnd && !ctx.isRangeStart) {
2318
+ rangeFillStyle = {
2319
+ position: "absolute",
2320
+ top: 0,
2321
+ bottom: 0,
2322
+ left: 0,
2323
+ right: "50%",
2324
+ backgroundColor: rangeFillTint
2325
+ };
2326
+ } else if (isInsideRange && !isSelectedLike) {
2327
+ rangeFillStyle = {
2328
+ position: "absolute",
2329
+ top: 0,
2330
+ bottom: 0,
2331
+ left: 0,
2332
+ right: 0,
2333
+ backgroundColor: rangeFillTint
2334
+ };
2335
+ }
2336
+ const gridcellProps = {
2337
+ role: "gridcell",
2338
+ ...isSelectedLike ? { "aria-selected": true } : {}
2339
+ };
2340
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2341
+ reactNative.View,
2342
+ {
2343
+ ...gridcellProps,
2344
+ style: wrapperStyle,
2345
+ children: [
2346
+ rangeFillStyle ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: rangeFillStyle }) : null,
2347
+ /* @__PURE__ */ jsxRuntime.jsx(
2348
+ DayCell,
2349
+ {
2350
+ ctx,
2351
+ onPress: () => onDayPress(date),
2352
+ ...onDayHover ? {
2353
+ onHoverIn: /* @__PURE__ */ __name(() => onDayHover(date), "onHoverIn"),
2354
+ onHoverOut: /* @__PURE__ */ __name(() => onDayHover(null), "onHoverOut")
2355
+ } : {},
2356
+ ...renderDay ? { renderDay } : {}
2357
+ }
2358
+ )
2359
+ ]
2360
+ },
2361
+ `${date.year}-${date.month}-${date.day}`
2362
+ );
2363
+ }) }, rowKey))
2364
+ ] });
2365
+ }, "DayGrid");
2366
+ var Footer = /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { paddingTop: 12 }, children }), "Footer");
2367
+ var ROW_KEYS2 = ["r0", "r1", "r2", "r3"];
2368
+ var MonthGrid = /* @__PURE__ */ __name(({ visibleMonth, locale, availableWidth, onSelect }) => {
2369
+ const colors = useThemeColors();
2370
+ const names = formatMonthNames(locale);
2371
+ const cellHeight = 56;
2372
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { width: availableWidth, paddingVertical: 8 }, children: ROW_KEYS2.map((rowKey, row) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", marginBottom: 4 }, children: [0, 1, 2].map((col) => {
2373
+ const idx = row * 3 + col;
2374
+ const monthNumber = idx + 1;
2375
+ const isCurrent = monthNumber === visibleMonth.month;
2376
+ const name = names[idx] ?? "";
2377
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flex: 1, paddingHorizontal: 4 }, children: /* @__PURE__ */ jsxRuntime.jsx(
2378
+ reactNative.Pressable,
2379
+ {
2380
+ accessibilityRole: "button",
2381
+ accessibilityLabel: name,
2382
+ onPress: () => onSelect(monthNumber),
2383
+ style: ({
2384
+ pressed,
2385
+ hovered,
2386
+ focused
2387
+ }) => {
2388
+ const base = {
2389
+ height: cellHeight,
2390
+ alignItems: "center",
2391
+ justifyContent: "center",
2392
+ borderRadius: 10
2393
+ };
2394
+ const transition = {
2395
+ transitionProperty: "background-color, transform, border-color",
2396
+ transitionDuration: "140ms",
2397
+ transitionTimingFunction: "cubic-bezier(0.2, 0, 0, 1)",
2398
+ outlineStyle: "none"
2399
+ };
2400
+ let bg;
2401
+ if (isCurrent) {
2402
+ bg = pressed ? colors.semantic.interactive.primaryPressed : hovered ? colors.semantic.interactive.primaryHover : colors.semantic.interactive.primary;
2403
+ } else if (pressed) {
2404
+ bg = colors.color.primary["200"];
2405
+ } else if (hovered) {
2406
+ bg = colors.color.primary["100"];
2407
+ } else {
2408
+ bg = "transparent";
2409
+ }
2410
+ const border = focused && !isCurrent ? { borderWidth: 2, borderColor: colors.semantic.interactive.primary } : { borderWidth: 0 };
2411
+ return [
2412
+ base,
2413
+ transition,
2414
+ { backgroundColor: bg, transform: [{ scale: pressed ? 0.96 : 1 }] },
2415
+ border
2416
+ ];
2417
+ },
2418
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2419
+ reactNative.Text,
2420
+ {
2421
+ style: {
2422
+ color: isCurrent ? colors.semantic.text.inverted : colors.semantic.text.default,
2423
+ fontSize: 14,
2424
+ fontWeight: isCurrent ? "600" : "500"
2425
+ },
2426
+ children: name
2427
+ }
2428
+ )
2429
+ }
2430
+ ) }, monthNumber);
2431
+ }) }, rowKey)) });
2432
+ }, "MonthGrid");
2433
+ var ROW_KEYS3 = ["r0", "r1", "r2"];
2434
+ var YearGrid = /* @__PURE__ */ __name(({ visibleMonth, availableWidth, onSelect }) => {
2435
+ const colors = useThemeColors();
2436
+ const decadeStart = visibleMonth.year - visibleMonth.year % 10;
2437
+ const years = Array.from({ length: 12 }, (_, i) => decadeStart + i - 1);
2438
+ const cellHeight = 60;
2439
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { width: availableWidth, paddingVertical: 8 }, children: ROW_KEYS3.map((rowKey, row) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", marginBottom: 4 }, children: [0, 1, 2, 3].map((col) => {
2440
+ const year = years[row * 4 + col];
2441
+ if (year === void 0) {
2442
+ return null;
2443
+ }
2444
+ const isCurrent = year === visibleMonth.year;
2445
+ const isAdjacentDecade = year < decadeStart || year >= decadeStart + 10;
2446
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flex: 1, paddingHorizontal: 4 }, children: /* @__PURE__ */ jsxRuntime.jsx(
2447
+ reactNative.Pressable,
2448
+ {
2449
+ accessibilityRole: "button",
2450
+ accessibilityLabel: String(year),
2451
+ onPress: () => onSelect(year),
2452
+ style: ({
2453
+ pressed,
2454
+ hovered,
2455
+ focused
2456
+ }) => {
2457
+ const base = {
2458
+ height: cellHeight,
2459
+ alignItems: "center",
2460
+ justifyContent: "center",
2461
+ borderRadius: 10
2462
+ };
2463
+ const transition = {
2464
+ transitionProperty: "background-color, transform, border-color",
2465
+ transitionDuration: "140ms",
2466
+ transitionTimingFunction: "cubic-bezier(0.2, 0, 0, 1)",
2467
+ outlineStyle: "none"
2468
+ };
2469
+ let bg;
2470
+ if (isCurrent) {
2471
+ bg = pressed ? colors.semantic.interactive.primaryPressed : hovered ? colors.semantic.interactive.primaryHover : colors.semantic.interactive.primary;
2472
+ } else if (pressed) {
2473
+ bg = colors.color.primary["200"];
2474
+ } else if (hovered) {
2475
+ bg = colors.color.primary["100"];
2476
+ } else {
2477
+ bg = "transparent";
2478
+ }
2479
+ const border = focused && !isCurrent ? { borderWidth: 2, borderColor: colors.semantic.interactive.primary } : { borderWidth: 0 };
2480
+ return [
2481
+ base,
2482
+ transition,
2483
+ { backgroundColor: bg, transform: [{ scale: pressed ? 0.96 : 1 }] },
2484
+ border
2485
+ ];
2486
+ },
2487
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2488
+ reactNative.Text,
2489
+ {
2490
+ style: {
2491
+ color: isCurrent ? colors.semantic.text.inverted : colors.semantic.text.default,
2492
+ fontSize: 14,
2493
+ fontWeight: isCurrent ? "600" : "500",
2494
+ opacity: isAdjacentDecade ? 0.45 : 1
2495
+ },
2496
+ children: year
2497
+ }
2498
+ )
2499
+ }
2500
+ ) }, year);
2501
+ }) }, rowKey)) });
2502
+ }, "YearGrid");
2503
+ var GRID_WIDTH = 7 * CELL_SIZE;
2504
+ var MONTH_GAP = 16;
2505
+ var ARROW_AREA = 32 + 8;
2506
+ var SURFACE_PADDING = 16;
2507
+ var SURFACE_BORDER = 1;
2508
+ var requiredOuterWidth = /* @__PURE__ */ __name((n) => 2 * (ARROW_AREA + SURFACE_PADDING + SURFACE_BORDER) + n * GRID_WIDTH + (n - 1) * MONTH_GAP, "requiredOuterWidth");
2509
+ var focusDayCell = /* @__PURE__ */ __name((root, date, force) => {
2510
+ if (!root) {
2511
+ return;
2512
+ }
2513
+ if (!force && !root.contains(document.activeElement)) {
2514
+ return;
2515
+ }
2516
+ const sel = `[data-day-key="${date.year}-${date.month}-${date.day}"]`;
2517
+ const cell = root.querySelector(sel);
2518
+ const isDisabled = cell?.disabled === true;
2519
+ if (cell && !isDisabled) {
2520
+ if (cell !== document.activeElement) {
2521
+ cell.focus();
2522
+ }
2523
+ return;
2524
+ }
2525
+ if (force && !root.contains(document.activeElement)) {
2526
+ root.focus();
2527
+ }
2528
+ }, "focusDayCell");
2529
+ var FadeIn = /* @__PURE__ */ __name(({ children }) => {
2530
+ const [mounted, setMounted] = react.useState(false);
2531
+ react.useEffect(() => {
2532
+ const id = requestAnimationFrame(() => setMounted(true));
2533
+ return () => cancelAnimationFrame(id);
2534
+ }, []);
2535
+ return /* @__PURE__ */ jsxRuntime.jsx(
2536
+ reactNative.View,
2537
+ {
2538
+ style: {
2539
+ opacity: mounted ? 1 : 0,
2540
+ transform: [{ translateY: mounted ? 0 : 4 }],
2541
+ transitionProperty: "opacity, transform",
2542
+ transitionDuration: "220ms",
2543
+ transitionTimingFunction: "cubic-bezier(0.2, 0, 0, 1)"
2544
+ },
2545
+ children
2546
+ }
2547
+ );
2548
+ }, "FadeIn");
2549
+ var resolveYearRange = /* @__PURE__ */ __name((input, minValue, maxValue, focusedYear) => {
2550
+ if (input) {
2551
+ return input;
2552
+ }
2553
+ if (minValue && maxValue) {
2554
+ return [minValue.year, maxValue.year];
2555
+ }
2556
+ if (minValue) {
2557
+ return [minValue.year, Math.max(minValue.year, focusedYear + 10)];
2558
+ }
2559
+ if (maxValue) {
2560
+ return [Math.min(maxValue.year, focusedYear - 100), maxValue.year];
2561
+ }
2562
+ return [focusedYear - 100, focusedYear + 10];
2563
+ }, "resolveYearRange");
2564
+ var pickVisibleMonths = /* @__PURE__ */ __name((input, measuredWidth) => {
2565
+ const target = typeof input === "number" ? input : 2;
2566
+ if (measuredWidth == null || measuredWidth === 0) {
2567
+ return typeof input === "number" ? input : 1;
2568
+ }
2569
+ for (let n = target; n >= 1; n--) {
2570
+ if (measuredWidth >= requiredOuterWidth(n)) {
2571
+ return n;
2572
+ }
2573
+ }
2574
+ return 1;
2575
+ }, "pickVisibleMonths");
2576
+ var CalendarRoot = /* @__PURE__ */ __name((props) => {
2577
+ const [containerWidth, setContainerWidth] = react.useState(null);
2578
+ const onLayout = react.useCallback((e) => {
2579
+ const next = e.nativeEvent.layout.width;
2580
+ setContainerWidth((prev) => prev === next ? prev : next);
2581
+ }, []);
2582
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { onLayout, style: { width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(CalendarSurface, { containerWidth: containerWidth ?? 0, ...props }) });
2583
+ }, "CalendarRoot");
2584
+ var CalendarSurface = /* @__PURE__ */ __name((props) => {
2585
+ const providerLocale = useLocale();
2586
+ const locale = props.locale ?? providerLocale;
2587
+ if ((props.mode ?? "single") === "range") {
2588
+ return /* @__PURE__ */ jsxRuntime.jsx(
2589
+ RangeCalendar,
2590
+ {
2591
+ ...props,
2592
+ locale
2593
+ }
2594
+ );
2595
+ }
2596
+ return /* @__PURE__ */ jsxRuntime.jsx(
2597
+ SingleOrMultiCalendar,
2598
+ {
2599
+ ...props,
2600
+ locale
2601
+ }
2602
+ );
2603
+ }, "CalendarSurface");
2604
+ var surfaceMetrics = /* @__PURE__ */ __name((visibleMonths) => {
2605
+ const innerWidth = 2 * ARROW_AREA + visibleMonths * GRID_WIDTH + (visibleMonths - 1) * MONTH_GAP;
2606
+ return {
2607
+ innerWidth,
2608
+ // Body grids row width (excludes arrow area)
2609
+ gridsRowWidth: visibleMonths * GRID_WIDTH + (visibleMonths - 1) * MONTH_GAP
2610
+ };
2611
+ }, "surfaceMetrics");
2612
+ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
2613
+ const { locale, renderDay, containerWidth } = props;
2614
+ const colors = useThemeColors();
2615
+ const firstDayOfWeek = props.firstDayOfWeek ?? getFirstDayOfWeek(locale);
2616
+ const weekendDays = props.weekendDays ?? getWeekendDays(locale);
2617
+ const visibleMonths = pickVisibleMonths(props.visibleMonths, containerWidth);
2618
+ const { innerWidth, gridsRowWidth } = surfaceMetrics(visibleMonths);
2619
+ const containerRef = react.useRef(null);
2620
+ const state = useCalendarState({
2621
+ ...props.mode !== void 0 ? { mode: props.mode } : {},
2622
+ locale,
2623
+ ...props.value !== void 0 ? { value: props.value } : {},
2624
+ ...props.defaultValue !== void 0 ? { defaultValue: props.defaultValue } : {},
2625
+ ...props.onChange !== void 0 ? { onChange: props.onChange } : {},
2626
+ ...props.view !== void 0 ? { view: props.view } : {},
2627
+ ...props.defaultView !== void 0 ? { defaultView: props.defaultView } : {},
2628
+ ...props.onViewChange !== void 0 ? { onViewChange: props.onViewChange } : {},
2629
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
2630
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
2631
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {}
2632
+ });
2633
+ const [anchor, setAnchor] = react.useState(state.focusedDate);
2634
+ const anchorRef = react.useRef(anchor);
2635
+ react.useEffect(() => {
2636
+ anchorRef.current = anchor;
2637
+ }, [anchor]);
2638
+ react.useEffect(() => {
2639
+ const start = anchorRef.current;
2640
+ const end = start.add({ months: visibleMonths });
2641
+ if (state.focusedDate.compare(start) < 0 || state.focusedDate.compare(end) >= 0) {
2642
+ setAnchor(state.focusedDate);
2643
+ }
2644
+ }, [state.focusedDate, visibleMonths]);
2645
+ const keyboardNavRef = react.useRef(false);
2646
+ react.useLayoutEffect(() => {
2647
+ focusDayCell(containerRef.current, state.focusedDate, keyboardNavRef.current);
2648
+ keyboardNavRef.current = false;
2649
+ }, [state.focusedDate, state.value]);
2650
+ const months = react.useMemo(
2651
+ () => Array.from({ length: visibleMonths }, (_, i) => anchor.add({ months: i })),
2652
+ [anchor, visibleMonths]
2653
+ );
2654
+ const keyboard = useCalendarKeyboard({
2655
+ focusedDate: state.focusedDate,
2656
+ moveFocus: /* @__PURE__ */ __name((delta) => {
2657
+ state.moveFocus(delta);
2658
+ if (delta.months || delta.years) {
2659
+ setAnchor((a) => {
2660
+ let next = a;
2661
+ if (delta.months) {
2662
+ next = next.add({ months: delta.months });
2663
+ }
2664
+ if (delta.years) {
2665
+ next = next.add({ years: delta.years });
2666
+ }
2667
+ return next;
2668
+ });
2669
+ }
2670
+ }, "moveFocus"),
2671
+ selectDate: state.selectDate,
2672
+ setView: state.setView,
2673
+ view: state.view,
2674
+ firstDayOfWeek
2675
+ });
2676
+ const onPrev = /* @__PURE__ */ __name(() => {
2677
+ if (state.view === "year") {
2678
+ setAnchor((a) => a.add({ years: -10 }));
2679
+ } else if (state.view === "month") {
2680
+ setAnchor((a) => a.add({ years: -1 }));
2681
+ } else {
2682
+ setAnchor((a) => a.add({ months: -1 }));
2683
+ }
2684
+ }, "onPrev");
2685
+ const onNext = /* @__PURE__ */ __name(() => {
2686
+ if (state.view === "year") {
2687
+ setAnchor((a) => a.add({ years: 10 }));
2688
+ } else if (state.view === "month") {
2689
+ setAnchor((a) => a.add({ years: 1 }));
2690
+ } else {
2691
+ setAnchor((a) => a.add({ months: 1 }));
2692
+ }
2693
+ }, "onNext");
2694
+ const onTitlePress = /* @__PURE__ */ __name(() => state.setView(state.view === "day" ? "month" : state.view === "month" ? "year" : "day"), "onTitlePress");
2695
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2696
+ reactNative.View,
2697
+ {
2698
+ ref: (node) => {
2699
+ containerRef.current = node;
2700
+ if (typeof props.ref === "function") {
2701
+ props.ref(node);
2702
+ } else if (props.ref) {
2703
+ props.ref.current = node;
2704
+ }
2705
+ },
2706
+ ...props.testID !== void 0 ? { testID: props.testID } : {},
2707
+ onKeyDown: (e) => {
2708
+ keyboardNavRef.current = true;
2709
+ keyboard.onKeyDown(e);
2710
+ },
2711
+ tabIndex: 0,
2712
+ style: {
2713
+ padding: SURFACE_PADDING,
2714
+ backgroundColor: colors.semantic.background.elevated,
2715
+ borderRadius: 16,
2716
+ borderWidth: SURFACE_BORDER,
2717
+ borderColor: colors.semantic.border.default,
2718
+ shadowColor: "#000",
2719
+ shadowOpacity: 0.04,
2720
+ shadowRadius: 12,
2721
+ shadowOffset: { width: 0, height: 4 },
2722
+ width: innerWidth + 2 * SURFACE_PADDING + 2 * SURFACE_BORDER,
2723
+ maxWidth: "100%",
2724
+ alignSelf: "center"
2725
+ },
2726
+ children: [
2727
+ /* @__PURE__ */ jsxRuntime.jsx(
2728
+ Caption,
2729
+ {
2730
+ months,
2731
+ locale,
2732
+ view: state.view,
2733
+ caption: props.caption ?? "title",
2734
+ gridWidth: GRID_WIDTH,
2735
+ monthGap: MONTH_GAP,
2736
+ yearRange: resolveYearRange(props.yearRange, props.minValue, props.maxValue, anchor.year),
2737
+ onPrev,
2738
+ onNext,
2739
+ onTitlePress,
2740
+ onSetMonth: (slot, m) => {
2741
+ const picked = (months[slot] ?? anchor).set({ month: m, day: 1 });
2742
+ setAnchor(picked.subtract({ months: slot }));
2743
+ },
2744
+ onSetYear: (slot, y) => {
2745
+ const picked = (months[slot] ?? anchor).set({ year: y, day: 1 });
2746
+ setAnchor(picked.subtract({ months: slot }));
2747
+ },
2748
+ children: props.children
2749
+ }
2750
+ ),
2751
+ /* @__PURE__ */ jsxRuntime.jsxs(FadeIn, { children: [
2752
+ state.view === "day" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth }, children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
2753
+ DayGrid,
2754
+ {
2755
+ visibleMonth: m,
2756
+ locale,
2757
+ mode: props.mode ?? "single",
2758
+ value: state.value,
2759
+ focusedDate: state.focusedDate,
2760
+ isUnavailable: state.isUnavailable,
2761
+ weekendDays,
2762
+ firstDayOfWeek,
2763
+ onDayPress: (date) => state.selectDate(date, "click"),
2764
+ ...renderDay ? { renderDay } : {}
2765
+ },
2766
+ `${m.year}-${m.month}`
2767
+ )) }),
2768
+ state.view === "month" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2769
+ MonthGrid,
2770
+ {
2771
+ visibleMonth: anchor,
2772
+ locale,
2773
+ availableWidth: gridsRowWidth,
2774
+ onSelect: (month) => {
2775
+ setAnchor(new date.CalendarDate(anchor.year, month, 1));
2776
+ state.setView("day");
2777
+ }
2778
+ }
2779
+ ) }),
2780
+ state.view === "year" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2781
+ YearGrid,
2782
+ {
2783
+ visibleMonth: anchor,
2784
+ availableWidth: gridsRowWidth,
2785
+ onSelect: (year) => {
2786
+ setAnchor(new date.CalendarDate(year, anchor.month, 1));
2787
+ state.setView("month");
2788
+ }
2789
+ }
2790
+ ) }),
2791
+ props.children && (props.caption ?? "title") !== "custom" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { children: props.children }) : null
2792
+ ] }, `smc-${state.view}`)
2793
+ ]
2794
+ }
2795
+ );
2796
+ }, "SingleOrMultiCalendar");
2797
+ var RangeCalendar = /* @__PURE__ */ __name((props) => {
2798
+ const { locale, renderDay, containerWidth } = props;
2799
+ const colors = useThemeColors();
2800
+ const firstDayOfWeek = props.firstDayOfWeek ?? getFirstDayOfWeek(locale);
2801
+ const weekendDays = props.weekendDays ?? getWeekendDays(locale);
2802
+ const visibleMonths = pickVisibleMonths(props.visibleMonths, containerWidth);
2803
+ const { innerWidth, gridsRowWidth } = surfaceMetrics(visibleMonths);
2804
+ const containerRef = react.useRef(null);
2805
+ const range = useRangeState({
2806
+ ...props.value !== void 0 ? { value: props.value } : {},
2807
+ ...props.defaultValue !== void 0 ? { defaultValue: props.defaultValue } : {},
2808
+ ...props.onChange !== void 0 ? { onChange: props.onChange } : {},
2809
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
2810
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
2811
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {},
2812
+ ...props.minNights !== void 0 ? { minNights: props.minNights } : {},
2813
+ ...props.maxNights !== void 0 ? { maxNights: props.maxNights } : {}
2814
+ });
2815
+ const initialFocus2 = range.value?.start ?? date.today(date.getLocalTimeZone());
2816
+ const [focusedDate, setFocusedDate] = react.useState(initialFocus2);
2817
+ const keyboardNavRef = react.useRef(false);
2818
+ react.useLayoutEffect(() => {
2819
+ focusDayCell(containerRef.current, focusedDate, keyboardNavRef.current);
2820
+ keyboardNavRef.current = false;
2821
+ }, [focusedDate, range.value]);
2822
+ const [anchor, setAnchor] = react.useState(initialFocus2);
2823
+ const [internalView, setInternalView] = react.useState(props.defaultView ?? "day");
2824
+ const isViewControlled = props.view !== void 0;
2825
+ const view = isViewControlled ? props.view : internalView;
2826
+ const setView = react.useCallback(
2827
+ (next) => {
2828
+ if (!isViewControlled) {
2829
+ setInternalView(next);
2830
+ }
2831
+ props.onViewChange?.(next);
2832
+ },
2833
+ [isViewControlled, props.onViewChange]
2834
+ );
2835
+ const months = react.useMemo(
2836
+ () => Array.from({ length: visibleMonths }, (_, i) => anchor.add({ months: i })),
2837
+ [anchor, visibleMonths]
2838
+ );
2839
+ const keyboard = useCalendarKeyboard({
2840
+ focusedDate,
2841
+ moveFocus: /* @__PURE__ */ __name((delta) => {
2842
+ setFocusedDate((f) => {
2843
+ let next = f;
2844
+ if (delta.days) {
2845
+ next = next.add({ days: delta.days });
2846
+ }
2847
+ if (delta.weeks) {
2848
+ next = next.add({ weeks: delta.weeks });
2849
+ }
2850
+ if (delta.months) {
2851
+ next = next.add({ months: delta.months });
2852
+ }
2853
+ if (delta.years) {
2854
+ next = next.add({ years: delta.years });
2855
+ }
2856
+ return next;
2857
+ });
2858
+ if (delta.months || delta.years) {
2859
+ setAnchor((a) => {
2860
+ let next = a;
2861
+ if (delta.months) {
2862
+ next = next.add({ months: delta.months });
2863
+ }
2864
+ if (delta.years) {
2865
+ next = next.add({ years: delta.years });
2866
+ }
2867
+ return next;
2868
+ });
2869
+ }
2870
+ }, "moveFocus"),
2871
+ selectDate: /* @__PURE__ */ __name((date) => range.selectDate(date, "keyboard"), "selectDate"),
2872
+ setView,
2873
+ view,
2874
+ firstDayOfWeek
2875
+ });
2876
+ const onPrev = /* @__PURE__ */ __name(() => {
2877
+ if (view === "year") {
2878
+ setAnchor((a) => a.add({ years: -10 }));
2879
+ } else if (view === "month") {
2880
+ setAnchor((a) => a.add({ years: -1 }));
2881
+ } else {
2882
+ setAnchor((a) => a.add({ months: -1 }));
2883
+ }
2884
+ }, "onPrev");
2885
+ const onNext = /* @__PURE__ */ __name(() => {
2886
+ if (view === "year") {
2887
+ setAnchor((a) => a.add({ years: 10 }));
2888
+ } else if (view === "month") {
2889
+ setAnchor((a) => a.add({ years: 1 }));
2890
+ } else {
2891
+ setAnchor((a) => a.add({ months: 1 }));
2892
+ }
2893
+ }, "onNext");
2894
+ const [drilldownSlot, setDrilldownSlot] = react.useState(0);
2895
+ const onTitlePress = /* @__PURE__ */ __name((clicked) => {
2896
+ const slot = months.findIndex((m) => m.year === clicked.year && m.month === clicked.month);
2897
+ setDrilldownSlot(slot >= 0 ? slot : 0);
2898
+ if (clicked.compare(anchor) !== 0) {
2899
+ setAnchor(clicked);
2900
+ }
2901
+ setView(view === "day" ? "month" : view === "month" ? "year" : "day");
2902
+ }, "onTitlePress");
2903
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2904
+ reactNative.View,
2905
+ {
2906
+ ref: (node) => {
2907
+ containerRef.current = node;
2908
+ if (typeof props.ref === "function") {
2909
+ props.ref(node);
2910
+ } else if (props.ref) {
2911
+ props.ref.current = node;
2912
+ }
2913
+ },
2914
+ ...props.testID !== void 0 ? { testID: props.testID } : {},
2915
+ onKeyDown: (e) => {
2916
+ keyboardNavRef.current = true;
2917
+ keyboard.onKeyDown(e);
2918
+ },
2919
+ tabIndex: 0,
2920
+ style: {
2921
+ padding: SURFACE_PADDING,
2922
+ backgroundColor: colors.semantic.background.elevated,
2923
+ borderRadius: 16,
2924
+ borderWidth: SURFACE_BORDER,
2925
+ borderColor: colors.semantic.border.default,
2926
+ shadowColor: "#000",
2927
+ shadowOpacity: 0.04,
2928
+ shadowRadius: 12,
2929
+ shadowOffset: { width: 0, height: 4 },
2930
+ width: innerWidth + 2 * SURFACE_PADDING + 2 * SURFACE_BORDER,
2931
+ maxWidth: "100%",
2932
+ alignSelf: "center"
2933
+ },
2934
+ children: [
2935
+ /* @__PURE__ */ jsxRuntime.jsx(
2936
+ Caption,
2937
+ {
2938
+ months,
2939
+ locale,
2940
+ view,
2941
+ caption: props.caption ?? "title",
2942
+ gridWidth: GRID_WIDTH,
2943
+ monthGap: MONTH_GAP,
2944
+ yearRange: resolveYearRange(props.yearRange, props.minValue, props.maxValue, anchor.year),
2945
+ onPrev,
2946
+ onNext,
2947
+ onTitlePress,
2948
+ onSetMonth: (slot, m) => {
2949
+ const picked = (months[slot] ?? anchor).set({ month: m, day: 1 });
2950
+ setAnchor(picked.subtract({ months: slot }));
2951
+ },
2952
+ onSetYear: (slot, y) => {
2953
+ const picked = (months[slot] ?? anchor).set({ year: y, day: 1 });
2954
+ setAnchor(picked.subtract({ months: slot }));
2955
+ },
2956
+ children: props.children
2957
+ }
2958
+ ),
2959
+ /* @__PURE__ */ jsxRuntime.jsxs(FadeIn, { children: [
2960
+ view === "day" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth }, children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
2961
+ DayGrid,
2962
+ {
2963
+ visibleMonth: m,
2964
+ locale,
2965
+ mode: "range",
2966
+ value: range.value,
2967
+ previewRange: range.previewRange,
2968
+ focusedDate,
2969
+ isUnavailable: range.isUnavailable,
2970
+ weekendDays,
2971
+ firstDayOfWeek,
2972
+ onDayPress: (date) => range.selectDate(date),
2973
+ onDayHover: (date) => range.setHoveredDate(date),
2974
+ ...renderDay ? { renderDay } : {}
2975
+ },
2976
+ `${m.year}-${m.month}`
2977
+ )) }),
2978
+ view === "month" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2979
+ MonthGrid,
2980
+ {
2981
+ visibleMonth: anchor,
2982
+ locale,
2983
+ availableWidth: gridsRowWidth,
2984
+ onSelect: (month) => {
2985
+ const picked = new date.CalendarDate(anchor.year, month, 1);
2986
+ setAnchor(picked.subtract({ months: drilldownSlot }));
2987
+ setView("day");
2988
+ }
2989
+ }
2990
+ ) }),
2991
+ view === "year" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2992
+ YearGrid,
2993
+ {
2994
+ visibleMonth: anchor,
2995
+ availableWidth: gridsRowWidth,
2996
+ onSelect: (year) => {
2997
+ const picked = new date.CalendarDate(year, anchor.month, 1);
2998
+ setAnchor(picked.subtract({ months: drilldownSlot }));
2999
+ setView("month");
3000
+ }
3001
+ }
3002
+ ) }),
3003
+ props.children && (props.caption ?? "title") !== "custom" ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { children: props.children }) : null
3004
+ ] }, `range-${view}`)
3005
+ ]
3006
+ }
3007
+ );
3008
+ }, "RangeCalendar");
3009
+ var CalendarCaption = /* @__PURE__ */ __name(({ children }) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children }), "CalendarCaption");
3010
+ CalendarCaption.displayName = "CalendarCaption";
3011
+ var Calendar = CalendarRoot;
3012
+ Calendar.Caption = CalendarCaption;
3013
+
3014
+ exports.Calendar = Calendar;
3015
+ exports.useCalendarCaption = useCalendarCaption;
3016
+ //# sourceMappingURL=index.cjs.map
3017
+ //# sourceMappingURL=index.cjs.map