@cube-dev/ui-kit 0.154.1 → 0.156.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (565) hide show
  1. package/dist/CHANGELOG.md +99 -0
  2. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  3. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  4. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  5. package/dist/_internal/hooks/use-event.js +1 -1
  6. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  7. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  8. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  9. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  10. package/dist/_internal/hooks/use-warn.js +1 -1
  11. package/dist/components/Block.js +1 -1
  12. package/dist/components/CollectionItem.js +1 -1
  13. package/dist/components/GlobalStyles.js +1 -1
  14. package/dist/components/GridProvider.js +1 -1
  15. package/dist/components/HiddenInput.js +1 -1
  16. package/dist/components/Root.js +1 -1
  17. package/dist/components/actions/Action/Action.js +1 -1
  18. package/dist/components/actions/Banner/Banner.js +1 -1
  19. package/dist/components/actions/Button/Button.js +1 -1
  20. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  21. package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
  22. package/dist/components/actions/ButtonSplit/context.js +1 -1
  23. package/dist/components/actions/CommandMenu/CommandMenu.d.ts +10 -1
  24. package/dist/components/actions/CommandMenu/CommandMenu.js +4 -3
  25. package/dist/components/actions/CommandMenu/CommandMenu.js.map +1 -1
  26. package/dist/components/actions/CommandMenu/styled.js +1 -1
  27. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  28. package/dist/components/actions/ItemActionContext.js +1 -1
  29. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  30. package/dist/components/actions/Link/Link.js +1 -1
  31. package/dist/components/actions/Menu/Menu.js +1 -1
  32. package/dist/components/actions/Menu/MenuItem.js +1 -1
  33. package/dist/components/actions/Menu/MenuSection.js +1 -1
  34. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  35. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  36. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  37. package/dist/components/actions/Menu/context.js +1 -1
  38. package/dist/components/actions/Menu/styled.js +1 -1
  39. package/dist/components/actions/index.js +1 -1
  40. package/dist/components/actions/use-action.js +1 -1
  41. package/dist/components/actions/use-anchored-menu.js +1 -1
  42. package/dist/components/actions/use-context-menu.js +1 -1
  43. package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
  44. package/dist/components/content/Alert/Alert.js +1 -1
  45. package/dist/components/content/Alert/use-alert.js +1 -1
  46. package/dist/components/content/Avatar/Avatar.js +1 -1
  47. package/dist/components/content/Badge/Badge.js +1 -1
  48. package/dist/components/content/Card/Card.js +1 -1
  49. package/dist/components/content/Content.js +1 -1
  50. package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  51. package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
  52. package/dist/components/content/Disclosure/Disclosure.js +1 -1
  53. package/dist/components/content/Divider.js +1 -1
  54. package/dist/components/content/Footer.js +1 -1
  55. package/dist/components/content/Header.js +1 -1
  56. package/dist/components/content/HotKeys/HotKeys.js +1 -1
  57. package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
  58. package/dist/components/content/InlineInput/InlineInput.js +1 -1
  59. package/dist/components/content/Item/Item.d.ts +2 -1
  60. package/dist/components/content/Item/Item.js +1 -1
  61. package/dist/components/content/Item/Item.js.map +1 -1
  62. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  63. package/dist/components/content/ItemCard/ItemCard.js +1 -1
  64. package/dist/components/content/Layout/GridLayout.js +1 -1
  65. package/dist/components/content/Layout/Layout.js +1 -1
  66. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  67. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  68. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  69. package/dist/components/content/Layout/LayoutContent.js +1 -1
  70. package/dist/components/content/Layout/LayoutContext.js +1 -1
  71. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  72. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  73. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  74. package/dist/components/content/Layout/LayoutHeader.js +1 -1
  75. package/dist/components/content/Layout/LayoutPane.js +1 -1
  76. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  77. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  78. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  79. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  80. package/dist/components/content/Layout/index.js +1 -1
  81. package/dist/components/content/Layout/utils.js +1 -1
  82. package/dist/components/content/Paragraph.js +1 -1
  83. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  84. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  85. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  86. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  87. package/dist/components/content/Result/Result.js +1 -1
  88. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  89. package/dist/components/content/Tag/Tag.js +1 -1
  90. package/dist/components/content/Text.d.ts +21 -42
  91. package/dist/components/content/Text.js +4 -5
  92. package/dist/components/content/Text.js.map +1 -1
  93. package/dist/components/content/TextItem/TextItem.js +1 -1
  94. package/dist/components/content/Title.js +2 -3
  95. package/dist/components/content/Title.js.map +1 -1
  96. package/dist/components/content/Tree/Tree.js +1 -1
  97. package/dist/components/content/Tree/TreeNode.js +1 -1
  98. package/dist/components/content/Tree/styled.js +1 -1
  99. package/dist/components/content/Tree/tree-index.js +1 -1
  100. package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
  101. package/dist/components/content/Tree/use-load-data.js +1 -1
  102. package/dist/components/content/highlightText.js +1 -1
  103. package/dist/components/content/use-auto-tooltip.d.ts +0 -1
  104. package/dist/components/content/use-auto-tooltip.js +1 -1
  105. package/dist/components/content/use-auto-tooltip.js.map +1 -1
  106. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  107. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  108. package/dist/components/fields/Checkbox/context.js +1 -1
  109. package/dist/components/fields/ColorPicker/ColorPicker.d.ts +67 -0
  110. package/dist/components/fields/ColorPicker/ColorPicker.js +240 -0
  111. package/dist/components/fields/ColorPicker/ColorPicker.js.map +1 -0
  112. package/dist/components/fields/ColorPicker/ColorPickerPanel.js +149 -0
  113. package/dist/components/fields/ColorPicker/ColorPickerPanel.js.map +1 -0
  114. package/dist/components/fields/ColorPicker/channels.d.ts +13 -0
  115. package/dist/components/fields/ColorPicker/channels.js +194 -0
  116. package/dist/components/fields/ColorPicker/channels.js.map +1 -0
  117. package/dist/components/fields/ColorPicker/color.d.ts +15 -0
  118. package/dist/components/fields/ColorPicker/color.js +282 -0
  119. package/dist/components/fields/ColorPicker/color.js.map +1 -0
  120. package/dist/components/fields/ColorPicker/index.d.ts +4 -0
  121. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  122. package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
  123. package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
  124. package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
  125. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  126. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  127. package/dist/components/fields/DatePicker/DateInputBase.js.map +1 -1
  128. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  129. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  130. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  131. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  132. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  133. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  134. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  135. package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
  136. package/dist/components/fields/DatePicker/PeriodPicker.js +1 -1
  137. package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
  138. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  139. package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
  140. package/dist/components/fields/DatePicker/YearPicker.js +1 -1
  141. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  142. package/dist/components/fields/DatePicker/period.js +1 -1
  143. package/dist/components/fields/DatePicker/props.js +1 -1
  144. package/dist/components/fields/DatePicker/utils.js +1 -1
  145. package/dist/components/fields/FileInput/FileInput.d.ts +2 -1
  146. package/dist/components/fields/FileInput/FileInput.js +1 -1
  147. package/dist/components/fields/FileInput/FileInput.js.map +1 -1
  148. package/dist/components/fields/FilterListBox/FilterListBox.d.ts +3 -3
  149. package/dist/components/fields/FilterListBox/FilterListBox.js +7 -6
  150. package/dist/components/fields/FilterListBox/FilterListBox.js.map +1 -1
  151. package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
  152. package/dist/components/fields/Input/Input.js +1 -1
  153. package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
  154. package/dist/components/fields/ListBox/ListBox.js +1 -1
  155. package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
  156. package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
  157. package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
  158. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  159. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  160. package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
  161. package/dist/components/fields/Picker/Picker.js +1 -1
  162. package/dist/components/fields/RadioGroup/Radio.js +1 -1
  163. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  164. package/dist/components/fields/RadioGroup/context.js +1 -1
  165. package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
  166. package/dist/components/fields/SearchInput/SearchInput.js +1 -1
  167. package/dist/components/fields/Select/Select.d.ts +2 -1
  168. package/dist/components/fields/Select/Select.js +1 -1
  169. package/dist/components/fields/Select/Select.js.map +1 -1
  170. package/dist/components/fields/Slider/Gradation.js +1 -1
  171. package/dist/components/fields/Slider/HueSlider.js +1 -1
  172. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  173. package/dist/components/fields/Slider/Slider.js +1 -1
  174. package/dist/components/fields/Slider/SliderBase.js +1 -1
  175. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  176. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  177. package/dist/components/fields/Slider/elements.js +1 -1
  178. package/dist/components/fields/Slider/index.js +1 -1
  179. package/dist/components/fields/Switch/Switch.js +1 -1
  180. package/dist/components/fields/TextArea/TextArea.js +1 -1
  181. package/dist/components/fields/TextInput/TextInput.js +1 -1
  182. package/dist/components/fields/TextInput/TextInputBase.d.ts +2 -1
  183. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  184. package/dist/components/fields/TextInput/TextInputBase.js.map +1 -1
  185. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  186. package/dist/components/fields/index.d.ts +4 -0
  187. package/dist/components/form/FieldWrapper/FieldWrapper.d.ts +2 -1
  188. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  189. package/dist/components/form/FieldWrapper/types.d.ts +2 -1
  190. package/dist/components/form/Form/Field.js +1 -1
  191. package/dist/components/form/Form/Form.js +1 -1
  192. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  193. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  194. package/dist/components/form/Form/SubmitError.js +1 -1
  195. package/dist/components/form/Form/index.js +1 -1
  196. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  197. package/dist/components/form/Form/use-field/use-field.js +1 -1
  198. package/dist/components/form/Form/use-form.js +1 -1
  199. package/dist/components/form/Form/validation.js +1 -1
  200. package/dist/components/form/Label.js +1 -1
  201. package/dist/components/form/validation/ValidationIndicator.js +1 -1
  202. package/dist/components/form/validation/resolve-validation-props.js +1 -1
  203. package/dist/components/form/validation/use-validation-props.js +1 -1
  204. package/dist/components/form/wrapper.js +1 -1
  205. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  206. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  207. package/dist/components/layout/Board/Board.d.ts +55 -1
  208. package/dist/components/layout/Board/Board.js +278 -75
  209. package/dist/components/layout/Board/Board.js.map +1 -1
  210. package/dist/components/layout/Board/BoardProvider.js +1 -1
  211. package/dist/components/layout/Board/BoardResponsive.js +1 -1
  212. package/dist/components/layout/Board/Widget.d.ts +16 -0
  213. package/dist/components/layout/Board/Widget.js +6 -3
  214. package/dist/components/layout/Board/Widget.js.map +1 -1
  215. package/dist/components/layout/Board/WidgetHost.js +81 -14
  216. package/dist/components/layout/Board/WidgetHost.js.map +1 -1
  217. package/dist/components/layout/Board/board-context.js +1 -1
  218. package/dist/components/layout/Board/board-context.js.map +1 -1
  219. package/dist/components/layout/Board/board-store.js +2 -2
  220. package/dist/components/layout/Board/board-store.js.map +1 -1
  221. package/dist/components/layout/Board/grid-core/calculate.js +1 -1
  222. package/dist/components/layout/Board/grid-core/collision.js +1 -1
  223. package/dist/components/layout/Board/grid-core/compactors.js +1 -1
  224. package/dist/components/layout/Board/grid-core/constraints.js +1 -1
  225. package/dist/components/layout/Board/grid-core/group-move.js +132 -0
  226. package/dist/components/layout/Board/grid-core/group-move.js.map +1 -0
  227. package/dist/components/layout/Board/grid-core/layout.js +1 -1
  228. package/dist/components/layout/Board/grid-core/sort.js +1 -1
  229. package/dist/components/layout/Board/index.d.ts +2 -1
  230. package/dist/components/layout/Board/index.js +2 -2
  231. package/dist/components/layout/Board/index.js.map +1 -1
  232. package/dist/components/layout/Board/responsive-utils.js +1 -1
  233. package/dist/components/layout/Board/use-board-layout.js +17 -12
  234. package/dist/components/layout/Board/use-board-layout.js.map +1 -1
  235. package/dist/components/layout/Board/use-board-registry.js +139 -20
  236. package/dist/components/layout/Board/use-board-registry.js.map +1 -1
  237. package/dist/components/layout/Board/use-board-select-modifier-key.js +24 -0
  238. package/dist/components/layout/Board/use-board-select-modifier-key.js.map +1 -0
  239. package/dist/components/layout/Board/use-board-selection.d.ts +8 -0
  240. package/dist/components/layout/Board/use-board-selection.js +113 -0
  241. package/dist/components/layout/Board/use-board-selection.js.map +1 -0
  242. package/dist/components/layout/Flex.js +1 -1
  243. package/dist/components/layout/Flow.js +1 -1
  244. package/dist/components/layout/Grid.js +1 -1
  245. package/dist/components/layout/Panel.js +1 -1
  246. package/dist/components/layout/Prefix.js +1 -1
  247. package/dist/components/layout/ResizablePanel.js +1 -1
  248. package/dist/components/layout/Space.js +1 -1
  249. package/dist/components/layout/Suffix.js +1 -1
  250. package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
  251. package/dist/components/navigation/Tabs/TabButton.js +1 -1
  252. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  253. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  254. package/dist/components/navigation/Tabs/TabPicker.js +1 -1
  255. package/dist/components/navigation/Tabs/Tabs.js +1 -1
  256. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  257. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  258. package/dist/components/navigation/Tabs/popover-placement.js +1 -1
  259. package/dist/components/navigation/Tabs/styled.js +1 -1
  260. package/dist/components/navigation/Tabs/types.js +1 -1
  261. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  262. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  263. package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
  264. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  265. package/dist/components/other/Calendar/Calendar.js +1 -1
  266. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  267. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  268. package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
  269. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  270. package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
  271. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  272. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  273. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  274. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  275. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  276. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  277. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  278. package/dist/components/overlays/Dialog/context.js +1 -1
  279. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  280. package/dist/components/overlays/Modal/Modal.js +1 -1
  281. package/dist/components/overlays/Modal/Modal.js.map +1 -1
  282. package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
  283. package/dist/components/overlays/Modal/Overlay.js +1 -1
  284. package/dist/components/overlays/Modal/Overlay.js.map +1 -1
  285. package/dist/components/overlays/Modal/Popover.js +1 -1
  286. package/dist/components/overlays/Modal/Tray.js +1 -1
  287. package/dist/components/overlays/Modal/Tray.js.map +1 -1
  288. package/dist/components/overlays/Modal/Underlay.js +1 -1
  289. package/dist/components/overlays/Notifications/Notification.js +1 -1
  290. package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
  291. package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
  292. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  293. package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
  294. package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
  295. package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
  296. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  297. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  298. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  299. package/dist/components/overlays/Notifications/index.js +1 -1
  300. package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
  301. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  302. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  303. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  304. package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
  305. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  306. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  307. package/dist/components/overlays/Toast/index.js +1 -1
  308. package/dist/components/overlays/Toast/useProgressToast.js +1 -1
  309. package/dist/components/overlays/Toast/useToast.js +1 -1
  310. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  311. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  312. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  313. package/dist/components/overlays/Tooltip/context.js +1 -1
  314. package/dist/components/overlays/Tooltip/context.js.map +1 -1
  315. package/dist/components/portal/Portal.js +1 -1
  316. package/dist/components/portal/PortalProvider.js +1 -1
  317. package/dist/components/portal/usePortal.js +1 -1
  318. package/dist/components/shared/DraggableCollection.js +1 -1
  319. package/dist/components/shared/InvalidIcon.js +1 -1
  320. package/dist/components/shared/ValidIcon.js +1 -1
  321. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  322. package/dist/components/status/Spin/Cube.js +1 -1
  323. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  324. package/dist/components/status/Spin/Spin.js +1 -1
  325. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  326. package/dist/data/item-themes.js +1 -1
  327. package/dist/data/themes.js +1 -1
  328. package/dist/eslint-plugin/defaults.generated.js +9 -1
  329. package/dist/eslint-plugin/defaults.generated.js.map +1 -1
  330. package/dist/eslint-plugin/index.js +1 -1
  331. package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
  332. package/dist/i18n/I18nProvider.js +1 -1
  333. package/dist/i18n/createFormatter.js +1 -1
  334. package/dist/i18n/index.js +1 -1
  335. package/dist/i18n/instance.js +1 -1
  336. package/dist/i18n/locales/de-DE/uikit.js +9 -1
  337. package/dist/i18n/locales/en-US/uikit.js +9 -1
  338. package/dist/i18n/locales/en-US/uikit.json.d.ts +9 -1
  339. package/dist/i18n/locales/es-ES/uikit.js +9 -1
  340. package/dist/i18n/locales/es-MX/uikit.js +9 -1
  341. package/dist/i18n/locales/fr-FR/uikit.js +9 -1
  342. package/dist/i18n/locales/it-IT/uikit.js +9 -1
  343. package/dist/i18n/locales/ja-JP/uikit.js +9 -1
  344. package/dist/i18n/locales/nb-NO/uikit.js +9 -1
  345. package/dist/i18n/locales/pt-BR/uikit.js +9 -1
  346. package/dist/i18n/locales/pt-PT/uikit.js +9 -1
  347. package/dist/i18n/locales/sv-SE/uikit.js +9 -1
  348. package/dist/i18n/locales/vi-VN/uikit.js +9 -1
  349. package/dist/i18n/locales.js +1 -1
  350. package/dist/i18n/useFormatter.js +1 -1
  351. package/dist/i18n/useI18n.js +1 -1
  352. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  353. package/dist/icons/AdjustmentsIcon.js +1 -1
  354. package/dist/icons/AiIcon.js +1 -1
  355. package/dist/icons/AreaChartIcon.js +1 -1
  356. package/dist/icons/BackwardIcon.js +1 -1
  357. package/dist/icons/BarChartIcon.js +1 -1
  358. package/dist/icons/BellFilledIcon.js +1 -1
  359. package/dist/icons/BellIcon.js +1 -1
  360. package/dist/icons/BooleanIcon.js +1 -1
  361. package/dist/icons/CalendarEditIcon.js +1 -1
  362. package/dist/icons/CalendarIcon.js +1 -1
  363. package/dist/icons/CaretDownIcon.js +1 -1
  364. package/dist/icons/CaretUpIcon.js +1 -1
  365. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  366. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  367. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  368. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  369. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  370. package/dist/icons/ChartBarLineIcon.js +1 -1
  371. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  372. package/dist/icons/ChartBarStackedIcon.js +1 -1
  373. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  374. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  375. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  376. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  377. package/dist/icons/ChartBubbleIcon.js +1 -1
  378. package/dist/icons/ChartDonut2Icon.js +1 -1
  379. package/dist/icons/ChartFunnelIcon.js +1 -1
  380. package/dist/icons/ChartHeatmapIcon.js +1 -1
  381. package/dist/icons/ChartKPIIcon.js +1 -1
  382. package/dist/icons/ChartPie2Icon.js +1 -1
  383. package/dist/icons/ChartScatterIcon.js +1 -1
  384. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  385. package/dist/icons/CheckCircleIcon.js +1 -1
  386. package/dist/icons/CheckIcon.js +1 -1
  387. package/dist/icons/CircleFilledIcon.js +1 -1
  388. package/dist/icons/ClearIcon.js +1 -1
  389. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  390. package/dist/icons/CloseCircleIcon.js +1 -1
  391. package/dist/icons/CloseIcon.js +1 -1
  392. package/dist/icons/CodeIcon.js +1 -1
  393. package/dist/icons/ColumnTotalIcon.js +1 -1
  394. package/dist/icons/CopyIcon.js +1 -1
  395. package/dist/icons/CountIcon.js +1 -1
  396. package/dist/icons/CubeIcon.js +1 -1
  397. package/dist/icons/CubePauseIcon.js +1 -1
  398. package/dist/icons/CubePlayIcon.js +1 -1
  399. package/dist/icons/CurrencyDollarIcon.js +1 -1
  400. package/dist/icons/DangerIcon.js +1 -1
  401. package/dist/icons/DashboardIcon.js +1 -1
  402. package/dist/icons/DatabaseIcon.js +1 -1
  403. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  404. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  405. package/dist/icons/DirectionIcon.js +1 -1
  406. package/dist/icons/DonutIcon.js +1 -1
  407. package/dist/icons/DownIcon.js +1 -1
  408. package/dist/icons/EditIcon.js +1 -1
  409. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  410. package/dist/icons/ExclamationCircleIcon.js +1 -1
  411. package/dist/icons/ExclamationIcon.js +1 -1
  412. package/dist/icons/EyeIcon.js +1 -1
  413. package/dist/icons/EyeInvisibleIcon.js +1 -1
  414. package/dist/icons/FilterIcon.js +1 -1
  415. package/dist/icons/FolderFilledIcon.js +1 -1
  416. package/dist/icons/FolderIcon.js +1 -1
  417. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  418. package/dist/icons/FolderOpenIcon.js +1 -1
  419. package/dist/icons/ForwardIcon.js +1 -1
  420. package/dist/icons/GripVerticalIcon.js +1 -1
  421. package/dist/icons/HierarchyIcon.js +1 -1
  422. package/dist/icons/HierarchyOpenIcon.js +1 -1
  423. package/dist/icons/Icon.js +1 -1
  424. package/dist/icons/InfoCircleIcon.js +1 -1
  425. package/dist/icons/InfoIcon.js +1 -1
  426. package/dist/icons/KeyIcon.js +1 -1
  427. package/dist/icons/LeftIcon.js +1 -1
  428. package/dist/icons/LineChartIcon.js +1 -1
  429. package/dist/icons/LoadingIcon.js +1 -1
  430. package/dist/icons/LockFilledIcon.js +1 -1
  431. package/dist/icons/LockIcon.js +1 -1
  432. package/dist/icons/MoreIcon.js +1 -1
  433. package/dist/icons/NotAllowedIcon.js +1 -1
  434. package/dist/icons/Number123Icon.js +1 -1
  435. package/dist/icons/NumberIcon.js +1 -1
  436. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  437. package/dist/icons/PauseCircleIcon.js +1 -1
  438. package/dist/icons/PauseIcon.js +1 -1
  439. package/dist/icons/PercentageIcon.js +1 -1
  440. package/dist/icons/PieChartIcon.js +1 -1
  441. package/dist/icons/PipetteIcon.d.ts +12 -0
  442. package/dist/icons/PipetteIcon.js +11 -0
  443. package/dist/icons/PipetteIcon.js.map +1 -0
  444. package/dist/icons/PlayCircleIcon.js +1 -1
  445. package/dist/icons/PlayIcon.js +1 -1
  446. package/dist/icons/PlusIcon.js +1 -1
  447. package/dist/icons/ProgressBarIcon.js +1 -1
  448. package/dist/icons/ReloadIcon.js +1 -1
  449. package/dist/icons/ReportIcon.js +1 -1
  450. package/dist/icons/ReturnIcon.js +1 -1
  451. package/dist/icons/RightIcon.js +1 -1
  452. package/dist/icons/RowTotalsIcon.js +1 -1
  453. package/dist/icons/SchemeIcon.js +1 -1
  454. package/dist/icons/SearchIcon.js +1 -1
  455. package/dist/icons/SemanticQueryIcon.js +1 -1
  456. package/dist/icons/SettingsIcon.js +1 -1
  457. package/dist/icons/ShieldFilledIcon.js +1 -1
  458. package/dist/icons/ShieldIcon.js +1 -1
  459. package/dist/icons/SlashIcon.js +1 -1
  460. package/dist/icons/SparklesIcon.js +1 -1
  461. package/dist/icons/SqlIcon.js +1 -1
  462. package/dist/icons/StatsIcon.js +1 -1
  463. package/dist/icons/StopIcon.js +1 -1
  464. package/dist/icons/StringIcon.js +1 -1
  465. package/dist/icons/SubtotalsIcon.js +1 -1
  466. package/dist/icons/SwitchIcon.js +1 -1
  467. package/dist/icons/TableIcon.js +1 -1
  468. package/dist/icons/ThumbsDownIcon.js +1 -1
  469. package/dist/icons/ThumbsUpIcon.js +1 -1
  470. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  471. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  472. package/dist/icons/ThunderboltIcon.js +1 -1
  473. package/dist/icons/TimeIcon.js +1 -1
  474. package/dist/icons/TrashIcon.js +1 -1
  475. package/dist/icons/UnlockIcon.js +1 -1
  476. package/dist/icons/UpIcon.js +1 -1
  477. package/dist/icons/UserGroupIcon.js +1 -1
  478. package/dist/icons/UserIcon.js +1 -1
  479. package/dist/icons/UserLockIcon.js +1 -1
  480. package/dist/icons/ViewIcon.js +1 -1
  481. package/dist/icons/WarningFilledIcon.js +1 -1
  482. package/dist/icons/WarningIcon.js +1 -1
  483. package/dist/icons/index.d.ts +1 -0
  484. package/dist/icons/wrap-icon.js +1 -1
  485. package/dist/index.d.ts +9 -3
  486. package/dist/index.js +13 -8
  487. package/dist/index.js.map +1 -1
  488. package/dist/props.d.ts +13 -0
  489. package/dist/provider.d.ts +1 -1
  490. package/dist/provider.js +1 -1
  491. package/dist/provider.js.map +1 -1
  492. package/dist/providers/TrackingProvider.js +1 -1
  493. package/dist/providers/navigationAdapter.default.js +1 -1
  494. package/dist/shared/form.d.ts +2 -1
  495. package/dist/tokens/base.js +1 -1
  496. package/dist/tokens/colors.js +1 -1
  497. package/dist/tokens/index.js +1 -1
  498. package/dist/tokens/layout.js +1 -1
  499. package/dist/tokens/lazy-styles.js +1 -1
  500. package/dist/tokens/palette-config.js +1 -1
  501. package/dist/tokens/palette.js +1 -1
  502. package/dist/tokens/shadows.js +1 -1
  503. package/dist/tokens/sizes.js +1 -1
  504. package/dist/tokens/spacing.js +1 -1
  505. package/dist/tokens/typography.js +1 -1
  506. package/dist/utils/ResizeSensor.js +1 -1
  507. package/dist/utils/is-dev-env.js +1 -1
  508. package/dist/utils/modules.js +1 -1
  509. package/dist/utils/promise.js +1 -1
  510. package/dist/utils/raf.js +1 -1
  511. package/dist/utils/random.js +1 -1
  512. package/dist/utils/range.js +1 -1
  513. package/dist/utils/react/RenderCache.js +1 -1
  514. package/dist/utils/react/Slots.js +1 -1
  515. package/dist/utils/react/chain.js +1 -1
  516. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  517. package/dist/utils/react/index.js +1 -1
  518. package/dist/utils/react/interactions.js +1 -1
  519. package/dist/utils/react/isTextOnly.js +1 -1
  520. package/dist/utils/react/mapProps.js +1 -1
  521. package/dist/utils/react/mergeProps.d.ts +1 -1
  522. package/dist/utils/react/mergeProps.js +1 -1
  523. package/dist/utils/react/mergeProps.js.map +1 -1
  524. package/dist/utils/react/nullableValue.d.ts +1 -1
  525. package/dist/utils/react/nullableValue.js +1 -1
  526. package/dist/utils/react/nullableValue.js.map +1 -1
  527. package/dist/utils/react/resolveIcon.js +1 -1
  528. package/dist/utils/react/sharedStore.js +1 -1
  529. package/dist/utils/react/useCombinedRefs.js +1 -1
  530. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  531. package/dist/utils/react/useEventBus.js +1 -1
  532. package/dist/utils/react/useId.js +1 -1
  533. package/dist/utils/react/useIsDarwin.js +1 -1
  534. package/dist/utils/react/useKeySymbols.js +1 -1
  535. package/dist/utils/react/useLayoutEffect.js +1 -1
  536. package/dist/utils/react/useLocalStorage.js +1 -1
  537. package/dist/utils/react/useMergeStyles.js +1 -1
  538. package/dist/utils/react/usePopoverSync.js +1 -1
  539. package/dist/utils/react/useQaProps.js +1 -1
  540. package/dist/utils/react/useViewportSize.js +1 -1
  541. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  542. package/dist/utils/selection.js +1 -1
  543. package/dist/utils/styles.js +1 -1
  544. package/dist/utils/tree.js +1 -1
  545. package/dist/utils/warnings.js +1 -1
  546. package/dist/version.js +3 -3
  547. package/docs/components/content/Text.md +1 -2
  548. package/docs/components/fields/ColorPicker.md +271 -0
  549. package/docs/components/layout/Board.md +154 -6
  550. package/docs/tasty/README.md +3 -1
  551. package/docs/tasty/ai-agents.md +21 -7
  552. package/docs/tasty/configuration.md +220 -30
  553. package/docs/tasty/debug.md +7 -7
  554. package/docs/tasty/design-system.md +2 -2
  555. package/docs/tasty/dsl.md +68 -8
  556. package/docs/tasty/injector.md +31 -4
  557. package/docs/tasty/methodology.md +1 -1
  558. package/docs/tasty/migration-v3.md +285 -0
  559. package/docs/tasty/pipeline.md +3 -3
  560. package/docs/tasty/plugins.md +349 -0
  561. package/docs/tasty/react-api.md +61 -1
  562. package/docs/tasty/ssr.md +41 -33
  563. package/docs/tasty/styles.md +27 -9
  564. package/docs/tasty/tasty-static.md +8 -6
  565. package/package.json +3 -3
@@ -0,0 +1,285 @@
1
+ # Migration Guide: v2 → v3
2
+
3
+ Everything that changes when you upgrade from `@tenphi/tasty` 2.x to 3.0, in the order you will hit it.
4
+
5
+ Most of the work is mechanical renames — see the [search-and-replace cheat sheet](#search-and-replace-cheat-sheet) at the end. The parts that need real attention are the [directional shorthand](#2-directional-shorthand) rule and the [behavior changes](#8-behavior-changes-that-are-not-renames).
6
+
7
+ - [At a glance](#at-a-glance)
8
+ - [1. Styles-object keys](#1-styles-object-keys)
9
+ - [2. Directional shorthand](#2-directional-shorthand)
10
+ - [3. Config keys](#3-config-keys)
11
+ - [4. Renamed exports](#4-renamed-exports)
12
+ - [5. Removed exports](#5-removed-exports)
13
+ - [6. Removed props](#6-removed-props)
14
+ - [7. Moved subpath](#7-moved-subpath)
15
+ - [8. Behavior changes that are not renames](#8-behavior-changes-that-are-not-renames)
16
+ - [9. New in v3](#9-new-in-v3)
17
+ - [Search-and-replace cheat sheet](#search-and-replace-cheat-sheet)
18
+ - [Not changed](#not-changed)
19
+
20
+ ---
21
+
22
+ ## At a glance
23
+
24
+ | v2.11 | v3.0 | Find it with |
25
+ |---|---|---|
26
+ | `'@properties': { … }` | `'@property': { … }` | `rg "'@properties'"` |
27
+ | `'@fontFace': { … }` | `'@font-face': { … }` | `rg "'@fontFace'"` |
28
+ | `'@counterStyle': { … }` | `'@counter-style': { … }` | `rg "'@counterStyle'"` |
29
+ | `padding: '2x 4x top right'` | `padding: '2x top, 4x right'` | dev-mode console warning |
30
+ | `fade: '3x 1x top bottom'` | `fade: '3x top, 1x bottom'` | dev-mode console warning |
31
+ | `configure({ funcs })` | `configure({ functions })` | `rg "funcs"` |
32
+ | `configure({ fontFace })` | `configure({ fontFaces })` | `rg "fontFace:"` |
33
+ | `configure({ counterStyle })` | `configure({ counterStyles })` | `rg "counterStyle:"` |
34
+ | `getCssText()` | `getCSSText()` | `rg "getCssText"` |
35
+ | `getCssTextForNode()` | `getCSSTextForNode()` | `rg "getCssTextForNode"` |
36
+ | `getCssTextForClasses()` | `getCSSTextForClasses()` | `rg "getCssTextForClasses"` |
37
+ | `getGlobalFontFace()` | `getGlobalFontFaces()` | `rg "getGlobalFontFace\b"` |
38
+ | `getGlobalCounterStyle()` | `getGlobalCounterStyles()` | `rg "getGlobalCounterStyle\b"` |
39
+ | `getGlobalFunction()` | `getGlobalFunctions()` | `rg "getGlobalFunction\b"` |
40
+ | `okhslFunc` / `okhstFunc` | `okhslFunction` / `okhstFunction` | `rg "okhs[lt]Func\b"` |
41
+ | `CssOptions` | `CSSOptions` | `rg "CssOptions"` |
42
+ | `ParserOptions.funcs` | `ParserOptions.functions` | `rg "funcs:"` |
43
+ | `StyleParser#setFuncs()` | `StyleParser#setFunctions()` | `rg "setFuncs"` |
44
+ | `ChunkInfo` (from `tastyDebug`) | `DebugChunkInfo` | `rg "ChunkInfo"` |
45
+ | `@tenphi/tasty/next` | `@tenphi/tasty/zero/next` | `rg "tasty/next"` |
46
+ | `getIsTestEnvironment()` | `isTestEnvironment()` | `rg "getIsTestEnvironment"` |
47
+ | `hydrateTastyCache()` | `hydrateTastyClasses()` | `rg "hydrateTastyCache"` |
48
+
49
+ ---
50
+
51
+ ## 1. Styles-object keys
52
+
53
+ At-rule keys now match the real CSS at-rule names Tasty already emits, so they are kebab-case rather than camelCase. The generated CSS is unchanged.
54
+
55
+ ```diff
56
+ const Card = tasty({
57
+ styles: {
58
+ - '@properties': { '$elevation': { syntax: '<number>' } },
59
+ - '@fontFace': { Inter: { src: 'url(/inter.woff2)' } },
60
+ - '@counterStyle': { dashes: { system: 'cyclic', symbols: '"—"' } },
61
+ + '@property': { '$elevation': { syntax: '<number>' } },
62
+ + '@font-face': { Inter: { src: 'url(/inter.woff2)' } },
63
+ + '@counter-style': { dashes: { system: 'cyclic', symbols: '"—"' } },
64
+ },
65
+ });
66
+ ```
67
+
68
+ `@keyframes` and `@starting` are unchanged — they were already spec-faithful.
69
+
70
+ ---
71
+
72
+ ## 2. Directional shorthand
73
+
74
+ **This is the one change that can alter rendered CSS without a rename.** A style group that names direction modifiers now takes a **single** value, applied to every direction it names.
75
+
76
+ The old form looked positional but never was: the parser buckets values and modifiers into separate arrays per comma group, so `'2x 4x top right'`, `'2x top 4x right'`, and `'top 2x right 4x'` were all the same input, and the pairing was decided by the order the *modifiers* happened to appear in. `'1x 2x right top'` and `'1x 2x top right'` produced different CSS, and `'1x 2x top top'` silently assigned `top` twice.
77
+
78
+ Per-side values now come from comma-separated groups:
79
+
80
+ ```diff
81
+ - padding: '2x 4x top right'
82
+ + padding: '2x top, 4x right'
83
+
84
+ - margin: 'right 1x top 2x'
85
+ + margin: '1x right, 2x top'
86
+
87
+ - inset: 'left 2x right 1x'
88
+ + inset: '2x left, 1x right'
89
+
90
+ - fade: '3x 1x top bottom'
91
+ + fade: '3x top, 1x bottom'
92
+ ```
93
+
94
+ Affects `padding`, `margin`, `inset`, `scrollMargin`, and `fade`. Extra values are ignored with a **development-mode warning** naming the offending value, so run your app in dev and watch the console — that is the reliable way to find every occurrence. Production is silent and never throws.
95
+
96
+ **Unchanged:** single-value directional groups (`padding: '2x top'`, `'1x left right'`), every value-only CSS shorthand form (`padding: '1x 2x'`, `'1x 2x 3x 4x'`, and `fade: '3x 1x'` — a group that names no direction is unambiguous and keeps plain shorthand order), CSS-wide keywords, and the `longhand` modifier.
97
+
98
+ `inset`'s `dock` modifier keeps its two-value form with sharper semantics: the first value applies to the named edge, the second to the perpendicular sides it spans, so `inset: '2x 4x bottom dock'` still gives `auto 32px 16px 32px`. A third value with `dock`, or a second value without it, now warns.
99
+
100
+ ---
101
+
102
+ ## 3. Config keys
103
+
104
+ ```diff
105
+ configure({
106
+ - funcs: { double: (groups) => `calc(2 * ${groups[0].output})` },
107
+ - fontFace: { Inter: { src: 'url(/inter.woff2)' } },
108
+ - counterStyle: { dashes: { system: 'cyclic', symbols: '"—"' } },
109
+ + functions: { double: (groups) => `calc(2 * ${groups[0].output})` },
110
+ + fontFaces: { Inter: { src: 'url(/inter.woff2)' } },
111
+ + counterStyles: { dashes: { system: 'cyclic', symbols: '"—"' } },
112
+ });
113
+ ```
114
+
115
+ `functions` is a single map holding both flavors, discriminated by value type:
116
+
117
+ - **bare key + function value** → a parse-time function, called as `name(...)`
118
+ - **`$$name` key + object value** → a declarative CSS `@function`, called as `$$name(...)`
119
+
120
+ A key whose prefix doesn't match its value type is ignored with a development warning.
121
+
122
+ > If you are coming from a pre-release build of v3, note the intermediate `function` config key never shipped. Upgraders from 2.x only ever wrote `funcs`.
123
+
124
+ ---
125
+
126
+ ## 4. Renamed exports
127
+
128
+ **Raw-CSS family** — aligned on the `CSS` initialism already used by `useRawCSS` / `injectRawCSS` / `getRawCSSText`:
129
+
130
+ - `getCssText()` → `getCSSText()`
131
+ - `getCssTextForNode()` → `getCSSTextForNode()`
132
+ - `StyleInjector#getCssTextForClasses()` → `getCSSTextForClasses()`
133
+ - `CssOptions` → `CSSOptions`
134
+
135
+ **Config getters** — pluralized to match their already-plural config keys:
136
+
137
+ - `getGlobalFontFace()` → `getGlobalFontFaces()`
138
+ - `getGlobalCounterStyle()` → `getGlobalCounterStyles()`
139
+ - `getGlobalFunction()` → `getGlobalFunctions()`
140
+
141
+ **Color functions** — aligned with the `useFunction` / `FunctionDefinition` family:
142
+
143
+ - `okhslFunc` → `okhslFunction`
144
+ - `okhstFunc` → `okhstFunction`
145
+ - `createColorFunc(name, channelLabel, convert)` → `createColorFunc(name, convert, label?)` — the label is now an optional trailing argument used only to format development warnings
146
+
147
+ **Parser** (`@tenphi/tasty/core`):
148
+
149
+ - `ParserOptions.funcs` → `ParserOptions.functions`
150
+ - `StyleParser#setFuncs()` → `StyleParser#setFunctions()`
151
+
152
+ **Debug types:** the debug-local `ChunkInfo` is now `DebugChunkInfo`, so it no longer collides with the parser's `ChunkInfo`.
153
+
154
+ ---
155
+
156
+ ## 5. Removed exports
157
+
158
+ | Removed | Use instead |
159
+ |---|---|
160
+ | `getIsTestEnvironment()` | `isTestEnvironment()` |
161
+ | `hydrateTastyCache()` | `hydrateTastyClasses()` |
162
+ | `customFunc()` | `configure({ functions })` |
163
+ | `getGlobalFuncs()` | `getGlobalFunctions()` for `@function` definitions; the parse-function registry is internal |
164
+ | `resetGlobalFuncs()` | `resetConfig()` |
165
+ | `setGlobalPredefinedTokens()` | `configure({ replaceTokens })` |
166
+ | `resetGlobalPredefinedTokens()` | `resetConfig()` |
167
+ | `setMiddlewareTransferCache()` / `getMiddlewareTransferCache()` | internal; no replacement needed |
168
+ | `clearWriterCache()` | internal test utility |
169
+ | `DEFAULT_PLUGINS` | nothing — it was never consumed, and passing it to `configure({ plugins })` was a no-op. The default `okhsl`/`okhst` functions are registered automatically. |
170
+ | `registerDefaultFunctions()` | internal bootstrap helper |
171
+ | `warn()` / `deprecationWarning()` | internal helpers with no callers |
172
+ | `Bucket` enum | parser-internal |
173
+ | `Props` type | inline `Record<string, any>` |
174
+ | `UseStylesOptions` | `useStyles()` takes `Styles \| undefined` directly |
175
+ | `GlobalStyledProps` | its only member was the already-dead `breakpoints` prop |
176
+ | duplicate `PropertyOptions` | the single `PropertyOptions` from `injector/types` |
177
+
178
+ `getGlobalFuncs()` deserves a note: it returned the **live mutable internal registry**, and writing to it bypassed the parser's cache invalidation, so the write silently never took effect. If you were mutating it, move to `configure({ functions })`.
179
+
180
+ ---
181
+
182
+ ## 6. Removed props
183
+
184
+ `css`, `block`, `inline`, and `breakpoints` are gone from `BaseProps` / `TastySpecificKeys`. All four were typed but never consumed — passing them did nothing in v2 either.
185
+
186
+ ---
187
+
188
+ ## 7. Moved subpath
189
+
190
+ ```diff
191
+ - import { withTasty } from '@tenphi/tasty/next';
192
+ + import { withTasty } from '@tenphi/tasty/zero/next';
193
+ ```
194
+
195
+ The zero-runtime Next.js wrapper already lived under the `zero` namespace internally; the top-level `/next` path collided confusingly with `@tenphi/tasty/ssr/next`, which is a different integration.
196
+
197
+ ---
198
+
199
+ ## 8. Behavior changes that are not renames
200
+
201
+ **Repeated `configure()` calls now merge.** `recipes`, `keyframes`, `properties`, `fontFaces`, `counterStyles`, and CSS `@function` definitions used to replace wholesale, so a design-system `configure()` followed by an application `configure()` silently dropped the design system's values. All of them now merge, with the later call winning on a key conflict — matching `tokens` and `globalStyles`, which already merged. If you were relying on a second call to *clear* a collection, use `resetConfig()`.
202
+
203
+ `configure({ polyfills })` is now correctly rejected after the first render, like every sibling option, and shallow-merges so an unrelated later call cannot switch a polyfill off.
204
+
205
+ **The `theme` prop is now implemented.** It maps to a `data-theme` attribute on the rendered element; previously it fell through and was spread onto the DOM raw. Augment `TastyThemeNames` for autocomplete.
206
+
207
+ **`tasty(Component, options)` no longer leaks factory-only options.** `variants`, `elements`, `styleProps`, `modProps`, and `tokenProps` are stripped instead of being passed to the wrapped component as runtime props, matching the element factory.
208
+
209
+ **Replacing a built-in style handler now warns.** Built-in handlers are shared across style names, so `configure({ handlers: { fill } })` also takes over `image` and the whole `background-*` family, and `configure({ handlers: { display } })` takes down `flow`, `gap`, `hide`, `overflow`, `whiteSpace`, and `textOverflow`. This was always true; what's new is that a development-mode warning now names exactly what was displaced. If you see it, either declare the whole group and delegate the rest to `styleHandlers.*`, or pick a narrower name. See [Plugins](plugins.md#custom-style-handlers).
210
+
211
+ **Multi-dependency custom handlers are fixed.** A handler whose dependencies mixed known and unknown style names was invoked once per chunk with only *part* of its dependencies, and could emit stale CSS. Unknown names now join their handler's chunk, so it is invoked once with all of them. No built-in style moved, so no existing class name changes.
212
+
213
+ **`isChecked` added to the root prop types.** It already worked at runtime; it was just missing from `BaseProps` / `AllBaseProps`.
214
+
215
+ **The `okhsl`/`okhst` "expected 3 values" warning is now development-only** and follows the `[Tasty]` prefix convention: `[Tasty] okhsl(): expected 3 values (H S L), got: …`. It previously fired in production.
216
+
217
+ ---
218
+
219
+ ## 9. New in v3
220
+
221
+ Nothing here is required to upgrade.
222
+
223
+ - **CSS `@function` support** — reusable, parameterized functions via the `'@function'` styles key, the `useFunction` style function, or `configure({ functions })`. Works across client, SSR/RSC, and zero-runtime. `configure({ polyfills: { functions: true } })` inlines every call into plain CSS for browsers that don't ship the at-rule yet. See [Style DSL](dsl.md#functions-function).
224
+ - **Custom color plugins with no core special-casing** — `okhsl`/`okhst` are now ordinary one-line plugins, and a third-party color space can achieve identical integration. New `createColorFunc` and `resolveFunctionColor` helpers.
225
+ - **`configure({ propHandlers })`** — props middleware for every component: props in, props out. The extension point for props that aren't style values.
226
+ - **`configure({ baseStyleProps })`** — expose style properties as props on every component without listing them in each `styleProps`.
227
+ - **`defineHandler(deps, fn)`** — infers a multi-dependency handler's parameter types from its dependency list.
228
+ - **Plugins can supply `properties`, `keyframes`, `fontFaces`, and `counterStyles`** in addition to what they already could.
229
+ - See [Plugins & Extension Points](plugins.md) for all of the above.
230
+
231
+ ---
232
+
233
+ ## Search-and-replace cheat sheet
234
+
235
+ Run these in order — the `Css` → `CSS` renames must happen before any broader pattern, and the quoted at-rule keys must stay quote-anchored so they can't hit `configure({ properties })`.
236
+
237
+ ```bash
238
+ # 1. Raw-CSS family (before anything that touches "Css")
239
+ rg -l 'getCssTextForClasses' | xargs sed -i '' 's/getCssTextForClasses/getCSSTextForClasses/g'
240
+ rg -l 'getCssTextForNode' | xargs sed -i '' 's/getCssTextForNode/getCSSTextForNode/g'
241
+ rg -l 'getCssText' | xargs sed -i '' 's/getCssText/getCSSText/g'
242
+ rg -l 'CssOptions' | xargs sed -i '' 's/CssOptions/CSSOptions/g'
243
+
244
+ # 2. Styles-object at-rule keys (quote-anchored)
245
+ rg -l "'@properties'" | xargs sed -i '' "s/'@properties'/'@property'/g"
246
+ rg -l "'@fontFace'" | xargs sed -i '' "s/'@fontFace'/'@font-face'/g"
247
+ rg -l "'@counterStyle'" | xargs sed -i '' "s/'@counterStyle'/'@counter-style'/g"
248
+
249
+ # 3. Config getters (word-anchored so the plural forms are not double-pluralized)
250
+ rg -l 'getGlobalFontFace\b' | xargs sed -i '' 's/getGlobalFontFace\b/getGlobalFontFaces/g'
251
+ rg -l 'getGlobalCounterStyle\b' | xargs sed -i '' 's/getGlobalCounterStyle\b/getGlobalCounterStyles/g'
252
+ rg -l 'getGlobalFunction\b' | xargs sed -i '' 's/getGlobalFunction\b/getGlobalFunctions/g'
253
+
254
+ # 4. Color functions and parser methods
255
+ rg -l 'okhslFunc\b' | xargs sed -i '' 's/okhslFunc\b/okhslFunction/g'
256
+ rg -l 'okhstFunc\b' | xargs sed -i '' 's/okhstFunc\b/okhstFunction/g'
257
+ rg -l 'setFuncs' | xargs sed -i '' 's/setFuncs/setFunctions/g'
258
+
259
+ # 5. Removed exports with direct replacements
260
+ rg -l 'getIsTestEnvironment' | xargs sed -i '' 's/getIsTestEnvironment/isTestEnvironment/g'
261
+ rg -l 'hydrateTastyCache' | xargs sed -i '' 's/hydrateTastyCache/hydrateTastyClasses/g'
262
+
263
+ # 6. Moved subpath
264
+ rg -l "@tenphi/tasty/next" | xargs sed -i '' "s|@tenphi/tasty/next|@tenphi/tasty/zero/next|g"
265
+
266
+ # 7. Verify nothing is left (should print nothing)
267
+ rg "getCssText|CssOptions|'@properties'|'@fontFace'|'@counterStyle'|okhs[lt]Func\b|setFuncs|getIsTestEnvironment|hydrateTastyCache|@tenphi/tasty/next|getGlobalFontFace\b|getGlobalCounterStyle\b|getGlobalFunction\b"
268
+ ```
269
+
270
+ `configure({ funcs })` → `functions`, `fontFace` → `fontFaces`, and `counterStyle` → `counterStyles` are deliberately **not** scripted: those words appear in many other contexts, so change them by hand and let TypeScript find the call sites.
271
+
272
+ The directional shorthand cannot be scripted at all — the whole point is that the old form's meaning was not recoverable from its text. Run your app in development and follow the console warnings.
273
+
274
+ ---
275
+
276
+ ## Not changed
277
+
278
+ Worth stating explicitly, because it's easy to assume otherwise:
279
+
280
+ - **At-rule styles-object keys are CSS-spec-faithful, not JS-conventional.** `@keyframes`, `@property`, `@font-face`, `@counter-style`, `@function`, `@starting` — kebab-case, matching what Tasty emits.
281
+ - **The `func()` injector method stays abbreviated.** `function` is a reserved word.
282
+ - `injector.fontFace()` and `injector.counterStyle()` keep their singular names — only the *config keys* and *getters* were pluralized.
283
+ - `useFontFace` and `useCounterStyle` are unchanged.
284
+ - `configure({ properties })` and `autoPropertyTypes` are unchanged; only the styles-object `@property` key was renamed.
285
+ - **The deprecated style aliases are retained deliberately.** `backgroundColor`, `background`, `backgroundImage`, `flex`, `grid`, and `flexDirection` still carry `@deprecated` tags and still work. They are the guardrail that discourages their use in projects that have not enabled `@tenphi/eslint-plugin-tasty` yet — read the tags as guidance, not as a removal notice.
@@ -6,7 +6,7 @@ This document describes the style rendering pipeline that transforms style objec
6
6
 
7
7
  ## Overview
8
8
 
9
- The pipeline takes a `Styles` object and produces an array of `CSSRule` objects ready for injection into the DOM. Entry points include `renderStylesPipeline` (full pipeline + optional class-name prefixing) and `renderStyles` (direct selector/class mode). The per-handler flow is:
9
+ The pipeline takes a `Styles` object and produces an array of `CSSRule` objects ready for injection into the DOM. The entry point is `renderStyles`, which has two overloads: called with a selector or class (`renderStyles(styles, '.t1')`) it returns the rules directly; called without one (`renderStyles(styles)`) it returns `{ rules }` for a caller that will allocate the class name itself. The per-handler flow is:
10
10
 
11
11
  ```
12
12
  Input: Styles Object
@@ -539,7 +539,7 @@ interface CSSRule {
539
539
  }
540
540
  ```
541
541
 
542
- When `renderStylesPipeline` runs **without** a class name, returned rules include `needsClassName: true` (compatibility field for the injector); that flag is not part of `CSSRule` inside `materialize.ts`.
542
+ When `renderStyles` runs **without** a selector, returned rules include `needsClassName: true` (compatibility field for the injector); that flag is not part of `CSSRule` inside `materialize.ts`.
543
543
 
544
544
  ---
545
545
 
@@ -691,7 +691,7 @@ Each snapshot yields distinct declarations; no merge.
691
691
 
692
692
  ### Stage 7: Materialize CSS
693
693
 
694
- Using `renderStyles(styles, '.t1')` (single class prefix; `renderStylesPipeline` doubles the class for specificity when a class name is supplied):
694
+ Using `renderStyles(styles, '.t1')` (the class is doubled — `.t1.t1` so Tasty owns specificity without `!important`):
695
695
 
696
696
  ```css
697
697
  .t1[data-hovered] {
@@ -0,0 +1,349 @@
1
+ # Plugins & Extension Points
2
+
3
+ How to extend Tasty: new value syntax, new units, new states, new style properties, new component props, and how to package any of it as a plugin.
4
+
5
+ - [What a plugin is](#what-a-plugin-is)
6
+ - [Choosing an extension point](#choosing-an-extension-point)
7
+ - [Custom style handlers](#custom-style-handlers)
8
+ - [Props middleware](#props-middleware)
9
+ - [Base style props](#base-style-props)
10
+ - [Typing your extension](#typing-your-extension)
11
+ - [Worked example: a `glaze` plugin](#worked-example-a-glaze-plugin)
12
+ - [Rendering modes and caveats](#rendering-modes-and-caveats)
13
+ - [Testing a plugin](#testing-a-plugin)
14
+
15
+ ---
16
+
17
+ ## What a plugin is
18
+
19
+ A plugin is a plain object with a `name` and any subset of the `configure()` options it is allowed to supply. There is no lifecycle and no init hook — a plugin is just pre-packaged configuration.
20
+
21
+ ```ts
22
+ import { configure } from '@tenphi/tasty';
23
+ import type { TastyPluginFactory } from '@tenphi/tasty';
24
+
25
+ const spacingPlugin: TastyPluginFactory = () => ({
26
+ name: 'spacing',
27
+ units: { gu: (n) => `calc(${n} * var(--grid-unit))` },
28
+ tokens: { '$grid-unit': '4px' },
29
+ });
30
+
31
+ configure({ plugins: [spacingPlugin()] });
32
+ ```
33
+
34
+ `TastyPluginFactory<TOptions>` types a factory that takes options; with no type argument it types a zero-argument factory.
35
+
36
+ **Ordering.** Plugins are applied in array order and merged key by key, so a later plugin overrides an earlier one for the same key. Options passed directly to `configure()` are applied last and win over every plugin.
37
+
38
+ **Configuration is locked after the first render.** `configure()` warns and does nothing once any style has been generated, so it must run before your first component renders — at module scope in your entry file, or in a design-system module every component imports. `resetConfig()` reopens it, but it exists for tests.
39
+
40
+ **Repeated `configure()` calls merge** for `tokens` and `globalStyles` (per selector). See [Configuration](configuration.md) for the current per-key semantics.
41
+
42
+ ---
43
+
44
+ ## Choosing an extension point
45
+
46
+ | You want to add | Use | Runs | Zero-runtime |
47
+ |---|---|---|---|
48
+ | New value syntax — `okhsl(…)`, `double(2x)` | `functions` (bare key) | parse time, per value | ✅ |
49
+ | A reusable CSS `@function` | `functions` (`$$name` key) | injected once, globally | ✅ |
50
+ | A new unit — `2gu` | `units` | parse time, per value | ✅ |
51
+ | A new state alias — `@mobile` | `states` | state-key parse | ✅ |
52
+ | A style property → **CSS declarations** | `handlers` | pipeline, per state snapshot | ✅ |
53
+ | A style property on every component | `baseStyleProps` | prop harvest | ✅ (styles only) |
54
+ | A **component prop** → anything | `propHandlers` | render, per component | ❌ (no props to run on) |
55
+ | A named bundle of styles | `recipes` | before chunking | ✅ |
56
+ | Typography scale tokens | `presets` | inject time | ✅ |
57
+ | `:root` variables | `tokens`, `replaceTokens` | inject time | ✅ |
58
+ | Global selector styles | `globalStyles` | inject time | ✅ |
59
+
60
+ Two distinctions do most of the work:
61
+
62
+ - **`handlers` vs `propHandlers`.** A handler turns a *style property* into CSS declarations and knows nothing about components. A prop handler turns a *component prop* into other props — including `styles`, which then flow through the normal handlers. Reach for `propHandlers` when the input isn't a style value (an options object, a domain concept) or when it should affect more than styles.
63
+ - **`recipes` vs `propHandlers`.** A recipe is a static named bundle. A prop handler computes its styles from a value.
64
+
65
+ ---
66
+
67
+ ## Custom style handlers
68
+
69
+ A handler receives a map of the style properties it declared and returns CSS declarations. See [Configuration → Custom Style Handlers](configuration.md#custom-style-handlers) for the definition forms, return shape, the shared-handler groups you must be careful of, and chunk membership. The essentials:
70
+
71
+ - Values arrive **state-resolved but unparsed** — the raw authored DSL string (`'2x'`, `'#purple.5'`, `true`, `4`). Call the exported `parseStyle()` / `parseColor()` yourself.
72
+ - Return a `CSSMap` with **kebab-case** keys, an array of them, or nothing. `$` is a selector suffix, not a property.
73
+ - Handlers must be pure and synchronous. They are called once per state combination and the results are cached.
74
+ - Use `defineHandler(deps, fn)` for multi-dependency handlers so the dependency types are inferred.
75
+
76
+ ```ts
77
+ import { configure, defineHandler, parseStyle } from '@tenphi/tasty';
78
+
79
+ configure({
80
+ handlers: {
81
+ // Every declaration set the handler returns can target its own selector.
82
+ stripe: defineHandler(['stripe'], ({ stripe }) => {
83
+ if (!stripe) return;
84
+
85
+ const { values } = parseStyle(String(stripe)).groups[0];
86
+
87
+ return [
88
+ { position: 'relative' },
89
+ {
90
+ $: '&::before',
91
+ content: '""',
92
+ position: 'absolute',
93
+ inset: '0 auto 0 0',
94
+ width: values[0],
95
+ background: 'var(--purple-color)',
96
+ },
97
+ ];
98
+ }),
99
+ },
100
+ });
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Props middleware
106
+
107
+ `propHandlers` are middleware over a component's props: props in, props out. They run at the very top of every tasty component's render, before any prop is destructured, so a handler can read and rewrite `styles`, `mods`, `tokens`, `variant`, `as`, `element`, and `qa`, and can strip its own props so they never reach the DOM.
108
+
109
+ ```ts
110
+ import { configure, mergeStyles } from '@tenphi/tasty';
111
+
112
+ configure({
113
+ propHandlers: {
114
+ glaze: (props) => {
115
+ const { glaze, ...rest } = props;
116
+ if (!glaze) return rest;
117
+
118
+ return { ...rest, styles: mergeStyles(glazeStyles(glaze), rest.styles) };
119
+ },
120
+ },
121
+ });
122
+ ```
123
+
124
+ **The key is the trigger.** By default a handler runs only when a prop matching its key is present, so an absent prop costs one property check rather than a call. Override that with a tuple:
125
+
126
+ | Definition | Runs when |
127
+ |---|---|
128
+ | `fn` | a prop named after the key is present |
129
+ | `['glaze', fn]` | `glaze` is present |
130
+ | `[['glaze', 'tint'], fn]` | either is present |
131
+ | `['*', fn]` | always |
132
+
133
+ **Chaining.** Handlers run in registration order — plugins first, then direct `configure()` — and each receives the previous one's output. Registering the same key twice replaces the handler in place, keeping its position.
134
+
135
+ **Returning nothing means unchanged**, with a development-mode warning, because that is almost always a forgotten `return props`. A non-object return is ignored with a warning.
136
+
137
+ ### Rules
138
+
139
+ - **Be pure. Never mutate the input.** Style values are cached by object identity, so mutating a value object in place yields a stale class name *and* stale CSS. Return fresh objects.
140
+ - **Memoize the styles you build, per input value.** A reference-stable (ideally frozen) styles object lets the cache key reuse its serialization instead of recomputing it on every render. This is the single highest-leverage thing you can do for performance.
141
+ - **Precedence is fixed** and not adjustable from a handler. Styles are merged as `factory defaults → styles → harvested style props`, and injected styles occupy the `styles` slot: they beat a component's own default styles and lose to a style prop passed at the call site. This matches how `recipe` already behaves.
142
+ - **Prefer returning `styles` over bare style props.** Returning `{ fill: '#red' }` only works if `fill` is harvestable on *that* component (in its `styleProps`, or promoted via `baseStyleProps`); otherwise it leaks to the DOM.
143
+
144
+ ### What it cannot do
145
+
146
+ - **`ref`** — `forwardRef` separates it from props, so it is out of reach.
147
+ - **Sub-elements** (`Card.Title`) — they have no `styles` prop and no style-prop harvest, so middleware does not run on them.
148
+ - **Zero-runtime mode** — see [Rendering modes](#rendering-modes-and-caveats).
149
+
150
+ ---
151
+
152
+ ## Base style props
153
+
154
+ A small set of style properties — `display`, `font`, `preset`, `hide`, `whiteSpace`, `opacity`, `transition` — are harvested as props on every `tasty()` component. `baseStyleProps` adds to that set globally:
155
+
156
+ ```ts
157
+ configure({ baseStyleProps: ['radius', 'shadow'] });
158
+
159
+ <Card radius="1r" shadow />
160
+ ```
161
+
162
+ Names must be real style properties, must start with a lowercase letter, and must not collide with a prop `tasty()` consumes itself (`as`, `styles`, `variant`, `mods`, `tokens`, …); invalid entries are dropped with a development warning.
163
+
164
+ `configure()` may run *after* your components are defined — each factory resolves its prop list lazily and refreshes when the registry changes.
165
+
166
+ **Costs and caveats.** Each name adds one property check per render of every component, forever, so keep the list short. The effect is app-global and cannot be scoped to a subtree — use a factory's own `styleProps` for that. Be wary of names that collide with real DOM or component props (`width`, `size`, `color`): promoting one means every component swallows it as a style, including when rendering `as={SomeThirdPartyComponent}`.
167
+
168
+ ---
169
+
170
+ ## Typing your extension
171
+
172
+ Four augmentation points, each matching a runtime registry:
173
+
174
+ ```ts
175
+ // tasty.d.ts
176
+ import type { StylePropValue } from '@tenphi/tasty';
177
+
178
+ declare module '@tenphi/tasty' {
179
+ // configure({ handlers }) — a new style property
180
+ interface StylesInterface {
181
+ stripe?: StylePropValue<string>;
182
+ }
183
+
184
+ // configure({ propHandlers }) — a new component prop
185
+ interface TastyCustomProps {
186
+ glaze: 'soft' | 'strong' | { tone: string; intensity?: number };
187
+ }
188
+
189
+ // configure({ baseStyleProps }) — promoted style names, typed like the style
190
+ interface TastyBaseStylePropNames {
191
+ radius: true;
192
+ shadow: true;
193
+ }
194
+
195
+ // configure({ tokens }) / recipes / presets — autocomplete for names
196
+ interface TastyNamedColors {
197
+ 'glaze-bg': true;
198
+ }
199
+ }
200
+ ```
201
+
202
+ `TastyCustomProps` keys become optional props on every component. `TastyBaseStylePropNames` entries are typed exactly like the style they name, so `radius="1r"` accepts the same values as `styles={{ radius: '1r' }}`.
203
+
204
+ **Also update `tasty.config.ts`.** The ESLint plugin and VS Code extension validate style and token names against it, and neither is derived from the runtime registries:
205
+
206
+ ```ts
207
+ // tasty.config.ts
208
+ export default {
209
+ styles: ['stripe'],
210
+ tokens: ['#glaze-bg'],
211
+ };
212
+ ```
213
+
214
+ `propHandlers` keys are JSX props rather than style keys, so they need no entry — but any *style* name or token a handler expands into does.
215
+
216
+ ---
217
+
218
+ ## Worked example: a `glaze` plugin
219
+
220
+ A `glaze` prop on every component that takes a configuration object and expands into color token declarations. This is the case `propHandlers` exists for: the value is an options object, not a style value, so it cannot be a style property.
221
+
222
+ ```ts
223
+ // glaze-plugin.ts
224
+ import { mergeStyles } from '@tenphi/tasty';
225
+ import type { Styles, TastyPluginFactory } from '@tenphi/tasty';
226
+
227
+ export interface GlazeConfig {
228
+ tone: string;
229
+ /** 0–100. Default 10. */
230
+ intensity?: number;
231
+ }
232
+
233
+ type GlazeValue = string | GlazeConfig;
234
+
235
+ // Memoized per value so the styles object is reference-stable across renders.
236
+ const cache = new Map<string, Styles>();
237
+
238
+ function glazeStyles(value: GlazeValue): Styles {
239
+ const { tone, intensity = 10 } =
240
+ typeof value === 'string' ? { tone: value } : value;
241
+ const key = `${tone}:${intensity}`;
242
+
243
+ let styles = cache.get(key);
244
+
245
+ if (!styles) {
246
+ styles = Object.freeze({
247
+ '#glaze-bg': `#${tone}.${intensity}`,
248
+ fill: '#glaze-bg',
249
+ transition: 'fill 0.2s',
250
+ }) as Styles;
251
+ cache.set(key, styles);
252
+ }
253
+
254
+ return styles;
255
+ }
256
+
257
+ export const glazePlugin: TastyPluginFactory = () => ({
258
+ name: 'glaze',
259
+
260
+ propHandlers: {
261
+ glaze: (props) => {
262
+ const { glaze, ...rest } = props;
263
+ if (!glaze) return rest;
264
+
265
+ return {
266
+ ...rest,
267
+ styles: mergeStyles(
268
+ glazeStyles(glaze as GlazeValue),
269
+ rest.styles as Styles,
270
+ ),
271
+ };
272
+ },
273
+ },
274
+
275
+ // Typed so `#glaze-bg` animates smoothly instead of snapping.
276
+ properties: {
277
+ '#glaze-bg': { syntax: '<color>', inherits: false, initialValue: 'transparent' },
278
+ },
279
+ });
280
+ ```
281
+
282
+ ```ts
283
+ // app entry, before the first render
284
+ import { configure } from '@tenphi/tasty';
285
+
286
+ import { glazePlugin } from './glaze-plugin';
287
+
288
+ configure({ plugins: [glazePlugin()] });
289
+ ```
290
+
291
+ ```tsx
292
+ <Element glaze="purple" />
293
+ <Element glaze={{ tone: 'success', intensity: 30 }} />
294
+ ```
295
+
296
+ ```ts
297
+ // tasty.d.ts
298
+ declare module '@tenphi/tasty' {
299
+ interface TastyCustomProps {
300
+ glaze: import('./glaze-plugin').GlazeConfig | string;
301
+ }
302
+ }
303
+ ```
304
+
305
+ The object value is unambiguous here precisely because `glaze` is a **prop**. A style *value* of the same shape would be indistinguishable from a state map (`{ tone: … }` looks exactly like `{ hovered: … }`), which is why this belongs in `propHandlers` rather than `handlers`.
306
+
307
+ ---
308
+
309
+ ## Rendering modes and caveats
310
+
311
+ | Mode | `functions` / `units` / `states` / `handlers` / `recipes` / `tokens` | `propHandlers` |
312
+ |---|---|---|
313
+ | Client | ✅ | ✅ |
314
+ | SSR / RSC | ✅ | ✅ |
315
+ | Zero-runtime (`tastyStatic`) | ✅ at build time | not applicable |
316
+
317
+ **Zero-runtime.** The Babel plugin transforms `tastyStatic()` calls, which take styles objects — there are no props in that pipeline, so there is nothing for props middleware to run on. Components you render through `tasty()` are untouched by the plugin and keep the runtime injector, so `propHandlers` work there exactly as in any client app; their CSS simply comes from the injector rather than the extracted stylesheet. Everything else runs at build time, which is why handlers, functions, and units must be pure functions of their input.
318
+
319
+ **Server and client must configure identically.** Class names are derived from resolved styles, so a handler or promoted prop registered on one side and not the other produces a hydration mismatch. This is the same requirement as `namePrefix` — see [SSR → Hydration mismatch warnings](ssr.md#hydration-mismatch-warnings).
320
+
321
+ ---
322
+
323
+ ## Testing a plugin
324
+
325
+ ```ts
326
+ import { configure, resetConfig, renderStyles } from '@tenphi/tasty';
327
+
328
+ describe('glaze plugin', () => {
329
+ beforeEach(() => resetConfig());
330
+ afterEach(() => resetConfig());
331
+
332
+ it('expands into a color token declaration', () => {
333
+ configure({ plugins: [glazePlugin()] });
334
+
335
+ const rules = renderStyles({ '#glaze-bg': '#purple.10' }, '.test');
336
+
337
+ expect(rules[0].declarations).toContain('--glaze-bg-color');
338
+ });
339
+ });
340
+ ```
341
+
342
+ Two things to know:
343
+
344
+ - **Create components inside each test.** `resetConfig()` does not clear the per-factory class-name cache or prop-list memo, so a module-scope component created in one test carries state into the next.
345
+ - **Dev-mode warnings may not fire.** `isDevEnv()` reports `false` for `NODE_ENV=test`. Warnings that check it lazily can be enabled with `vi.stubEnv('NODE_ENV', 'development')`; some older ones capture it at module load and cannot be triggered from a test at all.
346
+
347
+ ---
348
+
349
+ See [Configuration](configuration.md) for every option in detail, [Style DSL](dsl.md) for the value syntax your extensions produce, and [React API](react-api.md) for `tasty()`, `styleProps`, `modProps`, and `tokenProps`.