@galaxy-io/dls 1.6.0 → 2.0.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 (538) hide show
  1. package/README.md +47 -50
  2. package/biome/index.json +74 -0
  3. package/biome/plugins/no-hex-literal.grit +20 -0
  4. package/biome/plugins/no-inline-style.grit +13 -0
  5. package/biome/plugins/no-margin.grit +9 -0
  6. package/biome/plugins/warn/no-hex-literal.grit +23 -0
  7. package/biome/plugins/warn/no-inline-style.grit +13 -0
  8. package/biome/plugins/warn/no-margin.grit +9 -0
  9. package/dist/a11y/FocusScope.d.ts +44 -0
  10. package/dist/a11y/FocusScope.js +229 -0
  11. package/dist/a11y/VisuallyHidden.d.ts +21 -0
  12. package/dist/a11y/VisuallyHidden.js +30 -0
  13. package/dist/avatar/Avatar.d.ts +56 -14
  14. package/dist/avatar/Avatar.js +250 -96
  15. package/dist/avatar/AvatarGroup.d.ts +43 -0
  16. package/dist/avatar/AvatarGroup.js +153 -0
  17. package/dist/backgrounds/GridBackground.d.ts +48 -0
  18. package/dist/backgrounds/GridBackground.js +146 -0
  19. package/dist/beacons/Beacon.d.ts +86 -22
  20. package/dist/beacons/Beacon.js +170 -47
  21. package/dist/brand/GalaxyFilamentWordmark.d.ts +30 -0
  22. package/dist/brand/GalaxyFilamentWordmark.js +39 -0
  23. package/dist/brand/GalaxyLogomark.d.ts +26 -0
  24. package/dist/brand/GalaxyLogomark.js +41 -0
  25. package/dist/brand/GalaxyLogomarkAnimation.d.ts +36 -0
  26. package/dist/brand/GalaxyLogomarkAnimation.js +107 -0
  27. package/dist/brand/GalaxyWordmark.d.ts +30 -0
  28. package/dist/brand/GalaxyWordmark.js +63 -0
  29. package/dist/brand/assets/galaxy-logomark-animation.js +136678 -0
  30. package/dist/brand/brandMark.d.ts +26 -0
  31. package/dist/brand/brandMark.js +35 -0
  32. package/dist/buttons/Button.d.ts +148 -59
  33. package/dist/buttons/Button.js +437 -227
  34. package/dist/buttons/ButtonGroup.d.ts +38 -0
  35. package/dist/buttons/ButtonGroup.js +68 -0
  36. package/dist/buttons/CopyButton.d.ts +77 -0
  37. package/dist/buttons/CopyButton.js +65 -0
  38. package/dist/charts/AreaChart.d.ts +49 -0
  39. package/dist/charts/AreaChart.js +31 -0
  40. package/dist/charts/BarChart.d.ts +54 -67
  41. package/dist/charts/BarChart.js +136 -116
  42. package/dist/charts/ChartAxis.d.ts +35 -40
  43. package/dist/charts/ChartAxis.js +114 -90
  44. package/dist/charts/ChartCategoryTargets.d.ts +12 -26
  45. package/dist/charts/ChartCategoryTargets.js +32 -20
  46. package/dist/charts/ChartFrame.d.ts +69 -116
  47. package/dist/charts/ChartFrame.js +253 -119
  48. package/dist/charts/ChartGroupProvider.d.ts +30 -41
  49. package/dist/charts/ChartGroupProvider.js +20 -7
  50. package/dist/charts/ChartLegend.d.ts +27 -48
  51. package/dist/charts/ChartLegend.js +206 -125
  52. package/dist/charts/ChartMarkTargets.d.ts +12 -28
  53. package/dist/charts/ChartMarkTargets.js +33 -20
  54. package/dist/charts/ChartPrimitives.d.ts +50 -305
  55. package/dist/charts/ChartPrimitives.js +65 -413
  56. package/dist/charts/ChartTooltip.d.ts +20 -26
  57. package/dist/charts/ChartTooltip.js +77 -40
  58. package/dist/charts/Heatmap.d.ts +35 -0
  59. package/dist/charts/Heatmap.js +295 -0
  60. package/dist/charts/LineChart.d.ts +54 -47
  61. package/dist/charts/LineChart.js +159 -117
  62. package/dist/charts/PieChart.d.ts +32 -53
  63. package/dist/charts/PieChart.js +149 -135
  64. package/dist/charts/Sparkline.d.ts +107 -0
  65. package/dist/charts/Sparkline.js +244 -0
  66. package/dist/charts/StatChart.d.ts +37 -13
  67. package/dist/charts/StatChart.js +82 -35
  68. package/dist/charts/barChartGeometry.d.ts +138 -86
  69. package/dist/charts/barChartGeometry.js +122 -101
  70. package/dist/charts/barChartLegend.d.ts +14 -18
  71. package/dist/charts/barChartLegend.js +18 -13
  72. package/dist/charts/chartFormat.d.ts +12 -18
  73. package/dist/charts/chartFormat.js +20 -52
  74. package/dist/charts/chartPalette.d.ts +33 -0
  75. package/dist/charts/chartPalette.js +68 -0
  76. package/dist/charts/chartScales.d.ts +41 -108
  77. package/dist/charts/chartScales.js +62 -128
  78. package/dist/charts/constants.d.ts +96 -256
  79. package/dist/charts/constants.js +105 -275
  80. package/dist/charts/heatmapGeometry.d.ts +95 -0
  81. package/dist/charts/heatmapGeometry.js +155 -0
  82. package/dist/charts/lineChartGeometry.d.ts +108 -58
  83. package/dist/charts/lineChartGeometry.js +120 -78
  84. package/dist/charts/pieChartGeometry.d.ts +66 -40
  85. package/dist/charts/pieChartGeometry.js +68 -38
  86. package/dist/charts/types.d.ts +197 -466
  87. package/dist/charts/types.js +55 -144
  88. package/dist/charts/useCartesianChartLayout.d.ts +28 -59
  89. package/dist/charts/useCartesianChartLayout.js +47 -32
  90. package/dist/charts/useChartDimensions.d.ts +19 -40
  91. package/dist/charts/useChartDimensions.js +40 -56
  92. package/dist/charts/useChartFormatters.d.ts +6 -15
  93. package/dist/charts/useChartFormatters.js +4 -9
  94. package/dist/charts/useChartInteraction.d.ts +47 -116
  95. package/dist/charts/useChartInteraction.js +95 -71
  96. package/dist/charts/useChartTooltipPosition.d.ts +29 -39
  97. package/dist/charts/useChartTooltipPosition.js +14 -5
  98. package/dist/charts/useSeriesColorResolver.d.ts +11 -33
  99. package/dist/charts/useSeriesColorResolver.js +19 -12
  100. package/dist/chips/Chip.d.ts +155 -44
  101. package/dist/chips/Chip.js +329 -155
  102. package/dist/chips/ChipGroup.d.ts +53 -0
  103. package/dist/chips/ChipGroup.js +98 -0
  104. package/dist/drawer/Drawer.d.ts +81 -17
  105. package/dist/drawer/Drawer.js +370 -65
  106. package/dist/dropdown/Dropdown.d.ts +80 -63
  107. package/dist/dropdown/Dropdown.js +127 -129
  108. package/dist/editor/CodeEditor.d.ts +119 -40
  109. package/dist/editor/CodeEditor.js +490 -400
  110. package/dist/editor/CodeEditorReactWidget.d.ts +20 -17
  111. package/dist/editor/CodeEditorReactWidget.js +28 -21
  112. package/dist/feedback/Alert.d.ts +49 -0
  113. package/dist/feedback/Alert.js +172 -0
  114. package/dist/feedback/EmptyState.d.ts +39 -0
  115. package/dist/feedback/EmptyState.js +109 -0
  116. package/dist/feedback/ProgressBar.d.ts +125 -0
  117. package/dist/feedback/ProgressBar.js +183 -0
  118. package/dist/feedback/ProgressCircle.d.ts +99 -0
  119. package/dist/feedback/ProgressCircle.js +187 -0
  120. package/dist/feedback/Skeleton.d.ts +69 -0
  121. package/dist/feedback/Skeleton.js +130 -0
  122. package/dist/feedback/Spinner.d.ts +63 -0
  123. package/dist/feedback/Spinner.js +141 -0
  124. package/dist/fonts.css +70 -0
  125. package/dist/hooks/internal/useIsClient.d.ts +2 -0
  126. package/dist/hooks/internal/useIsClient.js +14 -0
  127. package/dist/hooks/useClipboard.d.ts +19 -0
  128. package/dist/hooks/useClipboard.js +45 -0
  129. package/dist/hooks/useControlledOpenState.d.ts +21 -0
  130. package/dist/hooks/useControlledOpenState.js +19 -0
  131. package/dist/hooks/useControlledState.d.ts +19 -0
  132. package/dist/hooks/useControlledState.js +22 -0
  133. package/dist/hooks/useDebouncedValue.d.ts +14 -0
  134. package/dist/hooks/useDebouncedValue.js +33 -0
  135. package/dist/hooks/useDisclosure.d.ts +26 -0
  136. package/dist/hooks/useDisclosure.js +36 -0
  137. package/dist/hooks/useDismiss.d.ts +23 -27
  138. package/dist/hooks/useDismiss.js +39 -27
  139. package/dist/hooks/useElementClientSize.d.ts +10 -10
  140. package/dist/hooks/useElementClientSize.js +8 -11
  141. package/dist/hooks/useElementWidth.d.ts +6 -13
  142. package/dist/hooks/useElementWidth.js +6 -14
  143. package/dist/hooks/useField.d.ts +47 -0
  144. package/dist/hooks/useField.js +40 -0
  145. package/dist/hooks/useHotkey.d.ts +77 -0
  146. package/dist/hooks/useHotkey.js +246 -0
  147. package/dist/hooks/useIsMac.d.ts +12 -0
  148. package/dist/hooks/useIsMac.js +27 -0
  149. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +17 -0
  150. package/dist/hooks/useIsomorphicLayoutEffect.js +20 -0
  151. package/dist/hooks/useLocalStorage.d.ts +28 -0
  152. package/dist/hooks/useLocalStorage.js +145 -0
  153. package/dist/hooks/useMediaQuery.d.ts +11 -0
  154. package/dist/hooks/useMediaQuery.js +23 -0
  155. package/dist/hooks/usePrefersReducedMotion.d.ts +12 -0
  156. package/dist/hooks/usePrefersReducedMotion.js +25 -0
  157. package/dist/hooks/useResize.d.ts +42 -62
  158. package/dist/hooks/useResize.js +43 -31
  159. package/dist/icons/Icon.d.ts +64 -37
  160. package/dist/icons/Icon.js +96 -37
  161. package/dist/icons/internal/IconSlot.d.ts +10 -0
  162. package/dist/icons/internal/IconSlot.js +32 -0
  163. package/dist/inputs/CheckboxGroup.d.ts +115 -0
  164. package/dist/inputs/CheckboxGroup.js +183 -0
  165. package/dist/inputs/CheckboxInput.d.ts +98 -28
  166. package/dist/inputs/CheckboxInput.js +218 -88
  167. package/dist/inputs/ColorInput.d.ts +115 -29
  168. package/dist/inputs/ColorInput.js +748 -326
  169. package/dist/inputs/CopyInput.d.ts +49 -20
  170. package/dist/inputs/CopyInput.js +57 -49
  171. package/dist/inputs/CronInput.d.ts +94 -0
  172. package/dist/inputs/CronInput.js +618 -0
  173. package/dist/inputs/DateInput.d.ts +175 -28
  174. package/dist/inputs/DateInput.js +1109 -451
  175. package/dist/inputs/DurationInput.d.ts +101 -0
  176. package/dist/inputs/DurationInput.js +441 -0
  177. package/dist/inputs/Field.d.ts +75 -0
  178. package/dist/inputs/Field.js +247 -0
  179. package/dist/inputs/Fieldset.d.ts +53 -0
  180. package/dist/inputs/Fieldset.js +149 -0
  181. package/dist/inputs/FileInput.d.ts +110 -0
  182. package/dist/inputs/FileInput.js +476 -0
  183. package/dist/inputs/Input.d.ts +148 -187
  184. package/dist/inputs/Input.js +339 -259
  185. package/dist/inputs/KeyValueInput.d.ts +120 -0
  186. package/dist/inputs/KeyValueInput.js +383 -0
  187. package/dist/inputs/MultiSelectInput.d.ts +165 -54
  188. package/dist/inputs/MultiSelectInput.js +175 -559
  189. package/dist/inputs/NumberInput.d.ts +65 -9
  190. package/dist/inputs/NumberInput.js +197 -40
  191. package/dist/inputs/PasswordInput.d.ts +17 -12
  192. package/dist/inputs/PasswordInput.js +33 -33
  193. package/dist/inputs/PinInput.d.ts +117 -0
  194. package/dist/inputs/PinInput.js +364 -0
  195. package/dist/inputs/RadioGroup.d.ts +115 -0
  196. package/dist/inputs/RadioGroup.js +179 -0
  197. package/dist/inputs/RadioInput.d.ts +87 -24
  198. package/dist/inputs/RadioInput.js +182 -95
  199. package/dist/inputs/SearchInput.d.ts +66 -0
  200. package/dist/inputs/SearchInput.js +156 -0
  201. package/dist/inputs/SelectInput.d.ts +195 -55
  202. package/dist/inputs/SelectInput.js +1308 -446
  203. package/dist/inputs/SliderInput.d.ts +150 -30
  204. package/dist/inputs/SliderInput.js +441 -186
  205. package/dist/inputs/SwitchInput.d.ts +109 -0
  206. package/dist/inputs/SwitchInput.js +248 -0
  207. package/dist/inputs/TagInput.d.ts +117 -0
  208. package/dist/inputs/TagInput.js +408 -0
  209. package/dist/inputs/TextAreaInput.d.ts +146 -44
  210. package/dist/inputs/TextAreaInput.js +292 -198
  211. package/dist/inputs/TextInput.d.ts +4 -13
  212. package/dist/inputs/TextInput.js +13 -48
  213. package/dist/inputs/ToggleInput.d.ts +120 -22
  214. package/dist/inputs/ToggleInput.js +262 -116
  215. package/dist/inputs/internal/bareField.d.ts +18 -0
  216. package/dist/inputs/internal/bareField.js +38 -0
  217. package/dist/inputs/internal/devWarn.d.ts +7 -0
  218. package/dist/inputs/internal/devWarn.js +30 -0
  219. package/dist/inputs/internal/fieldFrame.d.ts +34 -0
  220. package/dist/inputs/internal/fieldFrame.js +64 -0
  221. package/dist/inputs/internal/fieldWiring.d.ts +50 -0
  222. package/dist/inputs/internal/fieldWiring.js +38 -0
  223. package/dist/inputs/internal/innerButton.d.ts +2 -0
  224. package/dist/inputs/internal/innerButton.js +24 -0
  225. package/dist/inputs/internal/ownField.d.ts +45 -0
  226. package/dist/inputs/internal/ownField.js +58 -0
  227. package/dist/inputs/internal/predicates.d.ts +9 -0
  228. package/dist/inputs/internal/predicates.js +11 -0
  229. package/dist/inputs/internal/useComboboxPopover.d.ts +46 -0
  230. package/dist/inputs/internal/useComboboxPopover.js +92 -0
  231. package/dist/json/JsonViewer.d.ts +62 -0
  232. package/dist/json/JsonViewer.js +483 -0
  233. package/dist/layout/Box.d.ts +87 -0
  234. package/dist/layout/Box.js +109 -0
  235. package/dist/layout/Divider.d.ts +25 -0
  236. package/dist/layout/Divider.js +70 -0
  237. package/dist/layout/Flex.d.ts +139 -0
  238. package/dist/layout/Flex.js +165 -0
  239. package/dist/layout/FlexItem.d.ts +72 -0
  240. package/dist/layout/FlexItem.js +84 -0
  241. package/dist/layout/Grid.d.ts +140 -0
  242. package/dist/layout/Grid.js +178 -0
  243. package/dist/layout/Portal.d.ts +29 -0
  244. package/dist/layout/Portal.js +27 -0
  245. package/dist/layout/ResizablePanels.d.ts +88 -0
  246. package/dist/layout/ResizablePanels.js +198 -0
  247. package/dist/layout/ResizeHandle.d.ts +48 -0
  248. package/dist/layout/ResizeHandle.js +143 -0
  249. package/dist/layout/ScrollArea.d.ts +30 -0
  250. package/dist/layout/ScrollArea.js +138 -0
  251. package/dist/links/Link.d.ts +101 -1
  252. package/dist/links/Link.js +166 -4
  253. package/dist/lists/BulletedList.d.ts +25 -7
  254. package/dist/lists/BulletedList.js +72 -27
  255. package/dist/lists/DescriptionList.d.ts +91 -0
  256. package/dist/lists/DescriptionList.js +147 -0
  257. package/dist/menu/ContextMenu.d.ts +64 -0
  258. package/dist/menu/ContextMenu.js +34 -0
  259. package/dist/menu/Menu.d.ts +280 -0
  260. package/dist/menu/Menu.js +1003 -0
  261. package/dist/modal/ConfirmDialog.d.ts +55 -0
  262. package/dist/modal/ConfirmDialog.js +151 -0
  263. package/dist/modal/Modal.d.ts +64 -14
  264. package/dist/modal/Modal.js +189 -48
  265. package/dist/navigation/Breadcrumbs.d.ts +65 -0
  266. package/dist/navigation/Breadcrumbs.js +243 -0
  267. package/dist/navigation/CommandPalette.d.ts +83 -0
  268. package/dist/navigation/CommandPalette.js +509 -0
  269. package/dist/navigation/Pagination.d.ts +87 -0
  270. package/dist/navigation/Pagination.js +300 -0
  271. package/dist/navigation/SidebarNav.d.ts +107 -0
  272. package/dist/navigation/SidebarNav.js +341 -0
  273. package/dist/navigation/Stepper.d.ts +52 -0
  274. package/dist/navigation/Stepper.js +207 -0
  275. package/dist/navigation/Tabs.d.ts +113 -0
  276. package/dist/navigation/Tabs.js +543 -0
  277. package/dist/navigation/Topbar.d.ts +20 -0
  278. package/dist/navigation/Topbar.js +62 -0
  279. package/dist/overlay/OverlayProvider.d.ts +28 -32
  280. package/dist/overlay/OverlayProvider.js +42 -93
  281. package/dist/overlay/useOverlay.d.ts +88 -12
  282. package/dist/overlay/useOverlay.js +220 -43
  283. package/dist/overlays/Popover.d.ts +114 -0
  284. package/dist/overlays/Popover.js +389 -0
  285. package/dist/shapes/Circle.d.ts +84 -8
  286. package/dist/shapes/Circle.js +122 -20
  287. package/dist/shapes/Square.d.ts +84 -8
  288. package/dist/shapes/Square.js +123 -20
  289. package/dist/styles/mixins.d.ts +35 -0
  290. package/dist/styles/mixins.js +60 -0
  291. package/dist/styles.css +1 -202
  292. package/dist/table/InfiniteSpreadsheet.d.ts +140 -10
  293. package/dist/table/InfiniteSpreadsheet.js +762 -225
  294. package/dist/table/InfiniteTable.d.ts +116 -14
  295. package/dist/table/InfiniteTable.js +287 -429
  296. package/dist/table/SpreadsheetCellEditor.d.ts +54 -6
  297. package/dist/table/SpreadsheetCellEditor.js +163 -84
  298. package/dist/table/TableCore.d.ts +252 -0
  299. package/dist/table/TableCore.js +1077 -0
  300. package/dist/table/VirtualizedInfiniteTable.d.ts +104 -14
  301. package/dist/table/VirtualizedInfiniteTable.js +280 -219
  302. package/dist/table/types.d.ts +66 -244
  303. package/dist/table/types.js +0 -51
  304. package/dist/table/useInfiniteScrollSentinel.d.ts +25 -21
  305. package/dist/table/useInfiniteScrollSentinel.js +38 -30
  306. package/dist/table/useSpreadsheetCellNavigation.d.ts +44 -0
  307. package/dist/table/useSpreadsheetCellNavigation.js +141 -0
  308. package/dist/table/useTableColumnLayout.d.ts +90 -25
  309. package/dist/table/useTableColumnLayout.js +255 -50
  310. package/dist/table/useTableKeyboardNavigation.d.ts +32 -21
  311. package/dist/table/useTableKeyboardNavigation.js +95 -71
  312. package/dist/table/useTableRowSelection.d.ts +24 -25
  313. package/dist/table/useTableRowSelection.js +57 -84
  314. package/dist/table/useTableVirtualizer.d.ts +20 -0
  315. package/dist/table/useTableVirtualizer.js +48 -0
  316. package/dist/text/Bold.d.ts +5 -6
  317. package/dist/text/Bold.js +16 -15
  318. package/dist/text/Code.d.ts +5 -6
  319. package/dist/text/Code.js +16 -25
  320. package/dist/text/CodeBlock.d.ts +77 -0
  321. package/dist/text/CodeBlock.js +373 -0
  322. package/dist/text/EditableText.d.ts +55 -15
  323. package/dist/text/EditableText.js +153 -135
  324. package/dist/text/Ellipsis.d.ts +34 -8
  325. package/dist/text/Ellipsis.js +55 -23
  326. package/dist/text/Kbd.d.ts +72 -0
  327. package/dist/text/Kbd.js +284 -0
  328. package/dist/text/MarkdownText.d.ts +27 -10
  329. package/dist/text/MarkdownText.js +317 -300
  330. package/dist/text/RequiredMarker.d.ts +17 -5
  331. package/dist/text/RequiredMarker.js +34 -36
  332. package/dist/text/Selectable.d.ts +5 -6
  333. package/dist/text/Selectable.js +16 -13
  334. package/dist/text/Span.d.ts +82 -0
  335. package/dist/text/Span.js +115 -0
  336. package/dist/text/Text.d.ts +128 -41
  337. package/dist/text/Text.js +209 -76
  338. package/dist/theme/GalaxyProvider.d.ts +75 -0
  339. package/dist/theme/GalaxyProvider.js +223 -0
  340. package/dist/theme/ThemeSwitcher.d.ts +52 -0
  341. package/dist/theme/ThemeSwitcher.js +94 -0
  342. package/dist/theme/enums.d.ts +118 -0
  343. package/dist/theme/enums.js +144 -0
  344. package/dist/theme/tokens/dark.d.ts +2 -0
  345. package/dist/theme/tokens/dark.js +275 -0
  346. package/dist/theme/tokens/generate.d.ts +15 -0
  347. package/dist/theme/tokens/generate.js +47 -0
  348. package/dist/theme/tokens/light.d.ts +2 -0
  349. package/dist/theme/tokens/light.js +274 -0
  350. package/dist/theme/tokens/palette.d.ts +14 -0
  351. package/dist/theme/tokens/palette.js +153 -0
  352. package/dist/theme/tokens/scales.d.ts +26 -0
  353. package/dist/theme/tokens/scales.js +154 -0
  354. package/dist/theme/tokens/t.d.ts +3 -0
  355. package/dist/theme/tokens/t.js +25 -0
  356. package/dist/theme/tokens/types.d.ts +189 -0
  357. package/dist/theme/tokens/types.js +0 -0
  358. package/dist/theme/useGalaxyTheme.d.ts +46 -0
  359. package/dist/theme/useGalaxyTheme.js +36 -0
  360. package/dist/theme/useInverseScope.d.ts +18 -0
  361. package/dist/theme/useInverseScope.js +33 -0
  362. package/dist/three/GalaxyLogomark3D.d.ts +46 -0
  363. package/dist/three/GalaxyLogomark3D.js +134 -0
  364. package/dist/three/assets/galaxy-logomark.js +4 -0
  365. package/dist/three/galaxyLogomark3DScene.d.ts +27 -0
  366. package/dist/three/galaxyLogomark3DScene.js +165 -0
  367. package/dist/timeline/Timeline.d.ts +99 -0
  368. package/dist/timeline/Timeline.js +269 -0
  369. package/dist/toast/Toast.d.ts +43 -19
  370. package/dist/toast/Toast.js +130 -89
  371. package/dist/toast/ToastProvider.d.ts +23 -23
  372. package/dist/toast/ToastProvider.js +298 -101
  373. package/dist/toast/ToastViewport.d.ts +12 -0
  374. package/dist/toast/ToastViewport.js +210 -0
  375. package/dist/toast/useToast.d.ts +139 -5
  376. package/dist/toast/useToast.js +15 -13
  377. package/dist/tokens.css +654 -0
  378. package/dist/tooltip/Tooltip.d.ts +64 -44
  379. package/dist/tooltip/Tooltip.js +280 -73
  380. package/dist/tooltip/internal/LazyTooltip.d.ts +7 -0
  381. package/dist/tooltip/internal/LazyTooltip.js +53 -0
  382. package/dist/transform/Fade.d.ts +33 -11
  383. package/dist/transform/Fade.js +71 -19
  384. package/dist/transform/Flasher.d.ts +25 -0
  385. package/dist/transform/Flasher.js +39 -0
  386. package/dist/transform/Rotate.d.ts +24 -12
  387. package/dist/transform/Rotate.js +36 -22
  388. package/dist/transform/ScaleFade.d.ts +36 -11
  389. package/dist/transform/ScaleFade.js +86 -28
  390. package/dist/transform/internal/CollapseMotion.d.ts +10 -0
  391. package/dist/transform/internal/CollapseMotion.js +65 -0
  392. package/dist/tree/Tree.d.ts +85 -0
  393. package/dist/tree/Tree.js +387 -0
  394. package/dist/tree/treeRow.d.ts +39 -0
  395. package/dist/tree/treeRow.js +75 -0
  396. package/dist/utils/colors.d.ts +46 -13
  397. package/dist/utils/colors.js +92 -34
  398. package/dist/utils/css.d.ts +23 -0
  399. package/dist/utils/css.js +30 -0
  400. package/dist/utils/format.d.ts +58 -0
  401. package/dist/utils/format.js +220 -0
  402. package/dist/vite/index.d.ts +16 -0
  403. package/dist/vite/index.js +52 -0
  404. package/dist/widget/Widget.d.ts +164 -48
  405. package/dist/widget/Widget.js +335 -96
  406. package/dist/widget/WidgetGroup.d.ts +36 -0
  407. package/dist/widget/WidgetGroup.js +103 -0
  408. package/package.json +851 -157
  409. package/dist/accordion/Accordion.d.ts +0 -54
  410. package/dist/accordion/Accordion.js +0 -183
  411. package/dist/assets/components/GalaxyFilamentWordmarkDark.d.ts +0 -3
  412. package/dist/assets/components/GalaxyFilamentWordmarkDark.js +0 -14
  413. package/dist/assets/components/GalaxyFilamentWordmarkLight.d.ts +0 -3
  414. package/dist/assets/components/GalaxyFilamentWordmarkLight.js +0 -14
  415. package/dist/assets/components/GalaxyLogomarkDark.d.ts +0 -3
  416. package/dist/assets/components/GalaxyLogomarkDark.js +0 -11
  417. package/dist/assets/components/GalaxyLogomarkLight.d.ts +0 -3
  418. package/dist/assets/components/GalaxyLogomarkLight.js +0 -17
  419. package/dist/assets/components/GalaxyWordmarkDark.d.ts +0 -3
  420. package/dist/assets/components/GalaxyWordmarkDark.js +0 -15
  421. package/dist/assets/components/GalaxyWordmarkLight.d.ts +0 -3
  422. package/dist/assets/components/GalaxyWordmarkLight.js +0 -28
  423. package/dist/assets/models/galaxy-animation.js +0 -136666
  424. package/dist/assets/models/galaxy-logomark.js +0 -4
  425. package/dist/avatar/AvatarShimmer.d.ts +0 -30
  426. package/dist/avatar/AvatarShimmer.js +0 -22
  427. package/dist/backgrounds/CellGridBackground.d.ts +0 -24
  428. package/dist/backgrounds/CellGridBackground.js +0 -44
  429. package/dist/backgrounds/CrossGridBackground.d.ts +0 -26
  430. package/dist/backgrounds/CrossGridBackground.js +0 -49
  431. package/dist/backgrounds/DotGridBackground.d.ts +0 -24
  432. package/dist/backgrounds/DotGridBackground.js +0 -47
  433. package/dist/badge/Badge.d.ts +0 -42
  434. package/dist/badge/Badge.js +0 -99
  435. package/dist/charts/ChartEmptyState.d.ts +0 -17
  436. package/dist/charts/ChartEmptyState.js +0 -29
  437. package/dist/charts/ProgressBar.d.ts +0 -29
  438. package/dist/charts/ProgressBar.js +0 -65
  439. package/dist/charts/chartTheme.d.ts +0 -18
  440. package/dist/charts/chartTheme.js +0 -26
  441. package/dist/containers/FlexItem.d.ts +0 -50
  442. package/dist/containers/FlexItem.js +0 -91
  443. package/dist/containers/FlexWrapper.d.ts +0 -96
  444. package/dist/containers/FlexWrapper.js +0 -143
  445. package/dist/containers/GridWrapper.d.ts +0 -79
  446. package/dist/containers/GridWrapper.js +0 -125
  447. package/dist/containers/Spacing.d.ts +0 -23
  448. package/dist/containers/Spacing.js +0 -59
  449. package/dist/containers/Wrapper.d.ts +0 -26
  450. package/dist/containers/Wrapper.js +0 -54
  451. package/dist/dividers/HorizontalDivider.d.ts +0 -7
  452. package/dist/dividers/HorizontalDivider.js +0 -39
  453. package/dist/dividers/VerticalDivider.d.ts +0 -6
  454. package/dist/dividers/VerticalDivider.js +0 -21
  455. package/dist/icons/GalaxyFilamentWordmark.d.ts +0 -11
  456. package/dist/icons/GalaxyFilamentWordmark.js +0 -25
  457. package/dist/icons/GalaxyLogomark.d.ts +0 -13
  458. package/dist/icons/GalaxyLogomark.js +0 -27
  459. package/dist/icons/GalaxyLogomark3D.d.ts +0 -56
  460. package/dist/icons/GalaxyLogomark3D.js +0 -319
  461. package/dist/icons/GalaxyLogomarkAnimation.d.ts +0 -18
  462. package/dist/icons/GalaxyLogomarkAnimation.js +0 -48
  463. package/dist/icons/GalaxyWordmark.d.ts +0 -11
  464. package/dist/icons/GalaxyWordmark.js +0 -25
  465. package/dist/inputs/MultiTextInput.d.ts +0 -32
  466. package/dist/inputs/MultiTextInput.js +0 -180
  467. package/dist/inputs/SwitcherInput.d.ts +0 -27
  468. package/dist/inputs/SwitcherInput.js +0 -64
  469. package/dist/inputs/hooks.d.ts +0 -10
  470. package/dist/inputs/hooks.js +0 -22
  471. package/dist/overlay/constants.d.ts +0 -28
  472. package/dist/overlay/constants.js +0 -37
  473. package/dist/resizable/HorizontalResizeHandle.d.ts +0 -17
  474. package/dist/resizable/HorizontalResizeHandle.js +0 -38
  475. package/dist/resizable/VerticalResizeHandle.d.ts +0 -18
  476. package/dist/resizable/VerticalResizeHandle.js +0 -39
  477. package/dist/table/SpreadsheetCell.d.ts +0 -21
  478. package/dist/table/SpreadsheetCell.js +0 -71
  479. package/dist/table/SpreadsheetHeaderCell.d.ts +0 -23
  480. package/dist/table/SpreadsheetHeaderCell.js +0 -91
  481. package/dist/table/SpreadsheetMenuItem.d.ts +0 -14
  482. package/dist/table/SpreadsheetMenuItem.js +0 -33
  483. package/dist/table/SpreadsheetPrimitives.d.ts +0 -172
  484. package/dist/table/SpreadsheetPrimitives.js +0 -105
  485. package/dist/table/SpreadsheetRow.d.ts +0 -33
  486. package/dist/table/SpreadsheetRow.js +0 -73
  487. package/dist/table/SpreadsheetRowActionCell.d.ts +0 -14
  488. package/dist/table/SpreadsheetRowActionCell.js +0 -51
  489. package/dist/table/TableExpandCell.d.ts +0 -11
  490. package/dist/table/TableExpandCell.js +0 -24
  491. package/dist/table/TableExpandedRow.d.ts +0 -16
  492. package/dist/table/TableExpandedRow.js +0 -77
  493. package/dist/table/TableHeaderCellContent.d.ts +0 -30
  494. package/dist/table/TableHeaderCellContent.js +0 -48
  495. package/dist/table/TablePrimitives.d.ts +0 -313
  496. package/dist/table/TablePrimitives.js +0 -302
  497. package/dist/table/TableSelectCell.d.ts +0 -18
  498. package/dist/table/TableSelectCell.js +0 -27
  499. package/dist/table/TableStatusRow.d.ts +0 -18
  500. package/dist/table/TableStatusRow.js +0 -50
  501. package/dist/table/useSpreadsheetEditing.d.ts +0 -13
  502. package/dist/table/useSpreadsheetEditing.js +0 -41
  503. package/dist/table/useTableColumnResize.d.ts +0 -38
  504. package/dist/table/useTableColumnResize.js +0 -155
  505. package/dist/table/useTableRowExpansion.d.ts +0 -24
  506. package/dist/table/useTableRowExpansion.js +0 -62
  507. package/dist/table/utils.d.ts +0 -50
  508. package/dist/table/utils.js +0 -78
  509. package/dist/text/HotKeys.d.ts +0 -30
  510. package/dist/text/HotKeys.js +0 -74
  511. package/dist/text/Paragraph.d.ts +0 -33
  512. package/dist/text/Paragraph.js +0 -83
  513. package/dist/text/TextShimmer.d.ts +0 -14
  514. package/dist/text/TextShimmer.js +0 -34
  515. package/dist/theme/GalaxyTheme.d.ts +0 -67
  516. package/dist/theme/GalaxyTheme.js +0 -119
  517. package/dist/theme/constants.d.ts +0 -8
  518. package/dist/theme/constants.js +0 -38
  519. package/dist/theme/index.d.ts +0 -6
  520. package/dist/theme/index.js +0 -7
  521. package/dist/theme/types.d.ts +0 -195
  522. package/dist/theme/types.js +0 -10
  523. package/dist/theme/typography.d.ts +0 -2
  524. package/dist/theme/typography.js +0 -73
  525. package/dist/theme/variants/dark.d.ts +0 -2
  526. package/dist/theme/variants/dark.js +0 -125
  527. package/dist/theme/variants/light.d.ts +0 -2
  528. package/dist/theme/variants/light.js +0 -125
  529. package/dist/toast/ToastContainer.d.ts +0 -10
  530. package/dist/toast/ToastContainer.js +0 -31
  531. package/dist/toast/ToastWrapper.d.ts +0 -6
  532. package/dist/toast/ToastWrapper.js +0 -27
  533. package/dist/transform/Flash.d.ts +0 -7
  534. package/dist/transform/Flash.js +0 -18
  535. package/dist/transform/Spin.d.ts +0 -14
  536. package/dist/transform/Spin.js +0 -25
  537. package/dist/utils/linaria.d.ts +0 -1
  538. package/dist/utils/linaria.js +0 -8
@@ -1,496 +1,1154 @@
1
- import { withTheme } from "../theme/GalaxyTheme.js";
2
- import { getCssSizeValue } from "../utils/linaria.js";
3
- import Text, { TextSize, TextVariant, TextWeight } from "../text/Text.js";
4
- import Dropdown, { DropdownVariant } from "../dropdown/Dropdown.js";
1
+ import VisuallyHidden from "../a11y/VisuallyHidden.js";
2
+ import { Orientation } from "../theme/enums.js";
3
+ import Text, { TextSize, TextTransform, TextVariant, TextWeight } from "../text/Text.js";
4
+ import { useControlledState } from "../hooks/useControlledState.js";
5
+ import { useControlledOpenState } from "../hooks/useControlledOpenState.js";
6
+ import Flex, { AlignItems, FlexDirection } from "../layout/Flex.js";
7
+ import Box from "../layout/Box.js";
8
+ import Divider from "../layout/Divider.js";
9
+ import Popover, { PopoverRole, PopoverTrigger, PopoverVariant } from "../overlays/Popover.js";
5
10
  import Icon, { IconVariant } from "../icons/Icon.js";
6
- import FlexWrapper, { AlignItems, FlexDirection, JustifyContent } from "../containers/FlexWrapper.js";
7
- import Spacing from "../containers/Spacing.js";
8
- import { InputLabel, InputSize, InputVariant, getInputBorderColor, getInputHeight, getInputIconSize, getInputPadding, getInputSurfaceColor, getInputTextSize } from "./Input.js";
9
- import GridWrapper from "../containers/GridWrapper.js";
10
- import SelectInput from "./SelectInput.js";
11
+ import Button, { ButtonSize, ButtonVariant } from "../buttons/Button.js";
12
+ import FlexItem from "../layout/FlexItem.js";
13
+ import { FieldContext } from "../hooks/useField.js";
14
+ import { useDevWarning } from "./internal/devWarn.js";
15
+ import { useFieldWiring } from "./internal/fieldWiring.js";
16
+ import Field, { FieldSize } from "./Field.js";
17
+ import { rootStyle, useOwnField } from "./internal/ownField.js";
18
+ import { BareFieldContext, useIsBareField } from "./internal/bareField.js";
19
+ import "./internal/innerButton.js";
20
+ import { useDedupedOpen, useRestoreFocusAfterOutsidePress, useRetriedFocus } from "./internal/useComboboxPopover.js";
21
+ import SelectInput, { SelectInputSize, SelectInputVariant } from "./SelectInput.js";
11
22
  /* empty css */
12
23
  import { styled } from "@linaria/react";
13
- import { useCallback, useMemo, useRef, useState } from "react";
14
- import { jsx, jsxs } from "react/jsx-runtime";
15
- import { CalendarBlankIcon, CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";
24
+ import { forwardRef, useRef, useState } from "react";
25
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
26
+ import { cx } from "@linaria/core";
27
+ import { useMergeRefs } from "@floating-ui/react";
28
+ import { CalendarBlankIcon, CaretLeftIcon, CaretRightIcon, XIcon } from "@phosphor-icons/react";
16
29
  //#region src/inputs/DateInput.tsx
17
- var DateMonth = /* @__PURE__ */ function(DateMonth) {
18
- DateMonth["JANUARY"] = "JANUARY";
19
- DateMonth["FEBRUARY"] = "FEBRUARY";
20
- DateMonth["MARCH"] = "MARCH";
21
- DateMonth["APRIL"] = "APRIL";
22
- DateMonth["MAY"] = "MAY";
23
- DateMonth["JUNE"] = "JUNE";
24
- DateMonth["JULY"] = "JULY";
25
- DateMonth["AUGUST"] = "AUGUST";
26
- DateMonth["SEPTEMBER"] = "SEPTEMBER";
27
- DateMonth["OCTOBER"] = "OCTOBER";
28
- DateMonth["NOVEMBER"] = "NOVEMBER";
29
- DateMonth["DECEMBER"] = "DECEMBER";
30
- return DateMonth;
31
- }(DateMonth || {});
32
- var DateDay = /* @__PURE__ */ function(DateDay) {
33
- DateDay["SUNDAY"] = "SUNDAY";
34
- DateDay["MONDAY"] = "MONDAY";
35
- DateDay["TUESDAY"] = "TUESDAY";
36
- DateDay["WEDNESDAY"] = "WEDNESDAY";
37
- DateDay["THURSDAY"] = "THURSDAY";
38
- DateDay["FRIDAY"] = "FRIDAY";
39
- DateDay["SATURDAY"] = "SATURDAY";
40
- return DateDay;
41
- }(DateDay || {});
42
- var DATE_MONTH_TO_LABEL = {
43
- ["JANUARY"]: "January",
44
- ["FEBRUARY"]: "February",
45
- ["MARCH"]: "March",
46
- ["APRIL"]: "April",
47
- ["MAY"]: "May",
48
- ["JUNE"]: "June",
49
- ["JULY"]: "July",
50
- ["AUGUST"]: "August",
51
- ["SEPTEMBER"]: "September",
52
- ["OCTOBER"]: "October",
53
- ["NOVEMBER"]: "November",
54
- ["DECEMBER"]: "December"
30
+ /**
31
+ * The form control for choosing a calendar date, a date and time, or a range of either. A field
32
+ * shows the chosen value (or a placeholder) and opens a calendar panel below it: a month grid
33
+ * navigated with the arrow keys or the pointer, month and year selects, optional hour and minute
34
+ * selects (`hasTime`), and the app's presets ("Last 7 days"). The value is a `Date` (or a
35
+ * `{ start, end }` pair with `isRange`), never a string. `min` / `max` disable the days outside a
36
+ * window; `timeZone` reads the calendar, the time and the field text in an IANA zone and shows its
37
+ * short name.
38
+ *
39
+ * The field is a select-only combobox with a dialog popup (`Popover` `MANUAL`, `DIALOG`);
40
+ * DateInput moves focus into the grid on open (the WAI-ARIA date picker dialog). Calendar math runs
41
+ * on `{ year, month, day }` records through `Intl`, so DST and month lengths cannot shift a day.
42
+ *
43
+ * It does not validate (the app passes `error`), accept typed dates, or pick durations
44
+ * (`DurationInput`) or schedules (`CronInput`).
45
+ *
46
+ * SSR: closed by default, so the server renders the field only. Without `timeZone`, the field's
47
+ * text is formatted in the server's zone. Nothing here touches `window` or `document` at module
48
+ * scope; "today" is read when the panel renders.
49
+ */
50
+ /** Canonical rungs; DateInput supports all five (the Input rung table). */
51
+ var DateInputSize = /* @__PURE__ */ function(DateInputSize) {
52
+ /** 20px field, caption text, 12px icon. */
53
+ DateInputSize["X_SMALL"] = "X_SMALL";
54
+ /** 24px field, body_sm text, 12px icon. */
55
+ DateInputSize["SMALL"] = "SMALL";
56
+ /** 32px field, body_md text, 14px icon. The default (1.x `MEDIUM` was 28px). */
57
+ DateInputSize["MEDIUM"] = "MEDIUM";
58
+ /** 36px field, body_lg text, 14px icon. */
59
+ DateInputSize["LARGE"] = "LARGE";
60
+ /** 40px field, body_lg text, 16px icon. */
61
+ DateInputSize["X_LARGE"] = "X_LARGE";
62
+ return DateInputSize;
63
+ }({});
64
+ /** Resting fill of the field (Constitution V-A surface set; 1.x `InputVariant` unchanged). */
65
+ var DateInputVariant = /* @__PURE__ */ function(DateInputVariant) {
66
+ /** `background.base` fill. */
67
+ DateInputVariant["BASE"] = "BASE";
68
+ /** `background.primary` fill. The default. */
69
+ DateInputVariant["PRIMARY"] = "PRIMARY";
70
+ /** `background.secondary` fill. */
71
+ DateInputVariant["SECONDARY"] = "SECONDARY";
72
+ /** `background.tertiary` fill. */
73
+ DateInputVariant["TERTIARY"] = "TERTIARY";
74
+ return DateInputVariant;
75
+ }({});
76
+ /** Field widths without `fillWidth` (no width token exists; the `MENU_MAX_WIDTH` precedent). */
77
+ /** The presets column's narrowest width. */
78
+ /** The year select's width and the hour / minute selects' width (px, for `Box width`). */
79
+ var DATE_INPUT_YEAR_SELECT_WIDTH = 72;
80
+ /** The month carets: 10px on the panel's 24px (`SMALL`) buttons (the collapsible Widget's caret, small rung). */
81
+ var MONTH_CARET_PX = 10;
82
+ var DATE_INPUT_TIME_SELECT_WIDTH = 64;
83
+ /** Years shown without a bound: the current year − 100 to + 10 (1.x's range). */
84
+ var DATE_INPUT_YEARS_BEFORE = 100;
85
+ var DATE_INPUT_YEARS_AFTER = 10;
86
+ /** Frames to wait for the panel's portal before giving up on moving focus into the grid. */
87
+ var DATE_INPUT_FOCUS_RETRY_FRAMES = 10;
88
+ /** Fixed English copy (the DLS's built-in copy is English; Field Decision 15). */
89
+ var MONTH_NAMES = [
90
+ "January",
91
+ "February",
92
+ "March",
93
+ "April",
94
+ "May",
95
+ "June",
96
+ "July",
97
+ "August",
98
+ "September",
99
+ "October",
100
+ "November",
101
+ "December"
102
+ ];
103
+ var WEEKDAY_NAMES = [
104
+ "Sunday",
105
+ "Monday",
106
+ "Tuesday",
107
+ "Wednesday",
108
+ "Thursday",
109
+ "Friday",
110
+ "Saturday"
111
+ ];
112
+ /** Field icon px per rung: one step below the rung's III-A.4 icon (Mitch, 2026-10-04). */
113
+ var DATE_INPUT_SIZE_TO_ICON_PX_MAP = {
114
+ ["X_SMALL"]: 12,
115
+ ["SMALL"]: 12,
116
+ ["MEDIUM"]: 14,
117
+ ["LARGE"]: 14,
118
+ ["X_LARGE"]: 16
55
119
  };
56
- var DATE_DAY_TO_LABEL = {
57
- ["SUNDAY"]: "Sun",
58
- ["MONDAY"]: "Mon",
59
- ["TUESDAY"]: "Tue",
60
- ["WEDNESDAY"]: "Wed",
61
- ["THURSDAY"]: "Thu",
62
- ["FRIDAY"]: "Fri",
63
- ["SATURDAY"]: "Sat"
120
+ /** The clear button's rung: 20px up to MEDIUM, 24px for LARGE and X_LARGE (Input's). */
121
+ var DATE_INPUT_SIZE_TO_BUTTON_SIZE_MAP = {
122
+ ["X_SMALL"]: ButtonSize.X_SMALL,
123
+ ["SMALL"]: ButtonSize.X_SMALL,
124
+ ["MEDIUM"]: ButtonSize.X_SMALL,
125
+ ["LARGE"]: ButtonSize.SMALL,
126
+ ["X_LARGE"]: ButtonSize.SMALL
64
127
  };
65
- var INPUT_VARIANT_TO_DROPDOWN_VARIANT = {
66
- [InputVariant.TRANSPARENT]: DropdownVariant.TRANSPARENT,
67
- [InputVariant.BASE]: DropdownVariant.PRIMARY,
68
- [InputVariant.PRIMARY]: DropdownVariant.PRIMARY,
69
- [InputVariant.SECONDARY]: DropdownVariant.SECONDARY,
70
- [InputVariant.TERTIARY]: DropdownVariant.TERTIARY
128
+ /** The clear button's px per rung, for the reserved padding (16 on X_SMALL: `X_SMALL_INNER_BUTTON_CSS`). */
129
+ /** Field text step per rung (the canonical control text). */
130
+ var DATE_INPUT_SIZE_TO_TEXT_SIZE_MAP = {
131
+ ["X_SMALL"]: TextSize.CAPTION,
132
+ ["SMALL"]: TextSize.BODY_SM,
133
+ ["MEDIUM"]: TextSize.BODY_MD,
134
+ ["LARGE"]: TextSize.BODY_LG,
135
+ ["X_LARGE"]: TextSize.BODY_LG
71
136
  };
72
- var _exp = () => ({ $size }) => `0 ${getInputPadding($size)}`;
73
- var _exp2 = () => ({ $size }) => getInputHeight($size);
74
- var _exp3 = () => ({ $width, $fillWidth }) => $fillWidth ? "100%" : $width ? getCssSizeValue($width) : "auto";
75
- var _exp4 = () => ({ $isDisabled }) => $isDisabled ? "not-allowed" : "pointer";
76
- var _exp5 = () => ({ $isDisabled }) => $isDisabled ? .5 : 1;
77
- var _exp6 = () => ({ theme, $variant }) => getInputSurfaceColor(theme, $variant);
78
- var _exp7 = () => ({ theme, $variant, $isActive, $isError }) => {
79
- if ($isActive) return theme.color.border.selected;
80
- if ($isError) return theme.color.border.error;
81
- return getInputBorderColor(theme, $variant);
137
+ /** The `Field` a DateInput renders for its own `label` / `error` uses the same rung. */
138
+ var DATE_INPUT_SIZE_TO_FIELD_SIZE_MAP = {
139
+ ["X_SMALL"]: FieldSize.X_SMALL,
140
+ ["SMALL"]: FieldSize.SMALL,
141
+ ["MEDIUM"]: FieldSize.MEDIUM,
142
+ ["LARGE"]: FieldSize.LARGE,
143
+ ["X_LARGE"]: FieldSize.X_LARGE
82
144
  };
83
- var _exp8 = () => ({ theme, $variant, $isActive, $isDisabled }) => {
84
- if ($isDisabled) return getInputBorderColor(theme, $variant);
85
- if ($isActive) return theme.color.border.selected;
86
- return getInputBorderColor(theme, $variant);
145
+ /** Panel fill: SelectInput's map. A ghost field (`isGhost`) gets a readable `BASE` panel instead. */
146
+ var DATE_INPUT_VARIANT_TO_POPOVER_VARIANT_MAP = {
147
+ ["BASE"]: PopoverVariant.PRIMARY,
148
+ ["PRIMARY"]: PopoverVariant.PRIMARY,
149
+ ["SECONDARY"]: PopoverVariant.SECONDARY,
150
+ ["TERTIARY"]: PopoverVariant.TERTIARY
87
151
  };
88
- var StyledDateInput = withTheme(/*#__PURE__*/ styled("div")({
89
- name: "StyledDateInput",
90
- class: "s1902pw9",
91
- propsAsIs: false,
92
- vars: {
93
- "s1902pw9-0": [_exp()],
94
- "s1902pw9-1": [_exp2()],
95
- "s1902pw9-2": [_exp3()],
96
- "s1902pw9-3": [_exp4()],
97
- "s1902pw9-4": [_exp5()],
98
- "s1902pw9-5": [_exp6()],
99
- "s1902pw9-6": [_exp7()],
100
- "s1902pw9-7": [_exp8()]
101
- }
102
- }));
103
- var CalendarContainer = withTheme(/*#__PURE__*/ styled("div")({
104
- name: "CalendarContainer",
105
- class: "c179xo5d",
152
+ /** Holds the field box, the trailing parts and the status region. */
153
+ var Wrapper = /*#__PURE__*/ styled("div")({
154
+ name: "Wrapper",
155
+ class: "gx-DateInput-Wrapper-w1902pw9",
106
156
  propsAsIs: false
107
- }));
108
- var _exp9 = () => ({ $isDisabled }) => $isDisabled ? "not-allowed" : "pointer";
109
- var _exp0 = () => ({ $isDisabled, $isCurrentMonth }) => {
110
- if ($isDisabled) return .3;
111
- if (!$isCurrentMonth) return .4;
112
- return 1;
157
+ });
158
+ /** Without `isRange`: 240px. */
159
+ var SINGLE_WIDTH_CSS = "gx-DateInput-SINGLE_WIDTH_CSS-s179xo5d";
160
+ /** With `isRange`: 320px. */
161
+ var RANGE_WIDTH_CSS = "gx-DateInput-RANGE_WIDTH_CSS-r60emtx";
162
+ /**
163
+ * The combobox (focused element and Popover's reference). No outline; focus is `FOCUS_CSS`.
164
+ * Declared before the frame maps.
165
+ */
166
+ var Control = /*#__PURE__*/ styled("div")({
167
+ name: "Control",
168
+ class: "gx-DateInput-Control-c1e2nwo7",
169
+ propsAsIs: false
170
+ });
171
+ /** Rest look per variant: fill and hairline color. */
172
+ var DATE_INPUT_VARIANT_TO_CSS_MAP = {
173
+ ["BASE"]: "gx-DateInput-BASE-b1phezo9",
174
+ ["PRIMARY"]: "gx-DateInput-PRIMARY-p132k297",
175
+ ["SECONDARY"]: "gx-DateInput-SECONDARY-s14lrrd7",
176
+ ["TERTIARY"]: "gx-DateInput-TERTIARY-t19rohk5"
177
+ };
178
+ /** `isGhost`: no fill and no hairline at rest. Declared after the variant map, which it replaces. */
179
+ var GHOST_CSS = "gx-DateInput-GHOST_CSS-g1mgixmn";
180
+ /** Hover on an editable field: `border.hovered` (stronger than `border.primary`, Constitution III.6). */
181
+ var DATE_INPUT_VARIANT_TO_HOVER_CSS_MAP = {
182
+ ["BASE"]: "gx-DateInput-BASE-bvno65u",
183
+ ["PRIMARY"]: "gx-DateInput-PRIMARY-p1c49qmz",
184
+ ["SECONDARY"]: "gx-DateInput-SECONDARY-s2trf89",
185
+ ["TERTIARY"]: "gx-DateInput-TERTIARY-texkd8z"
186
+ };
187
+ /** Hover on an editable ghost field: the frame appears, `border.hovered` with no fill. */
188
+ var GHOST_HOVER_CSS = "gx-DateInput-GHOST_HOVER_CSS-gymba5f";
189
+ /**
190
+ * Height, start inset, gap and the end inset that reserves the icon zone (rung padding + icon +
191
+ * gap) per rung (SelectInput's table). The start inset subtracts the 0.5px hairline so the value
192
+ * starts on a whole pixel.
193
+ */
194
+ var DATE_INPUT_SIZE_TO_CSS_MAP = {
195
+ ["X_SMALL"]: "gx-DateInput-X_SMALL-x1a1xhli",
196
+ ["SMALL"]: "gx-DateInput-SMALL-s7h8e7l",
197
+ ["MEDIUM"]: "gx-DateInput-MEDIUM-m6tdnlc",
198
+ ["LARGE"]: "gx-DateInput-LARGE-l4w2d6x",
199
+ ["X_LARGE"]: "gx-DateInput-X_LARGE-xhdfnp7"
113
200
  };
114
- var _exp1 = () => ({ theme, $isSelected, $isToday }) => {
115
- if ($isSelected) return theme.color.background.tertiary;
116
- if ($isToday) return theme.color.background.tertiary;
117
- return "transparent";
201
+ /** With `isClearable`: the end inset also reserves the clear button and a gap. */
202
+ var DATE_INPUT_SIZE_TO_CLEARABLE_CSS_MAP = {
203
+ ["X_SMALL"]: "gx-DateInput-X_SMALL-xomc7wv",
204
+ ["SMALL"]: "gx-DateInput-SMALL-s63pu89",
205
+ ["MEDIUM"]: "gx-DateInput-MEDIUM-m1218f0q",
206
+ ["LARGE"]: "gx-DateInput-LARGE-l1raveum",
207
+ ["X_LARGE"]: "gx-DateInput-X_LARGE-x19gz466"
118
208
  };
119
- var _exp10 = () => ({ theme, $isSelected }) => {
120
- if ($isSelected) return `0.5px solid ${theme.color.border.primary}`;
121
- return "0.5px solid transparent";
209
+ /**
210
+ * Focus, from the mouse or the keyboard: `FIELD_FOCUS`, `border.focused` at 1px inside the frame. `:focus:hover`
211
+ * beats the hover map, so a ghost field keeps it. Not applied while disabled (the disabled
212
+ * combobox is a `tabIndex={-1}` div, which a click can still focus).
213
+ */
214
+ var FOCUS_CSS = "gx-DateInput-FOCUS_CSS-f3bchrm";
215
+ /** Open: `border.focused` (1.x's "selected" border). */
216
+ var OPEN_CSS = "gx-DateInput-OPEN_CSS-odi2lp8";
217
+ /** Error border at rest, on hover, with focus and while open. */
218
+ var ERROR_CSS = "gx-DateInput-ERROR_CSS-e10br3dp";
219
+ /** Disabled keeps the resting hairline; the text, the icon and the cursor say disabled. */
220
+ var DISABLED_CSS = "gx-DateInput-DISABLED_CSS-d19thxo8";
221
+ /** Read-only: no pointer affordance. */
222
+ var READ_ONLY_CSS = "gx-DateInput-READ_ONLY_CSS-r1fk36c6";
223
+ /** Stretch to the parent's width (wrapper, and the `Field` wrapper when there is one). */
224
+ var FILL_WIDTH_CSS = "gx-DateInput-FILL_WIDTH_CSS-f977rni";
225
+ /** The month buttons: a square of their 24px rung around the 10px caret (TableCore's expand button). */
226
+ var MONTH_CARET_BUTTON_CSS = "gx-DateInput-MONTH_CARET_BUTTON_CSS-mlmbz05";
227
+ /** The value (or placeholder) and the zone name, 2px apart. */
228
+ var ValueDisplay = /*#__PURE__*/ styled("span")({
229
+ name: "ValueDisplay",
230
+ class: "gx-DateInput-ValueDisplay-v5174l8",
231
+ propsAsIs: false
232
+ });
233
+ /** The zone name after the value: never wraps, never shrinks. */
234
+ var ZoneName = /*#__PURE__*/ styled("span")({
235
+ name: "ZoneName",
236
+ class: "gx-DateInput-ZoneName-z1v2jgx0",
237
+ propsAsIs: false
238
+ });
239
+ /** The calendar icon and the clear button, laid over the field's end. */
240
+ var Trailing = /*#__PURE__*/ styled("span")({
241
+ name: "Trailing",
242
+ class: "gx-DateInput-Trailing-t14on8ff",
243
+ propsAsIs: false
244
+ });
245
+ /** Trailing inset (the rung padding) and gap per rung. */
246
+ var DATE_INPUT_SIZE_TO_TRAILING_CSS_MAP = {
247
+ ["X_SMALL"]: "gx-DateInput-X_SMALL-xvfwun5",
248
+ ["SMALL"]: "gx-DateInput-SMALL-s1mzi1x2",
249
+ ["MEDIUM"]: "gx-DateInput-MEDIUM-m11jzfeq",
250
+ ["LARGE"]: "gx-DateInput-LARGE-l17kufpy",
251
+ ["X_LARGE"]: "gx-DateInput-X_LARGE-xzsw3xs"
122
252
  };
123
- var _exp11 = () => ({ theme, $isSelected }) => $isSelected ? theme.color.background.tertiary : theme.color.background.secondary;
124
- var DayCell = withTheme(/*#__PURE__*/ styled("button")({
253
+ /** Wraps the clear button: the only part of `Trailing` that takes the pointer. */
254
+ var ClearSlot = /*#__PURE__*/ styled("span")({
255
+ name: "ClearSlot",
256
+ class: "gx-DateInput-ClearSlot-cq0zkkh",
257
+ propsAsIs: false
258
+ });
259
+ /** Hidden clear button: keeps its width, leaves the tab order and the accessibility tree. */
260
+ var CLEAR_HIDDEN_CSS = "gx-DateInput-CLEAR_HIDDEN_CSS-c1t1xs4o";
261
+ /** The polite status region (VisuallyHidden takes no `role`). */
262
+ var StatusRegion = /*#__PURE__*/ styled("span")({
263
+ name: "StatusRegion",
264
+ class: "gx-DateInput-StatusRegion-su3lrrj",
265
+ propsAsIs: false
266
+ });
267
+ /** The panel content: presets, then the calendar column, 12px in and 12px apart. */
268
+ var PanelBody = /*#__PURE__*/ styled("div")({
269
+ name: "PanelBody",
270
+ class: "gx-DateInput-PanelBody-p18n6mtb",
271
+ propsAsIs: false
272
+ });
273
+ /** The presets column. */
274
+ var PresetList = /*#__PURE__*/ styled("div")({
275
+ name: "PresetList",
276
+ class: "gx-DateInput-PresetList-p1bpicw8",
277
+ propsAsIs: false
278
+ });
279
+ /** One preset. Declared before its state classes. */
280
+ var PresetButton = /*#__PURE__*/ styled("button")({
281
+ name: "PresetButton",
282
+ class: "gx-DateInput-PresetButton-p1n53t67",
283
+ propsAsIs: false
284
+ });
285
+ /** The preset whose value is the current value. */
286
+ var SELECTED_PRESET_CSS = "gx-DateInput-SELECTED_PRESET_CSS-s1if4h5q";
287
+ /** The month grid: seven 32px columns, no gaps, so a range band is continuous. */
288
+ var GridTable = /*#__PURE__*/ styled("table")({
289
+ name: "GridTable",
290
+ class: "gx-DateInput-GridTable-g6roixn",
291
+ propsAsIs: false
292
+ });
293
+ /** A weekday header cell. */
294
+ var WeekdayCell = /*#__PURE__*/ styled("th")({
295
+ name: "WeekdayCell",
296
+ class: "gx-DateInput-WeekdayCell-w1tj9b6w",
297
+ propsAsIs: false
298
+ });
299
+ /** A day cell: 32 × 32, carries the range band. */
300
+ var DayCell = /*#__PURE__*/ styled("td")({
125
301
  name: "DayCell",
126
- class: "d60emtx",
127
- propsAsIs: false,
128
- vars: {
129
- "d60emtx-0": [_exp9()],
130
- "d60emtx-1": [_exp0()],
131
- "d60emtx-2": [_exp1()],
132
- "d60emtx-3": [_exp10()],
133
- "d60emtx-4": [_exp11()]
302
+ class: "gx-DateInput-DayCell-d1fe1lym",
303
+ propsAsIs: false
304
+ });
305
+ /** Days strictly inside a committed range, and its ends' cells: the soft selection band. */
306
+ var IN_RANGE_CSS = "gx-DateInput-IN_RANGE_CSS-ic4r4p6";
307
+ /** While the range's end is pending: the band from the start to the hovered or active day. */
308
+ var RANGE_PREVIEW_CSS = "gx-DateInput-RANGE_PREVIEW_CSS-r12h464";
309
+ /** The band's start rounds its outer corners. */
310
+ var RANGE_START_CSS = "gx-DateInput-RANGE_START_CSS-r1w8ol8n";
311
+ /** The band's end rounds its outer corners. */
312
+ var RANGE_END_CSS = "gx-DateInput-RANGE_END_CSS-r1frmmpr";
313
+ /** A day. Declared before the day-state map. */
314
+ var DayButton = /*#__PURE__*/ styled("button")({
315
+ name: "DayButton",
316
+ class: "gx-DateInput-DayButton-dovvx2o",
317
+ propsAsIs: false
318
+ });
319
+ /** Text color, hover and fill per day state. */
320
+ var DAY_STATE_TO_CSS_MAP = {
321
+ DEFAULT: "gx-DateInput-DEFAULT-d1n3n4g9",
322
+ OUTSIDE: "gx-DateInput-OUTSIDE-o1l3iklu",
323
+ DISABLED: "gx-DateInput-DISABLED-d3avu2d",
324
+ SELECTED: "gx-DateInput-SELECTED-s1dkcpo"
325
+ };
326
+ /** Today: a hairline, and medium weight on the number (set on the text). */
327
+ var TODAY_CSS = "gx-DateInput-TODAY_CSS-tzq1kut";
328
+ /** Cached zone formatters (created lazily; no browser global involved). */
329
+ var ZONED_FORMATTERS = /* @__PURE__ */ new Map();
330
+ /** The `formatToParts` formatter for a zone. */
331
+ function getZonedFormatter(timeZone) {
332
+ let formatter = ZONED_FORMATTERS.get(timeZone);
333
+ if (formatter === void 0) {
334
+ formatter = new Intl.DateTimeFormat("en-US", {
335
+ timeZone,
336
+ hourCycle: "h23",
337
+ year: "numeric",
338
+ month: "numeric",
339
+ day: "numeric",
340
+ hour: "numeric",
341
+ minute: "numeric"
342
+ });
343
+ ZONED_FORMATTERS.set(timeZone, formatter);
134
344
  }
135
- }));
136
- var DEFAULT_MAX_DATE = /* @__PURE__ */ new Date();
137
- function defaultDateFormat(date) {
138
- return date.toLocaleDateString("en-US", {
345
+ return formatter;
346
+ }
347
+ /** The wall-clock parts of an instant, in `timeZone` (or the runtime's zone). */
348
+ function toZonedParts(date, timeZone) {
349
+ if (timeZone === void 0) return {
350
+ year: date.getFullYear(),
351
+ month: date.getMonth(),
352
+ day: date.getDate(),
353
+ hour: date.getHours(),
354
+ minute: date.getMinutes()
355
+ };
356
+ const values = {};
357
+ for (const part of getZonedFormatter(timeZone).formatToParts(date)) if (part.type !== "literal") values[part.type] = Number.parseInt(part.value, 10);
358
+ return {
359
+ year: values.year ?? 1970,
360
+ month: (values.month ?? 1) - 1,
361
+ day: values.day ?? 1,
362
+ hour: (values.hour ?? 0) % 24,
363
+ minute: values.minute ?? 0
364
+ };
365
+ }
366
+ /** The instant of wall-clock parts in `timeZone`. A skipped time lands after the gap; a repeated one takes the earlier instant. */
367
+ function fromZonedParts(parts, timeZone) {
368
+ if (timeZone === void 0) return new Date(parts.year, parts.month, parts.day, parts.hour, parts.minute);
369
+ const guess = Date.UTC(parts.year, parts.month, parts.day, parts.hour, parts.minute);
370
+ const offset = (ms) => {
371
+ const zoned = toZonedParts(new Date(ms), timeZone);
372
+ return Date.UTC(zoned.year, zoned.month, zoned.day, zoned.hour, zoned.minute) - Math.floor(ms / 6e4) * 6e4;
373
+ };
374
+ let instant = guess - offset(guess);
375
+ const corrected = guess - offset(instant);
376
+ if (corrected !== instant) instant = corrected;
377
+ return new Date(instant);
378
+ }
379
+ /** A sortable number for a day. */
380
+ function dayKey(day) {
381
+ return day.year * 1e4 + day.month * 100 + day.day;
382
+ }
383
+ /** Days in a month. */
384
+ function daysInMonth(year, month) {
385
+ return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
386
+ }
387
+ /** 0 = Sunday. */
388
+ function weekdayOf(day) {
389
+ return new Date(Date.UTC(day.year, day.month, day.day)).getUTCDay();
390
+ }
391
+ /** The day `count` days later (or earlier). */
392
+ function addDays(day, count) {
393
+ const date = new Date(Date.UTC(day.year, day.month, day.day + count));
394
+ return {
395
+ year: date.getUTCFullYear(),
396
+ month: date.getUTCMonth(),
397
+ day: date.getUTCDate()
398
+ };
399
+ }
400
+ /** The same day `count` months later, clamped to that month's length. */
401
+ function addMonths(day, count) {
402
+ const index = day.year * 12 + day.month + count;
403
+ const year = Math.floor(index / 12);
404
+ const month = index - year * 12;
405
+ return {
406
+ year,
407
+ month,
408
+ day: Math.min(day.day, daysInMonth(year, month))
409
+ };
410
+ }
411
+ /** True when two days are the same. */
412
+ function isSameDay(a, b) {
413
+ return a != null && b != null && dayKey(a) === dayKey(b);
414
+ }
415
+ /** Clamps a day into `[min, max]` (either may be absent). */
416
+ function clampDay(day, minDay, maxDay) {
417
+ if (minDay !== null && dayKey(day) < dayKey(minDay)) return minDay;
418
+ if (maxDay !== null && dayKey(day) > dayKey(maxDay)) return maxDay;
419
+ return day;
420
+ }
421
+ /** Clamps an instant into `[min, max]`. */
422
+ function clampInstant(date, min, max) {
423
+ if (min !== void 0 && date.getTime() < min.getTime()) return new Date(min.getTime());
424
+ if (max !== void 0 && date.getTime() > max.getTime()) return new Date(max.getTime());
425
+ return date;
426
+ }
427
+ /** Two digits ("07"). */
428
+ function pad2(value) {
429
+ return String(value).padStart(2, "0");
430
+ }
431
+ /** The full date for a day button's name ("Saturday, October 3, 2026"). */
432
+ function fullDateLabel(day) {
433
+ return `${WEEKDAY_NAMES[weekdayOf(day)] ?? ""}, ${MONTH_NAMES[day.month] ?? ""} ${day.day}, ${day.year}`;
434
+ }
435
+ /** The default field text: "Oct 3, 2026" (or "Oct 3, 2026, 14:30" with time) in the zone. */
436
+ function defaultFormat(date, hasTime, timeZone) {
437
+ const options = {
139
438
  month: "short",
140
439
  day: "numeric",
141
440
  year: "numeric"
441
+ };
442
+ if (hasTime) Object.assign(options, {
443
+ hour: "2-digit",
444
+ minute: "2-digit",
445
+ hourCycle: "h23"
142
446
  });
447
+ if (timeZone !== void 0) options.timeZone = timeZone;
448
+ return new Intl.DateTimeFormat("en-US", options).format(date);
143
449
  }
144
- var getInitialViewDate = (value) => {
145
- return value || /* @__PURE__ */ new Date();
146
- };
147
- /**
148
- * A date field with a calendar popover. Fully controlled — you own `value`.
149
- *
150
- * Works in `Date` objects throughout; there is no string parsing to get wrong.
151
- */
152
- var DateInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MEDIUM, value, placeholder = "Select date...", onChange, width, fillWidth = false, isDisabled = false, isRequired = false, error, minDate = new Date(1970, 0, 1), maxDate = DEFAULT_MAX_DATE, format = defaultDateFormat }) => {
153
- const [state, setState] = useState({
154
- isOpen: false,
155
- isHovered: false,
156
- viewDate: getInitialViewDate(value),
157
- isMonthSelectOpen: false,
158
- isYearSelectOpen: false
450
+ /** The zone's short name for an instant ("UTC", "EDT", "GMT+2"). */
451
+ function zoneName(date, timeZone) {
452
+ return new Intl.DateTimeFormat("en-US", {
453
+ timeZone,
454
+ timeZoneName: "short"
455
+ }).formatToParts(date).find((part) => part.type === "timeZoneName")?.value ?? timeZone;
456
+ }
457
+ /** True for a `DateRange` value. */
458
+ function isDateRange(value) {
459
+ return value !== null && !(value instanceof Date);
460
+ }
461
+ /** True when two values are the same instant(s). */
462
+ function isSameValue(a, b) {
463
+ if (a === null) return false;
464
+ if (isDateRange(a) && isDateRange(b)) return a.start.getTime() === b.start.getTime() && a.end.getTime() === b.end.getTime();
465
+ if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
466
+ return false;
467
+ }
468
+ /** The 42 days shown for a month: Sunday first, padded with the neighboring months. */
469
+ function monthGrid(view) {
470
+ const first = {
471
+ year: view.year,
472
+ month: view.month,
473
+ day: 1
474
+ };
475
+ const start = addDays(first, -weekdayOf(first));
476
+ return Array.from({ length: 42 }, (_, index) => addDays(start, index));
477
+ }
478
+ /** The field, the trailing parts and the calendar panel, wired to the nearest Field. */
479
+ function DateInputFrame({ dateProps, forwardedRef, isRoot }) {
480
+ const { isRange = false, value, defaultValue = null, onChange, presets, hasTime = false, min, max, timeZone, format, size = "MEDIUM", variant = "PRIMARY", isGhost = false, label: _label, placeholder, error, isError = false, isClearable = false, isDisabled = false, isReadOnly = false, isRequired = false, fillWidth = false, ariaLabel, isOpen, defaultIsOpen = false, onOpenChange, id, "aria-describedby": ariaDescribedBy, className, style, ...rest } = dateProps;
481
+ const isBare = useIsBareField();
482
+ const { field, controlId, describedBy, isInvalid, isRequired: isRequiredState, hasName } = useFieldWiring({
483
+ id,
484
+ ariaLabel,
485
+ ariaLabelAttribute: rest["aria-label"],
486
+ ariaLabelledBy: rest["aria-labelledby"],
487
+ ariaDescribedBy,
488
+ error,
489
+ isError,
490
+ isRequired
491
+ });
492
+ const panelId = `${controlId}-calendar`;
493
+ const headingId = `${controlId}-heading`;
494
+ const timeLabelId = `${controlId}-time`;
495
+ const startLabelId = `${controlId}-start`;
496
+ const endLabelId = `${controlId}-end`;
497
+ const controlRef = useRef(null);
498
+ const mergedRef = useMergeRefs([controlRef, forwardedRef]);
499
+ const panelRef = useRef(null);
500
+ const wrapperRef = useRef(null);
501
+ const isEditable = !isDisabled && !isReadOnly;
502
+ const [currentValue, setValue] = useControlledState({
503
+ value,
504
+ defaultValue,
505
+ onChange
159
506
  });
160
- const selectInteractionRef = useRef(false);
161
- const [prevValue, setPrevValue] = useState(value);
162
- if (value !== prevValue) {
163
- setPrevValue(value);
164
- if (value) setState((prev) => ({
165
- ...prev,
166
- viewDate: value
167
- }));
507
+ const { isOpen: isOpenState, setOpen: setOpenState } = useControlledOpenState({
508
+ isOpen,
509
+ defaultIsOpen,
510
+ onOpenChange
511
+ });
512
+ const isShown = isOpenState && isEditable;
513
+ const { setOpen, isShownRef } = useDedupedOpen(isShown, setOpenState);
514
+ const minDay = min === void 0 ? null : toZonedParts(min, timeZone);
515
+ const maxDay = max === void 0 ? null : toZonedParts(max, timeZone);
516
+ const isDayDisabled = (day) => minDay !== null && dayKey(day) < dayKey(minDay) || maxDay !== null && dayKey(day) > dayKey(maxDay);
517
+ const rangeValue = isRange && isDateRange(currentValue) ? currentValue : null;
518
+ const singleValue = !isRange && currentValue instanceof Date ? currentValue : null;
519
+ const hasValue = rangeValue !== null || singleValue !== null;
520
+ /** The day the grid starts on: the value's day (a range's start), else today, clamped. */
521
+ const initialActiveDay = () => {
522
+ return clampDay(toZonedParts(rangeValue?.start ?? singleValue ?? /* @__PURE__ */ new Date(), timeZone), minDay, maxDay);
523
+ };
524
+ const [activeDay, setActiveDay] = useState(() => initialActiveDay());
525
+ const [viewMonth, setViewMonth] = useState(() => ({
526
+ year: activeDay.year,
527
+ month: activeDay.month
528
+ }));
529
+ const [pendingStart, setPendingStart] = useState(null);
530
+ const [previewDay, setPreviewDay] = useState(null);
531
+ const [announcement, setAnnouncement] = useState("");
532
+ const shouldFocusDayRef = useRef(false);
533
+ const [lastShown, setLastShown] = useState(isShown);
534
+ if (lastShown !== isShown) {
535
+ setLastShown(isShown);
536
+ if (isShown) {
537
+ const next = initialActiveDay();
538
+ setActiveDay(next);
539
+ setViewMonth({
540
+ year: next.year,
541
+ month: next.month
542
+ });
543
+ shouldFocusDayRef.current = true;
544
+ } else {
545
+ setPendingStart(null);
546
+ setPreviewDay(null);
547
+ setAnnouncement("");
548
+ }
168
549
  }
169
- const handleToggle = useCallback(() => {
170
- if (isDisabled) return;
171
- setState((prev) => ({
172
- ...prev,
173
- isOpen: !prev.isOpen
174
- }));
175
- }, [isDisabled]);
176
- const handleClose = useCallback(() => {
177
- setState((prev) => {
178
- if (prev.isMonthSelectOpen || prev.isYearSelectOpen) return prev;
179
- if (selectInteractionRef.current) {
180
- selectInteractionRef.current = false;
181
- return prev;
182
- }
183
- return {
184
- ...prev,
185
- isOpen: false
186
- };
187
- });
188
- }, []);
189
- const handleMouseEnter = useCallback(() => {
190
- setState((prev) => ({
191
- ...prev,
192
- isHovered: true
193
- }));
194
- }, []);
195
- const handleMouseLeave = useCallback(() => {
196
- setState((prev) => ({
197
- ...prev,
198
- isHovered: false
199
- }));
200
- }, []);
201
- const handlePrevMonth = useCallback((e) => {
202
- e.stopPropagation();
203
- setState((prev) => {
204
- const newDate = new Date(prev.viewDate);
205
- newDate.setMonth(newDate.getMonth() - 1);
206
- return {
207
- ...prev,
208
- viewDate: newDate
209
- };
210
- });
211
- }, []);
212
- const handleNextMonth = useCallback((e) => {
213
- e.stopPropagation();
214
- setState((prev) => {
215
- const newDate = new Date(prev.viewDate);
216
- newDate.setMonth(newDate.getMonth() + 1);
217
- return {
218
- ...prev,
219
- viewDate: newDate
220
- };
221
- });
222
- }, []);
223
- const handleMonthChange = useCallback((option) => {
224
- selectInteractionRef.current = true;
225
- setState((prev) => {
226
- const newDate = new Date(prev.viewDate);
227
- newDate.setMonth(option.value);
228
- return {
229
- ...prev,
230
- viewDate: newDate,
231
- isMonthSelectOpen: false
232
- };
550
+ const dayButtonId = (day) => `${panelId}-day-${day.year}-${day.month}-${day.day}`;
551
+ const activeDayId = dayButtonId(activeDay);
552
+ useRetriedFocus(shouldFocusDayRef, isShown, () => controlRef.current?.ownerDocument.getElementById(activeDayId) ?? null, DATE_INPUT_FOCUS_RETRY_FRAMES);
553
+ /** Moves the active day (clamped into the bounds), follows it with the view, and focuses it. */
554
+ const moveActive = (next) => {
555
+ const clamped = clampDay(next, minDay, maxDay);
556
+ setActiveDay(clamped);
557
+ setViewMonth({
558
+ year: clamped.year,
559
+ month: clamped.month
233
560
  });
234
- }, []);
235
- const handleYearChange = useCallback((option) => {
236
- selectInteractionRef.current = true;
237
- setState((prev) => {
238
- const newDate = new Date(prev.viewDate);
239
- newDate.setFullYear(option.value);
240
- return {
241
- ...prev,
242
- viewDate: newDate,
243
- isYearSelectOpen: false
244
- };
245
- });
246
- }, []);
247
- const handleMonthSelectOpenChange = useCallback((isOpen) => {
248
- setState((prev) => ({
249
- ...prev,
250
- isMonthSelectOpen: isOpen,
251
- isYearSelectOpen: false
252
- }));
253
- }, []);
254
- const handleYearSelectOpenChange = useCallback((isOpen) => {
255
- setState((prev) => ({
256
- ...prev,
257
- isYearSelectOpen: isOpen,
258
- isMonthSelectOpen: false
259
- }));
260
- }, []);
261
- const handleDateSelect = useCallback((date) => {
262
- if (onChange) onChange(date);
263
- setState((prev) => ({
264
- ...prev,
265
- isOpen: false,
266
- isMonthSelectOpen: false,
267
- isYearSelectOpen: false
268
- }));
269
- }, [onChange]);
270
- const isDateDisabled = useCallback((date) => {
271
- if (minDate && date < minDate) return true;
272
- if (maxDate && date > maxDate) return true;
273
- return false;
274
- }, [minDate, maxDate]);
275
- const calendarDays = useMemo(() => {
276
- const year = state.viewDate.getFullYear();
277
- const month = state.viewDate.getMonth();
278
- const firstDayOfMonth = new Date(year, month, 1);
279
- const lastDayOfMonth = new Date(year, month + 1, 0);
280
- const startDay = firstDayOfMonth.getDay();
281
- const daysInMonth = lastDayOfMonth.getDate();
282
- const days = [];
283
- const prevMonthLastDay = new Date(year, month, 0).getDate();
284
- for (let i = startDay - 1; i >= 0; i--) {
285
- const date = new Date(year, month - 1, prevMonthLastDay - i);
286
- days.push({
287
- date,
288
- isCurrentMonth: false,
289
- isToday: isSameDay(date, /* @__PURE__ */ new Date()),
290
- isSelected: value ? isSameDay(date, value) : false,
291
- isDisabled: isDateDisabled(date)
292
- });
561
+ shouldFocusDayRef.current = true;
562
+ };
563
+ /** Changes the viewed month (header controls) and keeps the active day in it. */
564
+ const showMonth = (next) => {
565
+ setViewMonth(next);
566
+ const day = Math.min(activeDay.day, daysInMonth(next.year, next.month));
567
+ setActiveDay(clampDay({
568
+ ...next,
569
+ day
570
+ }, minDay, maxDay));
571
+ };
572
+ const close = () => setOpen(false);
573
+ useRestoreFocusAfterOutsidePress({
574
+ isShown,
575
+ focusRef: controlRef,
576
+ insideRefs: [wrapperRef, panelRef],
577
+ focusScopeRefs: [panelRef]
578
+ });
579
+ const commit = (next) => setValue(next);
580
+ /** Chooses a day (Selection rules). */
581
+ const chooseDay = (day) => {
582
+ if (isDayDisabled(day)) return;
583
+ setActiveDay(day);
584
+ if (!isRange) {
585
+ if (!hasTime) {
586
+ commit(fromZonedParts({
587
+ ...day,
588
+ hour: 0,
589
+ minute: 0
590
+ }, timeZone));
591
+ close();
592
+ return;
593
+ }
594
+ const time = singleValue === null ? {
595
+ hour: 0,
596
+ minute: 0
597
+ } : toZonedParts(singleValue, timeZone);
598
+ commit(clampInstant(fromZonedParts({
599
+ ...day,
600
+ hour: time.hour,
601
+ minute: time.minute
602
+ }, timeZone), min, max));
603
+ return;
293
604
  }
294
- for (let day = 1; day <= daysInMonth; day++) {
295
- const date = new Date(year, month, day);
296
- days.push({
297
- date,
298
- isCurrentMonth: true,
299
- isToday: isSameDay(date, /* @__PURE__ */ new Date()),
300
- isSelected: value ? isSameDay(date, value) : false,
301
- isDisabled: isDateDisabled(date)
302
- });
605
+ if (pendingStart === null) {
606
+ setPendingStart(day);
607
+ setPreviewDay(day);
608
+ setAnnouncement("Start date selected. Choose the end date.");
609
+ return;
303
610
  }
304
- const remainingDays = 42 - days.length;
305
- for (let i = 1; i <= remainingDays; i++) {
306
- const date = new Date(year, month + 1, i);
307
- days.push({
308
- date,
309
- isCurrentMonth: false,
310
- isToday: isSameDay(date, /* @__PURE__ */ new Date()),
311
- isSelected: value ? isSameDay(date, value) : false,
312
- isDisabled: isDateDisabled(date)
611
+ const [first, last] = dayKey(day) < dayKey(pendingStart) ? [day, pendingStart] : [pendingStart, day];
612
+ setPendingStart(null);
613
+ setPreviewDay(null);
614
+ setAnnouncement("");
615
+ if (!hasTime) {
616
+ commit({
617
+ start: fromZonedParts({
618
+ ...first,
619
+ hour: 0,
620
+ minute: 0
621
+ }, timeZone),
622
+ end: fromZonedParts({
623
+ ...last,
624
+ hour: 0,
625
+ minute: 0
626
+ }, timeZone)
313
627
  });
628
+ close();
629
+ return;
314
630
  }
315
- return days;
316
- }, [
317
- state.viewDate,
318
- value,
319
- isDateDisabled
320
- ]);
321
- const textVariant = useMemo(() => {
322
- if (value) return TextVariant.PRIMARY;
323
- if (state.isOpen || state.isHovered) return TextVariant.SECONDARY;
324
- return TextVariant.TERTIARY;
325
- }, [
326
- value,
327
- state.isOpen,
328
- state.isHovered
329
- ]);
330
- const displayValue = useMemo(() => {
331
- if (value) return format(value);
332
- return placeholder;
333
- }, [
334
- value,
335
- placeholder,
336
- format
337
- ]);
338
- const monthOptions = useMemo(() => Object.values(DateMonth).map((month, index) => ({
339
- id: String(index),
340
- label: DATE_MONTH_TO_LABEL[month],
341
- value: index
342
- })), []);
343
- const yearOptions = useMemo(() => {
344
- const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
345
- const minYear = minDate ? minDate.getFullYear() : currentYear - 100;
346
- const maxYear = maxDate ? maxDate.getFullYear() : currentYear + 10;
347
- const years = [];
348
- for (let year = maxYear; year >= minYear; year--) years.push({
349
- id: String(year),
350
- label: String(year),
351
- value: year
631
+ const startTime = rangeValue === null ? {
632
+ hour: 0,
633
+ minute: 0
634
+ } : toZonedParts(rangeValue.start, timeZone);
635
+ const endTime = rangeValue === null ? {
636
+ hour: 23,
637
+ minute: 59
638
+ } : toZonedParts(rangeValue.end, timeZone);
639
+ const start = clampInstant(fromZonedParts({
640
+ ...first,
641
+ hour: startTime.hour,
642
+ minute: startTime.minute
643
+ }, timeZone), min, max);
644
+ const end = clampInstant(fromZonedParts({
645
+ ...last,
646
+ hour: endTime.hour,
647
+ minute: endTime.minute
648
+ }, timeZone), min, max);
649
+ commit({
650
+ start,
651
+ end: end.getTime() < start.getTime() ? start : end
352
652
  });
353
- return years;
354
- }, [minDate, maxDate]);
355
- const selectedMonthOption = useMemo(() => monthOptions.find((opt) => opt.value === state.viewDate.getMonth()), [monthOptions, state.viewDate]);
356
- const selectedYearOption = useMemo(() => yearOptions.find((opt) => opt.value === state.viewDate.getFullYear()), [yearOptions, state.viewDate]);
357
- const calendarBody = /* @__PURE__ */ jsxs(CalendarContainer, {
358
- onClick: (e) => e.stopPropagation(),
359
- children: [/* @__PURE__ */ jsxs(FlexWrapper, {
653
+ };
654
+ const handleGridKeyDown = (event) => {
655
+ const step = {
656
+ ArrowRight: () => addDays(activeDay, 1),
657
+ ArrowLeft: () => addDays(activeDay, -1),
658
+ ArrowDown: () => addDays(activeDay, 7),
659
+ ArrowUp: () => addDays(activeDay, -7),
660
+ Home: () => addDays(activeDay, -weekdayOf(activeDay)),
661
+ End: () => addDays(activeDay, 6 - weekdayOf(activeDay)),
662
+ PageDown: () => addMonths(activeDay, event.shiftKey ? 12 : 1),
663
+ PageUp: () => addMonths(activeDay, event.shiftKey ? -12 : -1)
664
+ }[event.key];
665
+ if (step === void 0) return;
666
+ event.preventDefault();
667
+ const next = step();
668
+ moveActive(next);
669
+ if (pendingStart !== null) setPreviewDay(clampDay(next, minDay, maxDay));
670
+ };
671
+ /** The field's keys: Enter, Space, ArrowDown and Alt+ArrowDown open the panel. */
672
+ const handleControlKeyDown = (event) => {
673
+ if (event.defaultPrevented || !isEditable || isShown) return;
674
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
675
+ event.preventDefault();
676
+ setOpen(true);
677
+ }
678
+ };
679
+ const handleControlClick = () => {
680
+ if (!isEditable) return;
681
+ setOpen(!isShown);
682
+ };
683
+ /** Focus leaving both the field and the panel for another element closes the panel. */
684
+ const handleFocusOut = (event) => {
685
+ if (!isShownRef.current) return;
686
+ const next = event.relatedTarget;
687
+ if (next === null) return;
688
+ if (panelRef.current?.contains(next) || controlRef.current?.contains(next)) return;
689
+ close();
690
+ };
691
+ const clear = () => {
692
+ commit(null);
693
+ if (isShown) close();
694
+ controlRef.current?.focus();
695
+ };
696
+ const formatDate = (date) => (format ?? ((d) => defaultFormat(d, hasTime, timeZone)))(date);
697
+ const valueText = rangeValue !== null ? `${formatDate(rangeValue.start)} – ${formatDate(rangeValue.end)}` : singleValue !== null ? formatDate(singleValue) : null;
698
+ const zoneLabel = timeZone === void 0 ? null : zoneName(rangeValue?.start ?? singleValue ?? /* @__PURE__ */ new Date(), timeZone);
699
+ useDevWarning(!hasName, "[@galaxy-io/dls] DateInput has no accessible name. Pass `label`, wrap it in a labelled `Field`, or set `ariaLabel`. `placeholder` is not a name.");
700
+ const textSize = DATE_INPUT_SIZE_TO_TEXT_SIZE_MAP[size];
701
+ const shownPlaceholder = placeholder ?? (isRange ? "Select dates…" : "Select date…");
702
+ const isClearHidden = !hasValue || !isEditable;
703
+ const today = isShown ? toZonedParts(/* @__PURE__ */ new Date(), timeZone) : null;
704
+ const viewFirst = {
705
+ ...viewMonth,
706
+ day: 1
707
+ };
708
+ const viewLast = {
709
+ ...viewMonth,
710
+ day: daysInMonth(viewMonth.year, viewMonth.month)
711
+ };
712
+ const isMonthOutside = (month) => {
713
+ const first = {
714
+ ...month,
715
+ day: 1
716
+ };
717
+ const last = {
718
+ ...month,
719
+ day: daysInMonth(month.year, month.month)
720
+ };
721
+ return minDay !== null && dayKey(last) < dayKey(minDay) || maxDay !== null && dayKey(first) > dayKey(maxDay);
722
+ };
723
+ const previousMonth = addMonths(viewFirst, -1);
724
+ const nextMonth = addMonths(viewLast, 1);
725
+ const currentYear = today?.year ?? toZonedParts(/* @__PURE__ */ new Date(), timeZone).year;
726
+ const newestYear = Math.max(maxDay?.year ?? currentYear + DATE_INPUT_YEARS_AFTER, viewMonth.year);
727
+ const oldestYear = Math.min(minDay?.year ?? currentYear - DATE_INPUT_YEARS_BEFORE, viewMonth.year);
728
+ const yearOptions = [];
729
+ for (let year = newestYear; year >= oldestYear; year -= 1) yearOptions.push({
730
+ id: String(year),
731
+ label: String(year)
732
+ });
733
+ const monthOptions = MONTH_NAMES.map((name, month) => ({
734
+ id: String(month),
735
+ label: name,
736
+ ...isMonthOutside({
737
+ year: viewMonth.year,
738
+ month
739
+ }) ? { isDisabled: true } : {}
740
+ }));
741
+ const valueStartDay = rangeValue !== null ? toZonedParts(rangeValue.start, timeZone) : singleValue !== null ? toZonedParts(singleValue, timeZone) : null;
742
+ const valueEndDay = rangeValue !== null ? toZonedParts(rangeValue.end, timeZone) : null;
743
+ const previewEnd = pendingStart !== null ? previewDay ?? pendingStart : null;
744
+ const [previewFirst, previewLast] = pendingStart !== null && previewEnd !== null ? dayKey(previewEnd) < dayKey(pendingStart) ? [previewEnd, pendingStart] : [pendingStart, previewEnd] : [null, null];
745
+ const renderDay = (day) => {
746
+ const key = dayKey(day);
747
+ const isOutside = day.month !== viewMonth.month || day.year !== viewMonth.year;
748
+ const isDisabledDay = isDayDisabled(day);
749
+ const isPendingStart = isSameDay(day, pendingStart);
750
+ const isValueEnd = isSameDay(day, valueStartDay) || isSameDay(day, valueEndDay);
751
+ const isInCommitted = pendingStart === null && valueStartDay !== null && valueEndDay !== null && key >= dayKey(valueStartDay) && key <= dayKey(valueEndDay);
752
+ const isInPreview = previewFirst !== null && previewLast !== null && key >= dayKey(previewFirst) && key <= dayKey(previewLast);
753
+ const isSelected = isPendingStart || pendingStart === null && isValueEnd;
754
+ const state = isSelected ? "SELECTED" : isDisabledDay ? "DISABLED" : isOutside ? "OUTSIDE" : "DEFAULT";
755
+ const isToday = isSameDay(day, today);
756
+ const isActive = isSameDay(day, activeDay);
757
+ const isBandStart = isInCommitted && valueStartDay !== null && key === dayKey(valueStartDay) || isInPreview && previewFirst !== null && key === dayKey(previewFirst);
758
+ const isBandEnd = isInCommitted && valueEndDay !== null && key === dayKey(valueEndDay) || isInPreview && previewLast !== null && key === dayKey(previewLast);
759
+ return /* @__PURE__ */ jsx(DayCell, {
760
+ role: "gridcell",
761
+ "aria-selected": isSelected || isInCommitted,
762
+ className: cx(isRange && isInCommitted && IN_RANGE_CSS, isRange && isInPreview && RANGE_PREVIEW_CSS, isRange && isBandStart && RANGE_START_CSS, isRange && isBandEnd && RANGE_END_CSS),
763
+ children: /* @__PURE__ */ jsx(DayButton, {
764
+ type: "button",
765
+ id: dayButtonId(day),
766
+ tabIndex: isActive ? 0 : -1,
767
+ "aria-label": fullDateLabel(day),
768
+ ...isToday ? { "aria-current": "date" } : {},
769
+ ...isDisabledDay ? { "aria-disabled": true } : {},
770
+ onClick: () => chooseDay(day),
771
+ onPointerEnter: () => {
772
+ if (pendingStart !== null && !isDisabledDay) setPreviewDay(day);
773
+ },
774
+ onFocus: () => {
775
+ if (!isActive) setActiveDay(day);
776
+ },
777
+ className: cx(DAY_STATE_TO_CSS_MAP[state], isToday && TODAY_CSS),
778
+ children: /* @__PURE__ */ jsx(Text, {
779
+ as: "span",
780
+ size: TextSize.BODY_SM,
781
+ variant: TextVariant.INHERIT,
782
+ weight: isToday ? TextWeight.MEDIUM : TextWeight.REGULAR,
783
+ isTabular: true,
784
+ children: day.day
785
+ })
786
+ })
787
+ }, key);
788
+ };
789
+ const days = monthGrid(viewMonth);
790
+ const weeks = Array.from({ length: 6 }, (_, week) => days.slice(week * 7, week * 7 + 7));
791
+ /** One time row: a label, the hour and minute selects, and the zone name. */
792
+ const renderTimeRow = (which) => {
793
+ const labelId = which === "single" ? timeLabelId : which === "start" ? startLabelId : endLabelId;
794
+ const labelText = which === "single" ? "Time" : which === "start" ? "Start" : "End";
795
+ const instant = which === "single" ? singleValue : which === "start" ? rangeValue?.start : rangeValue?.end;
796
+ const isTimeDisabled = instant === null || instant === void 0;
797
+ const parts = isTimeDisabled ? null : toZonedParts(instant, timeZone);
798
+ const setTime = (hour, minute) => {
799
+ if (isTimeDisabled) return;
800
+ const next = clampInstant(fromZonedParts({
801
+ ...toZonedParts(instant, timeZone),
802
+ hour,
803
+ minute
804
+ }, timeZone), min, max);
805
+ if (which === "single") {
806
+ commit(next);
807
+ return;
808
+ }
809
+ if (rangeValue === null) return;
810
+ if (which === "start") commit({
811
+ start: next,
812
+ end: next.getTime() > rangeValue.end.getTime() ? next : rangeValue.end
813
+ });
814
+ else commit({
815
+ start: rangeValue.start,
816
+ end: next.getTime() < rangeValue.start.getTime() ? rangeValue.start : next
817
+ });
818
+ };
819
+ const hourId = `${labelId}-hour`;
820
+ const minuteId = `${labelId}-minute`;
821
+ return /* @__PURE__ */ jsxs(Flex, {
360
822
  alignItems: AlignItems.CENTER,
361
- justifyContent: JustifyContent.SPACE_BETWEEN,
362
- padding: "0 0 12px 0",
823
+ gap: 4,
363
824
  children: [
364
- /* @__PURE__ */ jsx(FlexWrapper, {
365
- onClick: handlePrevMonth,
366
- children: /* @__PURE__ */ jsx(Icon, {
367
- component: CaretLeftIcon,
368
- size: 16,
369
- variant: IconVariant.SECONDARY
825
+ /* @__PURE__ */ jsx(Box, {
826
+ minWidth: 40,
827
+ children: /* @__PURE__ */ jsx(Text, {
828
+ as: "span",
829
+ id: labelId,
830
+ size: TextSize.BODY_SM,
831
+ variant: TextVariant.SECONDARY,
832
+ children: labelText
370
833
  })
371
834
  }),
372
- /* @__PURE__ */ jsxs(FlexWrapper, {
373
- alignItems: AlignItems.CENTER,
374
- gap: 4,
375
- onClick: (e) => e.stopPropagation(),
376
- onMouseDown: (e) => e.stopPropagation(),
377
- children: [/* @__PURE__ */ jsx(SelectInput, {
378
- variant,
379
- size: InputSize.SMALL,
380
- options: monthOptions,
381
- value: selectedMonthOption,
382
- onChange: handleMonthChange,
383
- isOpen: state.isMonthSelectOpen,
384
- onOpenChange: handleMonthSelectOpenChange,
385
- width: 120
386
- }), /* @__PURE__ */ jsx(SelectInput, {
387
- variant,
388
- size: InputSize.SMALL,
389
- options: yearOptions,
390
- value: selectedYearOption,
391
- onChange: handleYearChange,
392
- isOpen: state.isYearSelectOpen,
393
- onOpenChange: handleYearSelectOpenChange,
394
- width: 70
395
- })]
396
- }),
397
- /* @__PURE__ */ jsx(FlexWrapper, {
398
- onClick: handleNextMonth,
399
- children: /* @__PURE__ */ jsx(Icon, {
400
- component: CaretRightIcon,
401
- size: 16,
402
- variant: IconVariant.SECONDARY
835
+ /* @__PURE__ */ jsx(Box, {
836
+ width: DATE_INPUT_TIME_SELECT_WIDTH,
837
+ children: /* @__PURE__ */ jsx(SelectInput, {
838
+ id: hourId,
839
+ ariaLabel: "Hour",
840
+ "aria-labelledby": `${labelId} ${hourId}`,
841
+ options: HOUR_OPTIONS,
842
+ value: parts === null ? null : pad2(parts.hour),
843
+ onChange: (next) => {
844
+ if (next !== null && parts !== null) setTime(Number(next), parts.minute);
845
+ },
846
+ size: SelectInputSize.SMALL,
847
+ variant: SelectInputVariant.SECONDARY,
848
+ isDisabled: isTimeDisabled,
849
+ placeholder: "--",
850
+ fillWidth: true
403
851
  })
404
- })
405
- ]
406
- }), /* @__PURE__ */ jsxs(GridWrapper, {
407
- columns: 7,
408
- gap: 2,
409
- children: [Object.values(DateDay).map((day) => /* @__PURE__ */ jsx(FlexWrapper, {
410
- alignItems: AlignItems.CENTER,
411
- justifyContent: JustifyContent.CENTER,
412
- height: 32,
413
- children: /* @__PURE__ */ jsx(Text, {
414
- size: TextSize.CAPTION,
852
+ }),
853
+ /* @__PURE__ */ jsx(Text, {
854
+ as: "span",
855
+ size: TextSize.BODY_SM,
415
856
  variant: TextVariant.TERTIARY,
416
- weight: TextWeight.MEDIUM,
417
- children: DATE_DAY_TO_LABEL[day].toUpperCase()
418
- })
419
- }, day)), calendarDays.map((day, index) => /* @__PURE__ */ jsx(DayCell, {
420
- $isSelected: day.isSelected,
421
- $isToday: day.isToday,
422
- $isCurrentMonth: day.isCurrentMonth,
423
- $isDisabled: day.isDisabled,
424
- onClick: () => !day.isDisabled && handleDateSelect(day.date),
425
- disabled: day.isDisabled,
426
- children: /* @__PURE__ */ jsx(Text, {
857
+ "aria-hidden": true,
858
+ children: ":"
859
+ }),
860
+ /* @__PURE__ */ jsx(Box, {
861
+ width: DATE_INPUT_TIME_SELECT_WIDTH,
862
+ children: /* @__PURE__ */ jsx(SelectInput, {
863
+ id: minuteId,
864
+ ariaLabel: "Minute",
865
+ "aria-labelledby": `${labelId} ${minuteId}`,
866
+ options: MINUTE_OPTIONS,
867
+ value: parts === null ? null : pad2(parts.minute),
868
+ onChange: (next) => {
869
+ if (next !== null && parts !== null) setTime(parts.hour, Number(next));
870
+ },
871
+ size: SelectInputSize.SMALL,
872
+ variant: SelectInputVariant.SECONDARY,
873
+ isDisabled: isTimeDisabled,
874
+ placeholder: "--",
875
+ fillWidth: true
876
+ })
877
+ }),
878
+ zoneLabel !== null && /* @__PURE__ */ jsx(Text, {
879
+ as: "span",
427
880
  size: TextSize.BODY_SM,
428
- variant: day.isSelected ? TextVariant.PRIMARY : TextVariant.SECONDARY,
429
- weight: day.isSelected || day.isToday ? TextWeight.MEDIUM : TextWeight.REGULAR,
430
- children: day.date.getDate()
881
+ variant: TextVariant.TERTIARY,
882
+ children: zoneLabel
431
883
  })
432
- }, index))]
433
- })]
434
- });
435
- return /* @__PURE__ */ jsxs(FlexWrapper, {
436
- direction: FlexDirection.COLUMN,
437
- gap: 4,
438
- fillWidth,
439
- children: [
440
- label && /* @__PURE__ */ jsx(InputLabel, {
441
- label,
442
- isRequired
443
- }),
444
- /* @__PURE__ */ jsx(Dropdown, {
445
- variant: INPUT_VARIANT_TO_DROPDOWN_VARIANT[variant],
446
- body: calendarBody,
447
- isOpen: state.isOpen,
448
- onClose: handleClose,
449
- noPadding: true,
450
- fillWidth,
451
- children: /* @__PURE__ */ jsxs(StyledDateInput, {
452
- $size: size,
453
- $variant: variant,
454
- $isActive: state.isOpen,
455
- $isDisabled: isDisabled,
456
- $isError: !!error,
457
- $width: width,
458
- $fillWidth: fillWidth,
459
- onClick: handleToggle,
460
- onMouseEnter: handleMouseEnter,
461
- onMouseLeave: handleMouseLeave,
462
- role: "button",
463
- tabIndex: isDisabled ? -1 : 0,
464
- "aria-haspopup": "dialog",
465
- "aria-expanded": state.isOpen,
466
- "aria-label": value ? displayValue : placeholder,
884
+ ]
885
+ }, which);
886
+ };
887
+ const presetList = presets;
888
+ const hasPresets = presetList !== void 0 && presetList.length > 0;
889
+ const isPresetDisabled = (preset) => {
890
+ return (isDateRange(preset.value) ? [preset.value.start, preset.value.end] : [preset.value]).some((instant) => isDayDisabled(toZonedParts(instant, timeZone)));
891
+ };
892
+ const body = /* @__PURE__ */ jsx(FieldContext.Provider, {
893
+ value: null,
894
+ children: /* @__PURE__ */ jsxs(PanelBody, {
895
+ onBlur: handleFocusOut,
896
+ children: [
897
+ hasPresets && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(PresetList, {
898
+ role: "group",
899
+ "aria-label": "Presets",
900
+ children: presetList.map((preset) => {
901
+ const isPresetSelected = isSameValue(currentValue, preset.value);
902
+ const isBlocked = isPresetDisabled(preset);
903
+ return /* @__PURE__ */ jsx(PresetButton, {
904
+ type: "button",
905
+ "aria-pressed": isPresetSelected,
906
+ disabled: isBlocked,
907
+ onClick: () => {
908
+ commit(preset.value);
909
+ close();
910
+ },
911
+ className: cx(isPresetSelected && SELECTED_PRESET_CSS),
912
+ children: /* @__PURE__ */ jsx(Text, {
913
+ as: "span",
914
+ size: TextSize.BODY_SM,
915
+ variant: isBlocked ? TextVariant.DISABLED : isPresetSelected ? TextVariant.PRIMARY : TextVariant.SECONDARY,
916
+ children: preset.label
917
+ })
918
+ }, preset.label);
919
+ })
920
+ }), /* @__PURE__ */ jsx(Divider, { orientation: Orientation.VERTICAL })] }),
921
+ /* @__PURE__ */ jsxs(Flex, {
922
+ direction: FlexDirection.COLUMN,
923
+ gap: 12,
467
924
  children: [
468
- /* @__PURE__ */ jsx(Text, {
469
- variant: textVariant,
470
- size: getInputTextSize(size),
471
- isEllipsis: true,
472
- cursor: !isDisabled ? "pointer" : "not-allowed",
473
- children: displayValue
925
+ /* @__PURE__ */ jsxs(Flex, {
926
+ alignItems: AlignItems.CENTER,
927
+ gap: 4,
928
+ children: [
929
+ /* @__PURE__ */ jsx(Button, {
930
+ variant: ButtonVariant.TERTIARY,
931
+ size: ButtonSize.SMALL,
932
+ leading: /* @__PURE__ */ jsx(Icon, {
933
+ component: CaretLeftIcon,
934
+ size: MONTH_CARET_PX,
935
+ variant: IconVariant.INHERIT
936
+ }),
937
+ ariaLabel: "Previous month",
938
+ className: MONTH_CARET_BUTTON_CSS,
939
+ isDisabled: isMonthOutside(previousMonth),
940
+ onClick: () => showMonth({
941
+ year: previousMonth.year,
942
+ month: previousMonth.month
943
+ })
944
+ }),
945
+ /* @__PURE__ */ jsx(FlexItem, {
946
+ grow: 1,
947
+ minWidth: 0,
948
+ children: /* @__PURE__ */ jsx(SelectInput, {
949
+ ariaLabel: "Month",
950
+ options: monthOptions,
951
+ value: String(viewMonth.month),
952
+ onChange: (next) => {
953
+ if (next !== null) showMonth({
954
+ year: viewMonth.year,
955
+ month: Number(next)
956
+ });
957
+ },
958
+ size: SelectInputSize.SMALL,
959
+ isGhost: true,
960
+ fillWidth: true
961
+ })
962
+ }),
963
+ /* @__PURE__ */ jsx(Box, {
964
+ width: DATE_INPUT_YEAR_SELECT_WIDTH,
965
+ children: /* @__PURE__ */ jsx(SelectInput, {
966
+ ariaLabel: "Year",
967
+ options: yearOptions,
968
+ value: String(viewMonth.year),
969
+ onChange: (next) => {
970
+ if (next === null) return;
971
+ const target = clampDay({
972
+ year: Number(next),
973
+ month: viewMonth.month,
974
+ day: 1
975
+ }, minDay, maxDay);
976
+ showMonth({
977
+ year: target.year,
978
+ month: target.month
979
+ });
980
+ },
981
+ size: SelectInputSize.SMALL,
982
+ isGhost: true,
983
+ fillWidth: true
984
+ })
985
+ }),
986
+ /* @__PURE__ */ jsx(Button, {
987
+ variant: ButtonVariant.TERTIARY,
988
+ size: ButtonSize.SMALL,
989
+ leading: /* @__PURE__ */ jsx(Icon, {
990
+ component: CaretRightIcon,
991
+ size: MONTH_CARET_PX,
992
+ variant: IconVariant.INHERIT
993
+ }),
994
+ ariaLabel: "Next month",
995
+ className: MONTH_CARET_BUTTON_CSS,
996
+ isDisabled: isMonthOutside(nextMonth),
997
+ onClick: () => showMonth({
998
+ year: nextMonth.year,
999
+ month: nextMonth.month
1000
+ })
1001
+ })
1002
+ ]
474
1003
  }),
475
- /* @__PURE__ */ jsx(Spacing, { left: 8 }),
476
- /* @__PURE__ */ jsx(Icon, {
477
- component: CalendarBlankIcon,
478
- size: getInputIconSize(size),
479
- variant: state.isOpen || state.isHovered ? IconVariant.SECONDARY : IconVariant.TERTIARY
480
- })
1004
+ /* @__PURE__ */ jsx(VisuallyHidden, {
1005
+ as: "h2",
1006
+ id: headingId,
1007
+ "aria-live": "polite",
1008
+ children: `${MONTH_NAMES[viewMonth.month] ?? ""} ${viewMonth.year}`
1009
+ }),
1010
+ /* @__PURE__ */ jsxs(GridTable, {
1011
+ role: "grid",
1012
+ "aria-labelledby": headingId,
1013
+ onKeyDown: handleGridKeyDown,
1014
+ children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: WEEKDAY_NAMES.map((weekday) => /* @__PURE__ */ jsx(WeekdayCell, {
1015
+ scope: "col",
1016
+ abbr: weekday,
1017
+ children: /* @__PURE__ */ jsx(Text, {
1018
+ as: "span",
1019
+ size: TextSize.CAPTION,
1020
+ weight: TextWeight.MEDIUM,
1021
+ variant: TextVariant.TERTIARY,
1022
+ transform: TextTransform.UPPERCASE,
1023
+ children: weekday.slice(0, 3)
1024
+ })
1025
+ }, weekday)) }) }), /* @__PURE__ */ jsx("tbody", { children: weeks.map((week) => /* @__PURE__ */ jsx("tr", { children: week.map(renderDay) }, dayKey(week[0] ?? viewFirst))) })]
1026
+ }),
1027
+ hasTime && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Divider, {}), /* @__PURE__ */ jsx(Flex, {
1028
+ direction: FlexDirection.COLUMN,
1029
+ gap: 8,
1030
+ children: isRange ? /* @__PURE__ */ jsxs(Fragment$1, { children: [renderTimeRow("start"), renderTimeRow("end")] }) : renderTimeRow("single")
1031
+ })] })
481
1032
  ]
1033
+ }),
1034
+ /* @__PURE__ */ jsx(StatusRegion, {
1035
+ role: "status",
1036
+ "aria-live": "polite",
1037
+ children: announcement
482
1038
  })
1039
+ ]
1040
+ })
1041
+ });
1042
+ const labelId = field?.labelId;
1043
+ return /* @__PURE__ */ jsxs(Wrapper, {
1044
+ ref: wrapperRef,
1045
+ className: cx(isRange ? RANGE_WIDTH_CSS : SINGLE_WIDTH_CSS, fillWidth && FILL_WIDTH_CSS, isRoot ? className : void 0),
1046
+ ...rootStyle(isRoot, style),
1047
+ children: [/* @__PURE__ */ jsx(Popover, {
1048
+ ref: panelRef,
1049
+ trigger: PopoverTrigger.MANUAL,
1050
+ role: PopoverRole.DIALOG,
1051
+ variant: isGhost ? PopoverVariant.BASE : DATE_INPUT_VARIANT_TO_POPOVER_VARIANT_MAP[variant],
1052
+ isOpen: isShown,
1053
+ onOpenChange: setOpen,
1054
+ isDisabled: !isEditable,
1055
+ id: panelId,
1056
+ ariaLabel: isRange ? "Choose dates" : "Choose date",
1057
+ body: /* @__PURE__ */ jsx(BareFieldContext.Provider, {
1058
+ value: false,
1059
+ children: body
483
1060
  }),
484
- error && /* @__PURE__ */ jsx(Text, {
485
- variant: TextVariant.ERROR,
486
- size: TextSize.BODY_SM,
487
- children: error
1061
+ children: /* @__PURE__ */ jsx(Control, {
1062
+ ref: mergedRef,
1063
+ id: controlId,
1064
+ role: "combobox",
1065
+ tabIndex: isDisabled ? -1 : 0,
1066
+ "aria-labelledby": labelId,
1067
+ "aria-label": ariaLabel,
1068
+ "aria-describedby": describedBy,
1069
+ "aria-invalid": isInvalid ? true : void 0,
1070
+ "aria-required": isRequiredState ? true : void 0,
1071
+ "aria-readonly": isReadOnly ? true : void 0,
1072
+ "aria-disabled": isDisabled ? true : void 0,
1073
+ onKeyDown: handleControlKeyDown,
1074
+ onClick: handleControlClick,
1075
+ onBlur: handleFocusOut,
1076
+ ...rest,
1077
+ className: cx(isGhost ? GHOST_CSS : DATE_INPUT_VARIANT_TO_CSS_MAP[variant], DATE_INPUT_SIZE_TO_CSS_MAP[size], isClearable && DATE_INPUT_SIZE_TO_CLEARABLE_CSS_MAP[size], isEditable && !isInvalid && (isGhost ? GHOST_HOVER_CSS : DATE_INPUT_VARIANT_TO_HOVER_CSS_MAP[variant]), !isDisabled && FOCUS_CSS, isShown && OPEN_CSS, isInvalid && !isDisabled && ERROR_CSS, isDisabled && DISABLED_CSS, isReadOnly && READ_ONLY_CSS, isBare && "gx-bareField-BARE_FIELD_CSS-b1memido"),
1078
+ children: /* @__PURE__ */ jsxs(ValueDisplay, { children: [/* @__PURE__ */ jsx(Text, {
1079
+ as: "span",
1080
+ size: textSize,
1081
+ variant: isDisabled ? TextVariant.DISABLED : valueText === null ? TextVariant.TERTIARY : TextVariant.PRIMARY,
1082
+ lineClamp: 1,
1083
+ isTabular: valueText !== null,
1084
+ children: valueText ?? shownPlaceholder
1085
+ }), zoneLabel !== null && /* @__PURE__ */ jsx(ZoneName, { children: /* @__PURE__ */ jsx(Text, {
1086
+ as: "span",
1087
+ size: textSize,
1088
+ variant: isDisabled ? TextVariant.DISABLED : TextVariant.TERTIARY,
1089
+ children: zoneLabel
1090
+ }) })] })
488
1091
  })
489
- ]
1092
+ }), /* @__PURE__ */ jsxs(Trailing, {
1093
+ className: DATE_INPUT_SIZE_TO_TRAILING_CSS_MAP[size],
1094
+ children: [isClearable && /* @__PURE__ */ jsx(ClearSlot, {
1095
+ className: cx(isClearHidden && CLEAR_HIDDEN_CSS),
1096
+ children: /* @__PURE__ */ jsx(Button, {
1097
+ variant: ButtonVariant.TERTIARY,
1098
+ size: DATE_INPUT_SIZE_TO_BUTTON_SIZE_MAP[size],
1099
+ icon: XIcon,
1100
+ ariaLabel: "Clear",
1101
+ onClick: clear,
1102
+ className: cx(size === "X_SMALL" && "gx-innerButton-X_SMALL_INNER_BUTTON_CSS-x1ep0pcd")
1103
+ })
1104
+ }), /* @__PURE__ */ jsx(Icon, {
1105
+ component: CalendarBlankIcon,
1106
+ size: DATE_INPUT_SIZE_TO_ICON_PX_MAP[size],
1107
+ variant: isDisabled ? IconVariant.DISABLED : IconVariant.SECONDARY,
1108
+ "aria-hidden": true
1109
+ })]
1110
+ })]
490
1111
  });
491
- };
492
- function isSameDay(date1, date2) {
493
- return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate();
494
1112
  }
1113
+ /** Hours "00"–"23". */
1114
+ var HOUR_OPTIONS = Array.from({ length: 24 }, (_, hour) => ({
1115
+ id: pad2(hour),
1116
+ label: pad2(hour)
1117
+ }));
1118
+ /** Minutes "00"–"59". */
1119
+ var MINUTE_OPTIONS = Array.from({ length: 60 }, (_, minute) => ({
1120
+ id: pad2(minute),
1121
+ label: pad2(minute)
1122
+ }));
1123
+ /** Choose a date, a date and time, or a range of either, in a field that opens a calendar. */
1124
+ var DateInput = forwardRef(function DateInput(props, ref) {
1125
+ const { label, error, isRequired = false, size = "MEDIUM", fillWidth = false } = props;
1126
+ const { id, className, style } = props;
1127
+ const ownField = useOwnField({
1128
+ componentName: "DateInput",
1129
+ label,
1130
+ error,
1131
+ isRequired,
1132
+ size: DATE_INPUT_SIZE_TO_FIELD_SIZE_MAP[size],
1133
+ id,
1134
+ className,
1135
+ style,
1136
+ rootClassName: fillWidth && FILL_WIDTH_CSS
1137
+ });
1138
+ if (ownField !== null) return /* @__PURE__ */ jsx(Field, {
1139
+ ...ownField,
1140
+ children: /* @__PURE__ */ jsx(DateInputFrame, {
1141
+ dateProps: props,
1142
+ forwardedRef: ref,
1143
+ isRoot: false
1144
+ })
1145
+ });
1146
+ return /* @__PURE__ */ jsx(DateInputFrame, {
1147
+ dateProps: props,
1148
+ forwardedRef: ref,
1149
+ isRoot: true
1150
+ });
1151
+ });
1152
+ DateInput.displayName = "DateInput";
495
1153
  //#endregion
496
- export { DateInput as default, defaultDateFormat };
1154
+ export { DateInputSize, DateInputVariant, DateInput as default };