@krizaka/ui 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/README.md +1 -1
  2. package/dist/achievement.js +1 -1
  3. package/dist/action-bar.js +1 -1
  4. package/dist/app-shell.js +1 -1
  5. package/dist/argument-card.js +2 -2
  6. package/dist/card-grid.js +1 -1
  7. package/dist/card.js +1 -1
  8. package/dist/choice-grid.js +1 -1
  9. package/dist/{chunk-OGJI5X4W.js → chunk-2PUDI7JS.js} +2 -2
  10. package/dist/chunk-4LOMIQVX.js +21 -0
  11. package/dist/chunk-4LOMIQVX.js.map +1 -0
  12. package/dist/{chunk-K3SWZXYT.js → chunk-DGQMDJXK.js} +2 -2
  13. package/dist/chunk-G3ETON2A.js +22 -0
  14. package/dist/chunk-G3ETON2A.js.map +1 -0
  15. package/dist/chunk-I5RVM5CW.js +27 -0
  16. package/dist/chunk-I5RVM5CW.js.map +1 -0
  17. package/dist/chunk-IZ7MV6HM.js +26 -0
  18. package/dist/chunk-IZ7MV6HM.js.map +1 -0
  19. package/dist/chunk-ZNMFG62E.js +20 -0
  20. package/dist/chunk-ZNMFG62E.js.map +1 -0
  21. package/dist/cn.d.ts +9 -1
  22. package/dist/cn.js +5 -3
  23. package/dist/code-block.js +1 -1
  24. package/dist/command.js +1 -1
  25. package/dist/confirm-button.js +1 -1
  26. package/dist/continue-prompt.js +1 -1
  27. package/dist/cta-panel.js +1 -1
  28. package/dist/data-table.js +2 -2
  29. package/dist/date-picker.d.ts +650 -61
  30. package/dist/date-picker.js +918 -122
  31. package/dist/date-picker.js.map +1 -1
  32. package/dist/decision-list.js +1 -1
  33. package/dist/dropdown-menu.js +1 -1
  34. package/dist/error-page.js +1 -1
  35. package/dist/field.js +1 -1
  36. package/dist/filter-bar.js +2 -2
  37. package/dist/form/server.d.ts +96 -0
  38. package/dist/form/server.js +82 -0
  39. package/dist/form/server.js.map +1 -0
  40. package/dist/form.d.ts +503 -0
  41. package/dist/form.js +760 -0
  42. package/dist/form.js.map +1 -0
  43. package/dist/gallery-page.js +1 -1
  44. package/dist/glow-card.js +1 -1
  45. package/dist/goal-gauge.js +1 -1
  46. package/dist/how-it-works-page.js +1 -1
  47. package/dist/landscape.js +1 -1
  48. package/dist/link-card.js +1 -1
  49. package/dist/longform-page.js +1 -1
  50. package/dist/marquee.js +1 -1
  51. package/dist/mascot-quote.js +1 -1
  52. package/dist/motion.css +18 -1
  53. package/dist/native/form.d.ts +376 -0
  54. package/dist/native/form.js +650 -0
  55. package/dist/native/form.js.map +1 -0
  56. package/dist/native.d.ts +351 -3
  57. package/dist/native.js +1205 -399
  58. package/dist/native.js.map +1 -1
  59. package/dist/nav-bar.js +1 -1
  60. package/dist/page-hero.js +2 -2
  61. package/dist/page.js +2 -2
  62. package/dist/popover.js +1 -1
  63. package/dist/pricing-page.js +1 -1
  64. package/dist/product-page.js +1 -1
  65. package/dist/profile-card.js +1 -1
  66. package/dist/promise-card.js +1 -1
  67. package/dist/scroll-stage.js +1 -1
  68. package/dist/stage-banner.js +1 -1
  69. package/dist/terminal-replay.js +1 -1
  70. package/dist/toast.js +1 -1
  71. package/dist/toc.js +1 -1
  72. package/dist/tooltip.js +1 -1
  73. package/package.json +50 -7
  74. package/registry/achievement.json +1 -1
  75. package/registry/action-bar.json +1 -1
  76. package/registry/alert.json +1 -1
  77. package/registry/app-shell.json +1 -1
  78. package/registry/argument-card.json +1 -1
  79. package/registry/audio-player.json +1 -1
  80. package/registry/auth-layout.json +1 -1
  81. package/registry/avatar.json +1 -1
  82. package/registry/badge.json +1 -1
  83. package/registry/button.json +1 -1
  84. package/registry/card-grid.json +1 -1
  85. package/registry/card.json +1 -1
  86. package/registry/catalogue-page.json +1 -1
  87. package/registry/changelog-page.json +1 -1
  88. package/registry/checkbox.json +89 -4
  89. package/registry/chip-link.json +1 -1
  90. package/registry/chip.json +1 -1
  91. package/registry/choice-grid.json +1 -1
  92. package/registry/cn.json +1 -1
  93. package/registry/code-block.json +1 -1
  94. package/registry/combobox.json +1 -1
  95. package/registry/command.json +1 -1
  96. package/registry/component-page.json +1 -1
  97. package/registry/confirm-button.json +1 -1
  98. package/registry/contact-page.json +1 -1
  99. package/registry/continue-prompt.json +1 -1
  100. package/registry/countdown.json +1 -1
  101. package/registry/cta-panel.json +1 -1
  102. package/registry/dashboard-layout.json +1 -1
  103. package/registry/data-table.json +1 -1
  104. package/registry/date-picker.json +1811 -236
  105. package/registry/decision-list.json +1 -1
  106. package/registry/detail-layout.json +1 -1
  107. package/registry/dialog.json +1 -1
  108. package/registry/docs-article-page.json +1 -1
  109. package/registry/docs-hub-page.json +1 -1
  110. package/registry/docs-layout.json +1 -1
  111. package/registry/dropdown-menu.json +1 -1
  112. package/registry/empty-state.json +1 -1
  113. package/registry/error-page.json +1 -1
  114. package/registry/examples/checkbox/native/terms.d.ts +4 -0
  115. package/registry/examples/checkbox/native/terms.dark.png +0 -0
  116. package/registry/examples/checkbox/native/terms.js +26 -0
  117. package/registry/examples/checkbox/native/terms.light.png +0 -0
  118. package/registry/examples/checkbox/native/terms.tsx +28 -0
  119. package/registry/examples/date-picker/birth-date-wheel.d.ts +4 -0
  120. package/registry/examples/date-picker/birth-date-wheel.js +13 -0
  121. package/registry/examples/date-picker/birth-date-wheel.tsx +11 -0
  122. package/registry/examples/date-picker/birth-date.d.ts +4 -0
  123. package/registry/examples/date-picker/birth-date.js +25 -0
  124. package/registry/examples/date-picker/birth-date.tsx +21 -0
  125. package/registry/examples/date-picker/calendar.js +1 -1
  126. package/registry/examples/date-picker/calendar.tsx +2 -6
  127. package/registry/examples/date-picker/day-strip.d.ts +4 -0
  128. package/registry/examples/date-picker/day-strip.js +28 -0
  129. package/registry/examples/date-picker/day-strip.tsx +27 -0
  130. package/registry/examples/date-picker/month-year.d.ts +4 -0
  131. package/registry/examples/date-picker/month-year.js +13 -0
  132. package/registry/examples/date-picker/month-year.tsx +10 -0
  133. package/registry/examples/date-picker/native/birth-date-wheel.d.ts +4 -0
  134. package/registry/examples/date-picker/native/birth-date-wheel.dark.png +0 -0
  135. package/registry/examples/date-picker/native/birth-date-wheel.js +13 -0
  136. package/registry/examples/date-picker/native/birth-date-wheel.light.png +0 -0
  137. package/registry/examples/date-picker/native/birth-date-wheel.tsx +9 -0
  138. package/registry/examples/date-picker/native/birth-date.d.ts +4 -0
  139. package/registry/examples/date-picker/native/birth-date.dark.png +0 -0
  140. package/registry/examples/date-picker/native/birth-date.js +30 -0
  141. package/registry/examples/date-picker/native/birth-date.light.png +0 -0
  142. package/registry/examples/date-picker/native/birth-date.tsx +27 -0
  143. package/registry/examples/date-picker/native/calendar.d.ts +4 -0
  144. package/registry/examples/date-picker/native/calendar.dark.png +0 -0
  145. package/registry/examples/date-picker/native/calendar.js +13 -0
  146. package/registry/examples/date-picker/native/calendar.light.png +0 -0
  147. package/registry/examples/date-picker/native/calendar.tsx +8 -0
  148. package/registry/examples/date-picker/native/day-strip.d.ts +4 -0
  149. package/registry/examples/date-picker/native/day-strip.dark.png +0 -0
  150. package/registry/examples/date-picker/native/day-strip.js +29 -0
  151. package/registry/examples/date-picker/native/day-strip.light.png +0 -0
  152. package/registry/examples/date-picker/native/day-strip.tsx +26 -0
  153. package/registry/examples/date-picker/native/month-year.d.ts +4 -0
  154. package/registry/examples/date-picker/native/month-year.dark.png +0 -0
  155. package/registry/examples/date-picker/native/month-year.js +13 -0
  156. package/registry/examples/date-picker/native/month-year.light.png +0 -0
  157. package/registry/examples/date-picker/native/month-year.tsx +8 -0
  158. package/registry/examples/date-picker/native/time-slots.d.ts +4 -0
  159. package/registry/examples/date-picker/native/time-slots.dark.png +0 -0
  160. package/registry/examples/date-picker/native/time-slots.js +15 -0
  161. package/registry/examples/date-picker/native/time-slots.light.png +0 -0
  162. package/registry/examples/date-picker/native/time-slots.tsx +15 -0
  163. package/registry/examples/date-picker/native/time-wheel.d.ts +4 -0
  164. package/registry/examples/date-picker/native/time-wheel.dark.png +0 -0
  165. package/registry/examples/date-picker/native/time-wheel.js +13 -0
  166. package/registry/examples/date-picker/native/time-wheel.light.png +0 -0
  167. package/registry/examples/date-picker/native/time-wheel.tsx +8 -0
  168. package/registry/examples/date-picker/time-slots.d.ts +4 -0
  169. package/registry/examples/date-picker/time-slots.js +26 -0
  170. package/registry/examples/date-picker/time-slots.tsx +25 -0
  171. package/registry/examples/date-picker/time-wheel.d.ts +4 -0
  172. package/registry/examples/date-picker/time-wheel.js +13 -0
  173. package/registry/examples/date-picker/time-wheel.tsx +10 -0
  174. package/registry/examples/date-picker/wheel.d.ts +4 -0
  175. package/registry/examples/date-picker/wheel.js +14 -0
  176. package/registry/examples/date-picker/wheel.tsx +16 -0
  177. package/registry/examples/field/native/default.d.ts +4 -0
  178. package/registry/examples/field/native/default.dark.png +0 -0
  179. package/registry/examples/field/native/default.js +29 -0
  180. package/registry/examples/field/native/default.light.png +0 -0
  181. package/registry/examples/field/native/default.tsx +23 -0
  182. package/registry/examples/form/amount.d.ts +4 -0
  183. package/registry/examples/form/amount.js +30 -0
  184. package/registry/examples/form/amount.tsx +36 -0
  185. package/registry/examples/form/audience.d.ts +4 -0
  186. package/registry/examples/form/audience.js +29 -0
  187. package/registry/examples/form/audience.tsx +31 -0
  188. package/registry/examples/form/native/amount.d.ts +4 -0
  189. package/registry/examples/form/native/amount.dark.png +0 -0
  190. package/registry/examples/form/native/amount.js +26 -0
  191. package/registry/examples/form/native/amount.light.png +0 -0
  192. package/registry/examples/form/native/amount.tsx +30 -0
  193. package/registry/examples/form/native/audience.d.ts +4 -0
  194. package/registry/examples/form/native/audience.dark.png +0 -0
  195. package/registry/examples/form/native/audience.js +24 -0
  196. package/registry/examples/form/native/audience.light.png +0 -0
  197. package/registry/examples/form/native/audience.tsx +24 -0
  198. package/registry/examples/form/native/profile.d.ts +4 -0
  199. package/registry/examples/form/native/profile.dark.png +0 -0
  200. package/registry/examples/form/native/profile.js +33 -0
  201. package/registry/examples/form/native/profile.light.png +0 -0
  202. package/registry/examples/form/native/profile.tsx +36 -0
  203. package/registry/examples/form/native/settings.d.ts +4 -0
  204. package/registry/examples/form/native/settings.dark.png +0 -0
  205. package/registry/examples/form/native/settings.js +25 -0
  206. package/registry/examples/form/native/settings.light.png +0 -0
  207. package/registry/examples/form/native/settings.tsx +23 -0
  208. package/registry/examples/form/native/sign-up.d.ts +4 -0
  209. package/registry/examples/form/native/sign-up.dark.png +0 -0
  210. package/registry/examples/form/native/sign-up.js +38 -0
  211. package/registry/examples/form/native/sign-up.light.png +0 -0
  212. package/registry/examples/form/native/sign-up.tsx +34 -0
  213. package/registry/examples/form/native/upload.d.ts +4 -0
  214. package/registry/examples/form/native/upload.dark.png +0 -0
  215. package/registry/examples/form/native/upload.js +23 -0
  216. package/registry/examples/form/native/upload.light.png +0 -0
  217. package/registry/examples/form/native/upload.tsx +22 -0
  218. package/registry/examples/form/profile.d.ts +4 -0
  219. package/registry/examples/form/profile.js +35 -0
  220. package/registry/examples/form/profile.tsx +40 -0
  221. package/registry/examples/form/report.d.ts +4 -0
  222. package/registry/examples/form/report.js +30 -0
  223. package/registry/examples/form/report.tsx +30 -0
  224. package/registry/examples/form/settings.d.ts +4 -0
  225. package/registry/examples/form/settings.js +30 -0
  226. package/registry/examples/form/settings.tsx +31 -0
  227. package/registry/examples/form/sign-up.d.ts +4 -0
  228. package/registry/examples/form/sign-up.js +38 -0
  229. package/registry/examples/form/sign-up.tsx +37 -0
  230. package/registry/examples/form/upload.d.ts +4 -0
  231. package/registry/examples/form/upload.js +32 -0
  232. package/registry/examples/form/upload.tsx +32 -0
  233. package/registry/field.json +104 -4
  234. package/registry/file-upload.json +1 -1
  235. package/registry/filter-bar.json +1 -1
  236. package/registry/form.json +2940 -0
  237. package/registry/gallery-page.json +1 -1
  238. package/registry/glow-card.json +1 -1
  239. package/registry/goal-gauge.json +1 -1
  240. package/registry/how-it-works-page.json +1 -1
  241. package/registry/image-cropper.json +1 -1
  242. package/registry/index.json +43 -10
  243. package/registry/iso.json +1 -1
  244. package/registry/kbd.json +1 -1
  245. package/registry/landing-page.json +1 -1
  246. package/registry/landscape.json +1 -1
  247. package/registry/legal-page.json +1 -1
  248. package/registry/link-card.json +1 -1
  249. package/registry/loader.json +1 -1
  250. package/registry/longform-page.json +1 -1
  251. package/registry/marketing-layout.json +1 -1
  252. package/registry/marquee.json +1 -1
  253. package/registry/mascot-quote.json +1 -1
  254. package/registry/mascot-state.json +2 -2
  255. package/registry/mascots.json +2 -2
  256. package/registry/media-capture.json +1 -1
  257. package/registry/meter.json +1 -1
  258. package/registry/nav-bar.json +1 -1
  259. package/registry/number-ticker.json +1 -1
  260. package/registry/page-header.json +1 -1
  261. package/registry/page-hero.json +1 -1
  262. package/registry/page.json +1 -1
  263. package/registry/pagination.json +1 -1
  264. package/registry/pointer-light.json +1 -1
  265. package/registry/popover.json +1 -1
  266. package/registry/pricing-page.json +1 -1
  267. package/registry/product-page.json +1 -1
  268. package/registry/profile-card.json +1 -1
  269. package/registry/progress.json +1 -1
  270. package/registry/promise-card.json +1 -1
  271. package/registry/radio-group.json +1 -1
  272. package/registry/scroll-stage.json +1 -1
  273. package/registry/search-field.json +1 -1
  274. package/registry/section-backdrop.json +1 -1
  275. package/registry/separator.json +1 -1
  276. package/registry/settings-layout.json +1 -1
  277. package/registry/skeleton.json +1 -1
  278. package/registry/slider.json +1 -1
  279. package/registry/slot.json +1 -1
  280. package/registry/spinner.json +1 -1
  281. package/registry/split-view.json +1 -1
  282. package/registry/stage-banner.json +1 -1
  283. package/registry/stat.json +1 -1
  284. package/registry/status-page.json +1 -1
  285. package/registry/stepper.json +1 -1
  286. package/registry/switch.json +1 -1
  287. package/registry/tabs.json +1 -1
  288. package/registry/tag-input.json +1 -1
  289. package/registry/terminal-replay.json +1 -1
  290. package/registry/theme.json +8 -1
  291. package/registry/toast.json +1 -1
  292. package/registry/toc.json +1 -1
  293. package/registry/tooltip.json +1 -1
  294. package/registry/video-player.json +1 -1
  295. package/registry/video-trimmer.json +1 -1
  296. package/registry/virtual.json +1 -1
  297. package/skills/date-picker/SKILL.md +43 -0
  298. package/skills/form/SKILL.md +44 -0
  299. package/dist/chunk-2USC2YT6.js +0 -17
  300. package/dist/chunk-2USC2YT6.js.map +0 -1
  301. package/dist/chunk-5AXLA4LK.js +0 -13
  302. package/dist/chunk-5AXLA4LK.js.map +0 -1
  303. package/dist/chunk-FJDSLNXK.js +0 -11
  304. package/dist/chunk-FJDSLNXK.js.map +0 -1
  305. package/dist/chunk-KNBYZGSQ.js +0 -11
  306. package/dist/chunk-KNBYZGSQ.js.map +0 -1
  307. package/dist/chunk-VCAAHCHL.js +0 -17
  308. package/dist/chunk-VCAAHCHL.js.map +0 -1
  309. /package/dist/{chunk-OGJI5X4W.js.map → chunk-2PUDI7JS.js.map} +0 -0
  310. /package/dist/{chunk-K3SWZXYT.js.map → chunk-DGQMDJXK.js.map} +0 -0
@@ -1,10 +1,12 @@
1
1
  "use client";
2
2
  import {
3
3
  cn,
4
- floating
5
- } from "./chunk-2USC2YT6.js";
4
+ floating,
5
+ twMergeConfig
6
+ } from "./chunk-I5RVM5CW.js";
6
7
  import {
7
- useControllable
8
+ useControllable,
9
+ usePrefersReducedMotion
8
10
  } from "./chunk-BRKMQ6JV.js";
9
11
  import {
10
12
  CalendarGlyph,
@@ -14,41 +16,122 @@ import {
14
16
 
15
17
  // src/date-picker/calendar.tsx
16
18
  import { formatDate, getDateTimeFormat } from "@krizaka/intl";
19
+ import * as React2 from "react";
20
+
21
+ // src/tv.ts
22
+ import { createTV } from "tailwind-variants";
23
+ var tv = createTV({ twMergeConfig });
24
+
25
+ // src/date-picker/month-picker.tsx
17
26
  import * as React from "react";
18
- import { tv } from "tailwind-variants";
19
- import { jsx, jsxs } from "react/jsx-runtime";
20
- var calendar = tv({
21
- slots: {
22
- root: "w-[17.5rem] select-none text-sm text-fg",
23
- header: "mb-2 flex items-center justify-between gap-2",
24
- title: "text-sm font-semibold capitalize",
25
- nav: "inline-flex h-8 w-8 items-center justify-center rounded-md text-fg-secondary hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40",
26
- grid: "w-full border-collapse",
27
- weekday: "h-8 w-10 text-center text-[11px] font-semibold uppercase text-fg-secondary",
28
- cell: "p-0 text-center",
29
- day: "relative h-10 w-10 rounded-lg text-sm tabular-nums text-fg transition-colors hover:bg-surface-3 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[outside]:text-fg-secondary data-[today]:font-bold data-[today]:not-data-[selected]:text-fg-accent data-[in-range]:rounded-none data-[in-range]:bg-accent-soft data-[selected]:bg-accent data-[selected]:text-on-accent data-[selected]:hover:bg-accent disabled:cursor-not-allowed disabled:text-fg-muted disabled:line-through disabled:opacity-50 disabled:hover:bg-transparent"
27
+
28
+ // src/date-picker/parts.ts
29
+ var DATE_PART_LENGTH = { day: 2, month: 2, year: 4 };
30
+ function datePartsOrder(locale) {
31
+ try {
32
+ const parts = new Intl.DateTimeFormat(locale, { day: "2-digit", month: "2-digit", year: "numeric" }).formatToParts(new Date(2001, 10, 22));
33
+ const order = parts.map((p) => p.type).filter((t) => t === "day" || t === "month" || t === "year");
34
+ if (order.length === 3) return order;
35
+ } catch {
30
36
  }
31
- });
32
- var pad = (n) => String(n).padStart(2, "0");
33
- var parts = (iso) => iso.split("-").map(Number);
37
+ return ["day", "month", "year"];
38
+ }
39
+ function composeDate(parts) {
40
+ if (!parts.day && !parts.month && !parts.year) return "";
41
+ const pad = (v) => v.length === 1 ? `0${v}` : v;
42
+ return `${parts.year}-${pad(parts.month)}-${pad(parts.day)}`;
43
+ }
44
+ function splitDate(value) {
45
+ const m = /^(\d*)-(\d*)-(\d*)$/.exec(value ?? "");
46
+ return m ? { year: m[1], month: m[2], day: m[3] } : { day: "", month: "", year: "" };
47
+ }
48
+ function isRealDate(value) {
49
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
50
+ const date = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
51
+ return !Number.isNaN(date.getTime()) && date.toISOString().slice(0, 10) === value;
52
+ }
53
+ function latestBirthDate(age, today = /* @__PURE__ */ new Date()) {
54
+ return new Date(Date.UTC(today.getFullYear() - age, today.getMonth(), today.getDate())).toISOString().slice(0, 10);
55
+ }
56
+ function daysInMonth(year, month) {
57
+ return new Date(Date.UTC(year, month, 0)).getUTCDate();
58
+ }
59
+ function isoParts(iso) {
60
+ const [year = 0, month = 0, day = 0] = iso.split("-").map(Number);
61
+ return { year, month, day };
62
+ }
63
+ function isoOf(year, month, day) {
64
+ const d = Math.min(Math.max(day, 1), daysInMonth(year, month));
65
+ return `${String(year).padStart(4, "0")}-${String(month).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
66
+ }
67
+ function todayIso(now = /* @__PURE__ */ new Date()) {
68
+ return isoOf(now.getFullYear(), now.getMonth() + 1, now.getDate());
69
+ }
70
+ function ageOn(birth, today = todayIso()) {
71
+ const b = isoParts(birth);
72
+ const t = isoParts(today);
73
+ return t.year - b.year - (t.month < b.month || t.month === b.month && t.day < b.day ? 1 : 0);
74
+ }
75
+ function monthNames(locale, style = "long") {
76
+ const format = new Intl.DateTimeFormat(locale, { month: style, timeZone: "UTC" });
77
+ return Array.from({ length: 12 }, (_, i) => format.format(new Date(Date.UTC(2001, i, 1))));
78
+ }
79
+ function yearRange(from, to) {
80
+ const step = from <= to ? 1 : -1;
81
+ return Array.from({ length: Math.abs(to - from) + 1 }, (_, i) => from + i * step);
82
+ }
83
+ function timeToMinutes(value) {
84
+ const m = /^(\d{1,2}):(\d{1,2})$/.exec(value ?? "");
85
+ if (!m) return null;
86
+ const h = Number(m[1]);
87
+ const min = Number(m[2]);
88
+ return h < 24 && min < 60 ? h * 60 + min : null;
89
+ }
90
+ function minutesToTime(minutes) {
91
+ const m = (Math.round(minutes) % 1440 + 1440) % 1440;
92
+ return `${String(Math.floor(m / 60)).padStart(2, "0")}:${String(m % 60).padStart(2, "0")}`;
93
+ }
94
+ function timeSlots(start, end, step = 30) {
95
+ const a = timeToMinutes(start);
96
+ const b = timeToMinutes(end);
97
+ if (a === null || b === null || step <= 0) return [];
98
+ const slots = [];
99
+ for (let m = a; m < b; m += step) slots.push(minutesToTime(m));
100
+ return slots;
101
+ }
102
+ function uses12Hours(locale) {
103
+ try {
104
+ const options = new Intl.DateTimeFormat(locale, { hour: "numeric" }).resolvedOptions();
105
+ return options.hourCycle ? options.hourCycle === "h12" || options.hourCycle === "h11" : Boolean(options.hour12);
106
+ } catch {
107
+ return false;
108
+ }
109
+ }
110
+ function dayPeriods(locale) {
111
+ const format = new Intl.DateTimeFormat(locale, { hour: "numeric", hour12: true, timeZone: "UTC" });
112
+ const period = (h) => format.formatToParts(new Date(Date.UTC(2001, 0, 1, h))).find((p) => p.type === "dayPeriod")?.value ?? (h < 12 ? "AM" : "PM");
113
+ return [period(9), period(15)];
114
+ }
115
+ function formatTime(locale, value) {
116
+ const minutes = timeToMinutes(value);
117
+ if (minutes === null) return "";
118
+ return new Intl.DateTimeFormat(locale, { hour: "numeric", minute: "2-digit", timeZone: "UTC" }).format(new Date(Date.UTC(2001, 0, 1, 0, minutes)));
119
+ }
34
120
  var toLocalDate = (iso) => {
35
- const [y, m, d] = parts(iso);
36
- return new Date(y, m - 1, d);
121
+ const { year, month, day } = isoParts(iso);
122
+ return new Date(year, month - 1, day);
37
123
  };
38
- var toIsoDate = (date) => `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
124
+ var toIsoDate = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
39
125
  var addDays = (iso, days) => {
40
126
  const date = toLocalDate(iso);
41
127
  date.setDate(date.getDate() + days);
42
128
  return toIsoDate(date);
43
129
  };
44
130
  var addMonths = (iso, months) => {
45
- const [y, m, d] = parts(iso);
46
- const first = new Date(y, m - 1 + months, 1);
47
- const last = new Date(first.getFullYear(), first.getMonth() + 1, 0).getDate();
48
- return toIsoDate(new Date(first.getFullYear(), first.getMonth(), Math.min(d, last)));
131
+ const { year, month, day } = isoParts(iso);
132
+ const first = new Date(year, month - 1 + months, 1);
133
+ return isoOf(first.getFullYear(), first.getMonth() + 1, day);
49
134
  };
50
- var monthOf = (iso) => `${iso.slice(0, 7)}-01`;
51
- var clampIso = (iso, min, max) => min && iso < min ? min : max && iso > max ? max : iso;
52
135
  function weekStartOf(locale) {
53
136
  try {
54
137
  const info = new Intl.Locale(locale);
@@ -58,7 +141,147 @@ function weekStartOf(locale) {
58
141
  return 1;
59
142
  }
60
143
  }
61
- var calendarLabels = { previousMonth: "Previous month", nextMonth: "Next month" };
144
+
145
+ // src/date-picker/month-picker.tsx
146
+ import { jsx, jsxs } from "react/jsx-runtime";
147
+ var monthPicker = tv({
148
+ slots: {
149
+ root: "inline-flex select-none flex-col gap-3 text-sm text-fg",
150
+ header: "flex items-center justify-between gap-2",
151
+ year: "text-sm font-semibold tabular-nums",
152
+ nav: "inline-flex h-9 w-9 items-center justify-center rounded-lg border border-border-subtle bg-surface-2 bg-sheen text-fg-secondary inset-shadow-edge transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-35",
153
+ grid: "kz-fade grid grid-cols-3 gap-1.5",
154
+ month: "relative h-11 min-w-[5.5rem] rounded-xl px-2 text-sm font-medium capitalize text-fg transition-[background-color,box-shadow,transform] duration-150 hover:bg-surface-3 active:scale-95 motion-reduce:transition-none motion-reduce:active:scale-100 focus-visible:outline-hidden focus-visible:focus-ring data-[current]:font-bold data-[current]:not-data-[selected]:text-fg-accent data-[selected]:bg-accent data-[selected]:bg-fill-shade data-[selected]:font-semibold data-[selected]:text-on-accent data-[selected]:shadow-glow data-[selected]:inset-shadow-edge-fill disabled:cursor-not-allowed disabled:text-fg-muted disabled:opacity-50 disabled:hover:bg-transparent"
155
+ },
156
+ variants: {
157
+ variant: {
158
+ plain: {},
159
+ card: { root: "rounded-2xl border border-border-default bg-surface-1 bg-sheen p-4 shadow-raised inset-shadow-edge" }
160
+ }
161
+ },
162
+ defaultVariants: { variant: "plain" }
163
+ });
164
+ var monthPickerLabels = { previousYear: "Previous year", nextYear: "Next year" };
165
+ function MonthPicker({ locale, value: valueProp, defaultValue = null, onValueChange, year: yearProp, onYearChange, min, max, current, autoFocus, bare, variant, labels: given, className }) {
166
+ const labels = { ...monthPickerLabels, ...given };
167
+ const s = monthPicker({ variant });
168
+ const [own, setOwn] = React.useState(defaultValue);
169
+ const value = valueProp !== void 0 ? valueProp : own;
170
+ const now = /* @__PURE__ */ new Date();
171
+ const thisMonth = current ?? `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
172
+ const [ownYear, setOwnYear] = React.useState(() => Number((value ?? thisMonth).slice(0, 4)));
173
+ const year = yearProp ?? ownYear;
174
+ const setYear = (y) => {
175
+ if (yearProp === void 0) setOwnYear(y);
176
+ onYearChange?.(y);
177
+ };
178
+ const names = React.useMemo(() => monthNames(locale, "short").map((n) => n.replace(/\.$/, "")), [locale]);
179
+ const longNames = React.useMemo(() => monthNames(locale, "long"), [locale]);
180
+ const iso = (y, m) => `${String(y).padStart(4, "0")}-${String(m).padStart(2, "0")}`;
181
+ const disabled = (m) => Boolean(min && m < min || max && m > max);
182
+ const [focused, setFocused] = React.useState(() => value && Number(value.slice(0, 4)) === year ? Number(value.slice(5, 7)) : Number(thisMonth.slice(5, 7)));
183
+ const grid = React.useRef(null);
184
+ const moved = React.useRef(Boolean(autoFocus));
185
+ React.useEffect(() => {
186
+ if (!moved.current) return;
187
+ moved.current = false;
188
+ grid.current?.querySelector(`[data-month="${iso(year, focused)}"]`)?.focus();
189
+ }, [year, focused]);
190
+ const pick = (m) => {
191
+ if (valueProp === void 0) setOwn(m);
192
+ onValueChange?.(m);
193
+ };
194
+ const move = (to) => {
195
+ moved.current = true;
196
+ const y = year + Math.floor((to - 1) / 12);
197
+ const m = ((to - 1) % 12 + 12) % 12 + 1;
198
+ if (y !== year) setYear(y);
199
+ setFocused(m);
200
+ };
201
+ const onKeyDown = (event) => {
202
+ const moves = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -3, ArrowDown: 3, PageUp: -12, PageDown: 12 };
203
+ if (event.key === "Home" || event.key === "End") {
204
+ event.preventDefault();
205
+ moved.current = true;
206
+ setFocused(event.key === "Home" ? 1 : 12);
207
+ return;
208
+ }
209
+ const by = moves[event.key];
210
+ if (by === void 0) return;
211
+ event.preventDefault();
212
+ move(focused + by);
213
+ };
214
+ const rows = [0, 1, 2, 3].map((r) => [1, 2, 3].map((c) => r * 3 + c));
215
+ return /* @__PURE__ */ jsxs("div", { className: s.root({ className }), children: [
216
+ bare ? null : /* @__PURE__ */ jsxs("div", { className: s.header(), children: [
217
+ /* @__PURE__ */ jsx("button", { type: "button", className: s.nav(), "aria-label": labels.previousYear, disabled: Boolean(min && year - 1 < Number(min.slice(0, 4))), onClick: () => setYear(year - 1), children: /* @__PURE__ */ jsx(ChevronGlyph, { direction: "left", className: "h-4 w-4" }) }),
218
+ /* @__PURE__ */ jsx("span", { className: s.year(), "aria-live": "polite", children: year }),
219
+ /* @__PURE__ */ jsx("button", { type: "button", className: s.nav(), "aria-label": labels.nextYear, disabled: Boolean(max && year + 1 > Number(max.slice(0, 4))), onClick: () => setYear(year + 1), children: /* @__PURE__ */ jsx(ChevronGlyph, { direction: "right", className: "h-4 w-4" }) })
220
+ ] }),
221
+ /* @__PURE__ */ jsx("div", { ref: grid, role: "grid", "aria-label": String(year), className: s.grid(), onKeyDown, children: rows.map((row) => /* @__PURE__ */ jsx("div", { role: "row", className: "contents", children: row.map((m) => {
222
+ const id = iso(year, m);
223
+ return /* @__PURE__ */ jsx("div", { role: "gridcell", "aria-selected": id === value || void 0, className: "flex", children: /* @__PURE__ */ jsxs(
224
+ "button",
225
+ {
226
+ type: "button",
227
+ "data-month": id,
228
+ tabIndex: m === focused ? 0 : -1,
229
+ "aria-current": id === thisMonth ? "date" : void 0,
230
+ "data-current": id === thisMonth ? "" : void 0,
231
+ "data-selected": id === value ? "" : void 0,
232
+ disabled: disabled(id),
233
+ className: s.month({ className: "w-full" }),
234
+ onClick: () => {
235
+ setFocused(m);
236
+ pick(id);
237
+ },
238
+ children: [
239
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: names[m - 1] }),
240
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: `${longNames[m - 1]} ${year}` })
241
+ ]
242
+ }
243
+ ) }, m);
244
+ }) }, row[0])) }, year)
245
+ ] });
246
+ }
247
+
248
+ // src/date-picker/calendar.tsx
249
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
250
+ var calendar = tv({
251
+ slots: {
252
+ root: "inline-flex select-none flex-col text-sm text-fg",
253
+ header: "mb-3 flex items-center justify-between gap-2",
254
+ caption: "inline-flex h-9 items-center gap-1.5 rounded-lg px-2.5 text-sm font-semibold capitalize text-fg transition-colors hover:bg-surface-3 focus-visible:outline-hidden focus-visible:focus-ring aria-expanded:bg-surface-3",
255
+ nav: "inline-flex h-9 w-9 items-center justify-center rounded-lg border border-border-subtle bg-surface-2 bg-sheen text-fg-secondary inset-shadow-edge transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-35",
256
+ months: "flex flex-col gap-6 sm:flex-row",
257
+ month: "kz-month flex flex-col gap-2",
258
+ monthTitle: "px-1 text-xs font-semibold capitalize text-fg-secondary",
259
+ grid: "border-separate border-spacing-y-1",
260
+ weekday: "h-7 w-10 pb-1 text-center text-[11px] font-semibold uppercase tracking-wider text-fg-secondary",
261
+ cell: "p-0 text-center data-[band]:bg-accent-soft data-[band=start]:rounded-l-xl data-[band=end]:rounded-r-xl data-[band=solo]:rounded-xl data-[band=preview]:bg-surface-3",
262
+ day: "relative h-10 w-10 rounded-xl text-sm tabular-nums text-fg transition-[background-color,box-shadow,transform] duration-150 hover:bg-surface-3 active:scale-95 motion-reduce:transition-none motion-reduce:active:scale-100 focus-visible:z-10 focus-visible:outline-hidden focus-visible:focus-ring data-[outside]:text-fg-secondary data-[outside]:font-normal data-[weekend]:not-data-[selected]:text-fg-secondary data-[today]:font-bold data-[today]:not-data-[selected]:text-fg-accent data-[in-range]:hover:bg-accent/15 data-[selected]:bg-accent data-[selected]:bg-fill-shade data-[selected]:font-semibold data-[selected]:text-on-accent data-[selected]:shadow-glow data-[selected]:inset-shadow-edge-fill data-[selected]:hover:bg-accent disabled:cursor-not-allowed disabled:text-fg-muted disabled:line-through disabled:opacity-50 disabled:hover:bg-transparent",
263
+ // Today: the node under the number (the marks' diamond), on-accent when today is the chosen day.
264
+ node: "pointer-events-none absolute bottom-1 left-1/2 h-1 w-1 -translate-x-1/2 rotate-45 rounded-[1px] bg-accent group-data-[selected]:bg-on-accent",
265
+ live: "sr-only"
266
+ },
267
+ variants: {
268
+ variant: {
269
+ plain: {},
270
+ card: { root: "rounded-2xl border border-border-default bg-surface-1 bg-sheen p-4 shadow-raised inset-shadow-edge" }
271
+ }
272
+ },
273
+ defaultVariants: { variant: "plain" }
274
+ });
275
+ var monthOf = (iso) => `${iso.slice(0, 7)}-01`;
276
+ var clampIso = (iso, min, max) => min && iso < min ? min : max && iso > max ? max : iso;
277
+ var monthsBetween = (a, b) => (Number(b.slice(0, 4)) - Number(a.slice(0, 4))) * 12 + Number(b.slice(5, 7)) - Number(a.slice(5, 7));
278
+ var calendarLabels = {
279
+ previousMonth: "Previous month",
280
+ nextMonth: "Next month",
281
+ chooseMonth: "Choose month and year",
282
+ previousYear: "Previous year",
283
+ nextYear: "Next year"
284
+ };
62
285
  function Calendar({
63
286
  locale,
64
287
  value,
@@ -67,53 +290,59 @@ function Calendar({
67
290
  month: monthProp,
68
291
  defaultMonth,
69
292
  onMonthChange,
293
+ numberOfMonths = 1,
70
294
  min,
71
295
  max,
72
296
  isDateDisabled,
73
297
  weekStartsOn,
74
298
  today: todayProp,
75
299
  autoFocus,
300
+ variant,
76
301
  labels: given,
77
302
  className
78
303
  }) {
79
304
  const labels = { ...calendarLabels, ...given };
80
- const s = calendar();
305
+ const s = calendar({ variant });
81
306
  const today = todayProp ?? toIsoDate(/* @__PURE__ */ new Date());
82
307
  const anchor = value ?? range?.start ?? clampIso(today, min, max);
83
- const [innerMonth, setInnerMonth] = React.useState(monthOf(defaultMonth ?? anchor));
308
+ const [innerMonth, setInnerMonth] = React2.useState(monthOf(defaultMonth ?? anchor));
84
309
  const month = monthProp ? monthOf(monthProp) : innerMonth;
85
- const [focused, setFocused] = React.useState(anchor.slice(0, 7) === month.slice(0, 7) ? anchor : month);
86
- const [hover, setHover] = React.useState(null);
87
- const grid = React.useRef(null);
88
- const moved = React.useRef(Boolean(autoFocus));
89
- const titleId = React.useId();
310
+ const shown = Array.from({ length: numberOfMonths }, (_, i) => addMonths(month, i));
311
+ const lastShown = shown[shown.length - 1];
312
+ const isShown = (iso) => iso.slice(0, 7) >= month.slice(0, 7) && iso.slice(0, 7) <= lastShown.slice(0, 7);
313
+ const [focused, setFocused] = React2.useState(isShown(anchor) ? anchor : month);
314
+ const [hover, setHover] = React2.useState(null);
315
+ const [view, setView] = React2.useState("days");
316
+ const [direction, setDirection] = React2.useState(null);
317
+ const root = React2.useRef(null);
318
+ const moved = React2.useRef(Boolean(autoFocus));
319
+ const titleId = React2.useId();
90
320
  const setMonth = (next) => {
91
321
  const m = monthOf(next);
322
+ setDirection(m > month ? "next" : m < month ? "previous" : null);
92
323
  if (!monthProp) setInnerMonth(m);
93
324
  onMonthChange?.(m);
94
325
  };
95
- const active = focused.slice(0, 7) === month.slice(0, 7) ? focused : month;
96
- React.useEffect(() => {
97
- if (!moved.current) return;
326
+ const active = isShown(focused) ? focused : month;
327
+ React2.useEffect(() => {
328
+ if (!moved.current || view !== "days") return;
98
329
  moved.current = false;
99
- grid.current?.querySelector(`[data-date="${active}"]`)?.focus();
100
- }, [active]);
330
+ root.current?.querySelector(`[data-date="${active}"]`)?.focus();
331
+ }, [active, view]);
101
332
  const disabled = (iso) => Boolean(min && iso < min || max && iso > max || isDateDisabled?.(iso));
102
333
  const start = weekStartsOn ?? weekStartOf(locale);
103
- const first = toLocalDate(month);
104
- const lead = (first.getDay() - start + 7) % 7;
105
- const gridStart = addDays(month, -lead);
106
- const days = Array.from({ length: 42 }, (_, i) => addDays(gridStart, i));
107
- const weeks = Array.from({ length: 6 }, (_, w) => days.slice(w * 7, w * 7 + 7)).filter((week, w) => w < 5 || week[0].slice(0, 7) === month.slice(0, 7));
108
334
  const weekdayShort = getDateTimeFormat(locale, { weekday: "short" });
109
335
  const weekdayLong = getDateTimeFormat(locale, { weekday: "long" });
110
- const title = getDateTimeFormat(locale, { month: "long", year: "numeric" }).format(first);
336
+ const titleFormat = getDateTimeFormat(locale, { month: "long", year: "numeric" });
337
+ const title = titleFormat.format(toLocalDate(month));
338
+ const fullTitle = numberOfMonths === 2 ? `${title} \u2013 ${titleFormat.format(toLocalDate(lastShown))}` : title;
111
339
  const rangeEnd = range ? range.end ?? hover : null;
112
340
  const [lo, hi] = range && rangeEnd ? range.start <= rangeEnd ? [range.start, rangeEnd] : [rangeEnd, range.start] : [null, null];
341
+ const previewing = Boolean(range && !range.end);
113
342
  const focusDay = (iso) => {
114
343
  moved.current = true;
115
344
  setFocused(iso);
116
- if (iso.slice(0, 7) !== month.slice(0, 7)) setMonth(iso);
345
+ if (!isShown(iso)) setMonth(iso < month ? iso : addMonths(iso, -(numberOfMonths - 1)));
117
346
  };
118
347
  const onKeyDown = (event) => {
119
348
  const weekday = (toLocalDate(active).getDay() - start + 7) % 7;
@@ -133,56 +362,381 @@ function Calendar({
133
362
  focusDay(move());
134
363
  };
135
364
  const prevDisabled = Boolean(min && addDays(month, -1) < min);
136
- const nextDisabled = Boolean(max && addMonths(month, 1) > max);
137
- return /* @__PURE__ */ jsxs("div", { className: s.root({ className }), children: [
138
- /* @__PURE__ */ jsxs("div", { className: s.header(), children: [
139
- /* @__PURE__ */ jsx("button", { type: "button", className: s.nav(), "aria-label": labels.previousMonth, disabled: prevDisabled, onClick: () => setMonth(addMonths(month, -1)), children: /* @__PURE__ */ jsx(ChevronGlyph, { direction: "left" }) }),
140
- /* @__PURE__ */ jsx("h2", { id: titleId, className: s.title(), "aria-live": "polite", children: title }),
141
- /* @__PURE__ */ jsx("button", { type: "button", className: s.nav(), "aria-label": labels.nextMonth, disabled: nextDisabled, onClick: () => setMonth(addMonths(month, 1)), children: /* @__PURE__ */ jsx(ChevronGlyph, { direction: "right" }) })
365
+ const nextDisabled = Boolean(max && addMonths(lastShown, 1) > max);
366
+ const band = (iso) => {
367
+ if (!lo || !hi) return void 0;
368
+ if (iso < lo || iso > hi) return void 0;
369
+ if (lo === hi) return void 0;
370
+ if (previewing && iso !== range?.start) return iso === lo ? "start" : iso === hi ? "end" : "preview";
371
+ return iso === lo ? "start" : iso === hi ? "end" : "middle";
372
+ };
373
+ const renderMonth = (first, index) => {
374
+ const firstDate = toLocalDate(first);
375
+ const lead = (firstDate.getDay() - start + 7) % 7;
376
+ const gridStart = addDays(first, -lead);
377
+ const days = Array.from({ length: 42 }, (_, i) => addDays(gridStart, i));
378
+ const weeks = Array.from({ length: 6 }, (_, w) => days.slice(w * 7, w * 7 + 7)).filter((week, w) => w < 5 || week[0].slice(0, 7) === first.slice(0, 7));
379
+ const monthTitle = titleFormat.format(firstDate);
380
+ const gridLabelId = `${titleId}-m${index}`;
381
+ return /* @__PURE__ */ jsxs2("div", { className: s.month(), "data-dir": direction ?? void 0, children: [
382
+ numberOfMonths === 2 ? /* @__PURE__ */ jsx2("div", { id: gridLabelId, className: s.monthTitle(), children: monthTitle }) : null,
383
+ /* @__PURE__ */ jsxs2("table", { role: "grid", "aria-label": monthTitle, className: s.grid(), onKeyDown, children: [
384
+ /* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: days.slice(0, 7).map((iso) => /* @__PURE__ */ jsx2("th", { scope: "col", abbr: weekdayLong.format(toLocalDate(iso)), className: s.weekday(), children: weekdayShort.format(toLocalDate(iso)).replace(/\.$/, "") }, iso)) }) }),
385
+ /* @__PURE__ */ jsx2("tbody", { children: weeks.map((week) => /* @__PURE__ */ jsx2("tr", { children: week.map((iso) => {
386
+ const outside = iso.slice(0, 7) !== first.slice(0, 7);
387
+ if (outside && numberOfMonths === 2) return /* @__PURE__ */ jsx2("td", { role: "gridcell", className: s.cell() }, iso);
388
+ const selected = iso === value || Boolean(range && (iso === range.start || iso === range.end));
389
+ const inRange = Boolean(lo && hi && iso > lo && iso < hi);
390
+ const dow = toLocalDate(iso).getDay();
391
+ return /* @__PURE__ */ jsx2("td", { role: "gridcell", "aria-selected": selected || inRange || void 0, "data-band": band(iso), className: s.cell(), children: /* @__PURE__ */ jsxs2(
392
+ "button",
393
+ {
394
+ type: "button",
395
+ "data-date": iso,
396
+ tabIndex: iso === active ? 0 : -1,
397
+ "aria-label": formatDate(toLocalDate(iso), { locale, style: "long" }),
398
+ "aria-current": iso === today ? "date" : void 0,
399
+ "data-today": iso === today ? "" : void 0,
400
+ "data-outside": outside ? "" : void 0,
401
+ "data-weekend": dow === 0 || dow === 6 ? "" : void 0,
402
+ "data-selected": selected ? "" : void 0,
403
+ "data-in-range": inRange ? "" : void 0,
404
+ disabled: disabled(iso),
405
+ className: s.day({ className: "group" }),
406
+ onClick: () => {
407
+ setFocused(iso);
408
+ onSelect?.(iso);
409
+ },
410
+ onMouseEnter: previewing ? () => setHover(iso) : void 0,
411
+ onFocus: previewing ? () => setHover(iso) : void 0,
412
+ children: [
413
+ Number(iso.slice(8)),
414
+ iso === today ? /* @__PURE__ */ jsx2("span", { "aria-hidden": true, className: s.node() }) : null
415
+ ]
416
+ }
417
+ ) }, iso);
418
+ }) }, week[0])) })
419
+ ] })
420
+ ] }, first);
421
+ };
422
+ return /* @__PURE__ */ jsxs2("div", { ref: root, className: s.root({ className }), children: [
423
+ /* @__PURE__ */ jsxs2("div", { className: s.header(), children: [
424
+ /* @__PURE__ */ jsx2(
425
+ "button",
426
+ {
427
+ type: "button",
428
+ className: s.nav(),
429
+ "aria-label": view === "days" ? labels.previousMonth : labels.previousYear,
430
+ disabled: view === "days" ? prevDisabled : Boolean(min && Number(month.slice(0, 4)) - 1 < Number(min.slice(0, 4))),
431
+ onClick: () => setMonth(addMonths(month, view === "days" ? -1 : -12)),
432
+ children: /* @__PURE__ */ jsx2(ChevronGlyph, { direction: "left", className: "h-4 w-4" })
433
+ }
434
+ ),
435
+ /* @__PURE__ */ jsxs2("button", { type: "button", className: s.caption(), "aria-expanded": view === "months", "aria-label": `${labels.chooseMonth}, ${fullTitle}`, onClick: () => setView(view === "days" ? "months" : "days"), children: [
436
+ /* @__PURE__ */ jsx2("span", { "aria-hidden": true, children: view === "days" ? fullTitle : month.slice(0, 4) }),
437
+ /* @__PURE__ */ jsx2(ChevronGlyph, { direction: view === "months" ? "up" : "down", className: "h-3.5 w-3.5 text-fg-secondary" })
438
+ ] }),
439
+ /* @__PURE__ */ jsx2(
440
+ "button",
441
+ {
442
+ type: "button",
443
+ className: s.nav(),
444
+ "aria-label": view === "days" ? labels.nextMonth : labels.nextYear,
445
+ disabled: view === "days" ? nextDisabled : Boolean(max && Number(month.slice(0, 4)) + 1 > Number(max.slice(0, 4))),
446
+ onClick: () => setMonth(addMonths(month, view === "days" ? 1 : 12)),
447
+ children: /* @__PURE__ */ jsx2(ChevronGlyph, { direction: "right", className: "h-4 w-4" })
448
+ }
449
+ )
142
450
  ] }),
143
- /* @__PURE__ */ jsxs("table", { ref: grid, role: "grid", "aria-labelledby": titleId, className: s.grid(), onKeyDown, children: [
144
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: days.slice(0, 7).map((iso) => /* @__PURE__ */ jsx("th", { scope: "col", abbr: weekdayLong.format(toLocalDate(iso)), className: s.weekday(), children: weekdayShort.format(toLocalDate(iso)).replace(/\.$/, "") }, iso)) }) }),
145
- /* @__PURE__ */ jsx("tbody", { children: weeks.map((week) => /* @__PURE__ */ jsx("tr", { children: week.map((iso) => {
146
- const selected = iso === value || range && (iso === range.start || iso === range.end);
147
- const inRange = Boolean(lo && hi && iso > lo && iso < hi);
148
- return /* @__PURE__ */ jsx("td", { role: "gridcell", "aria-selected": selected || inRange || void 0, className: s.cell(), children: /* @__PURE__ */ jsx(
149
- "button",
150
- {
151
- type: "button",
152
- "data-date": iso,
153
- tabIndex: iso === active ? 0 : -1,
154
- "aria-label": formatDate(toLocalDate(iso), { locale, style: "long" }),
155
- "aria-current": iso === today ? "date" : void 0,
156
- "data-today": iso === today ? "" : void 0,
157
- "data-outside": iso.slice(0, 7) !== month.slice(0, 7) ? "" : void 0,
158
- "data-selected": selected ? "" : void 0,
159
- "data-in-range": inRange ? "" : void 0,
160
- disabled: disabled(iso),
161
- className: s.day(),
162
- onClick: () => {
163
- setFocused(iso);
164
- onSelect?.(iso);
165
- },
166
- onMouseEnter: range && !range.end ? () => setHover(iso) : void 0,
167
- onFocus: range && !range.end ? () => setHover(iso) : void 0,
168
- children: Number(iso.slice(8))
451
+ /* @__PURE__ */ jsx2("span", { id: titleId, className: s.live(), "aria-live": "polite", children: fullTitle }),
452
+ view === "days" ? /* @__PURE__ */ jsx2("div", { className: s.months(), children: shown.map(renderMonth) }) : /* @__PURE__ */ jsx2(
453
+ MonthPicker,
454
+ {
455
+ locale,
456
+ bare: true,
457
+ year: Number(month.slice(0, 4)),
458
+ onYearChange: (y) => setMonth(`${y}-${month.slice(5, 7)}-01`),
459
+ value: month.slice(0, 7),
460
+ min: min?.slice(0, 7),
461
+ max: max?.slice(0, 7),
462
+ autoFocus: true,
463
+ onValueChange: (m) => {
464
+ if (!m) return;
465
+ const target = `${m}-01`;
466
+ setMonth(target);
467
+ setView("days");
468
+ moved.current = true;
469
+ setFocused(clampIso(addMonths(active, monthsBetween(monthOf(active), target)), min, max));
470
+ }
471
+ }
472
+ )
473
+ ] });
474
+ }
475
+
476
+ // src/date-picker/date-field.tsx
477
+ import * as React4 from "react";
478
+
479
+ // src/date-picker/wheel.tsx
480
+ import * as React3 from "react";
481
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
482
+ var wheel = tv({
483
+ slots: {
484
+ root: "relative inline-flex select-none items-stretch gap-1 rounded-2xl border border-border-default data-[invalid]:border-danger bg-surface-1 bg-sheen px-2 shadow-raised inset-shadow-edge",
485
+ band: "pointer-events-none absolute inset-x-1.5 top-1/2 -translate-y-1/2 rounded-xl border border-border-subtle bg-surface-3 inset-shadow-well",
486
+ column: "relative z-[1] min-w-14 flex-1 rounded-xl outline-hidden focus-visible:focus-ring-inset data-[disabled]:pointer-events-none data-[disabled]:opacity-40",
487
+ scroller: "kz-wheel h-full snap-y snap-mandatory overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [mask-image:linear-gradient(to_bottom,transparent,#000_30%,#000_70%,transparent)]",
488
+ item: "kz-wheel-item flex snap-center items-center justify-center px-2 text-base tabular-nums text-fg-secondary transition-colors data-[selected]:font-semibold data-[selected]:text-fg data-[disabled]:text-fg-muted data-[disabled]:line-through",
489
+ divider: "z-[1] self-center text-base font-semibold text-fg-secondary"
490
+ }
491
+ });
492
+ var ITEM = 40;
493
+ var VisibleContext = React3.createContext(5);
494
+ function WheelPicker({ label, children, visible = 5, "aria-describedby": describedBy, invalid, className }) {
495
+ const s = wheel();
496
+ return /* @__PURE__ */ jsx3(VisibleContext.Provider, { value: visible, children: /* @__PURE__ */ jsxs3("div", { role: "group", "aria-label": label, "aria-describedby": describedBy, "data-invalid": invalid ? "" : void 0, className: s.root({ className }), style: { height: ITEM * visible }, children: [
497
+ /* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: s.band(), style: { height: ITEM } }),
498
+ children
499
+ ] }) });
500
+ }
501
+ function WheelDivider({ children }) {
502
+ return /* @__PURE__ */ jsx3("span", { "aria-hidden": true, className: wheel().divider(), children });
503
+ }
504
+ var nearestEnabled = (options, index) => {
505
+ for (let d = 0; d < options.length; d++) {
506
+ if (options[index + d] && !options[index + d].disabled) return index + d;
507
+ if (options[index - d] && !options[index - d].disabled) return index - d;
508
+ }
509
+ return index;
510
+ };
511
+ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange, disabled, className }) {
512
+ const s = wheel();
513
+ const visible = React3.useContext(VisibleContext);
514
+ const [own, setOwn] = React3.useState(defaultValue ?? options[0]?.value ?? "");
515
+ const value = valueProp ?? own;
516
+ const index = Math.max(0, options.findIndex((o) => o.value === value));
517
+ const scroller = React3.useRef(null);
518
+ const settle = React3.useRef(null);
519
+ const programmatic = React3.useRef(false);
520
+ const reduce = usePrefersReducedMotion();
521
+ const mounted = React3.useRef(false);
522
+ const commit = React3.useCallback(
523
+ (i) => {
524
+ const target = nearestEnabled(options, Math.min(options.length - 1, Math.max(0, i)));
525
+ const option = options[target];
526
+ if (!option) return;
527
+ if (valueProp === void 0) setOwn(option.value);
528
+ if (option.value !== value) onValueChange?.(option.value);
529
+ },
530
+ [options, valueProp, value, onValueChange]
531
+ );
532
+ React3.useEffect(() => {
533
+ const el = scroller.current;
534
+ if (!el) return;
535
+ const top = index * ITEM;
536
+ if (Math.abs(el.scrollTop - top) < 1) return;
537
+ programmatic.current = true;
538
+ if (typeof el.scrollTo === "function") el.scrollTo({ top, behavior: mounted.current && !reduce ? "smooth" : "auto" });
539
+ else el.scrollTop = top;
540
+ mounted.current = true;
541
+ const t = setTimeout(() => programmatic.current = false, 400);
542
+ return () => clearTimeout(t);
543
+ }, [index, reduce]);
544
+ const onScroll = () => {
545
+ if (programmatic.current) return;
546
+ if (settle.current) clearTimeout(settle.current);
547
+ settle.current = setTimeout(() => {
548
+ const el = scroller.current;
549
+ if (el) commit(Math.round(el.scrollTop / ITEM));
550
+ }, 90);
551
+ };
552
+ React3.useEffect(() => () => void (settle.current && clearTimeout(settle.current)), []);
553
+ const onKeyDown = (event) => {
554
+ const step = (by) => {
555
+ let i = index + by;
556
+ while (options[i]?.disabled) i += Math.sign(by);
557
+ return options[i] ? i : index;
558
+ };
559
+ const moves = {
560
+ ArrowUp: () => step(-1),
561
+ ArrowDown: () => step(1),
562
+ PageUp: () => Math.max(0, nearestEnabled(options, index - 5)),
563
+ PageDown: () => Math.min(options.length - 1, nearestEnabled(options, index + 5)),
564
+ Home: () => nearestEnabled(options, 0),
565
+ End: () => nearestEnabled(options, options.length - 1)
566
+ };
567
+ const move = moves[event.key];
568
+ if (!move) return;
569
+ event.preventDefault();
570
+ commit(move());
571
+ };
572
+ const pad = (visible - 1) / 2 * ITEM;
573
+ const current = options[index];
574
+ return /* @__PURE__ */ jsx3(
575
+ "div",
576
+ {
577
+ role: "spinbutton",
578
+ tabIndex: disabled ? -1 : 0,
579
+ "aria-label": label,
580
+ "aria-valuenow": index,
581
+ "aria-valuemin": 0,
582
+ "aria-valuemax": Math.max(0, options.length - 1),
583
+ "aria-valuetext": current?.label,
584
+ "aria-disabled": disabled || void 0,
585
+ "data-disabled": disabled ? "" : void 0,
586
+ className: s.column({ className }),
587
+ onKeyDown,
588
+ children: /* @__PURE__ */ jsx3("div", { ref: scroller, "aria-hidden": true, className: s.scroller(), style: { paddingBlock: pad, scrollPaddingBlock: pad }, onScroll, children: options.map((o, i) => /* @__PURE__ */ jsx3(
589
+ "div",
590
+ {
591
+ "data-value": o.value,
592
+ "data-selected": i === index ? "" : void 0,
593
+ "data-disabled": o.disabled ? "" : void 0,
594
+ className: s.item(),
595
+ style: { height: ITEM },
596
+ onClick: () => !o.disabled && commit(i),
597
+ children: o.label
598
+ },
599
+ o.value
600
+ )) })
601
+ }
602
+ );
603
+ }
604
+
605
+ // src/date-picker/date-field.tsx
606
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
607
+ var dateField = tv({
608
+ slots: {
609
+ root: "flex flex-col gap-1.5 border-0 p-0",
610
+ legend: "mb-1.5 p-0 text-xs font-semibold text-fg-secondary",
611
+ row: "flex gap-2",
612
+ part: "flex flex-col gap-1 text-xs text-fg-secondary",
613
+ input: "h-11 rounded-lg border border-border-default bg-surface-2 px-2 text-center text-base tabular-nums text-fg inset-shadow-well transition-[border-color,box-shadow] placeholder:text-fg-muted focus-visible:border-accent focus-visible:outline-hidden focus-visible:focus-ring-inset aria-invalid:border-danger disabled:cursor-not-allowed disabled:opacity-50",
614
+ hint: "text-xs text-fg-secondary",
615
+ error: "flex items-center gap-1.5 text-xs font-medium text-fg-danger before:h-1.5 before:w-1.5 before:shrink-0 before:rounded-full before:bg-danger"
616
+ }
617
+ });
618
+ var dateFieldLabels = { day: "Day", month: "Month", year: "Year" };
619
+ function Caption({ id, hint, error }) {
620
+ const s = dateField();
621
+ if (error)
622
+ return /* @__PURE__ */ jsx4("p", { id: `${id}-error`, className: s.error(), children: error });
623
+ return hint ? /* @__PURE__ */ jsx4("p", { id: `${id}-hint`, className: s.hint(), children: hint }) : null;
624
+ }
625
+ function DateField({ label, locale, hint, error, disabled, name, labels: given, className, value: valueProp, defaultValue = "", onValueChange, onBlur, autoComplete }) {
626
+ const labels = { ...dateFieldLabels, ...given };
627
+ const s = dateField();
628
+ const id = React4.useId();
629
+ const [value, setValue] = useControllable(valueProp, defaultValue, onValueChange);
630
+ const order = React4.useMemo(() => datePartsOrder(locale), [locale]);
631
+ const [parts, setParts] = React4.useState(() => splitDate(value));
632
+ if ((value ?? "") !== composeDate(parts) && composeDate(splitDate(value)) === (value ?? "")) setParts(splitDate(value));
633
+ const refs = { day: React4.useRef(null), month: React4.useRef(null), year: React4.useRef(null) };
634
+ const describedBy = error ? `${id}-error` : hint ? `${id}-hint` : void 0;
635
+ return /* @__PURE__ */ jsxs4("fieldset", { className: s.root({ className }), "aria-describedby": describedBy, onBlur: (e) => !e.currentTarget.contains(e.relatedTarget) && onBlur?.(), children: [
636
+ /* @__PURE__ */ jsx4("legend", { className: s.legend(), children: label }),
637
+ /* @__PURE__ */ jsx4("div", { className: s.row(), children: order.map((part) => /* @__PURE__ */ jsxs4("label", { className: s.part(), children: [
638
+ labels[part],
639
+ /* @__PURE__ */ jsx4(
640
+ "input",
641
+ {
642
+ ref: refs[part],
643
+ inputMode: "numeric",
644
+ autoComplete: autoComplete === "bday" ? `bday-${part}` : "off",
645
+ maxLength: DATE_PART_LENGTH[part],
646
+ value: parts[part],
647
+ disabled,
648
+ "aria-invalid": error ? true : void 0,
649
+ className: s.input({ className: part === "year" ? "w-20" : "w-14" }),
650
+ onChange: (e) => {
651
+ const digits = e.target.value.replace(/\D/g, "").slice(0, DATE_PART_LENGTH[part]);
652
+ const next = { ...parts, [part]: digits };
653
+ setParts(next);
654
+ setValue(composeDate(next));
655
+ const following = order[order.indexOf(part) + 1];
656
+ if (digits.length === DATE_PART_LENGTH[part] && following) refs[following].current?.focus();
169
657
  }
170
- ) }, iso);
171
- }) }, week[0])) })
172
- ] })
658
+ }
659
+ )
660
+ ] }, part)) }),
661
+ name ? /* @__PURE__ */ jsx4("input", { type: "hidden", name, value: value ?? "" }) : null,
662
+ /* @__PURE__ */ jsx4(Caption, { id, hint, error })
663
+ ] });
664
+ }
665
+ function DateWheel({ label, locale, hint, error, disabled, name, labels: given, className, value: valueProp, defaultValue = null, onValueChange, min, max, defaultView }) {
666
+ const labels = { ...dateFieldLabels, ...given };
667
+ const id = React4.useId();
668
+ const [value, setValue] = useControllable(valueProp, defaultValue, (v) => v && onValueChange?.(v));
669
+ const today = todayIso();
670
+ const hi = max ?? today;
671
+ const lo = min ?? isoOf(Number(today.slice(0, 4)) - 120, 1, 1);
672
+ const shown = value || defaultView || hi;
673
+ const { year, month, day } = isoParts(shown);
674
+ const order = React4.useMemo(() => datePartsOrder(locale), [locale]);
675
+ const months = React4.useMemo(() => monthNames(locale, "long"), [locale]);
676
+ const number = React4.useMemo(() => new Intl.NumberFormat(locale, { useGrouping: false }), [locale]);
677
+ const inBounds = (iso) => iso >= lo && iso <= hi;
678
+ const set = (y, m, d) => {
679
+ let next = isoOf(y, m, d);
680
+ if (next > hi) next = hi;
681
+ if (next < lo) next = lo;
682
+ setValue(next);
683
+ };
684
+ const lastDay = daysInMonth(year, month);
685
+ const columns = {
686
+ day: /* @__PURE__ */ jsx4(
687
+ Wheel,
688
+ {
689
+ label: labels.day,
690
+ disabled,
691
+ options: Array.from({ length: lastDay }, (_, i) => ({ value: String(i + 1), label: number.format(i + 1), disabled: !inBounds(isoOf(year, month, i + 1)) })),
692
+ value: String(Math.min(day, lastDay)),
693
+ onValueChange: (v) => set(year, month, Number(v)),
694
+ className: "min-w-14"
695
+ },
696
+ "day"
697
+ ),
698
+ month: /* @__PURE__ */ jsx4(
699
+ Wheel,
700
+ {
701
+ label: labels.month,
702
+ disabled,
703
+ options: months.map((n, i) => ({ value: String(i + 1), label: n, disabled: isoOf(year, i + 1, daysInMonth(year, i + 1)) < lo || isoOf(year, i + 1, 1) > hi })),
704
+ value: String(month),
705
+ onValueChange: (v) => set(year, Number(v), day),
706
+ className: "min-w-32 capitalize"
707
+ },
708
+ "month"
709
+ ),
710
+ year: /* @__PURE__ */ jsx4(
711
+ Wheel,
712
+ {
713
+ label: labels.year,
714
+ disabled,
715
+ options: yearRange(Number(hi.slice(0, 4)), Number(lo.slice(0, 4))).map((y) => ({ value: String(y), label: number.format(y) })),
716
+ value: String(year),
717
+ onValueChange: (v) => set(Number(v), month, day),
718
+ className: "min-w-20"
719
+ },
720
+ "year"
721
+ )
722
+ };
723
+ return /* @__PURE__ */ jsxs4("div", { className: dateField().root({ className }), children: [
724
+ /* @__PURE__ */ jsx4("span", { "aria-hidden": true, className: dateField().legend(), children: label }),
725
+ /* @__PURE__ */ jsx4(WheelPicker, { label, "aria-describedby": error ? `${id}-error` : hint ? `${id}-hint` : void 0, invalid: Boolean(error), children: order.map((part) => columns[part]) }),
726
+ name ? /* @__PURE__ */ jsx4("input", { type: "hidden", name, value: value ?? "" }) : null,
727
+ /* @__PURE__ */ jsx4(Caption, { id, hint, error })
173
728
  ] });
174
729
  }
175
730
 
176
731
  // src/date-picker/date-picker.tsx
177
732
  import { formatDate as formatDate2, getDateTimeFormat as getDateTimeFormat2 } from "@krizaka/intl";
178
- import * as React2 from "react";
179
- import { tv as tv2 } from "tailwind-variants";
733
+ import * as React5 from "react";
180
734
 
181
735
  // src/popover/popover.tsx
182
736
  import { Popover as PopoverPrimitive } from "radix-ui";
183
- import { jsx as jsx2 } from "react/jsx-runtime";
737
+ import { jsx as jsx5 } from "react/jsx-runtime";
184
738
  function PopoverContent({ sideOffset = 8, collisionPadding = 8, container, className, ...props }) {
185
- return /* @__PURE__ */ jsx2(PopoverPrimitive.Portal, { container, children: /* @__PURE__ */ jsx2(
739
+ return /* @__PURE__ */ jsx5(PopoverPrimitive.Portal, { container, children: /* @__PURE__ */ jsx5(
186
740
  PopoverPrimitive.Content,
187
741
  {
188
742
  sideOffset,
@@ -201,24 +755,26 @@ var Popover = {
201
755
  };
202
756
 
203
757
  // src/date-picker/date-picker.tsx
204
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
205
- var datePicker = tv2({
758
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
759
+ var datePicker = tv({
206
760
  slots: {
207
761
  root: "flex w-full flex-col gap-1.5",
208
762
  label: "text-xs font-semibold text-fg-secondary",
209
763
  row: "relative flex w-full",
210
- trigger: "flex h-11 w-full items-center gap-2.5 rounded-lg border border-border-default bg-surface-2 px-3 text-left text-sm text-fg transition-[border-color,box-shadow] focus-visible:border-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[placeholder]:text-fg-muted aria-invalid:border-danger disabled:cursor-not-allowed disabled:opacity-50 data-[clearable]:pr-10",
211
- icon: "h-4 w-4 shrink-0 text-fg-secondary",
212
- clear: "absolute right-1.5 top-1/2 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-md text-fg-secondary hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
213
- content: "w-auto p-3",
214
- layout: "flex flex-col gap-3 sm:flex-row",
215
- presets: "flex flex-wrap gap-1.5 sm:w-36 sm:flex-col sm:flex-nowrap sm:border-r sm:border-border-default sm:pr-3",
216
- preset: "rounded-md px-2.5 py-1.5 text-left text-xs font-semibold text-fg-secondary hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-pressed:bg-accent-soft aria-pressed:text-fg",
764
+ // The field is a well (inset), the calendar opens on a raised, lit surface.
765
+ trigger: "group flex h-11 w-full items-center gap-2.5 rounded-lg border border-border-default bg-surface-2 px-3 text-left text-sm text-fg inset-shadow-well transition-[border-color,box-shadow] hover:border-border-strong focus-visible:border-accent focus-visible:outline-hidden focus-visible:focus-ring-inset data-[state=open]:border-accent data-[placeholder]:text-fg-muted aria-invalid:border-danger disabled:cursor-not-allowed disabled:opacity-50 data-[clearable]:pr-10",
766
+ icon: "h-4 w-4 shrink-0 text-fg-secondary transition-colors group-data-[state=open]:text-fg-accent",
767
+ clear: "absolute right-1.5 top-1/2 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-md text-fg-secondary hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:focus-ring",
768
+ content: "w-auto rounded-2xl bg-sheen p-4 shadow-floating inset-shadow-edge",
769
+ layout: "flex flex-col gap-4 sm:flex-row",
770
+ presets: "flex gap-1.5 overflow-x-auto pb-1 sm:w-40 sm:flex-col sm:overflow-visible sm:border-r sm:border-border-subtle sm:pb-0 sm:pr-4",
771
+ preset: "inline-flex shrink-0 items-center gap-2.5 whitespace-nowrap rounded-lg px-2.5 py-2 text-left text-xs font-semibold text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg focus-visible:outline-hidden focus-visible:focus-ring aria-pressed:bg-accent-soft aria-pressed:text-fg",
772
+ presetNode: "node shrink-0 group-aria-pressed:node-lit",
217
773
  hint: "text-xs text-fg-secondary",
218
774
  error: "flex items-center gap-1.5 text-xs font-medium text-fg-danger before:h-1.5 before:w-1.5 before:shrink-0 before:rounded-full before:bg-danger"
219
775
  }
220
776
  });
221
- var datePickerLabels = { previousMonth: "Previous month", nextMonth: "Next month", clear: "Clear date" };
777
+ var datePickerLabels = { ...calendarLabels, clear: "Clear date" };
222
778
  function Field({
223
779
  shared,
224
780
  text,
@@ -232,13 +788,13 @@ function Field({
232
788
  const { label, placeholder, clearable, hint, error, disabled, name, className } = shared;
233
789
  const labels = { ...datePickerLabels, ...shared.labels };
234
790
  const s = datePicker();
235
- const id = React2.useId();
791
+ const id = React5.useId();
236
792
  const describedBy = [hint ? `${id}-hint` : null, error ? `${id}-error` : null].filter(Boolean).join(" ") || void 0;
237
- return /* @__PURE__ */ jsxs2("div", { className: s.root({ className }), children: [
238
- /* @__PURE__ */ jsx3("label", { htmlFor: `${id}-trigger`, className: s.label(), children: label }),
239
- /* @__PURE__ */ jsxs2(Popover.Root, { open, onOpenChange: setOpen, children: [
240
- /* @__PURE__ */ jsxs2("div", { className: s.row(), children: [
241
- /* @__PURE__ */ jsx3(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs2(
793
+ return /* @__PURE__ */ jsxs5("div", { className: s.root({ className }), children: [
794
+ /* @__PURE__ */ jsx6("label", { htmlFor: `${id}-trigger`, className: s.label(), children: label }),
795
+ /* @__PURE__ */ jsxs5(Popover.Root, { open, onOpenChange: setOpen, children: [
796
+ /* @__PURE__ */ jsxs5("div", { className: s.row(), children: [
797
+ /* @__PURE__ */ jsx6(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
242
798
  "button",
243
799
  {
244
800
  id: `${id}-trigger`,
@@ -251,25 +807,25 @@ function Field({
251
807
  "data-clearable": clearable && hasValue ? "" : void 0,
252
808
  className: s.trigger(),
253
809
  children: [
254
- /* @__PURE__ */ jsx3(CalendarGlyph, { className: s.icon() }),
255
- /* @__PURE__ */ jsx3("span", { className: "truncate", children: text ?? placeholder ?? "" })
810
+ /* @__PURE__ */ jsx6(CalendarGlyph, { className: s.icon() }),
811
+ /* @__PURE__ */ jsx6("span", { className: "truncate", children: text ?? placeholder ?? "" })
256
812
  ]
257
813
  }
258
814
  ) }),
259
- clearable && hasValue && !disabled ? /* @__PURE__ */ jsx3("button", { type: "button", "aria-label": labels.clear, className: s.clear(), onClick: onClear, children: /* @__PURE__ */ jsx3(CloseGlyph, { className: "h-4 w-4" }) }) : null
815
+ clearable && hasValue && !disabled ? /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": labels.clear, className: s.clear(), onClick: onClear, children: /* @__PURE__ */ jsx6(CloseGlyph, { className: "h-4 w-4" }) }) : null
260
816
  ] }),
261
- /* @__PURE__ */ jsx3(Popover.Content, { align: "start", "aria-label": label, className: s.content(), children })
817
+ /* @__PURE__ */ jsx6(Popover.Content, { align: "start", "aria-label": label, className: s.content(), children })
262
818
  ] }),
263
- name ? /* @__PURE__ */ jsx3("input", { type: "hidden", name, value: hidden }) : null,
264
- hint ? /* @__PURE__ */ jsx3("p", { id: `${id}-hint`, className: s.hint(), children: hint }) : null,
265
- error ? /* @__PURE__ */ jsx3("p", { id: `${id}-error`, className: s.error(), children: error }) : null
819
+ name ? /* @__PURE__ */ jsx6("input", { type: "hidden", name, value: hidden }) : null,
820
+ hint ? /* @__PURE__ */ jsx6("p", { id: `${id}-hint`, className: s.hint(), children: hint }) : null,
821
+ error ? /* @__PURE__ */ jsx6("p", { id: `${id}-error`, className: s.error(), children: error }) : null
266
822
  ] });
267
823
  }
268
824
  function DatePicker({ value: valueProp, defaultValue = null, onValueChange, defaultOpen = false, ...shared }) {
269
825
  const [value, setValue] = useControllable(valueProp, defaultValue, onValueChange);
270
- const [open, setOpen] = React2.useState(defaultOpen);
826
+ const [open, setOpen] = React5.useState(defaultOpen);
271
827
  const { locale, format = "medium" } = shared;
272
- return /* @__PURE__ */ jsx3(
828
+ return /* @__PURE__ */ jsx6(
273
829
  Field,
274
830
  {
275
831
  shared,
@@ -279,7 +835,7 @@ function DatePicker({ value: valueProp, defaultValue = null, onValueChange, defa
279
835
  hidden: value ?? "",
280
836
  open,
281
837
  setOpen,
282
- children: /* @__PURE__ */ jsx3(
838
+ children: /* @__PURE__ */ jsx6(
283
839
  Calendar,
284
840
  {
285
841
  ...shared,
@@ -298,10 +854,10 @@ function formatRange(locale, start, end, style) {
298
854
  const formatter = getDateTimeFormat2(locale, { dateStyle: style });
299
855
  return formatter.formatRange ? formatter.formatRange(toLocalDate(start), toLocalDate(end)) : `${formatter.format(toLocalDate(start))} \u2013 ${formatter.format(toLocalDate(end))}`;
300
856
  }
301
- function DateRangePicker({ value: valueProp, defaultValue = null, onValueChange, presets, defaultOpen = false, ...shared }) {
857
+ function DateRangePicker({ value: valueProp, defaultValue = null, onValueChange, presets, numberOfMonths = 2, defaultOpen = false, ...shared }) {
302
858
  const [value, setValue] = useControllable(valueProp, defaultValue, onValueChange);
303
- const [draft, setDraft] = React2.useState(null);
304
- const [open, setOpenState] = React2.useState(defaultOpen);
859
+ const [draft, setDraft] = React5.useState(null);
860
+ const [open, setOpenState] = React5.useState(defaultOpen);
305
861
  const { locale, format = "medium" } = shared;
306
862
  const s = datePicker();
307
863
  const setOpen = (next) => {
@@ -317,7 +873,7 @@ function DateRangePicker({ value: valueProp, defaultValue = null, onValueChange,
317
873
  setOpen(false);
318
874
  }
319
875
  };
320
- return /* @__PURE__ */ jsx3(
876
+ return /* @__PURE__ */ jsx6(
321
877
  Field,
322
878
  {
323
879
  shared,
@@ -327,38 +883,278 @@ function DateRangePicker({ value: valueProp, defaultValue = null, onValueChange,
327
883
  hidden: value ? `${value.start}/${value.end}` : "",
328
884
  open,
329
885
  setOpen,
330
- children: /* @__PURE__ */ jsxs2("div", { className: s.layout(), children: [
331
- presets?.length ? /* @__PURE__ */ jsx3("div", { className: s.presets(), children: presets.map((preset) => /* @__PURE__ */ jsx3(
886
+ children: /* @__PURE__ */ jsxs5("div", { className: s.layout(), children: [
887
+ presets?.length ? /* @__PURE__ */ jsx6("div", { className: s.presets(), children: presets.map((preset) => /* @__PURE__ */ jsxs5(
332
888
  "button",
333
889
  {
334
890
  type: "button",
335
891
  "aria-pressed": value?.start === preset.start && value?.end === preset.end,
336
- className: s.preset(),
892
+ className: s.preset({ className: "group" }),
337
893
  onClick: () => {
338
894
  setValue({ start: preset.start, end: preset.end });
339
895
  setOpen(false);
340
896
  },
341
- children: preset.label
897
+ children: [
898
+ /* @__PURE__ */ jsx6("span", { "aria-hidden": true, className: s.presetNode() }),
899
+ preset.label
900
+ ]
342
901
  },
343
902
  preset.label
344
903
  )) }) : null,
345
- /* @__PURE__ */ jsx3(Calendar, { ...shared, autoFocus: true, range: shown, onSelect: pick })
904
+ /* @__PURE__ */ jsx6(Calendar, { ...shared, autoFocus: true, range: shown, onSelect: pick, numberOfMonths })
346
905
  ] })
347
906
  }
348
907
  );
349
908
  }
909
+
910
+ // src/date-picker/day-strip.tsx
911
+ import { formatDate as formatDate3, getDateTimeFormat as getDateTimeFormat3 } from "@krizaka/intl";
912
+ import * as React6 from "react";
913
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
914
+ var dayStrip = tv({
915
+ slots: {
916
+ root: "flex w-full min-w-0 flex-col gap-2",
917
+ header: "flex items-center justify-between gap-2",
918
+ title: "text-sm font-semibold capitalize text-fg",
919
+ navs: "flex gap-1.5",
920
+ nav: "inline-flex h-8 w-8 items-center justify-center rounded-lg border border-border-subtle bg-surface-2 bg-sheen text-fg-secondary inset-shadow-edge transition-colors hover:border-border-strong hover:text-fg focus-visible:outline-hidden focus-visible:focus-ring disabled:pointer-events-none disabled:opacity-35",
921
+ track: "-mx-1 flex snap-x snap-mandatory gap-2 overflow-x-auto scroll-smooth px-1 py-1.5 [scrollbar-width:none] motion-reduce:scroll-auto [&::-webkit-scrollbar]:hidden",
922
+ day: "relative flex h-[4.5rem] w-14 shrink-0 snap-start flex-col items-center justify-center gap-0.5 rounded-2xl border border-border-default bg-surface-2 bg-sheen text-fg inset-shadow-edge transition-[background-color,border-color,box-shadow,transform] duration-150 hover:border-border-strong active:scale-95 motion-reduce:transition-none motion-reduce:active:scale-100 focus-visible:outline-hidden focus-visible:focus-ring aria-checked:border-transparent aria-checked:bg-accent aria-checked:bg-fill-shade aria-checked:text-on-accent aria-checked:shadow-glow aria-checked:inset-shadow-edge-fill disabled:cursor-not-allowed disabled:border-dashed disabled:bg-transparent disabled:bg-none disabled:text-fg-muted disabled:shadow-none",
923
+ weekday: "text-[11px] font-semibold uppercase tracking-wider text-fg-secondary group-aria-checked:text-on-accent group-disabled:text-fg-muted",
924
+ number: "text-lg font-semibold tabular-nums leading-none",
925
+ // Today: the node of the marks above the number; a marked day: a dot under it.
926
+ node: "absolute top-1.5 h-1 w-1 rotate-45 rounded-[1px] bg-accent group-aria-checked:bg-on-accent",
927
+ mark: "h-1.5 w-1.5 rounded-full bg-fg-secondary group-aria-checked:bg-on-accent",
928
+ noMark: "h-1.5 w-1.5"
929
+ }
930
+ });
931
+ var dayStripLabels = { previous: "Earlier days", next: "Later days", marked: "has events" };
932
+ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValueChange, start, days = 14, isDateDisabled, isDateMarked, today: todayProp, showHeader = true, labels: given, className }) {
933
+ const labels = { ...dayStripLabels, ...given };
934
+ const s = dayStrip();
935
+ const today = todayProp ?? toIsoDate(/* @__PURE__ */ new Date());
936
+ const first = start ?? today;
937
+ const list = React6.useMemo(() => Array.from({ length: days }, (_, i) => addDays(first, i)), [first, days]);
938
+ const [value, setValue] = useControllable(valueProp, defaultValue, (v) => v && onValueChange?.(v));
939
+ const enabled = list.filter((d) => !isDateDisabled?.(d));
940
+ const tabStop = value && enabled.includes(value) ? value : enabled[0];
941
+ const track = React6.useRef(null);
942
+ const reduce = usePrefersReducedMotion();
943
+ const weekday = getDateTimeFormat3(locale, { weekday: "short" });
944
+ const monthTitle = getDateTimeFormat3(locale, { month: "long", year: "numeric" }).format(toLocalDate(value ?? first));
945
+ const reveal = (iso, focus) => {
946
+ const el = track.current?.querySelector(`[data-date="${iso}"]`);
947
+ if (!el) return;
948
+ if (focus) el.focus({ preventScroll: true });
949
+ el.scrollIntoView?.({ block: "nearest", inline: "nearest", behavior: reduce ? "auto" : "smooth" });
950
+ };
951
+ React6.useEffect(() => {
952
+ if (value) track.current?.querySelector(`[data-date="${value}"]`)?.scrollIntoView?.({ block: "nearest", inline: "center" });
953
+ }, []);
954
+ const onKeyDown = (event) => {
955
+ const i = enabled.indexOf(tabStop ?? "");
956
+ const moves = { ArrowRight: i + 1, ArrowDown: i + 1, ArrowLeft: i - 1, ArrowUp: i - 1, Home: 0, End: enabled.length - 1 };
957
+ const to = moves[event.key];
958
+ if (to === void 0) return;
959
+ event.preventDefault();
960
+ const next = enabled[Math.min(enabled.length - 1, Math.max(0, to))];
961
+ if (!next) return;
962
+ setValue(next);
963
+ reveal(next, true);
964
+ };
965
+ const page = (by) => {
966
+ const el = track.current;
967
+ if (!el) return;
968
+ el.scrollBy?.({ left: by * el.clientWidth * 0.8, behavior: reduce ? "auto" : "smooth" });
969
+ };
970
+ return /* @__PURE__ */ jsxs6("div", { className: s.root({ className }), children: [
971
+ showHeader ? /* @__PURE__ */ jsxs6("div", { className: s.header(), children: [
972
+ /* @__PURE__ */ jsx7("span", { className: s.title(), "aria-hidden": true, children: monthTitle }),
973
+ /* @__PURE__ */ jsxs6("span", { className: s.navs(), children: [
974
+ /* @__PURE__ */ jsx7("button", { type: "button", className: s.nav(), "aria-label": labels.previous, onClick: () => page(-1), children: /* @__PURE__ */ jsx7(ChevronGlyph, { direction: "left", className: "h-4 w-4" }) }),
975
+ /* @__PURE__ */ jsx7("button", { type: "button", className: s.nav(), "aria-label": labels.next, onClick: () => page(1), children: /* @__PURE__ */ jsx7(ChevronGlyph, { direction: "right", className: "h-4 w-4" }) })
976
+ ] })
977
+ ] }) : null,
978
+ /* @__PURE__ */ jsx7("div", { ref: track, role: "radiogroup", "aria-label": label, className: s.track(), onKeyDown, children: list.map((iso) => {
979
+ const marked = Boolean(isDateMarked?.(iso));
980
+ const name = formatDate3(toLocalDate(iso), { locale, style: "long" });
981
+ return /* @__PURE__ */ jsxs6(
982
+ "button",
983
+ {
984
+ type: "button",
985
+ role: "radio",
986
+ "data-date": iso,
987
+ "aria-checked": iso === value,
988
+ "aria-current": iso === today ? "date" : void 0,
989
+ "aria-label": marked ? `${name}, ${labels.marked}` : name,
990
+ tabIndex: iso === tabStop ? 0 : -1,
991
+ disabled: Boolean(isDateDisabled?.(iso)),
992
+ className: s.day({ className: "group" }),
993
+ onClick: () => setValue(iso),
994
+ children: [
995
+ iso === today ? /* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: s.node() }) : null,
996
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: s.weekday(), children: weekday.format(toLocalDate(iso)).replace(/\.$/, "") }),
997
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: s.number(), children: Number(iso.slice(8)) }),
998
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": true, className: marked ? s.mark() : s.noMark() })
999
+ ]
1000
+ },
1001
+ iso
1002
+ );
1003
+ }) })
1004
+ ] });
1005
+ }
1006
+
1007
+ // src/date-picker/time-picker.tsx
1008
+ import * as React7 from "react";
1009
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1010
+ var timePicker = tv({
1011
+ slots: {
1012
+ slots: "grid grid-cols-[repeat(auto-fill,minmax(5.5rem,1fr))] gap-2",
1013
+ slot: "h-11 rounded-xl border border-border-default bg-surface-2 bg-sheen px-3 text-sm font-semibold tabular-nums text-fg inset-shadow-edge transition-[background-color,border-color,box-shadow,transform] duration-150 hover:border-border-strong active:scale-[0.97] motion-reduce:transition-none motion-reduce:active:scale-100 focus-visible:outline-hidden focus-visible:focus-ring aria-checked:border-transparent aria-checked:bg-accent aria-checked:bg-fill-shade aria-checked:text-on-accent aria-checked:shadow-glow aria-checked:inset-shadow-edge-fill disabled:cursor-not-allowed disabled:border-dashed disabled:bg-transparent disabled:bg-none disabled:font-normal disabled:text-fg-muted disabled:line-through disabled:shadow-none",
1014
+ group: "flex flex-col gap-2",
1015
+ heading: "text-[11px] font-semibold uppercase tracking-wider text-fg-secondary"
1016
+ }
1017
+ });
1018
+ var timePickerLabels = { hours: "Hours", minutes: "Minutes", period: "AM/PM" };
1019
+ function TimePicker(props) {
1020
+ return props.variant === "slots" ? /* @__PURE__ */ jsx8(TimeSlots, { ...props }) : /* @__PURE__ */ jsx8(TimeWheels, { ...props });
1021
+ }
1022
+ function TimeWheels({ label, locale, value: valueProp, defaultValue = null, onValueChange, disabled, className, minuteStep = 5, hour12, labels: given }) {
1023
+ const labels = { ...timePickerLabels, ...given };
1024
+ const [value, setValue] = useControllable(valueProp, defaultValue, (v) => v && onValueChange?.(v));
1025
+ const twelve = hour12 ?? uses12Hours(locale);
1026
+ const total = timeToMinutes(value) ?? 9 * 60;
1027
+ const h24 = Math.floor(total / 60);
1028
+ const minute = total % 60;
1029
+ const pm = h24 >= 12;
1030
+ const two = (n) => String(n).padStart(2, "0");
1031
+ const number = React7.useMemo(() => new Intl.NumberFormat(locale, { minimumIntegerDigits: 2, useGrouping: false }), [locale]);
1032
+ const hours = twelve ? Array.from({ length: 12 }, (_, i) => ({ value: String(i === 0 ? 12 : i), label: String(i === 0 ? 12 : i) })).sort((a, b) => Number(a.value) % 12 - Number(b.value) % 12) : Array.from({ length: 24 }, (_, i) => ({ value: String(i), label: number.format(i) }));
1033
+ const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => ({ value: String(i * minuteStep), label: number.format(i * minuteStep) }));
1034
+ const shownMinute = String(Math.min(60 - minuteStep, Math.round(minute / minuteStep) * minuteStep));
1035
+ const [am, pmLabel] = dayPeriods(locale);
1036
+ const set = (h, m) => setValue(`${two(h)}:${two(m)}`);
1037
+ return /* @__PURE__ */ jsxs7(WheelPicker, { label: `${label}, ${value ? formatTime(locale, value) : ""}`.replace(/, $/, ""), className, children: [
1038
+ /* @__PURE__ */ jsx8(
1039
+ Wheel,
1040
+ {
1041
+ label: labels.hours,
1042
+ options: hours,
1043
+ disabled,
1044
+ value: twelve ? String(h24 % 12 === 0 ? 12 : h24 % 12) : String(h24),
1045
+ onValueChange: (v) => set(twelve ? Number(v) % 12 + (pm ? 12 : 0) : Number(v), minute)
1046
+ }
1047
+ ),
1048
+ /* @__PURE__ */ jsx8(WheelDivider, { children: ":" }),
1049
+ /* @__PURE__ */ jsx8(Wheel, { label: labels.minutes, options: minutes, disabled, value: shownMinute, onValueChange: (v) => set(h24, Number(v)) }),
1050
+ twelve ? /* @__PURE__ */ jsx8(
1051
+ Wheel,
1052
+ {
1053
+ label: labels.period,
1054
+ options: [
1055
+ { value: "am", label: am },
1056
+ { value: "pm", label: pmLabel }
1057
+ ],
1058
+ disabled,
1059
+ value: pm ? "pm" : "am",
1060
+ onValueChange: (v) => set(h24 % 12 + (v === "pm" ? 12 : 0), minute)
1061
+ }
1062
+ ) : null
1063
+ ] });
1064
+ }
1065
+ function TimeSlots({ label, locale, value: valueProp, defaultValue = null, onValueChange, disabled, className, slots, isTimeDisabled, groupLabels }) {
1066
+ const s = timePicker();
1067
+ const [value, setValue] = useControllable(valueProp, defaultValue, (v) => v && onValueChange?.(v));
1068
+ const enabled = slots.filter((t) => !disabled && !isTimeDisabled?.(t));
1069
+ const tabStop = value && enabled.includes(value) ? value : enabled[0];
1070
+ const root = React7.useRef(null);
1071
+ const onKeyDown = (event) => {
1072
+ const i = enabled.indexOf(tabStop ?? "");
1073
+ const moves = { ArrowRight: i + 1, ArrowDown: i + 1, ArrowLeft: i - 1, ArrowUp: i - 1, Home: 0, End: enabled.length - 1 };
1074
+ const to = moves[event.key];
1075
+ if (to === void 0) return;
1076
+ event.preventDefault();
1077
+ const next = enabled[(to + enabled.length) % enabled.length];
1078
+ if (!next) return;
1079
+ setValue(next);
1080
+ root.current?.querySelector(`[data-time="${next}"]`)?.focus();
1081
+ };
1082
+ const button = (t) => {
1083
+ const off = disabled || Boolean(isTimeDisabled?.(t));
1084
+ return /* @__PURE__ */ jsx8(
1085
+ "button",
1086
+ {
1087
+ type: "button",
1088
+ role: "radio",
1089
+ "data-time": t,
1090
+ "aria-checked": t === value,
1091
+ tabIndex: t === tabStop ? 0 : -1,
1092
+ disabled: off,
1093
+ className: s.slot(),
1094
+ onClick: () => setValue(t),
1095
+ children: formatTime(locale, t)
1096
+ },
1097
+ t
1098
+ );
1099
+ };
1100
+ const part = (t) => {
1101
+ const m = timeToMinutes(t) ?? 0;
1102
+ return m < 12 * 60 ? "morning" : m < 18 * 60 ? "afternoon" : "evening";
1103
+ };
1104
+ return /* @__PURE__ */ jsx8("div", { ref: root, role: "radiogroup", "aria-label": label, "aria-disabled": disabled || void 0, className, onKeyDown, children: groupLabels ? /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-4", children: ["morning", "afternoon", "evening"].map((p) => {
1105
+ const inPart = slots.filter((t) => part(t) === p);
1106
+ if (!inPart.length) return null;
1107
+ return /* @__PURE__ */ jsxs7("div", { role: "group", "aria-label": groupLabels[p], className: s.group(), children: [
1108
+ /* @__PURE__ */ jsx8("span", { "aria-hidden": true, className: s.heading(), children: groupLabels[p] }),
1109
+ /* @__PURE__ */ jsx8("div", { className: s.slots(), children: inPart.map(button) })
1110
+ ] }, p);
1111
+ }) }) : /* @__PURE__ */ jsx8("div", { className: s.slots(), children: slots.map(button) }) });
1112
+ }
350
1113
  export {
351
1114
  Calendar,
1115
+ DateField,
352
1116
  DatePicker,
353
1117
  DateRangePicker,
1118
+ DateWheel,
1119
+ DayStrip,
1120
+ MonthPicker,
1121
+ TimePicker,
1122
+ Wheel,
1123
+ WheelDivider,
1124
+ WheelPicker,
354
1125
  addDays,
355
1126
  addMonths,
1127
+ ageOn,
356
1128
  calendar,
357
1129
  calendarLabels,
1130
+ composeDate,
1131
+ dateField,
1132
+ dateFieldLabels,
1133
+ datePartsOrder,
358
1134
  datePicker,
359
1135
  datePickerLabels,
1136
+ dayPeriods,
1137
+ dayStrip,
1138
+ dayStripLabels,
1139
+ daysInMonth,
1140
+ formatTime,
1141
+ isRealDate,
1142
+ isoOf,
1143
+ latestBirthDate,
1144
+ minutesToTime,
1145
+ monthNames,
1146
+ monthPicker,
1147
+ monthPickerLabels,
1148
+ timePicker,
1149
+ timePickerLabels,
1150
+ timeSlots,
1151
+ timeToMinutes,
360
1152
  toIsoDate,
361
1153
  toLocalDate,
362
- weekStartOf
1154
+ todayIso,
1155
+ uses12Hours,
1156
+ weekStartOf,
1157
+ wheel,
1158
+ yearRange
363
1159
  };
364
1160
  //# sourceMappingURL=date-picker.js.map