@galaxy-io/dls 1.6.1 → 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 -30
  468. package/dist/inputs/SwitcherInput.js +0 -81
  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,360 +1,782 @@
1
- import { withTheme } from "../theme/GalaxyTheme.js";
2
- import { getCssSizeValue } from "../utils/linaria.js";
3
- import { hexToHsva, hsvaToHex } from "../utils/colors.js";
4
- import Text, { TextSize, TextVariant } from "../text/Text.js";
5
- import Dropdown, { DropdownVariant } from "../dropdown/Dropdown.js";
1
+ import { FontFamily } from "../theme/enums.js";
2
+ import Text, { TextSize, TextTransform, TextVariant } from "../text/Text.js";
3
+ import { useControlledState } from "../hooks/useControlledState.js";
4
+ import { useControlledOpenState } from "../hooks/useControlledOpenState.js";
5
+ import Flex, { AlignItems } from "../layout/Flex.js";
6
+ import { useGalaxyTheme } from "../theme/useGalaxyTheme.js";
7
+ import Popover, { PopoverRole, PopoverTrigger, PopoverVariant } from "../overlays/Popover.js";
6
8
  import Icon, { IconVariant } from "../icons/Icon.js";
7
- import FlexWrapper, { AlignItems, FlexDirection } from "../containers/FlexWrapper.js";
8
- import Spacing from "../containers/Spacing.js";
9
- import { InputLabel, InputSize, InputVariant, getInputBorderColor, getInputHeight, getInputIconSize, getInputPadding, getInputSurfaceColor, getInputTextSize } from "./Input.js";
10
- import GridWrapper from "../containers/GridWrapper.js";
9
+ import Rotate from "../transform/Rotate.js";
10
+ import Button, { ButtonSize, ButtonVariant } from "../buttons/Button.js";
11
+ import { FieldContext } from "../hooks/useField.js";
12
+ import { contrastRatio, hexToHsva, hexToRgb, hsvaToHex, rgbToHex } from "../utils/colors.js";
13
+ import { isDevelopment, useDevWarning } from "./internal/devWarn.js";
14
+ import { useFieldWiring } from "./internal/fieldWiring.js";
15
+ import Field, { FieldSize } from "./Field.js";
16
+ import { rootStyle, useOwnField } from "./internal/ownField.js";
17
+ import "./internal/innerButton.js";
18
+ import { InputSize, InputVariant } from "./Input.js";
19
+ import { useDedupedOpen, useRestoreFocusAfterOutsidePress, useRetriedFocus } from "./internal/useComboboxPopover.js";
20
+ import TextInput from "./TextInput.js";
11
21
  /* empty css */
12
22
  import { styled } from "@linaria/react";
13
- import { useCallback, useEffect, useMemo, useState } from "react";
23
+ import { cloneElement, forwardRef, useEffect, useRef, useState, version } from "react";
14
24
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
- import { CaretDownIcon } from "@phosphor-icons/react";
25
+ import { cx } from "@linaria/core";
26
+ import { useMergeRefs } from "@floating-ui/react";
27
+ import { CaretDownIcon, CheckIcon, XIcon } from "@phosphor-icons/react";
16
28
  import { Hue, Saturation } from "@uiw/react-color";
17
29
  //#region src/inputs/ColorInput.tsx
18
- var _exp = () => ({ $size }) => `0 ${getInputPadding($size)}`;
19
- var _exp2 = () => ({ $size }) => getInputHeight($size);
20
- var _exp3 = () => ({ $width, $fillWidth }) => $fillWidth ? "100%" : $width ? getCssSizeValue($width) : "auto";
21
- var _exp4 = () => ({ $isDisabled }) => $isDisabled ? "not-allowed" : "pointer";
22
- var _exp5 = () => ({ $isDisabled }) => $isDisabled ? .5 : 1;
23
- var _exp6 = () => ({ theme, $variant }) => getInputSurfaceColor(theme, $variant);
24
- var _exp7 = () => ({ theme, $variant, $isActive, $isError }) => {
25
- if ($isActive) return theme.color.border.selected;
26
- if ($isError) return theme.color.border.error;
27
- return getInputBorderColor(theme, $variant);
30
+ /**
31
+ * The form control for choosing one solid color, as a hex value. A field shows a swatch and the
32
+ * code (or a placeholder) and opens a picker panel: a saturation / brightness area and a hue
33
+ * slider (dragged or arrowed), a hex text field for typing or pasting a code, and the app's preset
34
+ * swatches. The value is a lowercase `#rrggbb` string.
35
+ *
36
+ * The committed value (`onChange`: a drag ends, a key steps, a code is entered, a swatch is
37
+ * picked) is separate from the live preview (`onPreviewChange`: every movement), so an app can
38
+ * recolor a preview while dragging and save once. The trigger can be the app's own focusable
39
+ * element (`children`, a `Button` with a project avatar).
40
+ *
41
+ * The panel is a `Popover` (`DIALOG`, `MANUAL`); ColorInput moves focus to the saturation area on
42
+ * open. It does not validate, pick alpha, or pick theme tokens (components read `t.color.*`;
43
+ * ColorInput is for user data such as a project or tag color).
44
+ *
45
+ * SSR: closed by default, so the server renders the field only. The `window` pointer listener is
46
+ * added only during a drag; nothing touches `window` or `document` at module scope.
47
+ */
48
+ /** Canonical rungs; ColorInput supports all five (the Input rung table). */
49
+ var ColorInputSize = /* @__PURE__ */ function(ColorInputSize) {
50
+ /** 20px field, caption text, 12px swatch and icons, 10px caret. */
51
+ ColorInputSize["X_SMALL"] = "X_SMALL";
52
+ /** 24px field, body_sm text, 12px swatch and icons, 10px caret. */
53
+ ColorInputSize["SMALL"] = "SMALL";
54
+ /** 32px field, body_md text, 14px swatch and icons, 12px caret. The default (1.x `MEDIUM` was 28px). */
55
+ ColorInputSize["MEDIUM"] = "MEDIUM";
56
+ /** 36px field, body_lg text, 14px swatch and icons, 12px caret. */
57
+ ColorInputSize["LARGE"] = "LARGE";
58
+ /** 40px field, body_lg text, 16px swatch and icons, 12px caret. */
59
+ ColorInputSize["X_LARGE"] = "X_LARGE";
60
+ return ColorInputSize;
61
+ }({});
62
+ /** Resting fill of the field (Constitution V-A surface set; 1.x `InputVariant` unchanged). */
63
+ var ColorInputVariant = /* @__PURE__ */ function(ColorInputVariant) {
64
+ /** `background.base` fill. */
65
+ ColorInputVariant["BASE"] = "BASE";
66
+ /** `background.primary` fill. The default. */
67
+ ColorInputVariant["PRIMARY"] = "PRIMARY";
68
+ /** `background.secondary` fill. */
69
+ ColorInputVariant["SECONDARY"] = "SECONDARY";
70
+ /** `background.tertiary` fill. */
71
+ ColorInputVariant["TERTIARY"] = "TERTIARY";
72
+ return ColorInputVariant;
73
+ }({});
74
+ /** React 19 moved an element's `ref` into `props`; React 18 keeps it on the element. */
75
+ var IS_REACT_19 = Number.parseInt(version, 10) >= 19;
76
+ /** The child's own ref, read where the running React version keeps it (Popover's helper). */
77
+ function getElementRef(element) {
78
+ return (IS_REACT_19 ? element.props : element).ref;
79
+ }
80
+ /** The field's width without `fillWidth` (no width token exists; the `MENU_MAX_WIDTH` precedent). */
81
+ /** 1.x's picker sizes. */
82
+ /** Swatches per row (10 × 24px + 9 × 4px fits the 280px picker). */
83
+ var PRESET_COLUMNS = 10;
84
+ /** Check mark px on a preset swatch. */
85
+ var PRESET_CHECK_PX = 14;
86
+ /** Frames to wait for the panel's portal before giving up on moving focus into it. */
87
+ var COLOR_INPUT_FOCUS_RETRY_FRAMES = 10;
88
+ /** The color a `null` value opens on (white), as 1.x did; never committed by opening. */
89
+ var WHITE_HSVA = {
90
+ h: 0,
91
+ s: 0,
92
+ v: 100,
93
+ a: 1
28
94
  };
29
- var _exp8 = () => ({ theme, $variant, $isActive, $isDisabled }) => {
30
- if ($isDisabled) return getInputBorderColor(theme, $variant);
31
- if ($isActive) return theme.color.border.selected;
32
- return getInputBorderColor(theme, $variant);
95
+ /** The field caret: 12px, 10px on the 20px and 24px rungs (the collapsible Widget's caret). */
96
+ var COLOR_INPUT_SIZE_TO_CARET_PX_MAP = {
97
+ ["X_SMALL"]: 10,
98
+ ["SMALL"]: 10,
99
+ ["MEDIUM"]: 12,
100
+ ["LARGE"]: 12,
101
+ ["X_LARGE"]: 12
33
102
  };
34
- var StyledColorInput = withTheme(/*#__PURE__*/ styled("div")({
35
- name: "StyledColorInput",
36
- class: "s161ysn8",
37
- propsAsIs: false,
38
- vars: {
39
- "s161ysn8-0": [_exp()],
40
- "s161ysn8-1": [_exp2()],
41
- "s161ysn8-2": [_exp3()],
42
- "s161ysn8-3": [_exp4()],
43
- "s161ysn8-4": [_exp5()],
44
- "s161ysn8-5": [_exp6()],
45
- "s161ysn8-6": [_exp7()],
46
- "s161ysn8-7": [_exp8()]
47
- }
48
- }));
49
- var ColorPickerContainer = /*#__PURE__*/ styled("div")({
50
- name: "ColorPickerContainer",
51
- class: "c10utehj",
103
+ /**
104
+ * The field swatch px per rung: the rung's icon slot, one step below III-A.4 (Mitch, 2026-10-04),
105
+ * so the value starts where an `Input` icon field's value starts.
106
+ */
107
+ /** The clear button's rung: 20px up to MEDIUM, 24px for LARGE and X_LARGE (Input's). */
108
+ var COLOR_INPUT_SIZE_TO_BUTTON_SIZE_MAP = {
109
+ ["X_SMALL"]: ButtonSize.X_SMALL,
110
+ ["SMALL"]: ButtonSize.X_SMALL,
111
+ ["MEDIUM"]: ButtonSize.X_SMALL,
112
+ ["LARGE"]: ButtonSize.SMALL,
113
+ ["X_LARGE"]: ButtonSize.SMALL
114
+ };
115
+ /** The clear button's px per rung, for the reserved padding (16 on X_SMALL: `X_SMALL_INNER_BUTTON_CSS`). */
116
+ /** Field text step per rung (the canonical control text). */
117
+ var COLOR_INPUT_SIZE_TO_TEXT_SIZE_MAP = {
118
+ ["X_SMALL"]: TextSize.CAPTION,
119
+ ["SMALL"]: TextSize.BODY_SM,
120
+ ["MEDIUM"]: TextSize.BODY_MD,
121
+ ["LARGE"]: TextSize.BODY_LG,
122
+ ["X_LARGE"]: TextSize.BODY_LG
123
+ };
124
+ /** The `Field` a ColorInput renders for its own `label` / `error` uses the same rung. */
125
+ var COLOR_INPUT_SIZE_TO_FIELD_SIZE_MAP = {
126
+ ["X_SMALL"]: FieldSize.X_SMALL,
127
+ ["SMALL"]: FieldSize.SMALL,
128
+ ["MEDIUM"]: FieldSize.MEDIUM,
129
+ ["LARGE"]: FieldSize.LARGE,
130
+ ["X_LARGE"]: FieldSize.X_LARGE
131
+ };
132
+ /** Panel fill: SelectInput's map. A ghost field (`isGhost`) gets a readable `BASE` panel instead. */
133
+ var COLOR_INPUT_VARIANT_TO_POPOVER_VARIANT_MAP = {
134
+ ["BASE"]: PopoverVariant.PRIMARY,
135
+ ["PRIMARY"]: PopoverVariant.PRIMARY,
136
+ ["SECONDARY"]: PopoverVariant.SECONDARY,
137
+ ["TERTIARY"]: PopoverVariant.TERTIARY
138
+ };
139
+ /** Holds the field box, the trailing parts; 160px unless `fillWidth`. */
140
+ var Wrapper = /*#__PURE__*/ styled("div")({
141
+ name: "Wrapper",
142
+ class: "gx-ColorInput-Wrapper-w161ysn8",
52
143
  propsAsIs: false
53
144
  });
54
- var StyledSaturation = /*#__PURE__*/ styled("div")({
55
- name: "StyledSaturation",
56
- class: "sjdhyd9",
145
+ /**
146
+ * The combobox (focused element and Popover's reference). No outline; focus is `FOCUS_CSS`.
147
+ * Declared before the frame maps.
148
+ */
149
+ var Control = /*#__PURE__*/ styled("div")({
150
+ name: "Control",
151
+ class: "gx-ColorInput-Control-c10utehj",
57
152
  propsAsIs: false
58
153
  });
59
- var _exp9 = () => ({ theme }) => theme.color.border.primary;
60
- var StyledHue = withTheme(/*#__PURE__*/ styled("div")({
61
- name: "StyledHue",
62
- class: "s1xfz2j",
63
- propsAsIs: false,
64
- vars: { "s1xfz2j-0": [_exp9()] }
65
- }));
66
- var _exp0 = () => ({ $left }) => $left ?? "0";
67
- var _exp1 = () => ({ theme }) => theme.color.background.base;
68
- var _exp10 = () => ({ theme }) => theme.color.border.primary;
69
- var HuePointerElement = withTheme(/*#__PURE__*/ styled("div")({
70
- name: "HuePointerElement",
71
- class: "hv4cfbr",
72
- propsAsIs: false,
73
- vars: {
74
- "hv4cfbr-0": [_exp0()],
75
- "hv4cfbr-1": [_exp1()],
76
- "hv4cfbr-2": [_exp10()]
77
- }
78
- }));
79
- var HuePointer = ({ left }) => /* @__PURE__ */ jsx(HuePointerElement, { $left: left });
80
- var ColorInputTriggerWrapper = /*#__PURE__*/ styled("div")({
81
- name: "ColorInputTriggerWrapper",
82
- class: "c1581w8r",
154
+ /** Rest look per variant: fill and hairline color. */
155
+ var COLOR_INPUT_VARIANT_TO_CSS_MAP = {
156
+ ["BASE"]: "gx-ColorInput-BASE-bjdhyd9",
157
+ ["PRIMARY"]: "gx-ColorInput-PRIMARY-p1xfz2j",
158
+ ["SECONDARY"]: "gx-ColorInput-SECONDARY-sv4cfbr",
159
+ ["TERTIARY"]: "gx-ColorInput-TERTIARY-t1581w8r"
160
+ };
161
+ /** `isGhost`: no fill and no hairline at rest. Declared after the variant map, which it replaces. */
162
+ var GHOST_CSS = "gx-ColorInput-GHOST_CSS-g2h225c";
163
+ /** Hover on an editable field: `border.hovered` (stronger than `border.primary`, Constitution III.6). */
164
+ var COLOR_INPUT_VARIANT_TO_HOVER_CSS_MAP = {
165
+ ["BASE"]: "gx-ColorInput-BASE-bnw6647",
166
+ ["PRIMARY"]: "gx-ColorInput-PRIMARY-pqgvsmn",
167
+ ["SECONDARY"]: "gx-ColorInput-SECONDARY-s1dtjd2a",
168
+ ["TERTIARY"]: "gx-ColorInput-TERTIARY-tu2d93e"
169
+ };
170
+ /** Hover on an editable ghost field: the frame appears, `border.hovered` with no fill. */
171
+ var GHOST_HOVER_CSS = "gx-ColorInput-GHOST_HOVER_CSS-g2ye5n";
172
+ /**
173
+ * Height, start inset, gap and the end inset that reserves the caret zone per rung (the
174
+ * SelectInput table). The start inset subtracts the 0.5px hairline so the swatch starts on a whole
175
+ * pixel.
176
+ */
177
+ var COLOR_INPUT_SIZE_TO_CSS_MAP = {
178
+ ["X_SMALL"]: "gx-ColorInput-X_SMALL-x12ezqo7",
179
+ ["SMALL"]: "gx-ColorInput-SMALL-sz7nzn8",
180
+ ["MEDIUM"]: "gx-ColorInput-MEDIUM-m1nwccez",
181
+ ["LARGE"]: "gx-ColorInput-LARGE-l156068l",
182
+ ["X_LARGE"]: "gx-ColorInput-X_LARGE-xewces2"
183
+ };
184
+ /** With `isClearable`: the end inset also reserves the clear button and a gap. */
185
+ var COLOR_INPUT_SIZE_TO_CLEARABLE_CSS_MAP = {
186
+ ["X_SMALL"]: "gx-ColorInput-X_SMALL-x1fjvwj0",
187
+ ["SMALL"]: "gx-ColorInput-SMALL-savtf9q",
188
+ ["MEDIUM"]: "gx-ColorInput-MEDIUM-m13v4q1",
189
+ ["LARGE"]: "gx-ColorInput-LARGE-l6qpixz",
190
+ ["X_LARGE"]: "gx-ColorInput-X_LARGE-x1yf0tnx"
191
+ };
192
+ /**
193
+ * Focus, from the mouse or the keyboard: `FIELD_FOCUS`, `border.focused` at 1px inside the frame. `:focus:hover`
194
+ * beats the hover map, so a ghost field keeps it. Not applied while disabled (the disabled
195
+ * combobox is a `tabIndex={-1}` div, which a click can still focus).
196
+ */
197
+ var FOCUS_CSS = "gx-ColorInput-FOCUS_CSS-f9y08ba";
198
+ /** Open: `border.focused` (1.x's "selected" border). */
199
+ var OPEN_CSS = "gx-ColorInput-OPEN_CSS-o1wj625e";
200
+ /** Error border at rest, on hover, with focus and while open. */
201
+ var ERROR_CSS = "gx-ColorInput-ERROR_CSS-e182yw4q";
202
+ /** Disabled keeps the resting hairline; the text, the icons and the cursor say disabled. */
203
+ var DISABLED_CSS = "gx-ColorInput-DISABLED_CSS-dueiui8";
204
+ /** Read-only: no pointer affordance. */
205
+ var READ_ONLY_CSS = "gx-ColorInput-READ_ONLY_CSS-rubkud3";
206
+ /** Stretch to the parent's width (wrapper, and the `Field` wrapper when there is one). */
207
+ var FILL_WIDTH_CSS = "gx-ColorInput-FILL_WIDTH_CSS-fhi9xkx";
208
+ /** The swatch and the code (or the placeholder). */
209
+ var ValueDisplay = /*#__PURE__*/ styled("span")({
210
+ name: "ValueDisplay",
211
+ class: "gx-ColorInput-ValueDisplay-v1ql0gs2",
83
212
  propsAsIs: false
84
213
  });
85
- var _exp11 = () => ({ $color }) => $color;
86
- var ColorInputPreviewSwatch = /*#__PURE__*/ styled("div")({
87
- name: "ColorInputPreviewSwatch",
88
- class: "c2h225c",
89
- propsAsIs: false,
90
- vars: { "c2h225c-0": [_exp11()] }
214
+ /** Gap between the swatch and the code per rung. */
215
+ var COLOR_INPUT_SIZE_TO_VALUE_CSS_MAP = {
216
+ ["X_SMALL"]: "gx-ColorInput-X_SMALL-x16qp03j",
217
+ ["SMALL"]: "gx-ColorInput-SMALL-sp370uh",
218
+ ["MEDIUM"]: "gx-ColorInput-MEDIUM-m1p7qx61",
219
+ ["LARGE"]: "gx-ColorInput-LARGE-lsi82l4",
220
+ ["X_LARGE"]: "gx-ColorInput-X_LARGE-x1i4cb4c"
221
+ };
222
+ /** A color chip; the color is the `--gx-color-input-swatch` custom property. */
223
+ var Swatch = /*#__PURE__*/ styled("span")({
224
+ name: "Swatch",
225
+ class: "gx-ColorInput-Swatch-s18gyim7",
226
+ propsAsIs: false
91
227
  });
92
- var _exp12 = () => ({ $isSelected }) => $isSelected ? "#ffffff" : "rgba(0, 0, 0, 0.15)";
93
- var _exp13 = () => ({ $color }) => $color;
94
- var ColorSwatch = /*#__PURE__*/ styled("button")({
95
- name: "ColorSwatch",
96
- class: "cnw6647",
97
- propsAsIs: false,
98
- vars: {
99
- "cnw6647-0": [_exp12()],
100
- "cnw6647-1": [_exp13()]
101
- }
228
+ /** The field swatch's size per rung (the icon px). */
229
+ var COLOR_INPUT_SIZE_TO_SWATCH_CSS_MAP = {
230
+ ["X_SMALL"]: "gx-ColorInput-X_SMALL-x985grc",
231
+ ["SMALL"]: "gx-ColorInput-SMALL-s19ylbz",
232
+ ["MEDIUM"]: "gx-ColorInput-MEDIUM-m1f25qfl",
233
+ ["LARGE"]: "gx-ColorInput-LARGE-lxtdcgy",
234
+ ["X_LARGE"]: "gx-ColorInput-X_LARGE-x3swctb"
235
+ };
236
+ /** The disabled field swatch: a disabled hairline, and no opacity, so the color stays true. */
237
+ var DISABLED_SWATCH_CSS = "gx-ColorInput-DISABLED_SWATCH_CSS-d11y75hr";
238
+ /** The hex row's preview swatch: 24px. */
239
+ var PREVIEW_SWATCH_CSS = "gx-ColorInput-PREVIEW_SWATCH_CSS-p1hod81r";
240
+ /** The caret and the clear button, laid over the field's end. */
241
+ var Trailing = /*#__PURE__*/ styled("span")({
242
+ name: "Trailing",
243
+ class: "gx-ColorInput-Trailing-t1nutfrb",
244
+ propsAsIs: false
102
245
  });
103
- var normalizeHex = (hex) => {
104
- let h = hex.trim().toLowerCase();
105
- if (!h.startsWith("#")) h = `#${h}`;
106
- if (h.length === 4) {
107
- const r = h[1], g = h[2], b = h[3];
108
- return `#${r}${r}${g}${g}${b}${b}`;
109
- }
110
- if (h.length !== 7) throw new Error(`Invalid hex color: "${hex}". Expected #RRGGBB or #RGB`);
111
- return h;
246
+ /** Trailing inset (the rung padding) and gap per rung. */
247
+ var COLOR_INPUT_SIZE_TO_TRAILING_CSS_MAP = {
248
+ ["X_SMALL"]: "gx-ColorInput-X_SMALL-x1fenl2i",
249
+ ["SMALL"]: "gx-ColorInput-SMALL-s1xswvsb",
250
+ ["MEDIUM"]: "gx-ColorInput-MEDIUM-m1n4tibk",
251
+ ["LARGE"]: "gx-ColorInput-LARGE-lnfo5di",
252
+ ["X_LARGE"]: "gx-ColorInput-X_LARGE-x1pa7cph"
112
253
  };
113
- var safeNormalizeHex = (hex) => {
114
- if (!hex) return null;
254
+ /** Wraps the clear button: the only part of `Trailing` that takes the pointer. */
255
+ var ClearSlot = /*#__PURE__*/ styled("span")({
256
+ name: "ClearSlot",
257
+ class: "gx-ColorInput-ClearSlot-c1l0qve6",
258
+ propsAsIs: false
259
+ });
260
+ /** Hidden clear button: keeps its width, leaves the tab order and the accessibility tree. */
261
+ var CLEAR_HIDDEN_CSS = "gx-ColorInput-CLEAR_HIDDEN_CSS-cjp6j9s";
262
+ /** The panel content: a 12px-inset column, 8px apart. */
263
+ var PanelBody = /*#__PURE__*/ styled("div")({
264
+ name: "PanelBody",
265
+ class: "gx-ColorInput-PanelBody-pne28cq",
266
+ propsAsIs: false
267
+ });
268
+ /**
269
+ * The saturation / brightness area's frame. The library sizes its element inline (200 × 200), so
270
+ * the frame stretches its one child (1.x's rule). The focused element is the library's inner
271
+ * `div` (inline `outline: none`), so FOCUS_RING's outline is drawn on the frame.
272
+ */
273
+ var SaturationFrame = /*#__PURE__*/ styled("div")({
274
+ name: "SaturationFrame",
275
+ class: "gx-ColorInput-SaturationFrame-supo66w",
276
+ propsAsIs: false
277
+ });
278
+ /** The hue slider's frame, with the same focus outline. */
279
+ var HueFrame = /*#__PURE__*/ styled("div")({
280
+ name: "HueFrame",
281
+ class: "gx-ColorInput-HueFrame-h1eh1bb8",
282
+ propsAsIs: false
283
+ });
284
+ /**
285
+ * The one pointer for both: a 12px ring (2px `background.base`, a 0.5px `text.primary` outline)
286
+ * that reads on any color and flips with the theme. Positions are custom properties.
287
+ */
288
+ var PointerRing = /*#__PURE__*/ styled("span")({
289
+ name: "PointerRing",
290
+ class: "gx-ColorInput-PointerRing-phnk6gl",
291
+ propsAsIs: false
292
+ });
293
+ /** The presets group: ten 24px swatches per row. */
294
+ var PresetGrid = /*#__PURE__*/ styled("div")({
295
+ name: "PresetGrid",
296
+ class: "gx-ColorInput-PresetGrid-p1nd6c19",
297
+ propsAsIs: false
298
+ });
299
+ /** One preset swatch. Declared before nothing composes onto it. */
300
+ var SwatchButton = /*#__PURE__*/ styled("button")({
301
+ name: "SwatchButton",
302
+ class: "gx-ColorInput-SwatchButton-s80qb26",
303
+ propsAsIs: false
304
+ });
305
+ /** The `pointer` render function for the area and the slider. */
306
+ function ColorPointer({ left, top }) {
307
+ const position = { "--gx-color-pointer-x": left === void 0 ? "0%" : String(left) };
308
+ if (top !== void 0) position["--gx-color-pointer-y"] = String(top);
309
+ return /* @__PURE__ */ jsx(PointerRing, {
310
+ "aria-hidden": true,
311
+ style: position
312
+ });
313
+ }
314
+ /** `#rgb` / `#rrggbb`, with or without `#` (what `hexToRgb` accepts, with real hex digits). */
315
+ var HEX_PATTERN = /^#?(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
316
+ /** Parses a value to lowercase `#rrggbb`, or `null` when it does not parse. */
317
+ function normalizeHex(value) {
318
+ if (value === null || value === void 0) return null;
319
+ if (!HEX_PATTERN.test(value.trim())) return null;
115
320
  try {
116
- return normalizeHex(hex);
321
+ return rgbToHex(hexToRgb(value));
117
322
  } catch {
118
323
  return null;
119
324
  }
120
- };
121
- /**
122
- * A hex color field with a picker popover. Fully controlled.
123
- *
124
- * `onPreviewChange` fires throughout the drag while `onChange` fires on commit —
125
- * drive a live preview from the first and persist from the second.
126
- */
127
- var ColorInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MEDIUM, value, placeholder = "Select color...", onChange, onPreviewChange, width, fillWidth = false, isDisabled = false, isRequired = false, error, pinnedHex = [], isOpen: controlledIsOpen, onOpenChange, children }) => {
128
- const [localState, setLocalState] = useState({
129
- isOpen: false,
130
- isHovered: false
325
+ }
326
+ /** The swatch custom property. */
327
+ function swatchStyle(hex) {
328
+ return { "--gx-color-input-swatch": hex };
329
+ }
330
+ /** The preset check mark's `hex` prop, when a contrasting color was resolved. */
331
+ function presetCheckColor(hex) {
332
+ return hex === void 0 ? {} : { hex };
333
+ }
334
+ /** The field (or the custom trigger), the trailing parts and the picker panel. */
335
+ function ColorInputFrame({ colorProps, forwardedRef, isRoot }) {
336
+ const { value, defaultValue = null, onChange, onPreviewChange, presets, size = "MEDIUM", variant = "PRIMARY", isGhost = false, label, placeholder = "Select color…", error, isError = false, isClearable = false, isDisabled = false, isReadOnly = false, isRequired = false, fillWidth = false, ariaLabel, isOpen, defaultIsOpen = false, onOpenChange, children, id, "aria-describedby": ariaDescribedBy, className, style, ...rest } = colorProps;
337
+ const { field, controlId, describedBy, isInvalid, isRequired: isRequiredState, hasName: hasOwnName } = useFieldWiring({
338
+ id,
339
+ ariaLabel,
340
+ ariaLabelAttribute: rest["aria-label"],
341
+ ariaLabelledBy: rest["aria-labelledby"],
342
+ ariaDescribedBy,
343
+ error,
344
+ isError,
345
+ isRequired
131
346
  });
132
- const isControlled = controlledIsOpen !== void 0;
133
- const isOpen = isControlled ? controlledIsOpen : localState.isOpen;
134
- const hsva = useMemo(() => {
135
- if (!value) return {
136
- h: 0,
137
- s: 0,
138
- v: 100,
139
- a: 1
140
- };
141
- try {
142
- const normalized = safeNormalizeHex(value);
143
- if (!normalized) return {
144
- h: 0,
145
- s: 0,
146
- v: 100,
147
- a: 1
148
- };
149
- return hexToHsva(normalized);
150
- } catch {
151
- return {
152
- h: 0,
153
- s: 0,
154
- v: 100,
155
- a: 1
156
- };
157
- }
158
- }, [value]);
159
- const [localHsva, setLocalHsva] = useState(hsva);
160
- const [prevHsva, setPrevHsva] = useState(hsva);
161
- if (hsva !== prevHsva) {
162
- setPrevHsva(hsva);
163
- setLocalHsva(hsva);
164
- }
165
- const handleToggle = useCallback(() => {
166
- if (isDisabled) return;
167
- const newIsOpen = !isOpen;
168
- if (!isControlled) setLocalState((prev) => ({
169
- ...prev,
170
- isOpen: newIsOpen
171
- }));
172
- if (onOpenChange) onOpenChange(newIsOpen);
173
- }, [
174
- isDisabled,
175
- isOpen,
176
- isControlled,
177
- onOpenChange
347
+ const panelId = `${controlId}-picker`;
348
+ const { theme } = useGalaxyTheme();
349
+ const triggerRef = useRef(null);
350
+ const mergedRef = useMergeRefs([
351
+ triggerRef,
352
+ forwardedRef,
353
+ children === void 0 ? void 0 : getElementRef(children)
178
354
  ]);
179
- const handleClose = useCallback(() => {
180
- const hex = hsvaToHex(localHsva);
181
- if (onChange) onChange(hex);
182
- if (!isControlled) setLocalState((prev) => ({
183
- ...prev,
184
- isOpen: false
185
- }));
186
- if (onOpenChange) onOpenChange(false);
187
- }, [
188
- isControlled,
189
- onOpenChange,
190
- localHsva,
355
+ const panelRef = useRef(null);
356
+ const wrapperRef = useRef(null);
357
+ const saturationFrameRef = useRef(null);
358
+ const isEditable = !isDisabled && !isReadOnly;
359
+ const isCustomTrigger = children !== void 0;
360
+ const [rawValue, setRawValue] = useControlledState({
361
+ value,
362
+ defaultValue,
191
363
  onChange
192
- ]);
193
- const handleMouseEnter = useCallback(() => {
194
- setLocalState((prev) => ({
195
- ...prev,
196
- isHovered: true
197
- }));
198
- }, []);
199
- const handleMouseLeave = useCallback(() => {
200
- setLocalState((prev) => ({
201
- ...prev,
202
- isHovered: false
203
- }));
204
- }, []);
364
+ });
365
+ const currentHex = normalizeHex(rawValue);
366
+ const invalidValue = rawValue !== null && currentHex === null ? rawValue : null;
367
+ const warnedRef = useRef(/* @__PURE__ */ new Set());
368
+ useEffect(() => {
369
+ if (invalidValue === null || !isDevelopment() || warnedRef.current.has(invalidValue)) return;
370
+ warnedRef.current.add(invalidValue);
371
+ console.warn(`[@galaxy-io/dls] ColorInput value "${invalidValue}" is not a #rgb / #rrggbb color; it is treated as null.`);
372
+ }, [invalidValue]);
373
+ useDevWarning(isCustomTrigger && (label !== void 0 || error !== void 0), "[@galaxy-io/dls] ColorInput with a custom trigger (`children`) ignores `label` and `error`. Wrap it in a `Field` and pass `ariaLabel`.");
205
374
  useEffect(() => {
206
- if (onPreviewChange && isOpen) onPreviewChange(hsvaToHex(localHsva));
207
- }, [
208
- localHsva,
375
+ if (!isCustomTrigger || !isDevelopment()) return;
376
+ const element = triggerRef.current;
377
+ if (element !== null && element.tabIndex < 0 && !element.matches("button, a[href], input")) console.warn("[@galaxy-io/dls] ColorInput's custom trigger is not focusable. Pass a focusable element that forwards its ref, such as a Button.");
378
+ }, [isCustomTrigger]);
379
+ const { isOpen: isOpenState, setOpen: setOpenState } = useControlledOpenState({
209
380
  isOpen,
210
- onPreviewChange
211
- ]);
212
- const handleSaturationChange = useCallback((hsva) => {
213
- setLocalHsva(hsva);
214
- }, []);
215
- const handleHueChange = useCallback((newHue) => {
216
- setLocalHsva((prev) => ({
217
- ...prev,
218
- h: newHue.h
219
- }));
220
- }, []);
221
- const handleColorSelect = useCallback((hex) => {
222
- const normalized = safeNormalizeHex(hex);
223
- if (normalized && onChange) {
224
- onChange(normalized);
225
- if (!isControlled) setLocalState((prev) => ({
226
- ...prev,
227
- isOpen: false
228
- }));
229
- if (onOpenChange) onOpenChange(false);
230
- }
231
- }, [
232
- onChange,
233
- isControlled,
381
+ defaultIsOpen,
234
382
  onOpenChange
235
- ]);
236
- const textVariant = useMemo(() => {
237
- if (value) return TextVariant.PRIMARY;
238
- if (isOpen || localState.isHovered) return TextVariant.SECONDARY;
239
- return TextVariant.TERTIARY;
240
- }, [
241
- value,
242
- isOpen,
243
- localState.isHovered
244
- ]);
245
- const displayValue = useMemo(() => {
246
- if (value) {
247
- const normalized = safeNormalizeHex(value);
248
- if (normalized) return normalized.toUpperCase();
249
- return value;
383
+ });
384
+ const isShown = isOpenState && isEditable;
385
+ const { setOpen, isShownRef } = useDedupedOpen(isShown, setOpenState);
386
+ const [local, setLocalState] = useState(() => currentHex === null ? WHITE_HSVA : hexToHsva(currentHex));
387
+ const localRef = useRef(local);
388
+ localRef.current = local;
389
+ const localHex = hsvaToHex(local);
390
+ const isDirtyRef = useRef(false);
391
+ const lastCommittedRef = useRef(currentHex);
392
+ const [seenValue, setSeenValue] = useState(currentHex);
393
+ const [lastShown, setLastShown] = useState(isShown);
394
+ const shouldFocusRef = useRef(false);
395
+ if (seenValue !== currentHex || lastShown !== isShown) {
396
+ const isOpening = lastShown !== isShown && isShown;
397
+ const isExternal = seenValue !== currentHex && currentHex !== lastCommittedRef.current;
398
+ setSeenValue(currentHex);
399
+ setLastShown(isShown);
400
+ if (isOpening || isExternal) {
401
+ setLocalState(currentHex === null ? WHITE_HSVA : hexToHsva(currentHex));
402
+ isDirtyRef.current = false;
403
+ lastCommittedRef.current = currentHex;
250
404
  }
251
- return placeholder;
252
- }, [value, placeholder]);
253
- const normalizedPinnedHex = useMemo(() => pinnedHex.map((hex) => safeNormalizeHex(hex)).filter((hex) => Boolean(hex)), [pinnedHex]);
254
- const hasPinnedColors = normalizedPinnedHex.length > 0;
255
- const pinnedColorColumns = Math.min(12, normalizedPinnedHex.length);
256
- const colorPickerBody = /* @__PURE__ */ jsxs(ColorPickerContainer, {
257
- $hasPinnedColors: hasPinnedColors,
258
- onClick: (e) => e.stopPropagation(),
259
- children: [
260
- /* @__PURE__ */ jsx(StyledSaturation, { children: /* @__PURE__ */ jsx(Saturation, {
261
- hsva: localHsva,
262
- onChange: handleSaturationChange
263
- }) }),
264
- /* @__PURE__ */ jsx(StyledHue, { children: /* @__PURE__ */ jsx(Hue, {
265
- hue: localHsva.h,
266
- onChange: handleHueChange,
267
- pointer: HuePointer
268
- }) }),
269
- hasPinnedColors && /* @__PURE__ */ jsx(GridWrapper, {
270
- columns: `repeat(${pinnedColorColumns}, 24px)`,
271
- gap: 4,
272
- children: normalizedPinnedHex.map((normalized, index) => /* @__PURE__ */ jsx(ColorSwatch, {
273
- $color: normalized,
274
- $isSelected: value === normalized,
275
- onClick: () => handleColorSelect(normalized)
276
- }, `pinned-${index}-${normalized}`))
277
- })
278
- ]
405
+ if (isOpening) shouldFocusRef.current = true;
406
+ }
407
+ /** Commits a color: `onChange` only when it differs from the current value. */
408
+ const commit = (hex) => {
409
+ isDirtyRef.current = false;
410
+ lastCommittedRef.current = hex;
411
+ if (hex !== currentHex) setRawValue(hex);
412
+ };
413
+ /** A local change: preview always; commit unless a drag is in progress. */
414
+ const isDraggingRef = useRef(false);
415
+ const changeLocal = (next, shouldCommit) => {
416
+ setLocalState(next);
417
+ localRef.current = next;
418
+ const hex = hsvaToHex(next);
419
+ onPreviewChange?.(hex);
420
+ if (shouldCommit) commit(hex);
421
+ else isDirtyRef.current = true;
422
+ };
423
+ const commitRef = useRef(commit);
424
+ commitRef.current = commit;
425
+ const dragFinishRef = useRef(null);
426
+ const handleDragStart = () => {
427
+ if (isDraggingRef.current) return;
428
+ isDraggingRef.current = true;
429
+ const finish = () => {
430
+ isDraggingRef.current = false;
431
+ dragFinishRef.current = null;
432
+ window.removeEventListener("pointerup", finish);
433
+ window.removeEventListener("pointercancel", finish);
434
+ commitRef.current(hsvaToHex(localRef.current));
435
+ };
436
+ dragFinishRef.current = finish;
437
+ window.addEventListener("pointerup", finish);
438
+ window.addEventListener("pointercancel", finish);
439
+ };
440
+ useEffect(() => () => {
441
+ const finish = dragFinishRef.current;
442
+ if (finish === null) return;
443
+ window.removeEventListener("pointerup", finish);
444
+ window.removeEventListener("pointercancel", finish);
445
+ }, []);
446
+ const wasShownRef = useRef(isShown);
447
+ useEffect(() => {
448
+ if (wasShownRef.current && !isShown && isDirtyRef.current) commitRef.current(hsvaToHex(localRef.current));
449
+ wasShownRef.current = isShown;
450
+ }, [isShown]);
451
+ useRetriedFocus(shouldFocusRef, isShown, () => saturationFrameRef.current?.querySelector("[role=\"slider\"]") ?? null, COLOR_INPUT_FOCUS_RETRY_FRAMES);
452
+ const [draft, setDraft] = useState(localHex.slice(1).toUpperCase());
453
+ const [draftSource, setDraftSource] = useState(localHex);
454
+ if (draftSource !== localHex) {
455
+ setDraftSource(localHex);
456
+ setDraft(localHex.slice(1).toUpperCase());
457
+ }
458
+ const parseDraft = (text) => normalizeHex(text.trim());
459
+ const commitDraft = (isBlur) => {
460
+ const hex = parseDraft(draft);
461
+ if (hex === null) {
462
+ if (isBlur) setDraft(localHex.slice(1).toUpperCase());
463
+ return;
464
+ }
465
+ changeLocal(hexToHsva(hex), true);
466
+ setDraft(hex.slice(1).toUpperCase());
467
+ };
468
+ const close = () => setOpen(false);
469
+ useRestoreFocusAfterOutsidePress({
470
+ isShown,
471
+ focusRef: triggerRef,
472
+ insideRefs: [
473
+ wrapperRef,
474
+ triggerRef,
475
+ panelRef
476
+ ],
477
+ focusScopeRefs: [panelRef]
279
478
  });
280
- return /* @__PURE__ */ jsxs(FlexWrapper, {
281
- direction: FlexDirection.COLUMN,
282
- gap: 4,
283
- fillWidth,
284
- children: [
285
- label && /* @__PURE__ */ jsx(InputLabel, {
286
- label,
287
- isRequired
288
- }),
289
- /* @__PURE__ */ jsx(Dropdown, {
290
- variant: DropdownVariant.PRIMARY,
291
- body: colorPickerBody,
292
- isOpen,
293
- onClose: handleClose,
294
- noPadding: true,
295
- fillWidth,
296
- children: children ? /* @__PURE__ */ jsx(ColorInputTriggerWrapper, {
297
- onClick: (e) => {
298
- e.stopPropagation();
299
- handleToggle();
300
- },
301
- onKeyDown: (e) => {
302
- if (e.key === "Enter" || e.key === " ") {
303
- e.preventDefault();
304
- handleToggle();
479
+ const clear = () => {
480
+ isDirtyRef.current = false;
481
+ lastCommittedRef.current = null;
482
+ setRawValue(null);
483
+ if (isShown) close();
484
+ triggerRef.current?.focus();
485
+ };
486
+ const validPresets = [];
487
+ for (const preset of presets ?? []) {
488
+ const hex = normalizeHex(preset);
489
+ if (hex !== null && !validPresets.includes(hex)) validPresets.push(hex);
490
+ }
491
+ const selectedPresetIndex = currentHex === null ? -1 : validPresets.indexOf(currentHex);
492
+ const [focusedPreset, setFocusedPreset] = useState(-1);
493
+ const rovingIndex = focusedPreset >= 0 && focusedPreset < validPresets.length ? focusedPreset : Math.max(selectedPresetIndex, 0);
494
+ const presetRefs = useRef([]);
495
+ const handlePresetKeyDown = (event) => {
496
+ const target = {
497
+ ArrowRight: rovingIndex + 1,
498
+ ArrowLeft: rovingIndex - 1,
499
+ ArrowDown: rovingIndex + PRESET_COLUMNS,
500
+ ArrowUp: rovingIndex - PRESET_COLUMNS,
501
+ Home: 0,
502
+ End: validPresets.length - 1
503
+ }[event.key];
504
+ if (target === void 0) return;
505
+ event.preventDefault();
506
+ const next = Math.max(0, Math.min(validPresets.length - 1, target));
507
+ setFocusedPreset(next);
508
+ presetRefs.current[next]?.focus();
509
+ };
510
+ const choosePreset = (hex) => {
511
+ changeLocal(hexToHsva(hex), true);
512
+ close();
513
+ };
514
+ /**
515
+ * The check mark's color on a swatch: the theme's resolved `text.primary` or `background.base`,
516
+ * whichever contrasts more with the swatch (passed as the Icon's `hex`; the swatch is an arbitrary
517
+ * color, so no single token reads on all of them). `undefined` falls back to `IconVariant.PRIMARY`.
518
+ */
519
+ const checkHex = (hex) => {
520
+ const primary = normalizeHex(theme.color.text.primary);
521
+ const base = normalizeHex(theme.color.background.base);
522
+ if (primary === null || base === null) return void 0;
523
+ return contrastRatio(primary, hex) >= contrastRatio(base, hex) ? primary : base;
524
+ };
525
+ /** Focus leaving both the trigger and the panel for another element closes the panel. */
526
+ const handleFocusOut = (event) => {
527
+ if (!isShownRef.current) return;
528
+ const next = event.relatedTarget;
529
+ if (next === null) return;
530
+ if (panelRef.current?.contains(next) || triggerRef.current?.contains(next)) return;
531
+ close();
532
+ };
533
+ /** Open keys on the field or the custom trigger. */
534
+ const handleTriggerKeyDown = (event) => {
535
+ if (event.defaultPrevented || !isEditable || isShown) return;
536
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
537
+ event.preventDefault();
538
+ setOpen(true);
539
+ }
540
+ };
541
+ const handleTriggerClick = (event) => {
542
+ if (event.defaultPrevented || !isEditable) return;
543
+ setOpen(!isShown);
544
+ };
545
+ useDevWarning(!isCustomTrigger && !hasOwnName, "[@galaxy-io/dls] ColorInput has no accessible name. Pass `label`, wrap it in a labelled `Field`, or set `ariaLabel`. `placeholder` is not a name.");
546
+ const body = /* @__PURE__ */ jsx(FieldContext.Provider, {
547
+ value: null,
548
+ children: /* @__PURE__ */ jsxs(PanelBody, {
549
+ onBlur: handleFocusOut,
550
+ children: [
551
+ /* @__PURE__ */ jsx(SaturationFrame, {
552
+ ref: saturationFrameRef,
553
+ onPointerDownCapture: handleDragStart,
554
+ children: /* @__PURE__ */ jsx(Saturation, {
555
+ hsva: local,
556
+ onChange: (next) => changeLocal({
557
+ ...next,
558
+ a: 1
559
+ }, !isDraggingRef.current),
560
+ pointer: ColorPointer,
561
+ role: "slider",
562
+ "aria-label": "Saturation and brightness",
563
+ "aria-valuemin": 0,
564
+ "aria-valuemax": 100,
565
+ "aria-valuenow": Math.round(local.s),
566
+ "aria-valuetext": `Saturation ${Math.round(local.s)}%, brightness ${Math.round(local.v)}%`
567
+ })
568
+ }),
569
+ /* @__PURE__ */ jsx(HueFrame, {
570
+ onPointerDownCapture: handleDragStart,
571
+ children: /* @__PURE__ */ jsx(Hue, {
572
+ hue: local.h,
573
+ onChange: (next) => changeLocal({
574
+ ...localRef.current,
575
+ h: next.h
576
+ }, !isDraggingRef.current),
577
+ pointer: ColorPointer,
578
+ width: "100%",
579
+ height: "100%",
580
+ radius: 0,
581
+ innerProps: {
582
+ role: "slider",
583
+ "aria-label": "Hue",
584
+ "aria-valuemin": 0,
585
+ "aria-valuemax": 360,
586
+ "aria-valuenow": Math.round(local.h),
587
+ "aria-valuetext": `${Math.round(local.h)} degrees`
305
588
  }
306
- },
307
- onMouseEnter: handleMouseEnter,
308
- onMouseLeave: handleMouseLeave,
309
- role: "button",
310
- tabIndex: isDisabled ? -1 : 0,
311
- "aria-haspopup": "dialog",
312
- "aria-expanded": isOpen,
313
- children
314
- }) : /* @__PURE__ */ jsxs(StyledColorInput, {
315
- $size: size,
316
- $variant: variant,
317
- $isActive: isOpen,
318
- $isDisabled: isDisabled,
319
- $isError: !!error,
320
- $width: width,
321
- $fillWidth: fillWidth,
322
- onClick: handleToggle,
323
- onMouseEnter: handleMouseEnter,
324
- onMouseLeave: handleMouseLeave,
325
- role: "button",
326
- tabIndex: isDisabled ? -1 : 0,
327
- "aria-haspopup": "dialog",
328
- "aria-expanded": isOpen,
329
- "aria-label": value ? displayValue : placeholder,
330
- children: [
331
- /* @__PURE__ */ jsxs(FlexWrapper, {
332
- alignItems: AlignItems.CENTER,
333
- gap: 8,
334
- children: [value && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ColorInputPreviewSwatch, { $color: value }), /* @__PURE__ */ jsx(Spacing, { left: 4 })] }), /* @__PURE__ */ jsx(Text, {
335
- variant: textVariant,
336
- size: getInputTextSize(size),
337
- isEllipsis: true,
338
- cursor: !isDisabled ? "pointer" : "not-allowed",
339
- children: displayValue
340
- })]
341
- }),
342
- /* @__PURE__ */ jsx(Spacing, { left: 8 }),
343
- /* @__PURE__ */ jsx(Icon, {
344
- component: CaretDownIcon,
345
- size: getInputIconSize(size),
346
- variant: isOpen || localState.isHovered ? IconVariant.SECONDARY : IconVariant.TERTIARY
347
- })
348
- ]
589
+ })
590
+ }),
591
+ /* @__PURE__ */ jsxs(Flex, {
592
+ alignItems: AlignItems.CENTER,
593
+ gap: 8,
594
+ children: [/* @__PURE__ */ jsx(Swatch, {
595
+ "aria-hidden": true,
596
+ className: PREVIEW_SWATCH_CSS,
597
+ style: swatchStyle(localHex)
598
+ }), /* @__PURE__ */ jsx(TextInput, {
599
+ size: InputSize.SMALL,
600
+ variant: InputVariant.SECONDARY,
601
+ family: FontFamily.MONO,
602
+ prefix: "#",
603
+ maxLength: 7,
604
+ ariaLabel: "Hex color",
605
+ fillWidth: true,
606
+ spellCheck: false,
607
+ value: draft,
608
+ onChange: setDraft,
609
+ onEnter: () => commitDraft(false),
610
+ onBlur: () => commitDraft(true)
611
+ })]
612
+ }),
613
+ validPresets.length > 0 && /* @__PURE__ */ jsx(PresetGrid, {
614
+ role: "group",
615
+ "aria-label": "Presets",
616
+ onKeyDown: handlePresetKeyDown,
617
+ children: validPresets.map((hex, index) => {
618
+ const isSelected = hex === currentHex;
619
+ return /* @__PURE__ */ jsx(SwatchButton, {
620
+ ref: (node) => {
621
+ presetRefs.current[index] = node;
622
+ },
623
+ type: "button",
624
+ "aria-label": hex.toUpperCase(),
625
+ "aria-pressed": isSelected,
626
+ tabIndex: index === rovingIndex ? 0 : -1,
627
+ onFocus: () => setFocusedPreset(index),
628
+ onClick: () => choosePreset(hex),
629
+ style: swatchStyle(hex),
630
+ children: isSelected && /* @__PURE__ */ jsx(Icon, {
631
+ component: CheckIcon,
632
+ size: PRESET_CHECK_PX,
633
+ variant: IconVariant.PRIMARY,
634
+ ...presetCheckColor(checkHex(hex)),
635
+ "aria-hidden": true
636
+ })
637
+ }, hex);
638
+ })
639
+ })
640
+ ]
641
+ })
642
+ });
643
+ const popoverProps = {
644
+ ref: panelRef,
645
+ trigger: PopoverTrigger.MANUAL,
646
+ role: PopoverRole.DIALOG,
647
+ variant: isGhost ? PopoverVariant.BASE : COLOR_INPUT_VARIANT_TO_POPOVER_VARIANT_MAP[variant],
648
+ isOpen: isShown,
649
+ onOpenChange: setOpen,
650
+ isDisabled: !isEditable,
651
+ id: panelId,
652
+ ariaLabel: "Choose color",
653
+ body
654
+ };
655
+ if (isCustomTrigger) {
656
+ const childProps = children.props;
657
+ const compose = (own, mine) => (event) => {
658
+ if (typeof own === "function") own(event);
659
+ mine(event);
660
+ };
661
+ const hasOwnName = childProps["aria-label"] !== void 0 || childProps["aria-labelledby"] !== void 0 || childProps.ariaLabel !== void 0;
662
+ const trigger = cloneElement(children, {
663
+ ...rest,
664
+ ref: mergedRef,
665
+ id: controlId,
666
+ ...hasOwnName || ariaLabel === void 0 ? {} : { "aria-label": ariaLabel },
667
+ ...describedBy === void 0 ? {} : { "aria-describedby": describedBy },
668
+ onClick: compose(childProps.onClick, handleTriggerClick),
669
+ onKeyDown: compose(childProps.onKeyDown, handleTriggerKeyDown),
670
+ onBlur: compose(childProps.onBlur, handleFocusOut)
671
+ });
672
+ return /* @__PURE__ */ jsx(Popover, {
673
+ ...popoverProps,
674
+ children: trigger
675
+ });
676
+ }
677
+ const textSize = COLOR_INPUT_SIZE_TO_TEXT_SIZE_MAP[size];
678
+ const caretPx = COLOR_INPUT_SIZE_TO_CARET_PX_MAP[size];
679
+ const isClearHidden = currentHex === null || !isEditable;
680
+ return /* @__PURE__ */ jsxs(Wrapper, {
681
+ ref: wrapperRef,
682
+ className: cx(fillWidth && FILL_WIDTH_CSS, isRoot ? className : void 0),
683
+ ...rootStyle(isRoot, style),
684
+ children: [/* @__PURE__ */ jsx(Popover, {
685
+ ...popoverProps,
686
+ children: /* @__PURE__ */ jsx(Control, {
687
+ ref: mergedRef,
688
+ id: controlId,
689
+ role: "combobox",
690
+ tabIndex: isDisabled ? -1 : 0,
691
+ "aria-labelledby": field?.labelId,
692
+ "aria-label": ariaLabel,
693
+ "aria-describedby": describedBy,
694
+ "aria-invalid": isInvalid ? true : void 0,
695
+ "aria-required": isRequiredState ? true : void 0,
696
+ "aria-readonly": isReadOnly ? true : void 0,
697
+ "aria-disabled": isDisabled ? true : void 0,
698
+ onKeyDown: handleTriggerKeyDown,
699
+ onClick: handleTriggerClick,
700
+ onBlur: handleFocusOut,
701
+ ...rest,
702
+ className: cx(isGhost ? GHOST_CSS : COLOR_INPUT_VARIANT_TO_CSS_MAP[variant], COLOR_INPUT_SIZE_TO_CSS_MAP[size], isClearable && COLOR_INPUT_SIZE_TO_CLEARABLE_CSS_MAP[size], isEditable && !isInvalid && (isGhost ? GHOST_HOVER_CSS : COLOR_INPUT_VARIANT_TO_HOVER_CSS_MAP[variant]), !isDisabled && FOCUS_CSS, isShown && OPEN_CSS, isInvalid && !isDisabled && ERROR_CSS, isDisabled && DISABLED_CSS, isReadOnly && READ_ONLY_CSS),
703
+ children: /* @__PURE__ */ jsx(ValueDisplay, {
704
+ className: COLOR_INPUT_SIZE_TO_VALUE_CSS_MAP[size],
705
+ children: currentHex === null ? /* @__PURE__ */ jsx(Text, {
706
+ as: "span",
707
+ size: textSize,
708
+ variant: isDisabled ? TextVariant.DISABLED : TextVariant.TERTIARY,
709
+ lineClamp: 1,
710
+ children: placeholder
711
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Swatch, {
712
+ "aria-hidden": true,
713
+ className: cx(COLOR_INPUT_SIZE_TO_SWATCH_CSS_MAP[size], isDisabled && DISABLED_SWATCH_CSS),
714
+ style: swatchStyle(currentHex)
715
+ }), /* @__PURE__ */ jsx(Text, {
716
+ as: "span",
717
+ size: textSize,
718
+ family: FontFamily.MONO,
719
+ variant: isDisabled ? TextVariant.DISABLED : TextVariant.PRIMARY,
720
+ transform: TextTransform.UPPERCASE,
721
+ lineClamp: 1,
722
+ children: currentHex
723
+ })] })
349
724
  })
350
- }),
351
- error && /* @__PURE__ */ jsx(Text, {
352
- variant: TextVariant.ERROR,
353
- size: TextSize.BODY_SM,
354
- children: error
355
725
  })
356
- ]
726
+ }), /* @__PURE__ */ jsxs(Trailing, {
727
+ className: COLOR_INPUT_SIZE_TO_TRAILING_CSS_MAP[size],
728
+ children: [isClearable && /* @__PURE__ */ jsx(ClearSlot, {
729
+ className: cx(isClearHidden && CLEAR_HIDDEN_CSS),
730
+ children: /* @__PURE__ */ jsx(Button, {
731
+ variant: ButtonVariant.TERTIARY,
732
+ size: COLOR_INPUT_SIZE_TO_BUTTON_SIZE_MAP[size],
733
+ icon: XIcon,
734
+ ariaLabel: "Clear",
735
+ onClick: clear,
736
+ className: cx(size === "X_SMALL" && "gx-innerButton-X_SMALL_INNER_BUTTON_CSS-x1ep0pcd")
737
+ })
738
+ }), /* @__PURE__ */ jsx(Rotate, {
739
+ isRotated: isShown,
740
+ "aria-hidden": true,
741
+ children: /* @__PURE__ */ jsx(Icon, {
742
+ component: CaretDownIcon,
743
+ size: caretPx,
744
+ variant: isDisabled ? IconVariant.DISABLED : IconVariant.SECONDARY
745
+ })
746
+ })]
747
+ })]
357
748
  });
358
- };
749
+ }
750
+ /** Choose one solid color as a hex value, in a field (or a custom trigger) that opens a picker. */
751
+ var ColorInput = forwardRef(function ColorInput(props, ref) {
752
+ const { label, error, isRequired = false, size = "MEDIUM", fillWidth = false, children } = props;
753
+ const { id, className, style } = props;
754
+ const ownField = useOwnField({
755
+ componentName: "ColorInput",
756
+ label,
757
+ error,
758
+ isRequired,
759
+ size: COLOR_INPUT_SIZE_TO_FIELD_SIZE_MAP[size],
760
+ id,
761
+ className,
762
+ style,
763
+ rootClassName: fillWidth && FILL_WIDTH_CSS,
764
+ isEnabled: children === void 0
765
+ });
766
+ if (ownField !== null) return /* @__PURE__ */ jsx(Field, {
767
+ ...ownField,
768
+ children: /* @__PURE__ */ jsx(ColorInputFrame, {
769
+ colorProps: props,
770
+ forwardedRef: ref,
771
+ isRoot: false
772
+ })
773
+ });
774
+ return /* @__PURE__ */ jsx(ColorInputFrame, {
775
+ colorProps: props,
776
+ forwardedRef: ref,
777
+ isRoot: true
778
+ });
779
+ });
780
+ ColorInput.displayName = "ColorInput";
359
781
  //#endregion
360
- export { ColorInput as default };
782
+ export { ColorInputSize, ColorInputVariant, ColorInput as default };