@sincpro/web-ui 0.0.0-stage → 0.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 (376) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -2
  3. package/dist/components/activity/Activity.d.ts +69 -0
  4. package/dist/components/activity/Activity.js +279 -0
  5. package/dist/components/activity/Messages.d.ts +66 -0
  6. package/dist/components/activity/Messages.js +46 -0
  7. package/dist/components/activity/Timeline.d.ts +21 -0
  8. package/dist/components/activity/Timeline.js +30 -0
  9. package/dist/components/activity/index.d.ts +3 -0
  10. package/dist/components/activity/index.js +4 -0
  11. package/dist/components/assist/AssistMark.d.ts +64 -0
  12. package/dist/components/assist/AssistMark.js +108 -0
  13. package/dist/components/assist/AssistPending.d.ts +24 -0
  14. package/dist/components/assist/AssistPending.js +26 -0
  15. package/dist/components/assist/AssistSuggestion.d.ts +42 -0
  16. package/dist/components/assist/AssistSuggestion.js +55 -0
  17. package/dist/components/assist/ChangeReview.d.ts +56 -0
  18. package/dist/components/assist/ChangeReview.js +121 -0
  19. package/dist/components/assist/assist.d.ts +77 -0
  20. package/dist/components/assist/assist.js +87 -0
  21. package/dist/components/assist/index.d.ts +5 -0
  22. package/dist/components/assist/index.js +7 -0
  23. package/dist/components/form/Form.d.ts +52 -0
  24. package/dist/components/form/Form.js +49 -0
  25. package/dist/components/form/Sheet.d.ts +47 -0
  26. package/dist/components/form/Sheet.js +90 -0
  27. package/dist/components/form/index.d.ts +2 -0
  28. package/dist/components/form/index.js +4 -0
  29. package/dist/components/frame/Chart.d.ts +13 -0
  30. package/dist/components/frame/Chart.js +24 -0
  31. package/dist/components/frame/FrameView.d.ts +33 -0
  32. package/dist/components/frame/FrameView.js +125 -0
  33. package/dist/components/frame/index.d.ts +3 -0
  34. package/dist/components/frame/index.js +3 -0
  35. package/dist/components/frame/model.d.ts +43 -0
  36. package/dist/components/frame/model.js +101 -0
  37. package/dist/components/index.d.ts +10 -0
  38. package/dist/components/index.js +11 -0
  39. package/dist/components/lines/LineItems.d.ts +111 -0
  40. package/dist/components/lines/LineItems.js +317 -0
  41. package/dist/components/lines/index.d.ts +1 -0
  42. package/dist/components/lines/index.js +2 -0
  43. package/dist/components/lines/lines.d.ts +23 -0
  44. package/dist/components/lines/lines.js +26 -0
  45. package/dist/components/listing/ColumnsMenu.d.ts +20 -0
  46. package/dist/components/listing/ColumnsMenu.js +46 -0
  47. package/dist/components/listing/GroupingLevels.d.ts +35 -0
  48. package/dist/components/listing/GroupingLevels.js +45 -0
  49. package/dist/components/listing/Listing.d.ts +27 -0
  50. package/dist/components/listing/Listing.js +86 -0
  51. package/dist/components/listing/ListingBar.d.ts +112 -0
  52. package/dist/components/listing/ListingBar.js +144 -0
  53. package/dist/components/listing/Pagination.d.ts +36 -0
  54. package/dist/components/listing/Pagination.js +69 -0
  55. package/dist/components/listing/RecordCard.d.ts +33 -0
  56. package/dist/components/listing/RecordCard.js +22 -0
  57. package/dist/components/listing/RecordLink.d.ts +7 -0
  58. package/dist/components/listing/RecordLink.js +22 -0
  59. package/dist/components/listing/Row.d.ts +110 -0
  60. package/dist/components/listing/Row.js +123 -0
  61. package/dist/components/listing/SortMenu.d.ts +62 -0
  62. package/dist/components/listing/SortMenu.js +105 -0
  63. package/dist/components/listing/ViewSwitcher.d.ts +24 -0
  64. package/dist/components/listing/ViewSwitcher.js +16 -0
  65. package/dist/components/listing/columns.d.ts +47 -0
  66. package/dist/components/listing/columns.js +72 -0
  67. package/dist/components/listing/grouping.d.ts +35 -0
  68. package/dist/components/listing/grouping.js +47 -0
  69. package/dist/components/listing/index.d.ts +17 -0
  70. package/dist/components/listing/index.js +20 -0
  71. package/dist/components/listing/modelColumns.d.ts +50 -0
  72. package/dist/components/listing/modelColumns.js +103 -0
  73. package/dist/components/listing/pages.d.ts +78 -0
  74. package/dist/components/listing/pages.js +135 -0
  75. package/dist/components/listing/selection.d.ts +21 -0
  76. package/dist/components/listing/selection.js +43 -0
  77. package/dist/components/listing/set.d.ts +48 -0
  78. package/dist/components/listing/set.js +24 -0
  79. package/dist/components/listing/tree.d.ts +28 -0
  80. package/dist/components/listing/tree.js +23 -0
  81. package/dist/components/navigation/CommandPalette.d.ts +40 -0
  82. package/dist/components/navigation/CommandPalette.js +114 -0
  83. package/dist/components/navigation/NavigationTree.d.ts +31 -0
  84. package/dist/components/navigation/NavigationTree.js +79 -0
  85. package/dist/components/navigation/commands.d.ts +30 -0
  86. package/dist/components/navigation/commands.js +30 -0
  87. package/dist/components/navigation/index.d.ts +3 -0
  88. package/dist/components/navigation/index.js +4 -0
  89. package/dist/components/record/Breadcrumb.d.ts +42 -0
  90. package/dist/components/record/Breadcrumb.js +98 -0
  91. package/dist/components/record/DirtyActions.d.ts +26 -0
  92. package/dist/components/record/DirtyActions.js +22 -0
  93. package/dist/components/record/Pager.d.ts +18 -0
  94. package/dist/components/record/Pager.js +33 -0
  95. package/dist/components/record/RecordHeader.d.ts +75 -0
  96. package/dist/components/record/RecordHeader.js +104 -0
  97. package/dist/components/record/RecordNotices.d.ts +37 -0
  98. package/dist/components/record/RecordNotices.js +75 -0
  99. package/dist/components/record/RecordSkeleton.d.ts +3 -0
  100. package/dist/components/record/RecordSkeleton.js +21 -0
  101. package/dist/components/record/SmartButtons.d.ts +35 -0
  102. package/dist/components/record/SmartButtons.js +38 -0
  103. package/dist/components/record/StatusBar.d.ts +51 -0
  104. package/dist/components/record/StatusBar.js +168 -0
  105. package/dist/components/record/ThumbBar.d.ts +36 -0
  106. package/dist/components/record/ThumbBar.js +86 -0
  107. package/dist/components/record/index.d.ts +6 -0
  108. package/dist/components/record/index.js +8 -0
  109. package/dist/components/search/CriteriaBuilder.d.ts +58 -0
  110. package/dist/components/search/CriteriaBuilder.js +278 -0
  111. package/dist/components/search/CriteriaChips.d.ts +22 -0
  112. package/dist/components/search/CriteriaChips.js +64 -0
  113. package/dist/components/search/FilterBuilder.d.ts +142 -0
  114. package/dist/components/search/FilterBuilder.js +421 -0
  115. package/dist/components/search/JoinWord.d.ts +8 -0
  116. package/dist/components/search/JoinWord.js +47 -0
  117. package/dist/components/search/JsonEditor.d.ts +19 -0
  118. package/dist/components/search/JsonEditor.js +78 -0
  119. package/dist/components/search/SearchBar.d.ts +78 -0
  120. package/dist/components/search/SearchBar.js +387 -0
  121. package/dist/components/search/criteria.d.ts +116 -0
  122. package/dist/components/search/criteria.js +159 -0
  123. package/dist/components/search/datePeriods.d.ts +122 -0
  124. package/dist/components/search/datePeriods.js +134 -0
  125. package/dist/components/search/dateRanges.d.ts +54 -0
  126. package/dist/components/search/dateRanges.js +89 -0
  127. package/dist/components/search/index.d.ts +9 -0
  128. package/dist/components/search/index.js +20 -0
  129. package/dist/components/search/model.d.ts +54 -0
  130. package/dist/components/search/model.js +37 -0
  131. package/dist/components/search/query.d.ts +166 -0
  132. package/dist/components/search/query.js +436 -0
  133. package/dist/components/shell/AppFrame.d.ts +14 -0
  134. package/dist/components/shell/AppFrame.js +80 -0
  135. package/dist/components/shell/TopBar.d.ts +73 -0
  136. package/dist/components/shell/TopBar.js +54 -0
  137. package/dist/components/shell/headerSlot.d.ts +17 -0
  138. package/dist/components/shell/headerSlot.js +21 -0
  139. package/dist/components/shell/index.d.ts +2 -0
  140. package/dist/components/shell/index.js +3 -0
  141. package/dist/foundations/aria.d.ts +14 -0
  142. package/dist/foundations/aria.js +18 -0
  143. package/dist/foundations/calendar.d.ts +28 -0
  144. package/dist/foundations/calendar.js +183 -0
  145. package/dist/foundations/copy.d.ts +703 -0
  146. package/dist/foundations/copy.es.d.ts +2 -0
  147. package/dist/foundations/copy.es.js +430 -0
  148. package/dist/foundations/copy.js +520 -0
  149. package/dist/foundations/density.d.ts +16 -0
  150. package/dist/foundations/density.js +21 -0
  151. package/dist/foundations/grouping.d.ts +281 -0
  152. package/dist/foundations/grouping.js +0 -0
  153. package/dist/foundations/index.d.ts +14 -0
  154. package/dist/foundations/index.js +30 -0
  155. package/dist/foundations/layout.d.ts +9 -0
  156. package/dist/foundations/layout.js +9 -0
  157. package/dist/foundations/pivot.d.ts +222 -0
  158. package/dist/foundations/pivot.js +198 -0
  159. package/dist/foundations/pivotSheet.d.ts +61 -0
  160. package/dist/foundations/pivotSheet.js +0 -0
  161. package/dist/foundations/slots.d.ts +67 -0
  162. package/dist/foundations/slots.js +63 -0
  163. package/dist/foundations/sticky.d.ts +53 -0
  164. package/dist/foundations/sticky.js +150 -0
  165. package/dist/foundations/surface.d.ts +9 -0
  166. package/dist/foundations/surface.js +26 -0
  167. package/dist/foundations/theme.d.ts +42 -0
  168. package/dist/foundations/theme.js +88 -0
  169. package/dist/foundations/types.d.ts +23 -0
  170. package/dist/foundations/types.js +50 -0
  171. package/dist/foundations/variants.d.ts +19 -0
  172. package/dist/foundations/variants.js +48 -0
  173. package/dist/foundations/xlsx.d.ts +86 -0
  174. package/dist/foundations/xlsx.js +0 -0
  175. package/dist/index.d.ts +19 -0
  176. package/dist/index.js +19 -0
  177. package/dist/primitives/block/Block.d.ts +66 -0
  178. package/dist/primitives/block/Block.js +34 -0
  179. package/dist/primitives/block/Line.d.ts +18 -0
  180. package/dist/primitives/block/Line.js +45 -0
  181. package/dist/primitives/block/SectionGrid.d.ts +30 -0
  182. package/dist/primitives/block/SectionGrid.js +29 -0
  183. package/dist/primitives/block/Steps.d.ts +76 -0
  184. package/dist/primitives/block/Steps.js +43 -0
  185. package/dist/primitives/block/index.d.ts +4 -0
  186. package/dist/primitives/block/index.js +7 -0
  187. package/dist/primitives/button/Button.d.ts +137 -0
  188. package/dist/primitives/button/Button.js +234 -0
  189. package/dist/primitives/button/index.d.ts +1 -0
  190. package/dist/primitives/button/index.js +2 -0
  191. package/dist/primitives/cell/CellStack.d.ts +47 -0
  192. package/dist/primitives/cell/CellStack.js +33 -0
  193. package/dist/primitives/cell/index.d.ts +1 -0
  194. package/dist/primitives/cell/index.js +3 -0
  195. package/dist/primitives/choice/ComboBox.d.ts +19 -0
  196. package/dist/primitives/choice/ComboBox.js +52 -0
  197. package/dist/primitives/choice/RadioGroup.d.ts +18 -0
  198. package/dist/primitives/choice/RadioGroup.js +50 -0
  199. package/dist/primitives/choice/SearchField.d.ts +33 -0
  200. package/dist/primitives/choice/SearchField.js +46 -0
  201. package/dist/primitives/choice/SegmentedControl.d.ts +16 -0
  202. package/dist/primitives/choice/SegmentedControl.js +69 -0
  203. package/dist/primitives/choice/Slider.d.ts +16 -0
  204. package/dist/primitives/choice/Slider.js +46 -0
  205. package/dist/primitives/choice/Switch.d.ts +14 -0
  206. package/dist/primitives/choice/Switch.js +65 -0
  207. package/dist/primitives/choice/ThemeSwitcher.d.ts +10 -0
  208. package/dist/primitives/choice/ThemeSwitcher.js +25 -0
  209. package/dist/primitives/choice/index.d.ts +8 -0
  210. package/dist/primitives/choice/index.js +11 -0
  211. package/dist/primitives/choice/options.d.ts +28 -0
  212. package/dist/primitives/choice/options.js +6 -0
  213. package/dist/primitives/date/Calendar.d.ts +31 -0
  214. package/dist/primitives/date/Calendar.js +134 -0
  215. package/dist/primitives/date/DatePicker.d.ts +42 -0
  216. package/dist/primitives/date/DatePicker.js +103 -0
  217. package/dist/primitives/date/DateTime.d.ts +35 -0
  218. package/dist/primitives/date/DateTime.js +100 -0
  219. package/dist/primitives/date/index.d.ts +3 -0
  220. package/dist/primitives/date/index.js +6 -0
  221. package/dist/primitives/dialog/Dialog.d.ts +118 -0
  222. package/dist/primitives/dialog/Dialog.js +121 -0
  223. package/dist/primitives/dialog/Drill.d.ts +90 -0
  224. package/dist/primitives/dialog/Drill.js +172 -0
  225. package/dist/primitives/dialog/index.d.ts +2 -0
  226. package/dist/primitives/dialog/index.js +4 -0
  227. package/dist/primitives/disclosure/Disclosure.d.ts +36 -0
  228. package/dist/primitives/disclosure/Disclosure.js +52 -0
  229. package/dist/primitives/disclosure/index.d.ts +1 -0
  230. package/dist/primitives/disclosure/index.js +2 -0
  231. package/dist/primitives/field/Checks.d.ts +57 -0
  232. package/dist/primitives/field/Checks.js +72 -0
  233. package/dist/primitives/field/DropZone.d.ts +42 -0
  234. package/dist/primitives/field/DropZone.js +52 -0
  235. package/dist/primitives/field/Field.d.ts +178 -0
  236. package/dist/primitives/field/Field.js +251 -0
  237. package/dist/primitives/field/Suggest.d.ts +48 -0
  238. package/dist/primitives/field/Suggest.js +43 -0
  239. package/dist/primitives/field/aria.d.ts +61 -0
  240. package/dist/primitives/field/aria.js +70 -0
  241. package/dist/primitives/field/context.d.ts +30 -0
  242. package/dist/primitives/field/context.js +13 -0
  243. package/dist/primitives/field/copy.d.ts +16 -0
  244. package/dist/primitives/field/copy.js +69 -0
  245. package/dist/primitives/field/index.d.ts +9 -0
  246. package/dist/primitives/field/index.js +15 -0
  247. package/dist/primitives/field/layout.d.ts +24 -0
  248. package/dist/primitives/field/layout.js +10 -0
  249. package/dist/primitives/field/mode.d.ts +9 -0
  250. package/dist/primitives/field/mode.js +13 -0
  251. package/dist/primitives/field/note.d.ts +55 -0
  252. package/dist/primitives/field/note.js +117 -0
  253. package/dist/primitives/hint/Hint.d.ts +31 -0
  254. package/dist/primitives/hint/Hint.js +42 -0
  255. package/dist/primitives/hint/index.d.ts +1 -0
  256. package/dist/primitives/hint/index.js +1 -0
  257. package/dist/primitives/index.d.ts +20 -0
  258. package/dist/primitives/index.js +21 -0
  259. package/dist/primitives/menu/Menu.d.ts +128 -0
  260. package/dist/primitives/menu/Menu.js +89 -0
  261. package/dist/primitives/menu/index.d.ts +1 -0
  262. package/dist/primitives/menu/index.js +2 -0
  263. package/dist/primitives/notice/Callout.d.ts +49 -0
  264. package/dist/primitives/notice/Callout.js +28 -0
  265. package/dist/primitives/notice/Flag.d.ts +13 -0
  266. package/dist/primitives/notice/Flag.js +31 -0
  267. package/dist/primitives/notice/Notice.d.ts +45 -0
  268. package/dist/primitives/notice/Notice.js +61 -0
  269. package/dist/primitives/notice/Toast.d.ts +55 -0
  270. package/dist/primitives/notice/Toast.js +142 -0
  271. package/dist/primitives/notice/index.d.ts +4 -0
  272. package/dist/primitives/notice/index.js +6 -0
  273. package/dist/primitives/overlay/Popover.d.ts +6 -0
  274. package/dist/primitives/overlay/Popover.js +27 -0
  275. package/dist/primitives/overlay/PopoverTrigger.d.ts +55 -0
  276. package/dist/primitives/overlay/PopoverTrigger.js +38 -0
  277. package/dist/primitives/overlay/Preview.d.ts +19 -0
  278. package/dist/primitives/overlay/Preview.js +60 -0
  279. package/dist/primitives/overlay/Tooltip.d.ts +38 -0
  280. package/dist/primitives/overlay/Tooltip.js +74 -0
  281. package/dist/primitives/overlay/index.d.ts +4 -0
  282. package/dist/primitives/overlay/index.js +7 -0
  283. package/dist/primitives/picker/Picker.d.ts +89 -0
  284. package/dist/primitives/picker/Picker.js +204 -0
  285. package/dist/primitives/picker/index.d.ts +1 -0
  286. package/dist/primitives/picker/index.js +2 -0
  287. package/dist/primitives/surface/Peek.d.ts +60 -0
  288. package/dist/primitives/surface/Peek.js +71 -0
  289. package/dist/primitives/surface/index.d.ts +1 -0
  290. package/dist/primitives/surface/index.js +2 -0
  291. package/dist/primitives/table/CellCopy.d.ts +20 -0
  292. package/dist/primitives/table/CellCopy.js +23 -0
  293. package/dist/primitives/table/CellEditor.d.ts +14 -0
  294. package/dist/primitives/table/CellEditor.js +83 -0
  295. package/dist/primitives/table/DataTable.d.ts +189 -0
  296. package/dist/primitives/table/DataTable.js +330 -0
  297. package/dist/primitives/table/EditableTable.d.ts +191 -0
  298. package/dist/primitives/table/EditableTable.js +617 -0
  299. package/dist/primitives/table/PivotTable.d.ts +14 -0
  300. package/dist/primitives/table/PivotTable.js +0 -0
  301. package/dist/primitives/table/ReportTable.d.ts +38 -0
  302. package/dist/primitives/table/ReportTable.js +106 -0
  303. package/dist/primitives/table/RowActions.d.ts +16 -0
  304. package/dist/primitives/table/RowActions.js +28 -0
  305. package/dist/primitives/table/SheetTable.d.ts +73 -0
  306. package/dist/primitives/table/SheetTable.js +230 -0
  307. package/dist/primitives/table/Table.d.ts +106 -0
  308. package/dist/primitives/table/Table.js +116 -0
  309. package/dist/primitives/table/index.d.ts +7 -0
  310. package/dist/primitives/table/index.js +9 -0
  311. package/dist/primitives/tabs/Tabs.d.ts +91 -0
  312. package/dist/primitives/tabs/Tabs.js +56 -0
  313. package/dist/primitives/tabs/index.d.ts +1 -0
  314. package/dist/primitives/tabs/index.js +1 -0
  315. package/dist/primitives/tag/Tag.d.ts +36 -0
  316. package/dist/primitives/tag/Tag.js +68 -0
  317. package/dist/primitives/tag/Tags.d.ts +57 -0
  318. package/dist/primitives/tag/Tags.js +104 -0
  319. package/dist/primitives/tag/TagsField.d.ts +35 -0
  320. package/dist/primitives/tag/TagsField.js +186 -0
  321. package/dist/primitives/tag/choices.d.ts +38 -0
  322. package/dist/primitives/tag/choices.js +26 -0
  323. package/dist/primitives/tag/index.d.ts +4 -0
  324. package/dist/primitives/tag/index.js +8 -0
  325. package/dist/primitives/toolbar/Toolbar.d.ts +13 -0
  326. package/dist/primitives/toolbar/Toolbar.js +36 -0
  327. package/dist/primitives/toolbar/index.d.ts +1 -0
  328. package/dist/primitives/toolbar/index.js +2 -0
  329. package/dist/primitives/tree/Tree.d.ts +56 -0
  330. package/dist/primitives/tree/Tree.js +74 -0
  331. package/dist/primitives/tree/index.d.ts +1 -0
  332. package/dist/primitives/tree/index.js +3 -0
  333. package/dist/primitives/value/Copyable.d.ts +48 -0
  334. package/dist/primitives/value/Copyable.js +71 -0
  335. package/dist/primitives/value/Fecha.d.ts +12 -0
  336. package/dist/primitives/value/Fecha.js +89 -0
  337. package/dist/primitives/value/Meter.d.ts +29 -0
  338. package/dist/primitives/value/Meter.js +46 -0
  339. package/dist/primitives/value/Metric.d.ts +42 -0
  340. package/dist/primitives/value/Metric.js +38 -0
  341. package/dist/primitives/value/Person.d.ts +90 -0
  342. package/dist/primitives/value/Person.js +208 -0
  343. package/dist/primitives/value/ProgressBar.d.ts +31 -0
  344. package/dist/primitives/value/ProgressBar.js +53 -0
  345. package/dist/primitives/value/Relation.d.ts +74 -0
  346. package/dist/primitives/value/Relation.js +74 -0
  347. package/dist/primitives/value/Totals.d.ts +121 -0
  348. package/dist/primitives/value/Totals.js +54 -0
  349. package/dist/primitives/value/Value.d.ts +40 -0
  350. package/dist/primitives/value/Value.js +80 -0
  351. package/dist/primitives/value/index.d.ts +9 -0
  352. package/dist/primitives/value/index.js +10 -0
  353. package/dist/tokens.css +1062 -0
  354. package/dist/views/index.d.ts +2 -0
  355. package/dist/views/index.js +3 -0
  356. package/dist/views/list/List.d.ts +119 -0
  357. package/dist/views/list/List.js +101 -0
  358. package/dist/views/list/ListView.d.ts +6 -0
  359. package/dist/views/list/ListView.js +295 -0
  360. package/dist/views/list/columns.d.ts +18 -0
  361. package/dist/views/list/columns.js +27 -0
  362. package/dist/views/list/derive.d.ts +87 -0
  363. package/dist/views/list/derive.js +207 -0
  364. package/dist/views/list/index.d.ts +2 -0
  365. package/dist/views/list/index.js +4 -0
  366. package/dist/views/list/presentations.d.ts +39 -0
  367. package/dist/views/list/presentations.js +105 -0
  368. package/dist/views/list/types.d.ts +284 -0
  369. package/dist/views/list/types.js +1 -0
  370. package/dist/views/list/useNarrowList.d.ts +17 -0
  371. package/dist/views/list/useNarrowList.js +32 -0
  372. package/dist/views/record/Record.d.ts +145 -0
  373. package/dist/views/record/Record.js +211 -0
  374. package/dist/views/record/index.d.ts +1 -0
  375. package/dist/views/record/index.js +2 -0
  376. package/package.json +113 -4
@@ -0,0 +1,134 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { parseDate } from "@internationalized/date";
4
+ import { AriaLocale } from "../../foundations/aria.js";
5
+ import { focusRing, tv } from "../../foundations/variants.js";
6
+ import { listOptionStyles } from "../field/aria.js";
7
+ import { Popover } from "../overlay/Popover.js";
8
+ import { ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";
9
+ import { Button as AriaButton, Calendar as AriaCalendar, CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, CalendarHeading, CalendarMonthPicker, CalendarYearPicker, ListBox, ListBoxItem, RangeCalendar as AriaRangeCalendar, Select as AriaSelect, SelectValue, useLocale, } from "react-aria-components";
10
+ /**
11
+ * The month grid — on its own, or inside the popover of a date picker.
12
+ *
13
+ * Context: keyboard and screen reader behave like a native calendar because React Aria
14
+ * implements the grid pattern (arrows move a day, PageUp/PageDown a month, Home/End the
15
+ * week). The selected day is the system's `primary`, not the gold: the gold is for the ONE
16
+ * action of a screen, and a calendar is not an action.
17
+ *
18
+ * The month and the year of the heading are two small selects: a birth date in 1987 or a
19
+ * contract signed in 2019 is two picks away, not eighty presses of «previous month». They
20
+ * are ALWAYS there, not behind a prop, because they cost nothing to the look — the words of
21
+ * the heading become the buttons, same weight, same color, the arrows where they were — and
22
+ * a prop is the one every app forgets on the one form (the birth date) that needed it.
23
+ */
24
+ const navButton = tv({
25
+ extend: focusRing,
26
+ base: "inline-flex size-(--size-control-sm) items-center justify-center rounded-control text-muted transition-colors duration-(--duration-instant) hover:bg-ink/6 hover:text-ink pressed:bg-ink/10 disabled:text-line-strong",
27
+ });
28
+ const jumpTrigger = tv({
29
+ extend: focusRing,
30
+ base: "inline-flex h-(--size-control-sm) items-center gap-1 rounded-control px-1.5 text-body font-semibold text-ink transition-colors duration-(--duration-instant) hover:bg-ink/6 pressed:bg-ink/10",
31
+ });
32
+ /* A word of the heading that opens a list. `first-letter` needs a block box: Spanish month
33
+ names are lower case, and a heading that starts «octubre» reads like a typo. */
34
+ function Jump({ "aria-label": label, value, onChange, items }) {
35
+ return (_jsxs(AriaSelect, { "aria-label": label, value: value, onChange: onChange, children: [_jsxs(AriaButton, { className: jumpTrigger, children: [_jsx(SelectValue, { className: "inline-block first-letter:uppercase", children: ({ selectedText }) => selectedText }), _jsx(ChevronDown, { "aria-hidden": true, className: "size-(--size-icon-sm) text-muted", strokeWidth: 2.5 })] }), _jsx(Popover, { placement: "bottom", className: "min-w-(--trigger-width)", children: _jsx(ListBox, { items: items, className: "max-h-[inherit] overflow-auto p-1 outline-0", children: (item) => (_jsx(ListBoxItem, { id: item.id, textValue: item.formatted, className: listOptionStyles, children: _jsx("span", { className: "block tabular-nums first-letter:uppercase", children: item.formatted }) })) }) })] }));
36
+ }
37
+ /* A century around the shown year: wide enough for a birth date or an old contract in one
38
+ pick, and `min`/`max` clip it (a birth date with `max` = today lists back from today).
39
+ The list opens scrolled to the shown year and typing «1987» jumps to it. */
40
+ const YEARS_LISTED = 100;
41
+ /** `jump` turns the heading into the month and year selects. Off only for two months side
42
+ * by side: their heading names a span («octubre – noviembre de 2026») that one month
43
+ * select cannot stand for. */
44
+ function Header({ jump }) {
45
+ const { direction } = useLocale();
46
+ const [Prev, Next] = direction === "rtl" ? [ChevronRight, ChevronLeft] : [ChevronLeft, ChevronRight];
47
+ return (_jsxs("header", { className: "mb-2 flex items-center gap-1", children: [_jsx(AriaButton, { slot: "previous", className: navButton, children: _jsx(Prev, { "aria-hidden": true, className: "size-(--size-icon-md)", strokeWidth: 2 }) }), jump ? (_jsxs("div", { className: "flex flex-1 items-center justify-center", children: [_jsx(CalendarMonthPicker, { format: "long", children: (aria) => _jsx(Jump, { ...aria }) }), _jsx(CalendarYearPicker, { visibleYears: YEARS_LISTED, children: (aria) => _jsx(Jump, { ...aria }) })] })) : (_jsx(CalendarHeading, { className: "flex-1 text-center text-body font-semibold text-ink first-letter:uppercase" })), _jsx(AriaButton, { slot: "next", className: navButton, children: _jsx(Next, { "aria-hidden": true, className: "size-(--size-icon-md)", strokeWidth: 2 }) })] }));
48
+ }
49
+ function WeekDays() {
50
+ return (_jsx(CalendarGridHeader, { children: (day) => (_jsx(CalendarHeaderCell, { className: "pb-1 text-micro font-medium text-muted", children: day })) }));
51
+ }
52
+ const dayCell = tv({
53
+ extend: focusRing,
54
+ base: "flex size-(--size-control-md) cursor-default items-center justify-center rounded-control text-meta tabular-nums outside-month:text-line-strong forced-color-adjust-none",
55
+ variants: {
56
+ isSelected: {
57
+ false: "text-ink hover:bg-ink/6 pressed:bg-ink/10",
58
+ true: "bg-primary font-medium text-surface invalid:bg-danger forced-colors:bg-[Highlight] forced-colors:text-[HighlightText]",
59
+ },
60
+ isDisabled: {
61
+ true: "text-line-strong hover:bg-transparent forced-colors:text-[GrayText]",
62
+ },
63
+ isToday: {
64
+ true: "font-semibold underline decoration-2 underline-offset-4",
65
+ },
66
+ },
67
+ });
68
+ /* ISO in, ISO out — the same contract as `DatePicker`. Inside a picker none of these are
69
+ passed and the calendar reads the picker's state from React Aria's context; only the
70
+ props that ARE given are forwarded, so an `undefined` never shadows that context. */
71
+ function iso(value) {
72
+ if (value === undefined)
73
+ return undefined;
74
+ if (value === null || value === "")
75
+ return null;
76
+ try {
77
+ return parseDate(value);
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ function defined(props) {
84
+ return Object.fromEntries(Object.entries(props).filter(([, v]) => v !== undefined));
85
+ }
86
+ /** One month, to pick one day. */
87
+ export function Calendar({ value, onChange, min, max, isUnavailable, ...rest }) {
88
+ const props = defined({
89
+ value: iso(value),
90
+ onChange: onChange === undefined ? undefined : (next) => onChange(next.toString()),
91
+ minValue: iso(min) ?? undefined,
92
+ maxValue: iso(max) ?? undefined,
93
+ isDateUnavailable: isUnavailable === undefined
94
+ ? undefined
95
+ : (date) => isUnavailable(date.toString()),
96
+ });
97
+ return (_jsx(AriaLocale, { children: _jsxs(AriaCalendar, { ...rest, ...props, className: "w-fit", children: [_jsx(Header, { jump: true }), _jsxs(CalendarGrid, { className: "border-separate border-spacing-0.5", children: [_jsx(WeekDays, {}), _jsx(CalendarGridBody, { children: (date) => _jsx(CalendarCell, { date: date, className: dayCell }) })] })] }) }));
98
+ }
99
+ const rangeDay = tv({
100
+ extend: focusRing,
101
+ base: "flex size-full items-center justify-center rounded-control forced-color-adjust-none",
102
+ variants: {
103
+ position: {
104
+ none: "text-ink group-hover:bg-ink/6 group-pressed:bg-ink/10",
105
+ middle: "text-ink group-hover:bg-primary/18",
106
+ cap: "bg-primary font-medium text-surface group-invalid:bg-danger forced-colors:bg-[Highlight] forced-colors:text-[HighlightText]",
107
+ },
108
+ isDisabled: {
109
+ true: "text-line-strong forced-colors:text-[GrayText]",
110
+ },
111
+ },
112
+ });
113
+ /** One or two months, to pick a span: the first click opens it, the second closes it. */
114
+ export function RangeCalendar({ months = 1, value, onChange, min, max, ...rest }) {
115
+ const start = iso(value?.start);
116
+ const end = iso(value?.end);
117
+ const props = defined({
118
+ value: value === undefined ? undefined : start && end ? { start, end } : null,
119
+ onChange: onChange === undefined
120
+ ? undefined
121
+ : (next) => onChange({ start: next.start.toString(), end: next.end.toString() }),
122
+ minValue: iso(min) ?? undefined,
123
+ maxValue: iso(max) ?? undefined,
124
+ });
125
+ return (_jsx(AriaLocale, { children: _jsxs(AriaRangeCalendar, { ...rest, ...props, visibleDuration: { months }, className: "w-fit", children: [_jsx(Header, { jump: months === 1 }), _jsx("div", { className: "flex gap-4", children: Array.from({ length: months }, (_, i) => (_jsxs(CalendarGrid, { offset: { months: i }, className: "border-separate border-spacing-y-0.5", children: [_jsx(WeekDays, {}), _jsx(CalendarGridBody, { children: (date) => (_jsx(CalendarCell, { date: date, className: "group size-(--size-control-md) cursor-default text-meta tabular-nums outside-month:invisible selected:bg-primary/10 selection-start:rounded-s-control selection-end:rounded-e-control", children: ({ formattedDate, isSelected, isSelectionStart, isSelectionEnd, isFocusVisible, isDisabled, }) => (_jsx("span", { className: rangeDay({
126
+ position: isSelected && (isSelectionStart || isSelectionEnd)
127
+ ? "cap"
128
+ : isSelected
129
+ ? "middle"
130
+ : "none",
131
+ isDisabled,
132
+ isFocusVisible,
133
+ }), children: formattedDate })) })) })] }, i))) })] }) }));
134
+ }
@@ -0,0 +1,42 @@
1
+ import { type FormMode } from "../field/mode.js";
2
+ /** The typed segments inside the field box — shared with `TimeField` and `DateTimePicker`
3
+ * (internal: not in the family barrel). */
4
+ export declare function Segments({ slot }: {
5
+ slot?: "start" | "end";
6
+ }): import("react").JSX.Element;
7
+ type Shared = {
8
+ id?: string;
9
+ describedBy?: string;
10
+ invalid?: boolean;
11
+ disabled?: boolean;
12
+ /** The earliest and latest day that can be chosen, as ISO dates. */
13
+ min?: string;
14
+ max?: string;
15
+ /** The name of the control when it is NOT inside a `Field` — a cell of an editable table.
16
+ * Inside a field, the field's label names it. */
17
+ "aria-label"?: string;
18
+ /** Forces the mode. By default it inherits the form's: in read mode it draws the value. */
19
+ mode?: FormMode;
20
+ };
21
+ /** A date typed by segments, without a calendar: for a form where dates are known by heart
22
+ * (a birth date, a contract date). */
23
+ export declare function DateField({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled, min, max, mode, "aria-label": ariaLabel, }: Shared & {
24
+ value: string | null;
25
+ onChange?: (next: string | null) => void;
26
+ }): import("react").JSX.Element;
27
+ /** A date typed by segments, or picked on a calendar from the button. */
28
+ export declare function DatePicker({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled, min, max, mode, "aria-label": ariaLabel, }: Shared & {
29
+ value: string | null;
30
+ onChange?: (next: string | null) => void;
31
+ }): import("react").JSX.Element;
32
+ export type DateRangeValue = {
33
+ start: string;
34
+ end: string;
35
+ };
36
+ /** A span of days — a period of a report, the validity of a contract — typed or picked on
37
+ * two months at once. */
38
+ export declare function DateRangePicker({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled, min, max, mode, "aria-label": ariaLabel, }: Shared & {
39
+ value: DateRangeValue | null;
40
+ onChange?: (next: DateRangeValue | null) => void;
41
+ }): import("react").JSX.Element;
42
+ export {};
@@ -0,0 +1,103 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { DateFormatter, parseDate } from "@internationalized/date";
4
+ import { AriaLocale } from "../../foundations/aria.js";
5
+ import { useUiCopy } from "../../foundations/copy.js";
6
+ import { tv } from "../../foundations/variants.js";
7
+ import { Calendar, RangeCalendar } from "./Calendar.js";
8
+ import { FieldButton, FieldGroup } from "../field/aria.js";
9
+ import { useFieldIds } from "../field/context.js";
10
+ import { ReadValue } from "../field/Field.js";
11
+ import { useFormMode } from "../field/mode.js";
12
+ import { Popover } from "../overlay/Popover.js";
13
+ import { CalendarDays } from "lucide-react";
14
+ import { DateField as AriaDateField, DateInput, DatePicker as AriaDatePicker, DateRangePicker as AriaDateRangePicker, DateSegment, Dialog, } from "react-aria-components";
15
+ /**
16
+ * Dates as an ERP stores them — ISO strings, `"2026-10-30"` — typed segment by segment or
17
+ * picked on a calendar.
18
+ *
19
+ * Context: the value is a string and not React Aria's `CalendarDate` because that is what
20
+ * every backend sends and every other control of the system takes. The conversion happens
21
+ * here, once, instead of at each of the hundred places an app reads a date.
22
+ *
23
+ * The field is SEGMENTED, not a free text box: the person types the day, the month and the
24
+ * year in the order of their locale (day/month/year in `es-BO`), the arrows step each one,
25
+ * and an impossible date cannot be written. That order comes from the copy table, never
26
+ * from the browser — see `AriaLocale`.
27
+ */
28
+ const segment = tv({
29
+ base: "rounded-mark px-0.5 tabular-nums caret-transparent outline-0 type-literal:px-0 forced-color-adjust-none",
30
+ variants: {
31
+ isPlaceholder: { true: "text-muted" },
32
+ isDisabled: { true: "text-muted forced-colors:text-[GrayText]" },
33
+ isFocused: {
34
+ true: "bg-primary text-surface forced-colors:bg-[Highlight] forced-colors:text-[HighlightText]",
35
+ },
36
+ },
37
+ });
38
+ /** The typed segments inside the field box — shared with `TimeField` and `DateTimePicker`
39
+ * (internal: not in the family barrel). */
40
+ export function Segments({ slot }) {
41
+ return (_jsx(DateInput, { slot: slot, className: "flex min-w-0 items-center px-2.5 whitespace-nowrap", children: (part) => _jsx(DateSegment, { segment: part, className: segment }) }));
42
+ }
43
+ function parse(iso) {
44
+ if (iso === null || iso === undefined || iso === "")
45
+ return null;
46
+ try {
47
+ return parseDate(iso);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ function useReadDate() {
54
+ const copy = useUiCopy();
55
+ /* `toDate("UTC")` is midnight in UTC, so the formatter has to read it in UTC too: in the
56
+ zone of the machine, anywhere west of Greenwich, the 30th was drawn as the 29th. */
57
+ const format = new DateFormatter(copy.locale, { dateStyle: "medium", timeZone: "UTC" });
58
+ return (iso) => {
59
+ const date = parse(iso);
60
+ return date === null ? "" : format.format(date.toDate("UTC"));
61
+ };
62
+ }
63
+ /** A date typed by segments, without a calendar: for a form where dates are known by heart
64
+ * (a birth date, a contract date). */
65
+ export function DateField({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled = false, min, max, mode, "aria-label": ariaLabel, }) {
66
+ const { id, labelledBy, describedBy, invalid } = useFieldIds({
67
+ id: ownId,
68
+ describedBy: ownDescribedBy,
69
+ invalid: ownInvalid,
70
+ });
71
+ const read = useReadDate();
72
+ if (useFormMode(mode) === "read")
73
+ return _jsx(ReadValue, { value: read(value) });
74
+ return (_jsx(AriaLocale, { children: _jsx(AriaDateField, { id: id, "aria-labelledby": labelledBy, "aria-label": ariaLabel, "aria-describedby": describedBy, value: parse(value), onChange: (next) => onChange?.(next === null ? null : next.toString()), minValue: parse(min) ?? undefined, maxValue: parse(max) ?? undefined, isInvalid: invalid, isDisabled: disabled, className: "w-full", children: _jsx(FieldGroup, { children: _jsx(Segments, {}) }) }) }));
75
+ }
76
+ /** A date typed by segments, or picked on a calendar from the button. */
77
+ export function DatePicker({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled = false, min, max, mode, "aria-label": ariaLabel, }) {
78
+ const { id, labelledBy, describedBy, invalid } = useFieldIds({
79
+ id: ownId,
80
+ describedBy: ownDescribedBy,
81
+ invalid: ownInvalid,
82
+ });
83
+ const read = useReadDate();
84
+ if (useFormMode(mode) === "read")
85
+ return _jsx(ReadValue, { value: read(value) });
86
+ return (_jsx(AriaLocale, { children: _jsxs(AriaDatePicker, { id: id, "aria-labelledby": labelledBy, "aria-label": ariaLabel, "aria-describedby": describedBy, value: parse(value), onChange: (next) => onChange?.(next === null ? null : next.toString()), minValue: parse(min) ?? undefined, maxValue: parse(max) ?? undefined, isInvalid: invalid, isDisabled: disabled, className: "w-full", children: [_jsxs(FieldGroup, { children: [_jsx(Segments, {}), _jsx(FieldButton, { className: "mr-1 ml-auto", children: _jsx(CalendarDays, { "aria-hidden": true, className: "size-(--size-icon-md)", strokeWidth: 2 }) })] }), _jsx(Popover, { placement: "bottom end", children: _jsx(Dialog, { className: "p-3 outline-0", children: _jsx(Calendar, {}) }) })] }) }));
87
+ }
88
+ /** A span of days — a period of a report, the validity of a contract — typed or picked on
89
+ * two months at once. */
90
+ export function DateRangePicker({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled = false, min, max, mode, "aria-label": ariaLabel, }) {
91
+ const { id, labelledBy, describedBy, invalid } = useFieldIds({
92
+ id: ownId,
93
+ describedBy: ownDescribedBy,
94
+ invalid: ownInvalid,
95
+ });
96
+ const read = useReadDate();
97
+ if (useFormMode(mode) === "read") {
98
+ return (_jsx(ReadValue, { value: value === null ? "" : `${read(value.start)} – ${read(value.end)}` }));
99
+ }
100
+ const start = parse(value?.start);
101
+ const end = parse(value?.end);
102
+ return (_jsx(AriaLocale, { children: _jsxs(AriaDateRangePicker, { id: id, "aria-labelledby": labelledBy, "aria-label": ariaLabel, "aria-describedby": describedBy, value: start === null || end === null ? null : { start, end }, onChange: (next) => onChange?.(next === null ? null : { start: next.start.toString(), end: next.end.toString() }), minValue: parse(min) ?? undefined, maxValue: parse(max) ?? undefined, isInvalid: invalid, isDisabled: disabled, className: "w-full", children: [_jsxs(FieldGroup, { children: [_jsx(Segments, { slot: "start" }), _jsx("span", { "aria-hidden": true, className: "text-muted", children: "\u2013" }), _jsx(Segments, { slot: "end" }), _jsx(FieldButton, { className: "mr-1 ml-auto", children: _jsx(CalendarDays, { "aria-hidden": true, className: "size-(--size-icon-md)", strokeWidth: 2 }) })] }), _jsx(Popover, { placement: "bottom end", children: _jsx(Dialog, { className: "p-3 outline-0", children: _jsx(RangeCalendar, { months: 2 }) }) })] }) }));
103
+ }
@@ -0,0 +1,35 @@
1
+ import { type FormMode } from "../field/mode.js";
2
+ type HourCycle = 12 | 24;
3
+ type Shared = {
4
+ id?: string;
5
+ describedBy?: string;
6
+ invalid?: boolean;
7
+ disabled?: boolean;
8
+ /** 12h or 24h. By default, the one of the copy's locale. Only the display: the value is
9
+ * always 24h. */
10
+ hourCycle?: HourCycle;
11
+ /** The name of the control when it is NOT inside a `Field` — a cell of an editable table.
12
+ * Inside a field, the field's label names it. */
13
+ "aria-label"?: string;
14
+ /** Forces the mode. By default it inherits the form's: in read mode it draws the value. */
15
+ mode?: FormMode;
16
+ };
17
+ /** A time of day typed by segments — the hour of an appointment, the opening of a shift.
18
+ * The value is `"HH:MM"` in 24h, or `null`. */
19
+ export declare function TimeField({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled, min, max, hourCycle, mode, "aria-label": ariaLabel, }: Shared & {
20
+ value: string | null;
21
+ onChange?: (next: string | null) => void;
22
+ /** The earliest and latest time that can be typed, as `"HH:MM"`. */
23
+ min?: string;
24
+ max?: string;
25
+ }): import("react").JSX.Element;
26
+ /** A day and its time — a delivery slot, an appointment: the day typed or picked on the
27
+ * calendar, the time typed after it. The value is a local `"YYYY-MM-DDTHH:MM"`, or `null`. */
28
+ export declare function DateTimePicker({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled, min, max, hourCycle, mode, "aria-label": ariaLabel, }: Shared & {
29
+ value: string | null;
30
+ onChange?: (next: string | null) => void;
31
+ /** The earliest and latest moment, as `"YYYY-MM-DDTHH:MM"` or a bare day `"YYYY-MM-DD"`. */
32
+ min?: string;
33
+ max?: string;
34
+ }): import("react").JSX.Element;
35
+ export {};
@@ -0,0 +1,100 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { DateFormatter, parseDateTime, parseTime, toCalendarDate, } from "@internationalized/date";
4
+ import { AriaLocale } from "../../foundations/aria.js";
5
+ import { useUiCopy } from "../../foundations/copy.js";
6
+ import { Calendar } from "./Calendar.js";
7
+ import { Segments } from "./DatePicker.js";
8
+ import { FieldButton, FieldGroup } from "../field/aria.js";
9
+ import { useFieldIds } from "../field/context.js";
10
+ import { ReadValue } from "../field/Field.js";
11
+ import { useFormMode } from "../field/mode.js";
12
+ import { Popover } from "../overlay/Popover.js";
13
+ import { CalendarDays } from "lucide-react";
14
+ import { DatePicker as AriaDatePicker, Dialog, TimeField as AriaTimeField, } from "react-aria-components";
15
+ /**
16
+ * A time of day, and a day with its time — an appointment, a delivery slot — as an ERP
17
+ * stores them: `"09:05"` and `"2026-10-30T09:05"`.
18
+ *
19
+ * Context: the same contract as `DatePicker` — a string in, a string out, converted here
20
+ * once. The time is 24h and without seconds because that is what a backend column of a
21
+ * time keeps; the time with a date is LOCAL and without a zone, because «the delivery is
22
+ * on the 30th at nine» is a wall-clock time where the warehouse is, not an instant: putting
23
+ * a zone on it is the backend's decision, not the field's.
24
+ *
25
+ * What the person SEES follows the locale of the copy: the hour cycle (12h with «p. m.» or
26
+ * 24h) is the one `Intl` gives that locale through `AriaLocale`. CLDR writes `es-BO` in 12h;
27
+ * a company that works in 24h passes `hourCycle={24}` — the value stays `"15:05"` either way.
28
+ */
29
+ const pad = (n) => String(n).padStart(2, "0");
30
+ const hhmm = (time) => `${pad(time.hour)}:${pad(time.minute)}`;
31
+ /* `"09:05"` or `"09:05:00"` — a column of type time often comes with its seconds. */
32
+ function parseClock(value) {
33
+ if (value === null || value === undefined || value === "")
34
+ return null;
35
+ try {
36
+ return parseTime(value);
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ /* `"2026-10-30T09:05"`; a bare `"2026-10-30"` is that day at midnight, so a `min` can be a day. */
43
+ function parseStamp(value) {
44
+ if (value === null || value === undefined || value === "")
45
+ return null;
46
+ try {
47
+ return parseDateTime(value);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ /* React Aria's `toString()` adds the seconds; the contract is to the minute. */
54
+ function stampOf(value) {
55
+ const time = "hour" in value ? hhmm(value) : "00:00";
56
+ return `${toCalendarDate(value).toString()}T${time}`;
57
+ }
58
+ /* Read mode draws what the segments would: the locale's format, its hour cycle unless the
59
+ control forces one. Everything is formatted in UTC from UTC parts, so the zone of the
60
+ machine never moves the clock. */
61
+ function useReadClock(options, hourCycle) {
62
+ const copy = useUiCopy();
63
+ return new DateFormatter(copy.locale, {
64
+ ...options,
65
+ timeZone: "UTC",
66
+ ...(hourCycle === undefined ? {} : { hourCycle: hourCycle === 24 ? "h23" : "h12" }),
67
+ });
68
+ }
69
+ /** A time of day typed by segments — the hour of an appointment, the opening of a shift.
70
+ * The value is `"HH:MM"` in 24h, or `null`. */
71
+ export function TimeField({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled = false, min, max, hourCycle, mode, "aria-label": ariaLabel, }) {
72
+ const { id, labelledBy, describedBy, invalid } = useFieldIds({
73
+ id: ownId,
74
+ describedBy: ownDescribedBy,
75
+ invalid: ownInvalid,
76
+ });
77
+ const format = useReadClock({ timeStyle: "short" }, hourCycle);
78
+ if (useFormMode(mode) === "read") {
79
+ const time = parseClock(value);
80
+ return (_jsx(ReadValue, { value: time === null
81
+ ? ""
82
+ : format.format(new Date(Date.UTC(1970, 0, 1, time.hour, time.minute))) }));
83
+ }
84
+ return (_jsx(AriaLocale, { children: _jsx(AriaTimeField, { id: id, "aria-labelledby": labelledBy, "aria-label": ariaLabel, "aria-describedby": describedBy, value: parseClock(value), onChange: (next) => onChange?.(next === null ? null : hhmm(next)), minValue: parseClock(min) ?? undefined, maxValue: parseClock(max) ?? undefined, hourCycle: hourCycle, isInvalid: invalid, isDisabled: disabled, className: "w-full", children: _jsx(FieldGroup, { children: _jsx(Segments, {}) }) }) }));
85
+ }
86
+ /** A day and its time — a delivery slot, an appointment: the day typed or picked on the
87
+ * calendar, the time typed after it. The value is a local `"YYYY-MM-DDTHH:MM"`, or `null`. */
88
+ export function DateTimePicker({ value, onChange, id: ownId, describedBy: ownDescribedBy, invalid: ownInvalid, disabled = false, min, max, hourCycle, mode, "aria-label": ariaLabel, }) {
89
+ const { id, labelledBy, describedBy, invalid } = useFieldIds({
90
+ id: ownId,
91
+ describedBy: ownDescribedBy,
92
+ invalid: ownInvalid,
93
+ });
94
+ const format = useReadClock({ dateStyle: "medium", timeStyle: "short" }, hourCycle);
95
+ if (useFormMode(mode) === "read") {
96
+ const stamp = parseStamp(value);
97
+ return _jsx(ReadValue, { value: stamp === null ? "" : format.format(stamp.toDate("UTC")) });
98
+ }
99
+ return (_jsx(AriaLocale, { children: _jsxs(AriaDatePicker, { id: id, "aria-labelledby": labelledBy, "aria-label": ariaLabel, "aria-describedby": describedBy, value: parseStamp(value), onChange: (next) => onChange?.(next === null ? null : stampOf(next)), minValue: parseStamp(min) ?? undefined, maxValue: parseStamp(max) ?? undefined, granularity: "minute", hourCycle: hourCycle, isInvalid: invalid, isDisabled: disabled, className: "w-full", children: [_jsxs(FieldGroup, { children: [_jsx(Segments, {}), _jsx(FieldButton, { className: "mr-1 ml-auto", children: _jsx(CalendarDays, { "aria-hidden": true, className: "size-(--size-icon-md)", strokeWidth: 2 }) })] }), _jsx(Popover, { placement: "bottom end", children: _jsx(Dialog, { className: "p-3 outline-0", children: _jsx(Calendar, {}) }) })] }) }));
100
+ }
@@ -0,0 +1,3 @@
1
+ export { Calendar, type CalendarProps, RangeCalendar, type RangeCalendarProps, } from "./Calendar.js";
2
+ export { DateField, DatePicker, DateRangePicker, type DateRangeValue, } from "./DatePicker.js";
3
+ export { DateTimePicker, TimeField } from "./DateTime.js";
@@ -0,0 +1,6 @@
1
+ /* LAS FECHAS Y LAS HORAS — escritas por segmentos o elegidas en un calendario, con el orden
2
+ del idioma de la copia. El valor es un ISO (`"2026-10-30"`, `"09:05"`,
3
+ `"2026-10-30T09:05"`), lo que manda cualquier backend. */
4
+ export { Calendar, RangeCalendar, } from "./Calendar.js";
5
+ export { DateField, DatePicker, DateRangePicker, } from "./DatePicker.js";
6
+ export { DateTimePicker, TimeField } from "./DateTime.js";
@@ -0,0 +1,118 @@
1
+ import { type ReactNode } from "react";
2
+ /** Where this dialog came from. It is drawn in the header, small. */
3
+ export interface DialogContext {
4
+ /** The category, in small caps: «factura», «cliente». It answers *what kind of
5
+ * thing is this about?* before saying which one. */
6
+ kind?: string;
7
+ /** Which one. The name of the resource. */
8
+ label: string;
9
+ /** What describes it without opening it: «saldo Bs. 12.450,00 · vence 15/11». */
10
+ detail?: string;
11
+ }
12
+ /** The scrim and the window recipes. Internal — exported only so a test can read the
13
+ * classes that make the bottom sheet: the modal is a portal and draws nothing on the
14
+ * server. */
15
+ export declare const dialogStyles: {
16
+ overlay: import("tailwind-variants/config").TVReturnType<{
17
+ isEntering: {
18
+ true: string;
19
+ };
20
+ isExiting: {
21
+ true: string;
22
+ };
23
+ }, undefined, "fixed inset-0 z-50 flex items-center justify-center bg-scrim/40 p-4 transition-opacity duration-(--duration-quick) ease-(--ease-out) max-sm:items-end max-sm:p-0 sm:p-8", undefined, undefined, undefined>;
24
+ modal: import("tailwind-variants/config").TVReturnType<{
25
+ width: {
26
+ sm: string;
27
+ md: string;
28
+ lg: string;
29
+ };
30
+ isEntering: {
31
+ true: string;
32
+ };
33
+ isExiting: {
34
+ true: string;
35
+ };
36
+ }, undefined, "flex max-h-full w-full flex-col overflow-hidden rounded-panel border border-line-strong bg-surface text-ink shadow-window outline-0 transition-[opacity,translate] duration-(--duration-panel) ease-(--ease-out) forced-colors:bg-[Canvas] max-sm:max-h-(--size-sheet) max-sm:max-w-none max-sm:rounded-b-none max-sm:border-x-0 max-sm:border-b-0", undefined, undefined, undefined>;
37
+ };
38
+ export type DialogWidth = "sm" | "md" | "lg";
39
+ export interface DialogProps {
40
+ open: boolean;
41
+ title: string;
42
+ /** One sentence under the title. It is also the dialog's description for assistive
43
+ * technology: what is read after the name, before the first field. */
44
+ subtitle?: string;
45
+ context?: DialogContext;
46
+ width?: DialogWidth;
47
+ /** Every way out goes through here: the × button, Escape and a press on the scrim. */
48
+ onClose: () => void;
49
+ /** Dock into the workspace. Absent when there is nowhere to dock. */
50
+ onExpand?: () => void;
51
+ /** Where it expands to, when «into a panel» says nothing: «open the catalog».
52
+ * It is the tooltip and the accessible name, and it is not drawn. */
53
+ expandLabel?: string;
54
+ footer?: ReactNode;
55
+ children: ReactNode;
56
+ }
57
+ /** The inside of the window: React Aria's `Dialog` with the header, body and footer.
58
+ *
59
+ * Internal — exported only so a test can read its markup, which the modal (a portal)
60
+ * does not produce on the server. */
61
+ export declare function DialogSurface({ title, subtitle, context, onClose, onExpand, expandLabel, footer, children, }: Omit<DialogProps, "open" | "width">): import("react").JSX.Element;
62
+ /**
63
+ * What has to be answered before moving on: a short form that blocks the page and keeps
64
+ * saying what it is about.
65
+ *
66
+ * Context: controlled by `open` + `onClose` — the screen that opens it owns the decision of
67
+ * when it is open, and every way out (×, Escape, the scrim) reports through `onClose`. It
68
+ * stays mounted for the exit transition after `open` turns `false`, so the window fades
69
+ * out instead of vanishing.
70
+ */
71
+ export declare function Dialog({ open, width, onClose, ...surface }: DialogProps): import("react").JSX.Element;
72
+ export interface WizardStep {
73
+ id: string;
74
+ label: string;
75
+ /** What is missing before you can move on. If it is present, «next» is turned
76
+ * off and this is drawn — a disabled button with no reason is a dead end. */
77
+ blocked?: string;
78
+ }
79
+ export interface WizardProps {
80
+ steps: readonly WizardStep[];
81
+ current: string;
82
+ /** A completed step was pressed: going back to review it. */
83
+ onStepChange?: (id: string) => void;
84
+ children: ReactNode;
85
+ onCancel?: () => void;
86
+ onBack?: () => void;
87
+ onNext?: () => void;
88
+ /** On the last step it stops being «next» and starts naming what is going to
89
+ * happen: «Crear orden». A button that says «next» on the last step hides that
90
+ * something gets executed there. */
91
+ nextLabel?: string;
92
+ busy?: boolean;
93
+ }
94
+ /** A dialog with steps, for what CANNOT be answered in one go.
95
+ *
96
+ * ── When a form deserves to be a wizard ─────────────────────────────
97
+ *
98
+ * Only when **one answer changes the following questions**. If the fields are
99
+ * independent, splitting them into steps simplifies nothing: it adds clicks and
100
+ * hides half the form, and whoever wants to review what they entered has to
101
+ * navigate backwards. A long but complete form is filled in faster than three
102
+ * short steps.
103
+ *
104
+ * The case that does justify it: a purchase order. Whether it is a local purchase
105
+ * or an import changes which conditions exist — an import asks for currency and
106
+ * incoterm, a local one for payment terms. There, step 2 cannot even be drawn
107
+ * until step 1 has been answered.
108
+ *
109
+ * ── The steps already completed can be clicked ──────────────────────
110
+ *
111
+ * Going back is not a mistake: it is reviewing. What you cannot do is jump
112
+ * ahead, because the next step does not know yet what to ask.
113
+ *
114
+ * ── It is the CONTENT of a `Dialog`, not a second one ────────────────
115
+ *
116
+ * The focus trap, Escape and the return of focus are the dialog's. The wizard
117
+ * only moves between steps, so it has no overlay behaviour of its own. */
118
+ export declare function Wizard({ steps, current, onStepChange, children, onCancel, onBack, onNext, nextLabel, busy, }: WizardProps): import("react").JSX.Element;