@cube-dev/ui-kit 0.0.0-canary-7464463 → 0.0.0-canary-a5d43c3

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 (552) hide show
  1. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  2. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  3. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  4. package/dist/_internal/hooks/use-event.js +1 -1
  5. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  6. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  7. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  8. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  9. package/dist/_internal/hooks/use-warn.js +1 -1
  10. package/dist/components/Block.js +1 -1
  11. package/dist/components/CollectionItem.js +1 -1
  12. package/dist/components/GlobalStyles.js +1 -1
  13. package/dist/components/GridProvider.js +1 -1
  14. package/dist/components/HiddenInput.js +1 -1
  15. package/dist/components/Root.js +1 -1
  16. package/dist/components/actions/Action/Action.js +1 -1
  17. package/dist/components/actions/Banner/Banner.js +1 -1
  18. package/dist/components/actions/Button/Button.js +1 -1
  19. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  20. package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
  21. package/dist/components/actions/ButtonSplit/context.js +1 -1
  22. package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
  23. package/dist/components/actions/CommandMenu/styled.js +1 -1
  24. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  25. package/dist/components/actions/ItemActionContext.js +1 -1
  26. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  27. package/dist/components/actions/Link/Link.js +1 -1
  28. package/dist/components/actions/Menu/Menu.js +1 -1
  29. package/dist/components/actions/Menu/MenuItem.js +1 -1
  30. package/dist/components/actions/Menu/MenuSection.js +1 -1
  31. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  32. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  33. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  34. package/dist/components/actions/Menu/context.js +1 -1
  35. package/dist/components/actions/Menu/styled.js +1 -1
  36. package/dist/components/actions/index.js +1 -1
  37. package/dist/components/actions/use-action.js +1 -1
  38. package/dist/components/actions/use-anchored-menu.js +1 -1
  39. package/dist/components/actions/use-context-menu.js +1 -1
  40. package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
  41. package/dist/components/content/Alert/Alert.js +1 -1
  42. package/dist/components/content/Alert/use-alert.js +1 -1
  43. package/dist/components/content/Avatar/Avatar.js +1 -1
  44. package/dist/components/content/Badge/Badge.js +1 -1
  45. package/dist/components/content/Card/Card.js +1 -1
  46. package/dist/components/content/Content.js +1 -1
  47. package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  48. package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
  49. package/dist/components/content/Disclosure/Disclosure.js +1 -1
  50. package/dist/components/content/Divider.js +1 -1
  51. package/dist/components/content/Footer.js +1 -1
  52. package/dist/components/content/Header.js +1 -1
  53. package/dist/components/content/HotKeys/HotKeys.js +1 -1
  54. package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
  55. package/dist/components/content/InlineInput/InlineInput.js +1 -1
  56. package/dist/components/content/Item/Item.js +1 -1
  57. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  58. package/dist/components/content/ItemCard/ItemCard.js +1 -1
  59. package/dist/components/content/Layout/GridLayout.js +1 -1
  60. package/dist/components/content/Layout/Layout.js +1 -1
  61. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  62. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  63. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  64. package/dist/components/content/Layout/LayoutContent.js +1 -1
  65. package/dist/components/content/Layout/LayoutContext.js +1 -1
  66. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  67. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  68. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  69. package/dist/components/content/Layout/LayoutHeader.js +1 -1
  70. package/dist/components/content/Layout/LayoutPane.js +1 -1
  71. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  72. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  73. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  74. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  75. package/dist/components/content/Layout/index.js +1 -1
  76. package/dist/components/content/Layout/utils.js +1 -1
  77. package/dist/components/content/Paragraph.js +1 -1
  78. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  79. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  80. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  81. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  82. package/dist/components/content/Result/Result.js +1 -1
  83. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  84. package/dist/components/content/Tag/Tag.js +1 -1
  85. package/dist/components/content/Text.js +1 -1
  86. package/dist/components/content/TextItem/TextItem.js +1 -1
  87. package/dist/components/content/Title.js +1 -1
  88. package/dist/components/content/Tree/Tree.js +1 -1
  89. package/dist/components/content/Tree/TreeNode.js +1 -1
  90. package/dist/components/content/Tree/styled.js +1 -1
  91. package/dist/components/content/Tree/tree-index.js +1 -1
  92. package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
  93. package/dist/components/content/Tree/use-load-data.js +1 -1
  94. package/dist/components/content/highlightText.js +1 -1
  95. package/dist/components/content/use-auto-tooltip.js +1 -1
  96. package/dist/components/data/DataTable/DataTable.js +73 -22
  97. package/dist/components/data/DataTable/DataTable.js.map +1 -1
  98. package/dist/components/data/DataTable/types.d.ts +56 -1
  99. package/dist/components/data/ItemTable/ItemTable.js +8 -3
  100. package/dist/components/data/ItemTable/ItemTable.js.map +1 -1
  101. package/dist/components/data/ItemTable/ItemTableBulkBar.js +1 -1
  102. package/dist/components/data/ItemTable/ItemTableDragPreview.js +1 -1
  103. package/dist/components/data/ItemTable/ItemTableFooter.js +1 -1
  104. package/dist/components/data/ItemTable/ItemTableToolbar.js +1 -1
  105. package/dist/components/data/ItemTable/types.d.ts +19 -0
  106. package/dist/components/data/TableBase/ColumnResizer.js +1 -1
  107. package/dist/components/data/TableBase/RowCollection.js +5 -3
  108. package/dist/components/data/TableBase/RowCollection.js.map +1 -1
  109. package/dist/components/data/TableBase/TableHeaderCell.js +115 -0
  110. package/dist/components/data/TableBase/TableHeaderCell.js.map +1 -0
  111. package/dist/components/data/TableBase/TableRow.js +1 -1
  112. package/dist/components/data/TableBase/TableView.js +192 -31
  113. package/dist/components/data/TableBase/TableView.js.map +1 -1
  114. package/dist/components/data/TableBase/column-menu.d.ts +36 -0
  115. package/dist/components/data/TableBase/column-menu.js +104 -0
  116. package/dist/components/data/TableBase/column-menu.js.map +1 -0
  117. package/dist/components/data/TableBase/column-tint.js +168 -0
  118. package/dist/components/data/TableBase/column-tint.js.map +1 -0
  119. package/dist/components/data/TableBase/index.d.ts +3 -2
  120. package/dist/components/data/TableBase/row-menu.js +11 -6
  121. package/dist/components/data/TableBase/row-menu.js.map +1 -1
  122. package/dist/components/data/TableBase/styled.js +36 -8
  123. package/dist/components/data/TableBase/styled.js.map +1 -1
  124. package/dist/components/data/TableBase/types.d.ts +94 -5
  125. package/dist/components/data/TableBase/types.js +1 -1
  126. package/dist/components/data/TableBase/types.js.map +1 -1
  127. package/dist/components/data/TableBase/use-cell-selection.js +0 -0
  128. package/dist/components/data/TableBase/use-column-order.js +100 -0
  129. package/dist/components/data/TableBase/use-column-order.js.map +1 -0
  130. package/dist/components/data/TableBase/use-container-width.js +1 -1
  131. package/dist/components/data/TableBase/use-row-move-animation.js +1 -1
  132. package/dist/components/data/TableBase/use-scrollability.js +1 -1
  133. package/dist/components/data/TableBase/use-table-columns.js +1 -1
  134. package/dist/components/data/TableBase/use-table-search.js +1 -1
  135. package/dist/components/data/TableBase/use-table-selection.js +1 -1
  136. package/dist/components/data/TableBase/use-table-sort.js +20 -1
  137. package/dist/components/data/TableBase/use-table-sort.js.map +1 -1
  138. package/dist/components/data/TableBase/use-table-sorts.js +40 -1
  139. package/dist/components/data/TableBase/use-table-sorts.js.map +1 -1
  140. package/dist/components/data/TableBase/use-table-storage.d.ts +1 -1
  141. package/dist/components/data/TableBase/use-table-storage.js +6 -2
  142. package/dist/components/data/TableBase/use-table-storage.js.map +1 -1
  143. package/dist/components/data/index.d.ts +2 -1
  144. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  145. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  146. package/dist/components/fields/Checkbox/context.js +1 -1
  147. package/dist/components/fields/ColorInput/ColorInput.js +1 -1
  148. package/dist/components/fields/ColorPicker/ColorPicker.js +1 -1
  149. package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +1 -1
  150. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  151. package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
  152. package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
  153. package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
  154. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  155. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  156. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  157. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  158. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  159. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  160. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  161. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  162. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  163. package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
  164. package/dist/components/fields/DatePicker/PeriodPicker.js +1 -1
  165. package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
  166. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  167. package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
  168. package/dist/components/fields/DatePicker/YearPicker.js +1 -1
  169. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  170. package/dist/components/fields/DatePicker/period.js +1 -1
  171. package/dist/components/fields/DatePicker/props.js +1 -1
  172. package/dist/components/fields/DatePicker/utils.js +1 -1
  173. package/dist/components/fields/FileInput/FileInput.js +1 -1
  174. package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
  175. package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
  176. package/dist/components/fields/Input/Input.js +1 -1
  177. package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
  178. package/dist/components/fields/ListBox/ListBox.js +1 -1
  179. package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
  180. package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
  181. package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
  182. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  183. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  184. package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
  185. package/dist/components/fields/Picker/Picker.js +1 -1
  186. package/dist/components/fields/RadioGroup/Radio.js +1 -1
  187. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  188. package/dist/components/fields/RadioGroup/context.js +1 -1
  189. package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
  190. package/dist/components/fields/SearchInput/SearchInput.js +1 -1
  191. package/dist/components/fields/Select/Select.js +1 -1
  192. package/dist/components/fields/Slider/Gradation.js +1 -1
  193. package/dist/components/fields/Slider/HueSlider.js +1 -1
  194. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  195. package/dist/components/fields/Slider/Slider.js +1 -1
  196. package/dist/components/fields/Slider/SliderBase.js +1 -1
  197. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  198. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  199. package/dist/components/fields/Slider/elements.js +1 -1
  200. package/dist/components/fields/Slider/index.js +1 -1
  201. package/dist/components/fields/Switch/Switch.js +1 -1
  202. package/dist/components/fields/TextArea/TextArea.js +1 -1
  203. package/dist/components/fields/TextInput/TextInput.js +1 -1
  204. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  205. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  206. package/dist/components/fields/color/ColorPanel.js +1 -1
  207. package/dist/components/fields/color/ColorSwatch.js +1 -1
  208. package/dist/components/fields/color/channels.js +1 -1
  209. package/dist/components/fields/color/color.js +1 -1
  210. package/dist/components/fields/color/context.js +1 -1
  211. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  212. package/dist/components/form/Form/Field.js +1 -1
  213. package/dist/components/form/Form/Form.js +1 -1
  214. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  215. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  216. package/dist/components/form/Form/SubmitError.js +1 -1
  217. package/dist/components/form/Form/index.js +1 -1
  218. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  219. package/dist/components/form/Form/use-field/use-field.js +1 -1
  220. package/dist/components/form/Form/use-form.js +1 -1
  221. package/dist/components/form/Form/validation.js +1 -1
  222. package/dist/components/form/Label.js +1 -1
  223. package/dist/components/form/validation/ValidationIndicator.js +1 -1
  224. package/dist/components/form/validation/resolve-validation-props.js +1 -1
  225. package/dist/components/form/validation/use-validation-props.js +1 -1
  226. package/dist/components/form/wrapper.js +1 -1
  227. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  228. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  229. package/dist/components/layout/Board/Board.js +1 -1
  230. package/dist/components/layout/Board/BoardProvider.js +1 -1
  231. package/dist/components/layout/Board/BoardResponsive.js +1 -1
  232. package/dist/components/layout/Board/Widget.js +1 -1
  233. package/dist/components/layout/Board/WidgetHost.js +1 -1
  234. package/dist/components/layout/Board/board-context.js +1 -1
  235. package/dist/components/layout/Board/board-store.js +1 -1
  236. package/dist/components/layout/Board/grid-core/calculate.js +1 -1
  237. package/dist/components/layout/Board/grid-core/collision.js +1 -1
  238. package/dist/components/layout/Board/grid-core/compactors.js +1 -1
  239. package/dist/components/layout/Board/grid-core/constraints.js +1 -1
  240. package/dist/components/layout/Board/grid-core/group-move.js +1 -1
  241. package/dist/components/layout/Board/grid-core/layout.js +1 -1
  242. package/dist/components/layout/Board/grid-core/sort.js +1 -1
  243. package/dist/components/layout/Board/index.js +1 -1
  244. package/dist/components/layout/Board/responsive-utils.js +1 -1
  245. package/dist/components/layout/Board/use-board-layout.js +1 -1
  246. package/dist/components/layout/Board/use-board-registry.js +1 -1
  247. package/dist/components/layout/Board/use-board-select-modifier-key.js +1 -1
  248. package/dist/components/layout/Board/use-board-selection.js +1 -1
  249. package/dist/components/layout/Flex.js +1 -1
  250. package/dist/components/layout/Flow.js +1 -1
  251. package/dist/components/layout/Grid.js +1 -1
  252. package/dist/components/layout/Panel.js +1 -1
  253. package/dist/components/layout/Prefix.js +1 -1
  254. package/dist/components/layout/ResizablePanel.js +1 -1
  255. package/dist/components/layout/Space.js +1 -1
  256. package/dist/components/layout/Suffix.js +1 -1
  257. package/dist/components/navigation/Pagination/Pagination.js +1 -1
  258. package/dist/components/navigation/Pagination/use-pagination.js +1 -1
  259. package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
  260. package/dist/components/navigation/Tabs/TabButton.js +1 -1
  261. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  262. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  263. package/dist/components/navigation/Tabs/TabPicker.js +1 -1
  264. package/dist/components/navigation/Tabs/Tabs.js +1 -1
  265. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  266. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  267. package/dist/components/navigation/Tabs/popover-placement.js +1 -1
  268. package/dist/components/navigation/Tabs/styled.js +1 -1
  269. package/dist/components/navigation/Tabs/types.js +1 -1
  270. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  271. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  272. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  273. package/dist/components/other/Calendar/Calendar.js +1 -1
  274. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  275. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  276. package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
  277. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  278. package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
  279. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  280. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  281. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  282. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  283. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  284. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  285. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  286. package/dist/components/overlays/Dialog/context.js +1 -1
  287. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  288. package/dist/components/overlays/Modal/Modal.js +1 -1
  289. package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
  290. package/dist/components/overlays/Modal/Overlay.js +1 -1
  291. package/dist/components/overlays/Modal/Popover.js +1 -1
  292. package/dist/components/overlays/Modal/Tray.js +1 -1
  293. package/dist/components/overlays/Modal/Underlay.js +1 -1
  294. package/dist/components/overlays/Notifications/Notification.js +1 -1
  295. package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
  296. package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
  297. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  298. package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
  299. package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
  300. package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
  301. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  302. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  303. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  304. package/dist/components/overlays/Notifications/index.js +1 -1
  305. package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
  306. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  307. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  308. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  309. package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
  310. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  311. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  312. package/dist/components/overlays/Toast/index.js +1 -1
  313. package/dist/components/overlays/Toast/useProgressToast.js +1 -1
  314. package/dist/components/overlays/Toast/useToast.js +1 -1
  315. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  316. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  317. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  318. package/dist/components/overlays/Tooltip/context.js +1 -1
  319. package/dist/components/portal/Portal.js +1 -1
  320. package/dist/components/portal/PortalProvider.js +1 -1
  321. package/dist/components/portal/usePortal.js +1 -1
  322. package/dist/components/shared/DraggableCollection.js +1 -1
  323. package/dist/components/shared/InvalidIcon.js +1 -1
  324. package/dist/components/shared/ValidIcon.js +1 -1
  325. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  326. package/dist/components/status/Spin/Cube.js +1 -1
  327. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  328. package/dist/components/status/Spin/Spin.js +1 -1
  329. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  330. package/dist/data/item-themes.js +1 -1
  331. package/dist/data/themes.js +1 -1
  332. package/dist/eslint-plugin/defaults.generated.js +9 -1
  333. package/dist/eslint-plugin/defaults.generated.js.map +1 -1
  334. package/dist/eslint-plugin/index.js +1 -1
  335. package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
  336. package/dist/i18n/I18nProvider.js +1 -1
  337. package/dist/i18n/createFormatter.js +1 -1
  338. package/dist/i18n/index.js +1 -1
  339. package/dist/i18n/instance.js +1 -1
  340. package/dist/i18n/locales/de-DE/uikit.js +5 -1
  341. package/dist/i18n/locales/en-US/uikit.js +5 -1
  342. package/dist/i18n/locales/en-US/uikit.json.d.ts +4 -0
  343. package/dist/i18n/locales/es-ES/uikit.js +5 -1
  344. package/dist/i18n/locales/es-MX/uikit.js +5 -1
  345. package/dist/i18n/locales/fr-FR/uikit.js +5 -1
  346. package/dist/i18n/locales/it-IT/uikit.js +5 -1
  347. package/dist/i18n/locales/ja-JP/uikit.js +5 -1
  348. package/dist/i18n/locales/nb-NO/uikit.js +5 -1
  349. package/dist/i18n/locales/pt-BR/uikit.js +5 -1
  350. package/dist/i18n/locales/pt-PT/uikit.js +5 -1
  351. package/dist/i18n/locales/sv-SE/uikit.js +5 -1
  352. package/dist/i18n/locales/vi-VN/uikit.js +5 -1
  353. package/dist/i18n/locales.js +1 -1
  354. package/dist/i18n/useFormatter.js +1 -1
  355. package/dist/i18n/useI18n.js +1 -1
  356. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  357. package/dist/icons/AdjustmentsIcon.js +1 -1
  358. package/dist/icons/AiIcon.js +1 -1
  359. package/dist/icons/AreaChartIcon.js +1 -1
  360. package/dist/icons/BackwardIcon.js +1 -1
  361. package/dist/icons/BarChartIcon.js +1 -1
  362. package/dist/icons/BellFilledIcon.js +1 -1
  363. package/dist/icons/BellIcon.js +1 -1
  364. package/dist/icons/BooleanIcon.js +1 -1
  365. package/dist/icons/CalendarEditIcon.js +1 -1
  366. package/dist/icons/CalendarIcon.js +1 -1
  367. package/dist/icons/CaretDownIcon.js +1 -1
  368. package/dist/icons/CaretUpIcon.js +1 -1
  369. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  370. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  371. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  372. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  373. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  374. package/dist/icons/ChartBarLineIcon.js +1 -1
  375. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  376. package/dist/icons/ChartBarStackedIcon.js +1 -1
  377. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  378. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  379. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  380. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  381. package/dist/icons/ChartBubbleIcon.js +1 -1
  382. package/dist/icons/ChartDonut2Icon.js +1 -1
  383. package/dist/icons/ChartFunnelIcon.js +1 -1
  384. package/dist/icons/ChartHeatmapIcon.js +1 -1
  385. package/dist/icons/ChartKPIIcon.js +1 -1
  386. package/dist/icons/ChartPie2Icon.js +1 -1
  387. package/dist/icons/ChartScatterIcon.js +1 -1
  388. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  389. package/dist/icons/CheckCircleIcon.js +1 -1
  390. package/dist/icons/CheckIcon.js +1 -1
  391. package/dist/icons/CircleFilledIcon.js +1 -1
  392. package/dist/icons/ClearIcon.js +1 -1
  393. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  394. package/dist/icons/CloseCircleIcon.js +1 -1
  395. package/dist/icons/CloseIcon.js +1 -1
  396. package/dist/icons/CodeIcon.js +1 -1
  397. package/dist/icons/ColumnTotalIcon.js +1 -1
  398. package/dist/icons/CopyIcon.js +1 -1
  399. package/dist/icons/CountIcon.js +1 -1
  400. package/dist/icons/CubeIcon.js +1 -1
  401. package/dist/icons/CubePauseIcon.js +1 -1
  402. package/dist/icons/CubePlayIcon.js +1 -1
  403. package/dist/icons/CurrencyDollarIcon.js +1 -1
  404. package/dist/icons/DangerIcon.js +1 -1
  405. package/dist/icons/DashboardIcon.js +1 -1
  406. package/dist/icons/DatabaseIcon.js +1 -1
  407. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  408. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  409. package/dist/icons/DirectionIcon.js +1 -1
  410. package/dist/icons/DonutIcon.js +1 -1
  411. package/dist/icons/DownIcon.js +1 -1
  412. package/dist/icons/EditIcon.js +1 -1
  413. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  414. package/dist/icons/ExclamationCircleIcon.js +1 -1
  415. package/dist/icons/ExclamationIcon.js +1 -1
  416. package/dist/icons/EyeIcon.js +1 -1
  417. package/dist/icons/EyeInvisibleIcon.js +1 -1
  418. package/dist/icons/FilterIcon.js +1 -1
  419. package/dist/icons/FolderFilledIcon.js +1 -1
  420. package/dist/icons/FolderIcon.js +1 -1
  421. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  422. package/dist/icons/FolderOpenIcon.js +1 -1
  423. package/dist/icons/ForwardIcon.js +1 -1
  424. package/dist/icons/GripVerticalIcon.js +1 -1
  425. package/dist/icons/HierarchyIcon.js +1 -1
  426. package/dist/icons/HierarchyOpenIcon.js +1 -1
  427. package/dist/icons/Icon.js +1 -1
  428. package/dist/icons/InfoCircleIcon.js +1 -1
  429. package/dist/icons/InfoIcon.js +1 -1
  430. package/dist/icons/KeyIcon.js +1 -1
  431. package/dist/icons/LeftIcon.js +1 -1
  432. package/dist/icons/LineChartIcon.js +1 -1
  433. package/dist/icons/LoadingIcon.js +1 -1
  434. package/dist/icons/LockFilledIcon.js +1 -1
  435. package/dist/icons/LockIcon.js +1 -1
  436. package/dist/icons/MoreIcon.js +1 -1
  437. package/dist/icons/NotAllowedIcon.js +1 -1
  438. package/dist/icons/Number123Icon.js +1 -1
  439. package/dist/icons/NumberIcon.js +1 -1
  440. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  441. package/dist/icons/PauseCircleIcon.js +1 -1
  442. package/dist/icons/PauseIcon.js +1 -1
  443. package/dist/icons/PercentageIcon.js +1 -1
  444. package/dist/icons/PieChartIcon.js +1 -1
  445. package/dist/icons/PipetteIcon.js +1 -1
  446. package/dist/icons/PlayCircleIcon.js +1 -1
  447. package/dist/icons/PlayIcon.js +1 -1
  448. package/dist/icons/PlusIcon.js +1 -1
  449. package/dist/icons/ProgressBarIcon.js +1 -1
  450. package/dist/icons/ReloadIcon.js +1 -1
  451. package/dist/icons/ReportIcon.js +1 -1
  452. package/dist/icons/ReturnIcon.js +1 -1
  453. package/dist/icons/RightIcon.js +1 -1
  454. package/dist/icons/RowTotalsIcon.js +1 -1
  455. package/dist/icons/SchemeIcon.js +1 -1
  456. package/dist/icons/SearchIcon.js +1 -1
  457. package/dist/icons/SemanticQueryIcon.js +1 -1
  458. package/dist/icons/SettingsIcon.js +1 -1
  459. package/dist/icons/ShieldFilledIcon.js +1 -1
  460. package/dist/icons/ShieldIcon.js +1 -1
  461. package/dist/icons/SlashIcon.js +1 -1
  462. package/dist/icons/SparklesIcon.js +1 -1
  463. package/dist/icons/SqlIcon.js +1 -1
  464. package/dist/icons/StatsIcon.js +1 -1
  465. package/dist/icons/StopIcon.js +1 -1
  466. package/dist/icons/StringIcon.js +1 -1
  467. package/dist/icons/SubtotalsIcon.js +1 -1
  468. package/dist/icons/SwitchIcon.js +1 -1
  469. package/dist/icons/TableIcon.js +1 -1
  470. package/dist/icons/ThumbsDownIcon.js +1 -1
  471. package/dist/icons/ThumbsUpIcon.js +1 -1
  472. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  473. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  474. package/dist/icons/ThunderboltIcon.js +1 -1
  475. package/dist/icons/TimeIcon.js +1 -1
  476. package/dist/icons/TrashIcon.js +1 -1
  477. package/dist/icons/UnlockIcon.js +1 -1
  478. package/dist/icons/UpIcon.js +1 -1
  479. package/dist/icons/UserGroupIcon.js +1 -1
  480. package/dist/icons/UserIcon.js +1 -1
  481. package/dist/icons/UserLockIcon.js +1 -1
  482. package/dist/icons/ViewIcon.js +1 -1
  483. package/dist/icons/WarningFilledIcon.js +1 -1
  484. package/dist/icons/WarningIcon.js +1 -1
  485. package/dist/icons/wrap-icon.js +1 -1
  486. package/dist/index.d.ts +4 -2
  487. package/dist/index.js +4 -2
  488. package/dist/index.js.map +1 -1
  489. package/dist/provider.js +1 -1
  490. package/dist/providers/TrackingProvider.js +1 -1
  491. package/dist/providers/navigationAdapter.default.js +1 -1
  492. package/dist/tokens/base.js +1 -1
  493. package/dist/tokens/color-theme.d.ts +86 -0
  494. package/dist/tokens/color-theme.js +156 -0
  495. package/dist/tokens/color-theme.js.map +1 -0
  496. package/dist/tokens/colors.js +1 -1
  497. package/dist/tokens/index.d.ts +1 -0
  498. package/dist/tokens/index.js +2 -1
  499. package/dist/tokens/index.js.map +1 -1
  500. package/dist/tokens/layout.js +1 -1
  501. package/dist/tokens/lazy-styles.js +1 -1
  502. package/dist/tokens/palette-config.d.ts +1 -1
  503. package/dist/tokens/palette-config.js +5 -17
  504. package/dist/tokens/palette-config.js.map +1 -1
  505. package/dist/tokens/palette.d.ts +1 -1
  506. package/dist/tokens/palette.js +44 -2
  507. package/dist/tokens/palette.js.map +1 -1
  508. package/dist/tokens/shadows.js +1 -1
  509. package/dist/tokens/sizes.js +1 -1
  510. package/dist/tokens/spacing.js +1 -1
  511. package/dist/tokens/typography.js +1 -1
  512. package/dist/utils/ResizeSensor.js +1 -1
  513. package/dist/utils/is-dev-env.js +1 -1
  514. package/dist/utils/modules.js +1 -1
  515. package/dist/utils/promise.js +1 -1
  516. package/dist/utils/raf.js +1 -1
  517. package/dist/utils/random.js +1 -1
  518. package/dist/utils/range.js +1 -1
  519. package/dist/utils/react/RenderCache.js +1 -1
  520. package/dist/utils/react/Slots.js +1 -1
  521. package/dist/utils/react/chain.js +1 -1
  522. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  523. package/dist/utils/react/index.js +1 -1
  524. package/dist/utils/react/interactions.js +1 -1
  525. package/dist/utils/react/isTextOnly.js +1 -1
  526. package/dist/utils/react/mapProps.js +1 -1
  527. package/dist/utils/react/mergeProps.js +1 -1
  528. package/dist/utils/react/nullableValue.js +1 -1
  529. package/dist/utils/react/resolveIcon.js +1 -1
  530. package/dist/utils/react/sharedStore.js +1 -1
  531. package/dist/utils/react/useBufferedValue.js +1 -1
  532. package/dist/utils/react/useCombinedRefs.js +1 -1
  533. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  534. package/dist/utils/react/useEventBus.js +1 -1
  535. package/dist/utils/react/useId.js +1 -1
  536. package/dist/utils/react/useIsDarwin.js +1 -1
  537. package/dist/utils/react/useKeySymbols.js +1 -1
  538. package/dist/utils/react/useLayoutEffect.js +1 -1
  539. package/dist/utils/react/useLocalStorage.js +1 -1
  540. package/dist/utils/react/useMergeStyles.js +1 -1
  541. package/dist/utils/react/usePopoverSync.js +1 -1
  542. package/dist/utils/react/useQaProps.js +1 -1
  543. package/dist/utils/react/useViewportSize.js +1 -1
  544. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  545. package/dist/utils/selection.js +1 -1
  546. package/dist/utils/styles.js +1 -1
  547. package/dist/utils/tree.js +1 -1
  548. package/dist/utils/warnings.js +1 -1
  549. package/dist/version.js +2 -2
  550. package/docs/Theming.md +13 -20
  551. package/docs/components/data/DataTable.md +107 -2
  552. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+
2
+ import { Styles } from "@tenphi/tasty";
3
+ import { ColorMap } from "@tenphi/glaze";
4
+
5
+ //#region src/tokens/color-theme.d.ts
6
+ interface ColorThemeConfig {
7
+ /**
8
+ * A hue in 0–360, or any colour Glaze parses — hex, `rgb()`, `hsl()`,
9
+ * `okhsl()`, `okhst()`, `oklch()`.
10
+ *
11
+ * From a colour only the HUE and SATURATION are taken; the lightness is
12
+ * discarded and re-derived per scheme. That is what makes the result adaptive
13
+ * rather than a value that happens to work in one theme.
14
+ */
15
+ hue: number | string;
16
+ /** 0–100. @default the palette's own saturation seed */
17
+ saturation?: number;
18
+ pastel?: boolean;
19
+ /**
20
+ * Extra colour definitions, merged over {@link TINT_RECIPE}. Anything Glaze's
21
+ * `theme.colors()` accepts, including `contrast` floors against a sibling.
22
+ */
23
+ colors?: ColorMap;
24
+ }
25
+ interface ColorTheme {
26
+ /**
27
+ * A hash of the config, and the token prefix — `'tint-1a2b3c'`.
28
+ *
29
+ * Content-addressed rather than positional so two components asking for the
30
+ * same colour name the same theme, and therefore share one injection. Also
31
+ * makes it safe to stamp on the DOM as an identifier.
32
+ */
33
+ name: string;
34
+ /**
35
+ * Tasty token declarations, one state map per colour:
36
+ * `{ '#tint-1a2b3c-surface': { '': …, '@dark': …, '@hc': …, '@dark & @hc': … } }`
37
+ */
38
+ tokens: Styles;
39
+ /** Token references by their unprefixed name — `{ surface: '#tint-1a2b3c-surface' }`. */
40
+ colors: Record<string, string>;
41
+ }
42
+ /**
43
+ * The hue and saturation of a colour, for use as a theme seed.
44
+ *
45
+ * ```ts
46
+ * colorThemeSeed('#0ea5e9'); // → { hue: 237.32, saturation: 98.19 }
47
+ * ```
48
+ */
49
+ declare function colorThemeSeed(value: string): {
50
+ hue: number;
51
+ saturation: number;
52
+ };
53
+ /**
54
+ * Build (or reuse) an adaptive theme from a hue.
55
+ *
56
+ * Pure and memoized: the same config returns the same object identity until the
57
+ * palette is re-seeded. Registering the tokens is {@link useColorTheme}'s job —
58
+ * this only computes them, so it is safe to call while rendering or from a test.
59
+ */
60
+ declare function getColorTheme(config: ColorThemeConfig): ColorTheme;
61
+ /**
62
+ * Register an adaptive theme's tokens once per document, and get it back.
63
+ *
64
+ * The tokens land on `body` under a slot keyed by the theme's name, which is a
65
+ * hash of the config — so every component asking for the same colour shares one
66
+ * injection no matter how many of them there are. Tasty's global-style slots are
67
+ * also permanent, which is what makes that safe: one component unmounting cannot
68
+ * strip tokens another is still referencing.
69
+ *
70
+ * `body` rather than `:root`, which emits nothing at all — the same selector
71
+ * `GlobalStyles` uses for the palette's own tokens. Custom properties inherit, so
72
+ * anything rendered inside the document sees them; the one thing this cannot
73
+ * reach is content portalled outside `<body>`, which nothing does.
74
+ *
75
+ * Because the slot id hashes the CONFIG rather than the resolved values,
76
+ * re-seeding the palette replaces the same slot instead of leaking a new one.
77
+ *
78
+ * ```tsx
79
+ * const theme = useColorTheme({ hue: '#0ea5e9' });
80
+ * // theme.colors.surface → '#tint-1a2b3c-surface'
81
+ * ```
82
+ */
83
+ declare function useColorTheme(config: ColorThemeConfig): ColorTheme;
84
+ //#endregion
85
+ export { ColorTheme, ColorThemeConfig, colorThemeSeed, getColorTheme, useColorTheme };
86
+ //# sourceMappingURL=color-theme.d.ts.map
@@ -0,0 +1,156 @@
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
+ import { DEFAULT_SATURATION, getPaletteConfig, getPaletteVersion, usePaletteVersion } from "./palette-config.js";
3
+ import { TINT_RECIPE } from "./palette.js";
4
+ import { useGlobalStyles } from "@tenphi/tasty";
5
+ import { glaze } from "@tenphi/glaze";
6
+
7
+ //#region src/tokens/color-theme.ts
8
+ /**
9
+ * FNV-1a, base36. Short, stable and dependency-free.
10
+ *
11
+ * These hashes name CSS custom properties and land in DOM attributes, so they
12
+ * have to be deterministic across processes (SSR and the client must agree) and
13
+ * safe as identifiers — but not cryptographic.
14
+ */
15
+ function hashString(input) {
16
+ let hash = 2166136261;
17
+ for (let i = 0; i < input.length; i++) {
18
+ hash ^= input.charCodeAt(i);
19
+ hash = Math.imul(hash, 16777619) >>> 0;
20
+ }
21
+ return hash.toString(36);
22
+ }
23
+ /**
24
+ * Hashes the RESOLVED seed, not the config as written.
25
+ *
26
+ * `{ hue: '#0ea5e9' }` and `{ hue: 237.32, saturation: 98.19 }` are the same
27
+ * colour said two ways; hashing the input would give them two names, two
28
+ * injections and two sets of generated rules. Rounded, because a seed that
29
+ * differs in the twelfth decimal is the same colour to every eye and every
30
+ * renderer — and an unrounded float would defeat the deduplication it is here to
31
+ * provide.
32
+ */
33
+ function hashSeed(seed) {
34
+ return `tint-${hashString(JSON.stringify([
35
+ seed.hue.toFixed(4),
36
+ seed.saturation.toFixed(4),
37
+ seed.pastel,
38
+ seed.colors ? stableStringify(seed.colors) : null
39
+ ]))}`;
40
+ }
41
+ /** Key order must not change the hash, or two identical configs get two slots. */
42
+ function stableStringify(value) {
43
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
44
+ if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
45
+ return `{${Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(",")}}`;
46
+ }
47
+ /**
48
+ * The hue and saturation of a colour, for use as a theme seed.
49
+ *
50
+ * ```ts
51
+ * colorThemeSeed('#0ea5e9'); // → { hue: 237.32, saturation: 98.19 }
52
+ * ```
53
+ */
54
+ function colorThemeSeed(value) {
55
+ const light = glaze.color(value).resolve().light;
56
+ return {
57
+ hue: light.h,
58
+ saturation: light.s * 100
59
+ };
60
+ }
61
+ /**
62
+ * Cached by `${paletteVersion}:${name}`.
63
+ *
64
+ * The palette version is in the KEY rather than triggering a clear, so a stale
65
+ * entry is simply unreachable. `lastVersion` still clears the map on a change,
66
+ * or repeated `setPaletteConfig` calls would grow it without bound.
67
+ */
68
+ const cache = /* @__PURE__ */ new Map();
69
+ let lastVersion = -1;
70
+ /**
71
+ * Build (or reuse) an adaptive theme from a hue.
72
+ *
73
+ * Pure and memoized: the same config returns the same object identity until the
74
+ * palette is re-seeded. Registering the tokens is {@link useColorTheme}'s job —
75
+ * this only computes them, so it is safe to call while rendering or from a test.
76
+ */
77
+ function getColorTheme(config) {
78
+ const version = getPaletteVersion();
79
+ if (version !== lastVersion) {
80
+ cache.clear();
81
+ lastVersion = version;
82
+ }
83
+ const paletteConfig = getPaletteConfig();
84
+ const parsed = typeof config.hue === "string" ? colorThemeSeed(config.hue) : null;
85
+ const seed = {
86
+ hue: parsed ? parsed.hue : config.hue,
87
+ saturation: config.saturation ?? parsed?.saturation ?? paletteConfig.saturation ?? DEFAULT_SATURATION,
88
+ pastel: config.pastel ?? paletteConfig.pastel ?? false,
89
+ colors: config.colors
90
+ };
91
+ const name = hashSeed(seed);
92
+ const cached = cache.get(name);
93
+ if (cached) return cached;
94
+ const { hue, saturation } = seed;
95
+ const overrides = {
96
+ ...paletteConfig.contrastLevel != null ? { contrastLevel: paletteConfig.contrastLevel } : null,
97
+ ...seed.pastel ? { pastel: true } : null
98
+ };
99
+ const theme = glaze(hue, saturation, Object.keys(overrides).length ? overrides : void 0);
100
+ theme.colors({
101
+ ...TINT_RECIPE,
102
+ ...config.colors
103
+ });
104
+ const raw = theme.tasty({ format: "oklch" });
105
+ const tokens = {};
106
+ const colors = {};
107
+ for (const [key, value] of Object.entries(raw)) {
108
+ if (!key.startsWith("#")) {
109
+ tokens[key] = value;
110
+ continue;
111
+ }
112
+ const bare = key.slice(1);
113
+ const token = `#${name}-${bare}`;
114
+ tokens[token] = value;
115
+ colors[bare] = token;
116
+ }
117
+ const result = {
118
+ name,
119
+ tokens,
120
+ colors
121
+ };
122
+ cache.set(name, result);
123
+ return result;
124
+ }
125
+ /**
126
+ * Register an adaptive theme's tokens once per document, and get it back.
127
+ *
128
+ * The tokens land on `body` under a slot keyed by the theme's name, which is a
129
+ * hash of the config — so every component asking for the same colour shares one
130
+ * injection no matter how many of them there are. Tasty's global-style slots are
131
+ * also permanent, which is what makes that safe: one component unmounting cannot
132
+ * strip tokens another is still referencing.
133
+ *
134
+ * `body` rather than `:root`, which emits nothing at all — the same selector
135
+ * `GlobalStyles` uses for the palette's own tokens. Custom properties inherit, so
136
+ * anything rendered inside the document sees them; the one thing this cannot
137
+ * reach is content portalled outside `<body>`, which nothing does.
138
+ *
139
+ * Because the slot id hashes the CONFIG rather than the resolved values,
140
+ * re-seeding the palette replaces the same slot instead of leaking a new one.
141
+ *
142
+ * ```tsx
143
+ * const theme = useColorTheme({ hue: '#0ea5e9' });
144
+ * // theme.colors.surface → '#tint-1a2b3c-surface'
145
+ * ```
146
+ */
147
+ function useColorTheme(config) {
148
+ usePaletteVersion();
149
+ const theme = getColorTheme(config);
150
+ useGlobalStyles("body", theme.tokens, { id: `cube-color-theme-${theme.name}` });
151
+ return theme;
152
+ }
153
+
154
+ //#endregion
155
+ export { colorThemeSeed, getColorTheme, hashString, useColorTheme };
156
+ //# sourceMappingURL=color-theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-theme.js","names":[],"sources":["../../src/tokens/color-theme.ts"],"sourcesContent":["import { glaze } from '@tenphi/glaze';\nimport { useGlobalStyles } from '@tenphi/tasty';\n\n// Imported for its SIDE EFFECT as much as for `TINT_RECIPE`.\n//\n// `palette.ts` runs `glaze.configure({ states: { dark: '@dark', highContrast:\n// '@hc' }, modes: …, darkTone: … })` at module scope, and that global config is\n// what makes a theme emit `'@dark'` / `'@hc'` keys at all. Without this import\n// a runtime theme falls back to Glaze's defaults — `@media(prefers-color-scheme:\n// dark)` keys and NO high-contrast tier — which still renders, so the failure is\n// silent. `color-theme.test.ts` asserts the `'@hc'` key exists to catch it.\nimport { TINT_RECIPE } from './palette';\nimport {\n DEFAULT_SATURATION,\n getPaletteConfig,\n getPaletteVersion,\n usePaletteVersion,\n} from './palette-config';\n\nimport type { ColorMap, GlazeConfigOverride } from '@tenphi/glaze';\nimport type { Styles } from '@tenphi/tasty';\n\nexport interface ColorThemeConfig {\n /**\n * A hue in 0–360, or any colour Glaze parses — hex, `rgb()`, `hsl()`,\n * `okhsl()`, `okhst()`, `oklch()`.\n *\n * From a colour only the HUE and SATURATION are taken; the lightness is\n * discarded and re-derived per scheme. That is what makes the result adaptive\n * rather than a value that happens to work in one theme.\n */\n hue: number | string;\n /** 0–100. @default the palette's own saturation seed */\n saturation?: number;\n pastel?: boolean;\n /**\n * Extra colour definitions, merged over {@link TINT_RECIPE}. Anything Glaze's\n * `theme.colors()` accepts, including `contrast` floors against a sibling.\n */\n colors?: ColorMap;\n}\n\nexport interface ColorTheme {\n /**\n * A hash of the config, and the token prefix — `'tint-1a2b3c'`.\n *\n * Content-addressed rather than positional so two components asking for the\n * same colour name the same theme, and therefore share one injection. Also\n * makes it safe to stamp on the DOM as an identifier.\n */\n name: string;\n /**\n * Tasty token declarations, one state map per colour:\n * `{ '#tint-1a2b3c-surface': { '': …, '@dark': …, '@hc': …, '@dark & @hc': … } }`\n */\n tokens: Styles;\n /** Token references by their unprefixed name — `{ surface: '#tint-1a2b3c-surface' }`. */\n colors: Record<string, string>;\n}\n\n/**\n * FNV-1a, base36. Short, stable and dependency-free.\n *\n * These hashes name CSS custom properties and land in DOM attributes, so they\n * have to be deterministic across processes (SSR and the client must agree) and\n * safe as identifiers — but not cryptographic.\n */\nexport function hashString(input: string): string {\n let hash = 0x811c9dc5;\n\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n // >>> 0 keeps it an unsigned 32-bit int; `Math.imul` is the 32-bit multiply.\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n\n return hash.toString(36);\n}\n\n/**\n * Hashes the RESOLVED seed, not the config as written.\n *\n * `{ hue: '#0ea5e9' }` and `{ hue: 237.32, saturation: 98.19 }` are the same\n * colour said two ways; hashing the input would give them two names, two\n * injections and two sets of generated rules. Rounded, because a seed that\n * differs in the twelfth decimal is the same colour to every eye and every\n * renderer — and an unrounded float would defeat the deduplication it is here to\n * provide.\n */\nfunction hashSeed(seed: ResolvedSeed): string {\n return `tint-${hashString(\n JSON.stringify([\n seed.hue.toFixed(4),\n seed.saturation.toFixed(4),\n seed.pastel,\n seed.colors ? stableStringify(seed.colors) : null,\n ]),\n )}`;\n}\n\ninterface ResolvedSeed {\n hue: number;\n saturation: number;\n pastel: boolean;\n colors?: ColorMap;\n}\n\n/** Key order must not change the hash, or two identical configs get two slots. */\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(',')}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>).sort(\n ([a], [b]) => (a < b ? -1 : a > b ? 1 : 0),\n );\n\n return `{${entries\n .map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)\n .join(',')}}`;\n}\n\n/**\n * The hue and saturation of a colour, for use as a theme seed.\n *\n * ```ts\n * colorThemeSeed('#0ea5e9'); // → { hue: 237.32, saturation: 98.19 }\n * ```\n */\nexport function colorThemeSeed(value: string): {\n hue: number;\n saturation: number;\n} {\n const light = glaze.color(value).resolve().light;\n\n // Glaze reports saturation as a 0–1 factor; the palette's seeds are 0–100.\n return { hue: light.h, saturation: light.s * 100 };\n}\n\n/**\n * Cached by `${paletteVersion}:${name}`.\n *\n * The palette version is in the KEY rather than triggering a clear, so a stale\n * entry is simply unreachable. `lastVersion` still clears the map on a change,\n * or repeated `setPaletteConfig` calls would grow it without bound.\n */\nconst cache = new Map<string, ColorTheme>();\nlet lastVersion = -1;\n\n/**\n * Build (or reuse) an adaptive theme from a hue.\n *\n * Pure and memoized: the same config returns the same object identity until the\n * palette is re-seeded. Registering the tokens is {@link useColorTheme}'s job —\n * this only computes them, so it is safe to call while rendering or from a test.\n */\nexport function getColorTheme(config: ColorThemeConfig): ColorTheme {\n const version = getPaletteVersion();\n\n if (version !== lastVersion) {\n cache.clear();\n lastVersion = version;\n }\n\n const paletteConfig = getPaletteConfig();\n const parsed =\n typeof config.hue === 'string' ? colorThemeSeed(config.hue) : null;\n const seed: ResolvedSeed = {\n hue: parsed ? parsed.hue : (config.hue as number),\n saturation:\n config.saturation ??\n parsed?.saturation ??\n paletteConfig.saturation ??\n DEFAULT_SATURATION,\n pastel: config.pastel ?? paletteConfig.pastel ?? false,\n colors: config.colors,\n };\n\n const name = hashSeed(seed);\n const cached = cache.get(name);\n\n if (cached) return cached;\n\n const { hue, saturation } = seed;\n\n // `pastel` and `contrastLevel` are instance-level in Glaze, not settable\n // through `glaze.configure`, so a runtime theme has to carry them itself or it\n // would ignore a pastel palette. Omitted entirely when off, so the default\n // output is provably the same as passing nothing.\n const overrides: GlazeConfigOverride = {\n ...(paletteConfig.contrastLevel != null\n ? { contrastLevel: paletteConfig.contrastLevel }\n : null),\n ...(seed.pastel ? { pastel: true } : null),\n };\n\n const theme = glaze(\n hue,\n saturation,\n Object.keys(overrides).length ? overrides : undefined,\n );\n\n theme.colors({ ...TINT_RECIPE, ...config.colors });\n\n // `prefix` is a palette-only option, so the keys are renamed here. `oklch`\n // because that is what the palette emits; tasty converts to the configured\n // colour space on the way out either way.\n const raw = theme.tasty({ format: 'oklch' }) as Record<string, unknown>;\n const tokens: Styles = {};\n const colors: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(raw)) {\n // Only the `#colour` entries are renamed; `splitHue` is off, so there are no\n // `$…-hue` companions to worry about, but a future one must not be mangled.\n if (!key.startsWith('#')) {\n (tokens as Record<string, unknown>)[key] = value;\n continue;\n }\n\n const bare = key.slice(1);\n const token = `#${name}-${bare}`;\n\n (tokens as Record<string, unknown>)[token] = value;\n colors[bare] = token;\n }\n\n const result: ColorTheme = { name, tokens, colors };\n\n cache.set(name, result);\n\n return result;\n}\n\n/**\n * Register an adaptive theme's tokens once per document, and get it back.\n *\n * The tokens land on `body` under a slot keyed by the theme's name, which is a\n * hash of the config — so every component asking for the same colour shares one\n * injection no matter how many of them there are. Tasty's global-style slots are\n * also permanent, which is what makes that safe: one component unmounting cannot\n * strip tokens another is still referencing.\n *\n * `body` rather than `:root`, which emits nothing at all — the same selector\n * `GlobalStyles` uses for the palette's own tokens. Custom properties inherit, so\n * anything rendered inside the document sees them; the one thing this cannot\n * reach is content portalled outside `<body>`, which nothing does.\n *\n * Because the slot id hashes the CONFIG rather than the resolved values,\n * re-seeding the palette replaces the same slot instead of leaking a new one.\n *\n * ```tsx\n * const theme = useColorTheme({ hue: '#0ea5e9' });\n * // theme.colors.surface → '#tint-1a2b3c-surface'\n * ```\n */\nexport function useColorTheme(config: ColorThemeConfig): ColorTheme {\n // Subscribes this component to a re-seed. `getColorTheme` reads the version\n // itself for its cache, so the value is unused here — the subscription is the\n // point, and it is what makes the tokens below re-inject.\n usePaletteVersion();\n\n const theme = getColorTheme(config);\n\n useGlobalStyles('body', theme.tokens, {\n id: `cube-color-theme-${theme.name}`,\n });\n\n return theme;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-7464463 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
2
  import { getPaletteVersion } from "./palette-config.js";
3
3
  import { BASE_TOKENS } from "./base.js";
4
4
  import { lazyStyles } from "./lazy-styles.js";
@@ -3,6 +3,7 @@ import { DEFAULT_PALETTE_CONFIG, PaletteCodeSeed, PaletteConfig, PaletteThemeNam
3
3
  import { SIZES, SIZE_NAME_TO_KEY, SIZE_TOKENS, SizeKey, SizeName } from "./sizes.js";
4
4
  import { PALETTE_TOKENS, RenderPaletteOptions, getCodeTheme, getPalette, getPaletteTokens, renderPaletteTokens } from "./palette.js";
5
5
  import { COLOR_TOKENS, getColorTokens, renderColorTokens } from "./colors.js";
6
+ import { ColorTheme, ColorThemeConfig, colorThemeSeed, getColorTheme, useColorTheme } from "./color-theme.js";
6
7
  import { SPACE_TOKENS } from "./spacing.js";
7
8
  import { SHADOW_TOKENS } from "./shadows.js";
8
9
  import { LAYOUT_TOKENS } from "./layout.js";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-7464463 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
2
  import { DEFAULT_PALETTE_CONFIG, getPaletteConfig, getPaletteConfigInput, getPaletteVersion, invalidatePaletteTokens, resetPaletteConfig, resolvePaletteConfig, setPaletteConfig, subscribePaletteConfig, usePaletteConfig, usePaletteVersion } from "./palette-config.js";
3
3
  import { BASE_TOKENS } from "./base.js";
4
4
  import { lazyStyles } from "./lazy-styles.js";
@@ -9,6 +9,7 @@ import { LAYOUT_TOKENS } from "./layout.js";
9
9
  import { SIZES, SIZE_NAME_TO_KEY, SIZE_TOKENS } from "./sizes.js";
10
10
  import { SPACE_TOKENS } from "./spacing.js";
11
11
  import { TYPOGRAPHY_PRESETS } from "./typography.js";
12
+ import { colorThemeSeed, getColorTheme, useColorTheme } from "./color-theme.js";
12
13
  import { generateTypographyTokens } from "@tenphi/tasty";
13
14
 
14
15
  //#region src/tokens/index.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/tokens/index.ts"],"sourcesContent":["/**\n * Design tokens for the Cube UI Kit.\n *\n * This module exports all design tokens used throughout the design system.\n * All token keys use $ prefix for CSS custom properties.\n *\n * Categories:\n * - Colors: Base color palette with -color and -color-rgb variants\n * - Typography: Font presets for headings, text, paragraphs, etc.\n * - Sizes: Component size values (XS, SM, MD, LG, XL)\n * - Spacing: Space tokens using gap multipliers\n * - Shadows: Shadow definitions for elevation\n * - Layout: Common layout dimensions\n * - Base: Core design system values\n */\n\nimport { generateTypographyTokens } from '@tenphi/tasty';\n\nimport { BASE_TOKENS } from './base';\nimport { getColorTokens } from './colors';\nimport { LAYOUT_TOKENS } from './layout';\nimport { lazyStyles } from './lazy-styles';\nimport { getPaletteVersion } from './palette-config';\nimport { SHADOW_TOKENS } from './shadows';\nimport { SIZE_TOKENS } from './sizes';\nimport { SPACE_TOKENS } from './spacing';\nimport { TYPOGRAPHY_PRESETS } from './typography';\n\nimport type { Styles } from '@tenphi/tasty';\nimport type { SizeKey, SizeName } from './sizes';\n\n/**\n * All design tokens combined into a single Styles object.\n * Keys use $ prefix for CSS custom properties.\n *\n * Color tokens resolve against the current palette config (see\n * {@link getColorTokens}), and this map is memoized against that config's\n * version so `setPaletteConfig()` invalidates it. Prefer this over the lazy\n * {@link TOKENS} proxy when applying styles from React (`GlobalStyles`).\n *\n * Includes:\n * - Base tokens ($gap, $radius, etc.)\n * - Space tokens ($space-xs, $space-sm, etc.)\n * - Size tokens ($size-xs, $size-sm, etc.)\n * - Shadow tokens ($shadow, $item-shadow, etc.)\n * - Layout tokens ($max-content-width, $topbar-height, etc.)\n * - Typography tokens ($h1-font-size, $t3-line-height, etc.)\n * - Color tokens ($purple-color, $purple-color-rgb, etc.)\n */\nlet tokensCache: Styles | null = null;\nlet cachedVersion = -1;\n\nexport function getTokens(): Styles {\n const version = getPaletteVersion();\n\n if (!tokensCache || cachedVersion !== version) {\n tokensCache = {\n ...BASE_TOKENS,\n ...SPACE_TOKENS,\n ...SIZE_TOKENS,\n ...SHADOW_TOKENS,\n ...LAYOUT_TOKENS,\n ...generateTypographyTokens(TYPOGRAPHY_PRESETS),\n ...getColorTokens(),\n };\n cachedVersion = version;\n }\n return tokensCache;\n}\n\n/** Lazy proxy of {@link getTokens}. Prefer `getTokens()` in new code. */\nexport const TOKENS: Styles = lazyStyles(getTokens);\n\n// Re-export category modules for direct access\nexport { COLOR_TOKENS, getColorTokens, renderColorTokens } from './colors';\nexport {\n getCodeTheme,\n getPalette,\n getPaletteTokens,\n PALETTE_TOKENS,\n renderPaletteTokens,\n} from './palette';\nexport type { RenderPaletteOptions } from './palette';\nexport {\n DEFAULT_PALETTE_CONFIG,\n getPaletteConfig,\n getPaletteConfigInput,\n invalidatePaletteTokens,\n resetPaletteConfig,\n resolvePaletteConfig,\n setPaletteConfig,\n subscribePaletteConfig,\n usePaletteConfig,\n usePaletteVersion,\n} from './palette-config';\nexport type {\n PaletteCodeSeed,\n PaletteConfig,\n PaletteThemeName,\n PaletteThemeSeed,\n ResolvedPaletteConfig,\n} from './palette-config';\nexport { SIZES, SIZE_NAME_TO_KEY, SIZE_TOKENS } from './sizes';\nexport type { SizeKey, SizeName } from './sizes';\nexport { SPACE_TOKENS } from './spacing';\nexport { SHADOW_TOKENS } from './shadows';\nexport { LAYOUT_TOKENS } from './layout';\nexport { BASE_TOKENS } from './base';\nexport { TYPOGRAPHY_PRESETS } from './typography';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAI,cAA6B;AACjC,IAAI,gBAAgB;AAEpB,SAAgB,YAAoB;CAClC,MAAM,UAAU,mBAAmB;AAEnC,KAAI,CAAC,eAAe,kBAAkB,SAAS;AAC7C,gBAAc;GACZ,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG,yBAAyB,mBAAmB;GAC/C,GAAG,gBAAgB;GACpB;AACD,kBAAgB;;AAElB,QAAO;;;AAIT,MAAa,SAAiB,WAAW,UAAU"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/tokens/index.ts"],"sourcesContent":["/**\n * Design tokens for the Cube UI Kit.\n *\n * This module exports all design tokens used throughout the design system.\n * All token keys use $ prefix for CSS custom properties.\n *\n * Categories:\n * - Colors: Base color palette with -color and -color-rgb variants\n * - Typography: Font presets for headings, text, paragraphs, etc.\n * - Sizes: Component size values (XS, SM, MD, LG, XL)\n * - Spacing: Space tokens using gap multipliers\n * - Shadows: Shadow definitions for elevation\n * - Layout: Common layout dimensions\n * - Base: Core design system values\n */\n\nimport { generateTypographyTokens } from '@tenphi/tasty';\n\nimport { BASE_TOKENS } from './base';\nimport { getColorTokens } from './colors';\nimport { LAYOUT_TOKENS } from './layout';\nimport { lazyStyles } from './lazy-styles';\nimport { getPaletteVersion } from './palette-config';\nimport { SHADOW_TOKENS } from './shadows';\nimport { SIZE_TOKENS } from './sizes';\nimport { SPACE_TOKENS } from './spacing';\nimport { TYPOGRAPHY_PRESETS } from './typography';\n\nimport type { Styles } from '@tenphi/tasty';\nimport type { SizeKey, SizeName } from './sizes';\n\n/**\n * All design tokens combined into a single Styles object.\n * Keys use $ prefix for CSS custom properties.\n *\n * Color tokens resolve against the current palette config (see\n * {@link getColorTokens}), and this map is memoized against that config's\n * version so `setPaletteConfig()` invalidates it. Prefer this over the lazy\n * {@link TOKENS} proxy when applying styles from React (`GlobalStyles`).\n *\n * Includes:\n * - Base tokens ($gap, $radius, etc.)\n * - Space tokens ($space-xs, $space-sm, etc.)\n * - Size tokens ($size-xs, $size-sm, etc.)\n * - Shadow tokens ($shadow, $item-shadow, etc.)\n * - Layout tokens ($max-content-width, $topbar-height, etc.)\n * - Typography tokens ($h1-font-size, $t3-line-height, etc.)\n * - Color tokens ($purple-color, $purple-color-rgb, etc.)\n */\nlet tokensCache: Styles | null = null;\nlet cachedVersion = -1;\n\nexport function getTokens(): Styles {\n const version = getPaletteVersion();\n\n if (!tokensCache || cachedVersion !== version) {\n tokensCache = {\n ...BASE_TOKENS,\n ...SPACE_TOKENS,\n ...SIZE_TOKENS,\n ...SHADOW_TOKENS,\n ...LAYOUT_TOKENS,\n ...generateTypographyTokens(TYPOGRAPHY_PRESETS),\n ...getColorTokens(),\n };\n cachedVersion = version;\n }\n return tokensCache;\n}\n\n/** Lazy proxy of {@link getTokens}. Prefer `getTokens()` in new code. */\nexport const TOKENS: Styles = lazyStyles(getTokens);\n\n// Re-export category modules for direct access\nexport { COLOR_TOKENS, getColorTokens, renderColorTokens } from './colors';\n// Adaptive one-off themes built at runtime from an arbitrary hue, named by a\n// hash of their config so identical requests share one injection.\nexport { colorThemeSeed, getColorTheme, useColorTheme } from './color-theme';\nexport type { ColorTheme, ColorThemeConfig } from './color-theme';\nexport {\n getCodeTheme,\n getPalette,\n getPaletteTokens,\n PALETTE_TOKENS,\n renderPaletteTokens,\n} from './palette';\nexport type { RenderPaletteOptions } from './palette';\nexport {\n DEFAULT_PALETTE_CONFIG,\n getPaletteConfig,\n getPaletteConfigInput,\n invalidatePaletteTokens,\n resetPaletteConfig,\n resolvePaletteConfig,\n setPaletteConfig,\n subscribePaletteConfig,\n usePaletteConfig,\n usePaletteVersion,\n} from './palette-config';\nexport type {\n PaletteCodeSeed,\n PaletteConfig,\n PaletteThemeName,\n PaletteThemeSeed,\n ResolvedPaletteConfig,\n} from './palette-config';\nexport { SIZES, SIZE_NAME_TO_KEY, SIZE_TOKENS } from './sizes';\nexport type { SizeKey, SizeName } from './sizes';\nexport { SPACE_TOKENS } from './spacing';\nexport { SHADOW_TOKENS } from './shadows';\nexport { LAYOUT_TOKENS } from './layout';\nexport { BASE_TOKENS } from './base';\nexport { TYPOGRAPHY_PRESETS } from './typography';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAI,cAA6B;AACjC,IAAI,gBAAgB;AAEpB,SAAgB,YAAoB;CAClC,MAAM,UAAU,mBAAmB;AAEnC,KAAI,CAAC,eAAe,kBAAkB,SAAS;AAC7C,gBAAc;GACZ,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG,yBAAyB,mBAAmB;GAC/C,GAAG,gBAAgB;GACpB;AACD,kBAAgB;;AAElB,QAAO;;;AAIT,MAAa,SAAiB,WAAW,UAAU"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-7464463 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
2
  //#region src/tokens/layout.ts
3
3
  /**
4
4
  * Layout-related tokens for common UI dimensions.
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-7464463 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
2
  //#region src/tokens/lazy-styles.ts
3
3
  /**
4
4
  * Proxy that defers to `factory()` on every property / enumeration access.
@@ -19,7 +19,7 @@ interface PaletteThemeSeed {
19
19
  * reason.
20
20
  */
21
21
  interface PaletteCodeSeed {
22
- /** Saturation (0–100). Defaults to {@link DEFAULT_CODE_SATURATION}, not to `saturation`. */
22
+ /** Saturation (0–100). Defaults to {@link DEFAULT_SATURATION}, not to `saturation`. */
23
23
  saturation?: number;
24
24
  }
25
25
  /** Names of the themes whose seeds can be overridden individually. */
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-7464463 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
2
  import { useSyncExternalStore } from "react";
3
3
 
4
4
  //#region src/tokens/palette-config.ts
@@ -20,19 +20,7 @@ const DEFAULT_DANGER_HUE = 23.1;
20
20
  const DEFAULT_WARNING_HUE = 84.3;
21
21
  const DEFAULT_NOTE_HUE = 302.3;
22
22
  /** Seed saturation. Per-color `saturation` in the recipe is a 0–1 factor of it. */
23
- const DEFAULT_SATURATION = 100;
24
- /**
25
- * Seed saturation for the `code-*` syntax family, deliberately **not** the same
26
- * constant as {@link DEFAULT_SATURATION}.
27
- *
28
- * The two were one value until the app seed moved to 100 for the pastel palette.
29
- * Sharing it would have dragged the syntax colors along for the ride — the exact
30
- * coupling that `PaletteCodeSeed` and the `pastel` opt-out both exist to prevent,
31
- * and the reason the code family answers to its own saturation and nothing else.
32
- * Splitting the constant is what lets the app seed move while the code palette
33
- * stays on the value it was calibrated against.
34
- */
35
- const DEFAULT_CODE_SATURATION = 80;
23
+ const DEFAULT_SATURATION = 80;
36
24
  const DEFAULT_THEME_HUES = {
37
25
  success: DEFAULT_SUCCESS_HUE,
38
26
  danger: DEFAULT_DANGER_HUE,
@@ -47,7 +35,7 @@ function resolveConfig(input) {
47
35
  hue,
48
36
  baseHue: input.baseHue ?? hue,
49
37
  saturation,
50
- pastel: input.pastel ?? true,
38
+ pastel: input.pastel ?? false,
51
39
  contrastLevel: input.contrastLevel ?? "auto",
52
40
  themes: {
53
41
  success: {
@@ -66,7 +54,7 @@ function resolveConfig(input) {
66
54
  hue: themes.note?.hue ?? DEFAULT_THEME_HUES.note,
67
55
  saturation: themes.note?.saturation ?? saturation
68
56
  },
69
- code: { saturation: themes.code?.saturation ?? DEFAULT_CODE_SATURATION }
57
+ code: { saturation: themes.code?.saturation ?? DEFAULT_SATURATION }
70
58
  }
71
59
  };
72
60
  }
@@ -317,5 +305,5 @@ function usePaletteConfig() {
317
305
  }
318
306
 
319
307
  //#endregion
320
- export { DEFAULT_PALETTE_CONFIG, getPaletteConfig, getPaletteConfigInput, getPaletteVersion, invalidatePaletteTokens, resetPaletteConfig, resolvePaletteConfig, setPaletteConfig, subscribePaletteConfig, usePaletteConfig, usePaletteVersion };
308
+ export { DEFAULT_PALETTE_CONFIG, DEFAULT_SATURATION, getPaletteConfig, getPaletteConfigInput, getPaletteVersion, invalidatePaletteTokens, resetPaletteConfig, resolvePaletteConfig, setPaletteConfig, subscribePaletteConfig, usePaletteConfig, usePaletteVersion };
321
309
  //# sourceMappingURL=palette-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"palette-config.js","names":[],"sources":["../../src/tokens/palette-config.ts"],"sourcesContent":["import { useSyncExternalStore } from 'react';\n\n/**\n * Runtime configuration for the Glaze-generated color palette.\n *\n * The palette recipe itself lives in `./palette.ts`; this module owns only the\n * *seeds* it is built from, plus a version counter the token caches watch. It\n * deliberately imports nothing else — not the token modules, not `glaze` — so\n * there is no import cycle and no ordering hazard.\n *\n * Reading is free; writing rebuilds the palette on the next token read. See\n * `Getting Started/Theming` in Storybook for the full contract.\n */\n\n// ============================================================================\n// Default seeds\n// ============================================================================\n\n/** Brand hue. Drives the `default`, `primary`, `purple` and `special` themes. */\nexport const DEFAULT_HUE = 280.3;\nexport const DEFAULT_SUCCESS_HUE = 156.9;\nexport const DEFAULT_DANGER_HUE = 23.1;\nexport const DEFAULT_WARNING_HUE = 84.3;\nexport const DEFAULT_NOTE_HUE = 302.3;\n\n/** Seed saturation. Per-color `saturation` in the recipe is a 0–1 factor of it. */\nexport const DEFAULT_SATURATION = 100;\n\n/**\n * Seed saturation for the `code-*` syntax family, deliberately **not** the same\n * constant as {@link DEFAULT_SATURATION}.\n *\n * The two were one value until the app seed moved to 100 for the pastel palette.\n * Sharing it would have dragged the syntax colors along for the ride — the exact\n * coupling that `PaletteCodeSeed` and the `pastel` opt-out both exist to prevent,\n * and the reason the code family answers to its own saturation and nothing else.\n * Splitting the constant is what lets the app seed move while the code palette\n * stays on the value it was calibrated against.\n */\nexport const DEFAULT_CODE_SATURATION = 80;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Hue / saturation seed override for one colored theme. */\nexport interface PaletteThemeSeed {\n /** Hue in degrees (0–360). */\n hue?: number;\n /** Saturation (0–100). Defaults to the palette-level `saturation`. */\n saturation?: number;\n}\n\n/**\n * The `code-*` syntax family takes a saturation and nothing else — and answers to\n * nothing else either. This is the one knob that moves it.\n *\n * Its hues are absolute literals by design, so syntax colors never rotate with the\n * brand — strings would collide with numbers the moment the brand went green. Unlike\n * every other theme, its saturation does **not** inherit the palette-level one: the\n * code palette is calibrated once and stays there, so re-seeding the app cannot\n * quietly wash out a code block. {@link PaletteConfig.pastel} skips it for the same\n * reason.\n */\nexport interface PaletteCodeSeed {\n /** Saturation (0–100). Defaults to {@link DEFAULT_CODE_SATURATION}, not to `saturation`. */\n saturation?: number;\n}\n\n/** Names of the themes whose seeds can be overridden individually. */\nexport type PaletteThemeName =\n | 'success'\n | 'danger'\n | 'warning'\n | 'note'\n | 'code';\n\n/**\n * Palette tuning. Every field is optional; omitted fields keep their default,\n * and per-theme fields left unset inherit the palette-level value.\n */\nexport interface PaletteConfig {\n /**\n * Accent hue in degrees (0–360) — the brand.\n *\n * Drives the `accent-*` family on every theme, `primary` / `purple` / `special`,\n * and the brand-tinted odds and ends (`focus`, the loading faces, the disabled\n * chip). Also the default for {@link PaletteConfig.baseHue}.\n */\n hue?: number;\n /**\n * Hue of the **base** zone in degrees (0–360): the neutral chrome — `surface`\n * and its ladder, the `surface-text*` ramp, `border`, `placeholder`. Defaults to\n * `hue`, so the chrome carries a faint tint of the brand unless you say otherwise.\n *\n * Splitting it lets the chrome sit on a different hue from the accent — a warm\n * grey UI with a cool blue brand, say. Only the `default` theme is affected: a\n * colored theme's tinted `surface` deliberately follows *its own* hue, because a\n * danger banner should read as red.\n */\n baseHue?: number;\n /**\n * Seed saturation (0–100), and the fallback for every theme that does not set\n * its own.\n *\n * One scale for the whole theme, by design. Every color's own `saturation` is a\n * 0–1 factor of this seed — `surface` at 0.12, `border` at 0.175, the text ramp\n * at 0.2, the accent family at ~1.0 — so moving it rescales the palette while\n * keeping those proportions. Unlike hue, which is configured separately for the\n * brand and for each status theme, saturation is deliberately not split: the\n * ratio between a subtle surface tint and a saturated accent is part of the\n * design.\n */\n saturation?: number;\n /**\n * Global. Widens the usable chroma range by relaxing the sRGB-safe limit,\n * producing a softer, more even palette across hues. Glaze treats `pastel` as\n * instance-level, so it is threaded into every theme.\n *\n * Every theme except `code`. The syntax family is calibrated on its own\n * saturation and is deliberately left out — softening it collapses the chroma\n * spread the syntax hues rely on to stay apart. To soften a code block, lower\n * {@link PaletteCodeSeed.saturation} instead.\n */\n pastel?: boolean;\n /**\n * Global. `'auto'` (the default) keeps the two-tier model: normal colors plus\n * a separate high-contrast tier driven by `<html data-contrast=\"high\">` /\n * `prefers-contrast: more`.\n *\n * A number (0–100) replaces that switch with a slider — and, because a manual\n * level already carries the contrast preference, **drops the high-contrast\n * tier entirely**. `0` reproduces the normal output and `100` the\n * high-contrast output, bit for bit.\n */\n contrastLevel?: number | 'auto';\n /** Per-theme seed overrides. */\n themes?: {\n success?: PaletteThemeSeed;\n danger?: PaletteThemeSeed;\n warning?: PaletteThemeSeed;\n note?: PaletteThemeSeed;\n code?: PaletteCodeSeed;\n };\n}\n\n/** {@link PaletteConfig} with every field resolved to a concrete value. */\nexport interface ResolvedPaletteConfig {\n hue: number;\n baseHue: number;\n saturation: number;\n pastel: boolean;\n contrastLevel: number | 'auto';\n themes: {\n success: { hue: number; saturation: number };\n danger: { hue: number; saturation: number };\n warning: { hue: number; saturation: number };\n note: { hue: number; saturation: number };\n code: { saturation: number };\n };\n}\n\n// ============================================================================\n// Resolution\n// ============================================================================\n\nconst DEFAULT_THEME_HUES = {\n success: DEFAULT_SUCCESS_HUE,\n danger: DEFAULT_DANGER_HUE,\n warning: DEFAULT_WARNING_HUE,\n note: DEFAULT_NOTE_HUE,\n} as const;\n\nfunction resolveConfig(input: PaletteConfig): ResolvedPaletteConfig {\n const saturation = input.saturation ?? DEFAULT_SATURATION;\n const themes = input.themes ?? {};\n\n const hue = input.hue ?? DEFAULT_HUE;\n\n return {\n hue,\n baseHue: input.baseHue ?? hue,\n saturation,\n pastel: input.pastel ?? true,\n contrastLevel: input.contrastLevel ?? 'auto',\n themes: {\n success: {\n hue: themes.success?.hue ?? DEFAULT_THEME_HUES.success,\n saturation: themes.success?.saturation ?? saturation,\n },\n danger: {\n hue: themes.danger?.hue ?? DEFAULT_THEME_HUES.danger,\n saturation: themes.danger?.saturation ?? saturation,\n },\n warning: {\n hue: themes.warning?.hue ?? DEFAULT_THEME_HUES.warning,\n saturation: themes.warning?.saturation ?? saturation,\n },\n note: {\n hue: themes.note?.hue ?? DEFAULT_THEME_HUES.note,\n saturation: themes.note?.saturation ?? saturation,\n },\n // Deliberately NOT `?? saturation`: the code palette is calibrated once and\n // does not follow the palette-level seed. See `PaletteCodeSeed`.\n code: { saturation: themes.code?.saturation ?? DEFAULT_CODE_SATURATION },\n },\n };\n}\n\n/**\n * The palette as it ships, with no tuning applied. Frozen — it is the baseline\n * every resolution falls back to, so a stray write to it would move the defaults\n * for the whole process.\n */\nexport const DEFAULT_PALETTE_CONFIG: ResolvedPaletteConfig = freezeConfig(\n resolveConfig({}),\n);\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * The last config *as written*, sparse — not the resolved one. Keeping the sparse\n * form is what makes inheritance live: a `saturation` with no `themes.danger.\n * saturation` beside it means danger genuinely follows the palette, rather than\n * having been frozen at whatever the palette read when it was set.\n */\nlet input: PaletteConfig = {};\nlet resolved: ResolvedPaletteConfig = DEFAULT_PALETTE_CONFIG;\nlet version = 0;\n\nconst listeners = new Set<() => void>();\n\nfunction mergeSeed<T extends PaletteThemeSeed | PaletteCodeSeed>(\n base: T | undefined,\n patch: T | undefined,\n): T | undefined {\n if (!base) return patch;\n // A patch that omits the theme entirely says nothing about it, so the base\n // survives. Clearing one of its fields is `{ theme: { hue: undefined } }`.\n if (!patch) return base;\n\n return { ...base, ...patch };\n}\n\n/**\n * Layer a patch over a base config. Used by {@link resolvePaletteConfig} for\n * previews — *not* by {@link setPaletteConfig}, which replaces.\n */\nfunction mergeInput(base: PaletteConfig, patch: PaletteConfig): PaletteConfig {\n const next: PaletteConfig = { ...base, ...patch };\n\n if (base.themes || patch.themes) {\n next.themes = {\n success: mergeSeed(base.themes?.success, patch.themes?.success),\n danger: mergeSeed(base.themes?.danger, patch.themes?.danger),\n warning: mergeSeed(base.themes?.warning, patch.themes?.warning),\n note: mergeSeed(base.themes?.note, patch.themes?.note),\n code: mergeSeed(base.themes?.code, patch.themes?.code),\n };\n }\n\n return next;\n}\n\nfunction isSameConfig(a: ResolvedPaletteConfig, b: ResolvedPaletteConfig) {\n return (\n a.hue === b.hue &&\n a.baseHue === b.baseHue &&\n a.saturation === b.saturation &&\n a.pastel === b.pastel &&\n a.contrastLevel === b.contrastLevel &&\n a.themes.code.saturation === b.themes.code.saturation &&\n (['success', 'danger', 'warning', 'note'] as const).every(\n (name) =>\n a.themes[name].hue === b.themes[name].hue &&\n a.themes[name].saturation === b.themes[name].saturation,\n )\n );\n}\n\n/**\n * Which fields are *explicitly set*, as an order-independent signature.\n *\n * Two configs can resolve to identical values yet differ in which of those values\n * are pinned rather than inherited — pinning `primary.saturation` to the number it\n * already inherited is the obvious case. That difference is invisible to\n * {@link isSameConfig} but visible through {@link getPaletteConfigInput}, so it has\n * to count as a change or a settings UI reading it would never re-render.\n */\nfunction pinSignature(config: PaletteConfig): string {\n const set = (value: unknown) => (value === undefined ? '0' : '1');\n\n return [\n set(config.hue),\n set(config.baseHue),\n set(config.saturation),\n set(config.pastel),\n set(config.contrastLevel),\n set(config.themes?.code?.saturation),\n ...(['success', 'danger', 'warning', 'note'] as const).flatMap((name) => [\n set(config.themes?.[name]?.hue),\n set(config.themes?.[name]?.saturation),\n ]),\n ].join('');\n}\n\n/**\n * Snapshot a config so the store owns it outright.\n *\n * Two hazards this closes. The caller's object stays theirs, so mutating it after\n * the call cannot desync `input` from `resolved`. And what we hand back from\n * {@link getPaletteConfig} / {@link getPaletteConfigInput} is frozen, so a caller\n * who writes to it gets a clear failure rather than silently corrupting the store\n * — the version would not bump, and every token cache would go on serving values\n * that no longer match the config.\n */\nfunction freezeConfig<T extends PaletteConfig | ResolvedPaletteConfig>(\n config: T,\n): T {\n const themes = config.themes;\n\n if (themes) {\n for (const seed of Object.values(themes)) {\n if (seed) Object.freeze(seed);\n }\n Object.freeze(themes);\n }\n\n return Object.freeze(config);\n}\n\n/** {@link freezeConfig} on a copy, for a config we did not create ourselves. */\nfunction snapshotConfig(config: PaletteConfig): PaletteConfig {\n const themes = config.themes;\n\n return freezeConfig({\n ...config,\n ...(themes\n ? {\n themes: {\n ...(themes.success ? { success: { ...themes.success } } : null),\n ...(themes.danger ? { danger: { ...themes.danger } } : null),\n ...(themes.warning ? { warning: { ...themes.warning } } : null),\n ...(themes.note ? { note: { ...themes.note } } : null),\n ...(themes.code ? { code: { ...themes.code } } : null),\n },\n }\n : null),\n });\n}\n\nfunction commit(nextInput: PaletteConfig) {\n const nextResolved = resolveConfig(nextInput);\n\n // Bail before bumping the version when nothing observable moved, so re-applying\n // the same config — an inline `<Root palette={{ … }}>` literal on every\n // render, a StrictMode double render — costs nothing.\n if (\n isSameConfig(resolved, nextResolved) &&\n pinSignature(input) === pinSignature(nextInput)\n ) {\n return;\n }\n\n input = snapshotConfig(nextInput);\n resolved = freezeConfig(nextResolved);\n version++;\n\n listeners.forEach((listener) => listener());\n}\n\n/**\n * Set the palette config.\n *\n * **Replaces**, like `useState` — the config you pass *is* the config, resolved\n * against the shipped defaults. Nothing accumulates, so a field you leave out is a\n * field you do not have: dropping a customization means dropping it from the\n * object, and re-applying the same object twice is the same as applying it once.\n *\n * ```ts\n * setPaletteConfig({ hue: 200, baseHue: 60 });\n * setPaletteConfig({ hue: 200 }); // baseHue is gone — back to inheriting `hue`\n * ```\n *\n * To adjust one field of the config already in place — a slider in a settings UI —\n * pass an updater. It receives the config as written, sparse, so spreading it\n * preserves which fields are pinned and which still inherit:\n *\n * ```ts\n * setPaletteConfig((config) => ({ ...config, hue: 200 }));\n * ```\n *\n * The palette is rebuilt lazily on the next token read, and any mounted `<Root>`\n * re-injects the token block — no component re-render is involved, because every\n * color in the kit resolves through a CSS custom property.\n */\nexport function setPaletteConfig(\n config: PaletteConfig | ((previous: PaletteConfig) => PaletteConfig),\n): void {\n commit(typeof config === 'function' ? config(input) : config);\n}\n\n/**\n * Drop all tuning and restore the palette the kit ships with. Identical to\n * `setPaletteConfig({})`; it exists to be readable at a call site.\n */\nexport function resetPaletteConfig(): void {\n commit({});\n}\n\n/**\n * Force every token to re-resolve without changing the palette config.\n *\n * Only needed if you drive Glaze directly — `glaze.configure({ darkTone })` and\n * the like. Glaze invalidates its own caches, but the kit's token maps are\n * memoized against *this* module's version, so they need telling. Calling it\n * before the first paint is unnecessary; nothing has been resolved yet.\n */\nexport function invalidatePaletteTokens(): void {\n version++;\n listeners.forEach((listener) => listener());\n}\n\n/** The current config, with every field resolved to a concrete value. */\nexport function getPaletteConfig(): ResolvedPaletteConfig {\n return resolved;\n}\n\n/**\n * The config **as set**, sparse — omitted fields are the ones still inheriting.\n *\n * {@link getPaletteConfig} resolves everything to concrete values, which loses the\n * distinction between \"explicitly 80\" and \"80 because it follows the brand\". A\n * settings UI needs that distinction to show an inherited value as inherited, and\n * to offer a way back:\n *\n * ```ts\n * const pinned = getPaletteConfigInput().baseHue !== undefined;\n *\n * // Re-link it to the brand by dropping the field.\n * setPaletteConfig(({ baseHue, ...config }) => config);\n * ```\n *\n * It is also the value handed to a {@link setPaletteConfig} updater.\n */\nexport function getPaletteConfigInput(): PaletteConfig {\n return input;\n}\n\n/**\n * Resolve a patch **over** the current config, without applying it.\n *\n * This one layers, unlike {@link setPaletteConfig}: a preview wants \"the theme in\n * use, but in dark\", so the fields it does not mention have to come from the live\n * config rather than from the defaults. The store is not touched and no listener\n * fires.\n */\nexport function resolvePaletteConfig(\n config?: PaletteConfig,\n): ResolvedPaletteConfig {\n if (!config) return resolved;\n\n return resolveConfig(mergeInput(input, config));\n}\n\n/**\n * Increments whenever the resolved config changes. The token caches in\n * `./palette.ts`, `./colors.ts` and `./index.ts` compare against it instead of\n * memoizing forever — the same idiom Glaze uses for its own config version.\n */\nexport function getPaletteVersion(): number {\n return version;\n}\n\n/** Subscribe to palette config changes. Returns an unsubscribe function. */\nexport function subscribePaletteConfig(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n// ============================================================================\n// React bindings\n// ============================================================================\n\n/**\n * Re-render on palette config changes. Returns the version, not the config, so\n * the snapshot is a primitive and React never warns about an uncached snapshot.\n */\nexport function usePaletteVersion(): number {\n return useSyncExternalStore(\n subscribePaletteConfig,\n getPaletteVersion,\n getPaletteVersion,\n );\n}\n\n/**\n * Read and tune the palette from React, `useState`-style — including the part\n * where the setter *replaces*. A control that changes one field wants the updater\n * form, or it will drop every other field:\n *\n * ```tsx\n * const [palette, setPalette] = usePaletteConfig();\n *\n * <HueSlider\n * value={palette.hue}\n * onChange={(hue) => setPalette((config) => ({ ...config, hue }))}\n * />\n * ```\n *\n * The first element is the *resolved* config, so `palette.hue` is always a number.\n * The updater's argument is the sparse one — see {@link getPaletteConfigInput}.\n *\n * The config is global process state, so every consumer of this hook — and every\n * mounted `<Root>` — sees the same palette.\n */\nexport function usePaletteConfig(): readonly [\n ResolvedPaletteConfig,\n typeof setPaletteConfig,\n] {\n usePaletteVersion();\n\n return [getPaletteConfig(), setPaletteConfig];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"palette-config.js","names":[],"sources":["../../src/tokens/palette-config.ts"],"sourcesContent":["import { useSyncExternalStore } from 'react';\n\n/**\n * Runtime configuration for the Glaze-generated color palette.\n *\n * The palette recipe itself lives in `./palette.ts`; this module owns only the\n * *seeds* it is built from, plus a version counter the token caches watch. It\n * deliberately imports nothing else — not the token modules, not `glaze` — so\n * there is no import cycle and no ordering hazard.\n *\n * Reading is free; writing rebuilds the palette on the next token read. See\n * `Getting Started/Theming` in Storybook for the full contract.\n */\n\n// ============================================================================\n// Default seeds\n// ============================================================================\n\n/** Brand hue. Drives the `default`, `primary`, `purple` and `special` themes. */\nexport const DEFAULT_HUE = 280.3;\nexport const DEFAULT_SUCCESS_HUE = 156.9;\nexport const DEFAULT_DANGER_HUE = 23.1;\nexport const DEFAULT_WARNING_HUE = 84.3;\nexport const DEFAULT_NOTE_HUE = 302.3;\n\n/** Seed saturation. Per-color `saturation` in the recipe is a 0–1 factor of it. */\nexport const DEFAULT_SATURATION = 80;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Hue / saturation seed override for one colored theme. */\nexport interface PaletteThemeSeed {\n /** Hue in degrees (0–360). */\n hue?: number;\n /** Saturation (0–100). Defaults to the palette-level `saturation`. */\n saturation?: number;\n}\n\n/**\n * The `code-*` syntax family takes a saturation and nothing else — and answers to\n * nothing else either. This is the one knob that moves it.\n *\n * Its hues are absolute literals by design, so syntax colors never rotate with the\n * brand — strings would collide with numbers the moment the brand went green. Unlike\n * every other theme, its saturation does **not** inherit the palette-level one: the\n * code palette is calibrated once and stays there, so re-seeding the app cannot\n * quietly wash out a code block. {@link PaletteConfig.pastel} skips it for the same\n * reason.\n */\nexport interface PaletteCodeSeed {\n /** Saturation (0–100). Defaults to {@link DEFAULT_SATURATION}, not to `saturation`. */\n saturation?: number;\n}\n\n/** Names of the themes whose seeds can be overridden individually. */\nexport type PaletteThemeName =\n | 'success'\n | 'danger'\n | 'warning'\n | 'note'\n | 'code';\n\n/**\n * Palette tuning. Every field is optional; omitted fields keep their default,\n * and per-theme fields left unset inherit the palette-level value.\n */\nexport interface PaletteConfig {\n /**\n * Accent hue in degrees (0–360) — the brand.\n *\n * Drives the `accent-*` family on every theme, `primary` / `purple` / `special`,\n * and the brand-tinted odds and ends (`focus`, the loading faces, the disabled\n * chip). Also the default for {@link PaletteConfig.baseHue}.\n */\n hue?: number;\n /**\n * Hue of the **base** zone in degrees (0–360): the neutral chrome — `surface`\n * and its ladder, the `surface-text*` ramp, `border`, `placeholder`. Defaults to\n * `hue`, so the chrome carries a faint tint of the brand unless you say otherwise.\n *\n * Splitting it lets the chrome sit on a different hue from the accent — a warm\n * grey UI with a cool blue brand, say. Only the `default` theme is affected: a\n * colored theme's tinted `surface` deliberately follows *its own* hue, because a\n * danger banner should read as red.\n */\n baseHue?: number;\n /**\n * Seed saturation (0–100), and the fallback for every theme that does not set\n * its own.\n *\n * One scale for the whole theme, by design. Every color's own `saturation` is a\n * 0–1 factor of this seed — `surface` at 0.12, `border` at 0.175, the text ramp\n * at 0.2, the accent family at ~1.0 — so moving it rescales the palette while\n * keeping those proportions. Unlike hue, which is configured separately for the\n * brand and for each status theme, saturation is deliberately not split: the\n * ratio between a subtle surface tint and a saturated accent is part of the\n * design.\n */\n saturation?: number;\n /**\n * Global. Widens the usable chroma range by relaxing the sRGB-safe limit,\n * producing a softer, more even palette across hues. Glaze treats `pastel` as\n * instance-level, so it is threaded into every theme.\n *\n * Every theme except `code`. The syntax family is calibrated on its own\n * saturation and is deliberately left out — softening it collapses the chroma\n * spread the syntax hues rely on to stay apart. To soften a code block, lower\n * {@link PaletteCodeSeed.saturation} instead.\n */\n pastel?: boolean;\n /**\n * Global. `'auto'` (the default) keeps the two-tier model: normal colors plus\n * a separate high-contrast tier driven by `<html data-contrast=\"high\">` /\n * `prefers-contrast: more`.\n *\n * A number (0–100) replaces that switch with a slider — and, because a manual\n * level already carries the contrast preference, **drops the high-contrast\n * tier entirely**. `0` reproduces the normal output and `100` the\n * high-contrast output, bit for bit.\n */\n contrastLevel?: number | 'auto';\n /** Per-theme seed overrides. */\n themes?: {\n success?: PaletteThemeSeed;\n danger?: PaletteThemeSeed;\n warning?: PaletteThemeSeed;\n note?: PaletteThemeSeed;\n code?: PaletteCodeSeed;\n };\n}\n\n/** {@link PaletteConfig} with every field resolved to a concrete value. */\nexport interface ResolvedPaletteConfig {\n hue: number;\n baseHue: number;\n saturation: number;\n pastel: boolean;\n contrastLevel: number | 'auto';\n themes: {\n success: { hue: number; saturation: number };\n danger: { hue: number; saturation: number };\n warning: { hue: number; saturation: number };\n note: { hue: number; saturation: number };\n code: { saturation: number };\n };\n}\n\n// ============================================================================\n// Resolution\n// ============================================================================\n\nconst DEFAULT_THEME_HUES = {\n success: DEFAULT_SUCCESS_HUE,\n danger: DEFAULT_DANGER_HUE,\n warning: DEFAULT_WARNING_HUE,\n note: DEFAULT_NOTE_HUE,\n} as const;\n\nfunction resolveConfig(input: PaletteConfig): ResolvedPaletteConfig {\n const saturation = input.saturation ?? DEFAULT_SATURATION;\n const themes = input.themes ?? {};\n\n const hue = input.hue ?? DEFAULT_HUE;\n\n return {\n hue,\n baseHue: input.baseHue ?? hue,\n saturation,\n pastel: input.pastel ?? false,\n contrastLevel: input.contrastLevel ?? 'auto',\n themes: {\n success: {\n hue: themes.success?.hue ?? DEFAULT_THEME_HUES.success,\n saturation: themes.success?.saturation ?? saturation,\n },\n danger: {\n hue: themes.danger?.hue ?? DEFAULT_THEME_HUES.danger,\n saturation: themes.danger?.saturation ?? saturation,\n },\n warning: {\n hue: themes.warning?.hue ?? DEFAULT_THEME_HUES.warning,\n saturation: themes.warning?.saturation ?? saturation,\n },\n note: {\n hue: themes.note?.hue ?? DEFAULT_THEME_HUES.note,\n saturation: themes.note?.saturation ?? saturation,\n },\n // Deliberately NOT `?? saturation`: the code palette is calibrated once and\n // does not follow the palette-level seed. See `PaletteCodeSeed`.\n code: { saturation: themes.code?.saturation ?? DEFAULT_SATURATION },\n },\n };\n}\n\n/**\n * The palette as it ships, with no tuning applied. Frozen — it is the baseline\n * every resolution falls back to, so a stray write to it would move the defaults\n * for the whole process.\n */\nexport const DEFAULT_PALETTE_CONFIG: ResolvedPaletteConfig = freezeConfig(\n resolveConfig({}),\n);\n\n// ============================================================================\n// Store\n// ============================================================================\n\n/**\n * The last config *as written*, sparse — not the resolved one. Keeping the sparse\n * form is what makes inheritance live: a `saturation` with no `themes.danger.\n * saturation` beside it means danger genuinely follows the palette, rather than\n * having been frozen at whatever the palette read when it was set.\n */\nlet input: PaletteConfig = {};\nlet resolved: ResolvedPaletteConfig = DEFAULT_PALETTE_CONFIG;\nlet version = 0;\n\nconst listeners = new Set<() => void>();\n\nfunction mergeSeed<T extends PaletteThemeSeed | PaletteCodeSeed>(\n base: T | undefined,\n patch: T | undefined,\n): T | undefined {\n if (!base) return patch;\n // A patch that omits the theme entirely says nothing about it, so the base\n // survives. Clearing one of its fields is `{ theme: { hue: undefined } }`.\n if (!patch) return base;\n\n return { ...base, ...patch };\n}\n\n/**\n * Layer a patch over a base config. Used by {@link resolvePaletteConfig} for\n * previews — *not* by {@link setPaletteConfig}, which replaces.\n */\nfunction mergeInput(base: PaletteConfig, patch: PaletteConfig): PaletteConfig {\n const next: PaletteConfig = { ...base, ...patch };\n\n if (base.themes || patch.themes) {\n next.themes = {\n success: mergeSeed(base.themes?.success, patch.themes?.success),\n danger: mergeSeed(base.themes?.danger, patch.themes?.danger),\n warning: mergeSeed(base.themes?.warning, patch.themes?.warning),\n note: mergeSeed(base.themes?.note, patch.themes?.note),\n code: mergeSeed(base.themes?.code, patch.themes?.code),\n };\n }\n\n return next;\n}\n\nfunction isSameConfig(a: ResolvedPaletteConfig, b: ResolvedPaletteConfig) {\n return (\n a.hue === b.hue &&\n a.baseHue === b.baseHue &&\n a.saturation === b.saturation &&\n a.pastel === b.pastel &&\n a.contrastLevel === b.contrastLevel &&\n a.themes.code.saturation === b.themes.code.saturation &&\n (['success', 'danger', 'warning', 'note'] as const).every(\n (name) =>\n a.themes[name].hue === b.themes[name].hue &&\n a.themes[name].saturation === b.themes[name].saturation,\n )\n );\n}\n\n/**\n * Which fields are *explicitly set*, as an order-independent signature.\n *\n * Two configs can resolve to identical values yet differ in which of those values\n * are pinned rather than inherited — pinning `primary.saturation` to the number it\n * already inherited is the obvious case. That difference is invisible to\n * {@link isSameConfig} but visible through {@link getPaletteConfigInput}, so it has\n * to count as a change or a settings UI reading it would never re-render.\n */\nfunction pinSignature(config: PaletteConfig): string {\n const set = (value: unknown) => (value === undefined ? '0' : '1');\n\n return [\n set(config.hue),\n set(config.baseHue),\n set(config.saturation),\n set(config.pastel),\n set(config.contrastLevel),\n set(config.themes?.code?.saturation),\n ...(['success', 'danger', 'warning', 'note'] as const).flatMap((name) => [\n set(config.themes?.[name]?.hue),\n set(config.themes?.[name]?.saturation),\n ]),\n ].join('');\n}\n\n/**\n * Snapshot a config so the store owns it outright.\n *\n * Two hazards this closes. The caller's object stays theirs, so mutating it after\n * the call cannot desync `input` from `resolved`. And what we hand back from\n * {@link getPaletteConfig} / {@link getPaletteConfigInput} is frozen, so a caller\n * who writes to it gets a clear failure rather than silently corrupting the store\n * — the version would not bump, and every token cache would go on serving values\n * that no longer match the config.\n */\nfunction freezeConfig<T extends PaletteConfig | ResolvedPaletteConfig>(\n config: T,\n): T {\n const themes = config.themes;\n\n if (themes) {\n for (const seed of Object.values(themes)) {\n if (seed) Object.freeze(seed);\n }\n Object.freeze(themes);\n }\n\n return Object.freeze(config);\n}\n\n/** {@link freezeConfig} on a copy, for a config we did not create ourselves. */\nfunction snapshotConfig(config: PaletteConfig): PaletteConfig {\n const themes = config.themes;\n\n return freezeConfig({\n ...config,\n ...(themes\n ? {\n themes: {\n ...(themes.success ? { success: { ...themes.success } } : null),\n ...(themes.danger ? { danger: { ...themes.danger } } : null),\n ...(themes.warning ? { warning: { ...themes.warning } } : null),\n ...(themes.note ? { note: { ...themes.note } } : null),\n ...(themes.code ? { code: { ...themes.code } } : null),\n },\n }\n : null),\n });\n}\n\nfunction commit(nextInput: PaletteConfig) {\n const nextResolved = resolveConfig(nextInput);\n\n // Bail before bumping the version when nothing observable moved, so re-applying\n // the same config — an inline `<Root palette={{ … }}>` literal on every\n // render, a StrictMode double render — costs nothing.\n if (\n isSameConfig(resolved, nextResolved) &&\n pinSignature(input) === pinSignature(nextInput)\n ) {\n return;\n }\n\n input = snapshotConfig(nextInput);\n resolved = freezeConfig(nextResolved);\n version++;\n\n listeners.forEach((listener) => listener());\n}\n\n/**\n * Set the palette config.\n *\n * **Replaces**, like `useState` — the config you pass *is* the config, resolved\n * against the shipped defaults. Nothing accumulates, so a field you leave out is a\n * field you do not have: dropping a customization means dropping it from the\n * object, and re-applying the same object twice is the same as applying it once.\n *\n * ```ts\n * setPaletteConfig({ hue: 200, baseHue: 60 });\n * setPaletteConfig({ hue: 200 }); // baseHue is gone — back to inheriting `hue`\n * ```\n *\n * To adjust one field of the config already in place — a slider in a settings UI —\n * pass an updater. It receives the config as written, sparse, so spreading it\n * preserves which fields are pinned and which still inherit:\n *\n * ```ts\n * setPaletteConfig((config) => ({ ...config, hue: 200 }));\n * ```\n *\n * The palette is rebuilt lazily on the next token read, and any mounted `<Root>`\n * re-injects the token block — no component re-render is involved, because every\n * color in the kit resolves through a CSS custom property.\n */\nexport function setPaletteConfig(\n config: PaletteConfig | ((previous: PaletteConfig) => PaletteConfig),\n): void {\n commit(typeof config === 'function' ? config(input) : config);\n}\n\n/**\n * Drop all tuning and restore the palette the kit ships with. Identical to\n * `setPaletteConfig({})`; it exists to be readable at a call site.\n */\nexport function resetPaletteConfig(): void {\n commit({});\n}\n\n/**\n * Force every token to re-resolve without changing the palette config.\n *\n * Only needed if you drive Glaze directly — `glaze.configure({ darkTone })` and\n * the like. Glaze invalidates its own caches, but the kit's token maps are\n * memoized against *this* module's version, so they need telling. Calling it\n * before the first paint is unnecessary; nothing has been resolved yet.\n */\nexport function invalidatePaletteTokens(): void {\n version++;\n listeners.forEach((listener) => listener());\n}\n\n/** The current config, with every field resolved to a concrete value. */\nexport function getPaletteConfig(): ResolvedPaletteConfig {\n return resolved;\n}\n\n/**\n * The config **as set**, sparse — omitted fields are the ones still inheriting.\n *\n * {@link getPaletteConfig} resolves everything to concrete values, which loses the\n * distinction between \"explicitly 80\" and \"80 because it follows the brand\". A\n * settings UI needs that distinction to show an inherited value as inherited, and\n * to offer a way back:\n *\n * ```ts\n * const pinned = getPaletteConfigInput().baseHue !== undefined;\n *\n * // Re-link it to the brand by dropping the field.\n * setPaletteConfig(({ baseHue, ...config }) => config);\n * ```\n *\n * It is also the value handed to a {@link setPaletteConfig} updater.\n */\nexport function getPaletteConfigInput(): PaletteConfig {\n return input;\n}\n\n/**\n * Resolve a patch **over** the current config, without applying it.\n *\n * This one layers, unlike {@link setPaletteConfig}: a preview wants \"the theme in\n * use, but in dark\", so the fields it does not mention have to come from the live\n * config rather than from the defaults. The store is not touched and no listener\n * fires.\n */\nexport function resolvePaletteConfig(\n config?: PaletteConfig,\n): ResolvedPaletteConfig {\n if (!config) return resolved;\n\n return resolveConfig(mergeInput(input, config));\n}\n\n/**\n * Increments whenever the resolved config changes. The token caches in\n * `./palette.ts`, `./colors.ts` and `./index.ts` compare against it instead of\n * memoizing forever — the same idiom Glaze uses for its own config version.\n */\nexport function getPaletteVersion(): number {\n return version;\n}\n\n/** Subscribe to palette config changes. Returns an unsubscribe function. */\nexport function subscribePaletteConfig(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n// ============================================================================\n// React bindings\n// ============================================================================\n\n/**\n * Re-render on palette config changes. Returns the version, not the config, so\n * the snapshot is a primitive and React never warns about an uncached snapshot.\n */\nexport function usePaletteVersion(): number {\n return useSyncExternalStore(\n subscribePaletteConfig,\n getPaletteVersion,\n getPaletteVersion,\n );\n}\n\n/**\n * Read and tune the palette from React, `useState`-style — including the part\n * where the setter *replaces*. A control that changes one field wants the updater\n * form, or it will drop every other field:\n *\n * ```tsx\n * const [palette, setPalette] = usePaletteConfig();\n *\n * <HueSlider\n * value={palette.hue}\n * onChange={(hue) => setPalette((config) => ({ ...config, hue }))}\n * />\n * ```\n *\n * The first element is the *resolved* config, so `palette.hue` is always a number.\n * The updater's argument is the sparse one — see {@link getPaletteConfigInput}.\n *\n * The config is global process state, so every consumer of this hook — and every\n * mounted `<Root>` — sees the same palette.\n */\nexport function usePaletteConfig(): readonly [\n ResolvedPaletteConfig,\n typeof setPaletteConfig,\n] {\n usePaletteVersion();\n\n return [getPaletteConfig(), setPaletteConfig];\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { PaletteConfig } from "./palette-config.js";
3
3
  import { Styles, Tokens } from "@tenphi/tasty";
4
- import { GlazePalette, GlazeTheme } from "@tenphi/glaze";
4
+ import { ColorMap, GlazePalette, GlazeTheme } from "@tenphi/glaze";
5
5
 
6
6
  //#region src/tokens/palette.d.ts
7
7
  /** Which resolved scheme variant {@link renderPaletteTokens} should return. */
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-7464463 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a5d43c3 | Cube Dev Team */
2
2
  import { getPaletteConfig, getPaletteVersion, resolvePaletteConfig } from "./palette-config.js";
3
3
  import { lazyStyles } from "./lazy-styles.js";
4
4
  import { glaze } from "@tenphi/glaze";
@@ -198,6 +198,48 @@ const TINTED_SURFACE_OVERRIDE = {
198
198
  }
199
199
  };
200
200
  /**
201
+ * A tinted surface, a banding step, and text guaranteed to read on both.
202
+ *
203
+ * The recipe behind {@link getColorTheme} in `./color-theme.ts`, which builds
204
+ * one-off themes at runtime from an arbitrary hue. It lives here so it shares
205
+ * `TINTED_SURFACE_SATURATION`, the tone offsets and the text ramp with
206
+ * {@link TINTED_SURFACE_OVERRIDE} above rather than forking them — a runtime tint
207
+ * and a built-in theme's `surface` should be the same colour for the same hue.
208
+ *
209
+ * Three colours, because that is what banded, readable table column needs:
210
+ * `surface` for even rows, `surface-2` one tone step down for odd rows and
211
+ * pinned totals, and `surface-2-text`.
212
+ *
213
+ * The text is anchored to `surface-2`, not `surface`. `surface-2` has the lower
214
+ * contrast headroom in BOTH schemes — a darker background under dark text in
215
+ * light, a lighter one under light text in dark — so solving the floor there
216
+ * clears it on both bands. The neutral ramp's own `surface-2-text` is shaped the
217
+ * same way for the same reason.
218
+ */
219
+ const TINT_RECIPE = {
220
+ surface: {
221
+ tone: [100 - TINTED_SURFACE_TONE_OFFSET, 100 - TINTED_SURFACE_TONE_OFFSET * 2],
222
+ saturation: TINTED_SURFACE_SATURATION
223
+ },
224
+ "surface-2": {
225
+ base: "surface",
226
+ tone: ["-2", "-4"],
227
+ saturation: TINTED_SURFACE_SATURATION
228
+ },
229
+ "surface-2-text": {
230
+ base: "surface-2",
231
+ tone: `${TEXT_TONE - TINTED_SURFACE_TONE_OFFSET - SURFACE_2_TEXT_OFFSET}`,
232
+ saturation: .25,
233
+ contrast: ["AA", "AAA"]
234
+ },
235
+ "surface-2-text-soft": {
236
+ base: "surface-2",
237
+ tone: `${TEXT_SOFT_TONE - TINTED_SURFACE_TONE_OFFSET - SURFACE_2_TEXT_OFFSET}`,
238
+ saturation: .25,
239
+ contrast: ["AA", "AAA"]
240
+ }
241
+ };
242
+ /**
201
243
  * Build the full palette from a resolved config.
202
244
  *
203
245
  * Pure: it reads nothing but its argument (and the global Glaze config, which
@@ -708,5 +750,5 @@ function renderPaletteTokens(options = {}) {
708
750
  const PALETTE_TOKENS = lazyStyles(getPaletteTokens);
709
751
 
710
752
  //#endregion
711
- export { PALETTE_TOKENS, getCodeTheme, getPalette, getPaletteTokens, renderPaletteTokens };
753
+ export { PALETTE_TOKENS, TINT_RECIPE, getCodeTheme, getPalette, getPaletteTokens, renderPaletteTokens };
712
754
  //# sourceMappingURL=palette.js.map