haze-ui 1.29.0 → 1.30.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 (386) hide show
  1. package/README.md +58 -0
  2. package/cli/theme.mjs +446 -0
  3. package/dist/components/Accordion/Accordion.js +1 -0
  4. package/dist/components/Accordion/AccordionItem.js +3 -0
  5. package/dist/components/Affix/Affix.js +1 -0
  6. package/dist/components/Alert/Alert.js +3 -0
  7. package/dist/components/Anchor/Anchor.js +21 -15
  8. package/dist/components/AppShell/AppShell.js +5 -0
  9. package/dist/components/ApprovalCard/ApprovalCard.js +8 -0
  10. package/dist/components/AspectRatio/AspectRatio.js +2 -0
  11. package/dist/components/AsyncSection/AsyncSection.js +8 -0
  12. package/dist/components/Avatar/Avatar.js +11 -6
  13. package/dist/components/AvatarGroup/AvatarGroup.js +9 -6
  14. package/dist/components/BackToTop/BackToTop.js +5 -4
  15. package/dist/components/Badge/Badge.js +1 -0
  16. package/dist/components/Banner/Banner.js +3 -0
  17. package/dist/components/BottomSheet/BottomSheet.js +21 -16
  18. package/dist/components/Breadcrumb/Breadcrumb.js +11 -7
  19. package/dist/components/Breadcrumb/BreadcrumbItem.js +2 -0
  20. package/dist/components/Button/Button.js +13 -11
  21. package/dist/components/Button/ButtonLink.js +15 -13
  22. package/dist/components/Calendar/Calendar.js +523 -368
  23. package/dist/components/Calendar/date.js +35 -10
  24. package/dist/components/Card/Card.js +1 -0
  25. package/dist/components/Carousel/Carousel.js +157 -60
  26. package/dist/components/Carousel/CarouselSlide.js +3 -1
  27. package/dist/components/Cascader/Cascader.js +48 -35
  28. package/dist/components/Chart/Chart.js +5 -4
  29. package/dist/components/Chart/chart-elements.js +14 -10
  30. package/dist/components/ChatContainer/ChatContainer.js +9 -7
  31. package/dist/components/ChatInput/ChatInput.js +12 -9
  32. package/dist/components/ChatMessage/ChatMessage.js +83 -44
  33. package/dist/components/Checkbox/CheckboxCore.js +2 -0
  34. package/dist/components/Chip/Chip.js +3 -0
  35. package/dist/components/CodeBlock/CodeBlock.js +18 -9
  36. package/dist/components/Collapsible/Collapsible.js +24 -21
  37. package/dist/components/ColorPicker/ColorPicker.js +85 -14
  38. package/dist/components/ColorPicker/ColorPickerCore.js +6 -0
  39. package/dist/components/ColorPicker/ColorPickerPanel.js +277 -0
  40. package/dist/components/ColorPicker/color-math.js +168 -0
  41. package/dist/components/ColorPicker/color-picker-styles.js +7 -0
  42. package/dist/components/ColorPicker/index.js +3 -3
  43. package/dist/components/Combobox/Combobox.js +31 -24
  44. package/dist/components/Combobox/ComboboxGroup.js +7 -5
  45. package/dist/components/Combobox/ComboboxOption.js +1 -0
  46. package/dist/components/Command/Command.js +44 -37
  47. package/dist/components/Command/CommandDialog.js +8 -8
  48. package/dist/components/ConfigProvider/ConfigContext.js +30 -0
  49. package/dist/components/ConfigProvider/ConfigProvider.js +14 -0
  50. package/dist/components/ConfigProvider/index.js +4 -0
  51. package/dist/components/ConfigProvider/useConfigDefaults.js +10 -0
  52. package/dist/components/ConfirmDialog/ConfirmDialog.js +18 -11
  53. package/dist/components/Container/Container.js +1 -0
  54. package/dist/components/ContextMenu/ContextMenu.js +7 -6
  55. package/dist/components/ContextMenu/ContextMenuContent.js +4 -4
  56. package/dist/components/ContextMenu/ContextMenuItem.js +1 -0
  57. package/dist/components/ContextMenu/ContextMenuSeparator.js +1 -0
  58. package/dist/components/ContextMenu/ContextMenuTrigger.js +1 -0
  59. package/dist/components/ConversationList/ConversationItem.js +4 -0
  60. package/dist/components/ConversationList/ConversationList.js +1 -0
  61. package/dist/components/CountUp/CountUp.js +6 -5
  62. package/dist/components/DataTable/CellEditor.js +4 -4
  63. package/dist/components/DataTable/DataTable.js +236 -168
  64. package/dist/components/DateRangePicker/DateRangePickerCore.js +9 -0
  65. package/dist/components/Datepicker/Datepicker.js +14 -11
  66. package/dist/components/Datepicker/DatepickerCore.js +75 -60
  67. package/dist/components/Datepicker/datetime.js +14 -3
  68. package/dist/components/Descriptions/Descriptions.js +6 -0
  69. package/dist/components/Dialog/Dialog.js +13 -11
  70. package/dist/components/DiffViewer/DiffViewer.js +22 -13
  71. package/dist/components/Disclosure/Disclosure.js +10 -7
  72. package/dist/components/Divider/Divider.js +2 -0
  73. package/dist/components/Drawer/Drawer.js +10 -9
  74. package/dist/components/DropdownMenu/DropdownMenu.js +58 -35
  75. package/dist/components/DropdownMenu/DropdownMenuCheckboxItem.js +63 -0
  76. package/dist/components/DropdownMenu/DropdownMenuContent.js +5 -5
  77. package/dist/components/DropdownMenu/DropdownMenuGroup.js +26 -0
  78. package/dist/components/DropdownMenu/DropdownMenuItem.js +29 -10
  79. package/dist/components/DropdownMenu/DropdownMenuRadioGroup.js +30 -0
  80. package/dist/components/DropdownMenu/DropdownMenuRadioItem.js +59 -0
  81. package/dist/components/DropdownMenu/DropdownMenuSeparator.js +1 -0
  82. package/dist/components/DropdownMenu/DropdownMenuSub.js +1 -0
  83. package/dist/components/DropdownMenu/DropdownMenuSubTrigger.js +1 -0
  84. package/dist/components/DropdownMenu/DropdownMenuTrigger.js +1 -0
  85. package/dist/components/DropdownMenu/dropdown-menu-item-styles.js +7 -0
  86. package/dist/components/DropdownMenu/index.js +12 -8
  87. package/dist/components/Ellipsis/Ellipsis.js +11 -8
  88. package/dist/components/Empty/Empty.js +4 -0
  89. package/dist/components/FileInput/FileInput.js +7 -5
  90. package/dist/components/FilePreview/FilePreview.js +19 -1
  91. package/dist/components/Flex/Flex.js +1 -0
  92. package/dist/components/FloatButton/FloatButton.js +4 -0
  93. package/dist/components/FloatButton/FloatButtonGroup.js +18 -13
  94. package/dist/components/Fullscreen/Fullscreen.js +6 -3
  95. package/dist/components/Grid/Grid.js +12 -7
  96. package/dist/components/Grid/GridItem.js +17 -7
  97. package/dist/components/Grid/grid-item-styles.js +58 -0
  98. package/dist/components/HoverCard/HoverCard.js +46 -43
  99. package/dist/components/Icon/Icon.js +1 -0
  100. package/dist/components/Image/Image.js +10 -7
  101. package/dist/components/Image/ImagePreview.js +42 -34
  102. package/dist/components/InlineCompletion/InlineCompletion.js +15 -11
  103. package/dist/components/InlineEdit/InlineEdit.js +8 -6
  104. package/dist/components/Input/InputCore.js +1 -0
  105. package/dist/components/JsonView/JsonView.js +104 -79
  106. package/dist/components/Kbd/Kbd.js +1 -0
  107. package/dist/components/List/List.js +1 -0
  108. package/dist/components/List/ListItem.js +1 -0
  109. package/dist/components/LocaleProvider/LocaleProvider.js +4 -4
  110. package/dist/components/LocaleProvider/ar-sa.js +24 -2
  111. package/dist/components/LocaleProvider/de-de.js +24 -2
  112. package/dist/components/LocaleProvider/es-es.js +24 -2
  113. package/dist/components/LocaleProvider/fr-fr.js +24 -2
  114. package/dist/components/LocaleProvider/it-it.js +24 -2
  115. package/dist/components/LocaleProvider/ja-jp.js +24 -2
  116. package/dist/components/LocaleProvider/ko-kr.js +24 -2
  117. package/dist/components/LocaleProvider/locale.js +24 -2
  118. package/dist/components/LocaleProvider/pt-br.js +24 -2
  119. package/dist/components/LocaleProvider/ru-ru.js +24 -2
  120. package/dist/components/LocaleProvider/zh-cn.js +24 -2
  121. package/dist/components/LogViewer/LogViewer.js +25 -14
  122. package/dist/components/MarkdownRenderer/MarkdownRenderer.js +6 -5
  123. package/dist/components/MarkdownRenderer/markdown-blocks.js +1 -1
  124. package/dist/components/Masonry/Masonry.js +13 -10
  125. package/dist/components/Mentions/MentionsCore.js +15 -11
  126. package/dist/components/Menu/Menu.js +58 -36
  127. package/dist/components/Menu/MenuCheckboxItem.js +63 -0
  128. package/dist/components/Menu/MenuDivider.js +1 -0
  129. package/dist/components/Menu/MenuGroup.js +26 -0
  130. package/dist/components/Menu/MenuItem.js +28 -9
  131. package/dist/components/Menu/MenuRadioGroup.js +30 -0
  132. package/dist/components/Menu/MenuRadioItem.js +59 -0
  133. package/dist/components/Menu/MenuSub.js +1 -0
  134. package/dist/components/Menu/MenuSubTrigger.js +1 -0
  135. package/dist/components/Menu/index.js +11 -7
  136. package/dist/components/Menu/menu-item-styles.js +7 -0
  137. package/dist/components/ModelPicker/ModelPicker.js +3 -0
  138. package/dist/components/NavigationBar/NavLink.js +7 -6
  139. package/dist/components/NavigationBar/NavigationBar.js +4 -0
  140. package/dist/components/NumberInput/NumberInputCore.js +4 -0
  141. package/dist/components/OTPInput/OTPInputCore.js +9 -7
  142. package/dist/components/Pagination/Pagination.js +125 -33
  143. package/dist/components/PasswordInput/PasswordInputCore.js +9 -6
  144. package/dist/components/Popover/Popover.js +9 -7
  145. package/dist/components/Progress/Progress.js +5 -0
  146. package/dist/components/PromptInput/PromptInput.js +49 -41
  147. package/dist/components/QRCode/QRCode.js +9 -7
  148. package/dist/components/Radio/Radio.js +2 -0
  149. package/dist/components/Radio/RadioGroupCore.js +7 -6
  150. package/dist/components/Rating/RatingCore.js +18 -15
  151. package/dist/components/Resizable/Resizable.js +25 -22
  152. package/dist/components/Result/Result.js +5 -0
  153. package/dist/components/ScrollArea/ScrollArea.js +1 -0
  154. package/dist/components/Segmented/SegmentedCore.js +9 -7
  155. package/dist/components/Select/Option.js +1 -0
  156. package/dist/components/Select/OptionGroup.js +1 -0
  157. package/dist/components/Select/SelectCore.js +11 -8
  158. package/dist/components/Select/SelectFloating.js +54 -36
  159. package/dist/components/Sidebar/Sidebar.js +52 -42
  160. package/dist/components/Signature/Signature.js +101 -91
  161. package/dist/components/Skeleton/Skeleton.js +1 -0
  162. package/dist/components/Slider/SliderCore.js +149 -43
  163. package/dist/components/Sources/Sources.js +31 -21
  164. package/dist/components/Spinner/Spinner.js +1 -0
  165. package/dist/components/Stat/Stat.js +7 -0
  166. package/dist/components/StepTimeline/StepTimeline.js +6 -0
  167. package/dist/components/Stepper/Step.js +8 -1
  168. package/dist/components/Stepper/Stepper.js +7 -6
  169. package/dist/components/StreamingText/StreamingText.js +62 -29
  170. package/dist/components/SwipeAction/SwipeAction.js +11 -9
  171. package/dist/components/Switch/SwitchCore.js +9 -5
  172. package/dist/components/Table/Table.js +2 -0
  173. package/dist/components/Table/TableBody.js +1 -0
  174. package/dist/components/Table/TableCell.js +1 -0
  175. package/dist/components/Table/TableHead.js +1 -0
  176. package/dist/components/Table/TableRow.js +1 -0
  177. package/dist/components/Tabs/Tab.js +1 -0
  178. package/dist/components/Tabs/TabList.js +5 -4
  179. package/dist/components/Tabs/TabPanel.js +1 -0
  180. package/dist/components/Tabs/Tabs.js +1 -0
  181. package/dist/components/Tag/Tag.js +2 -0
  182. package/dist/components/TagGroup/SortableTagGroup.js +7 -6
  183. package/dist/components/TagGroup/TagGroup.js +1 -0
  184. package/dist/components/TagGroup/TagGroupItem.js +3 -0
  185. package/dist/components/TagInput/SortableTagInputCore.js +13 -10
  186. package/dist/components/TagInput/TagInputCore.js +17 -12
  187. package/dist/components/Textarea/TextareaCore.js +1 -0
  188. package/dist/components/ThinkingIndicator/ThinkingIndicator.js +18 -4
  189. package/dist/components/TimePicker/TimePicker.js +30 -14
  190. package/dist/components/TimePicker/TimePickerCore.js +1 -0
  191. package/dist/components/TimePicker/TimePickerPanel.js +260 -0
  192. package/dist/components/TimePicker/time-picker-styles.js +7 -0
  193. package/dist/components/TimePicker/time.js +51 -0
  194. package/dist/components/Timeline/Timeline.js +14 -1
  195. package/dist/components/Toast/Toast.js +94 -48
  196. package/dist/components/Toast/ToastContainer.js +60 -56
  197. package/dist/components/Toast/ToastContext.js +3 -1
  198. package/dist/components/Toast/toast2.js +20 -14
  199. package/dist/components/Toast/useToast.js +36 -11
  200. package/dist/components/Toggle/ToggleCore.js +1 -0
  201. package/dist/components/TokenCounter/TokenCounter.js +8 -1
  202. package/dist/components/ToolCallCard/ToolCallCard.js +18 -2
  203. package/dist/components/Toolbar/Toolbar.js +9 -8
  204. package/dist/components/Toolbar/ToolbarButton.js +1 -0
  205. package/dist/components/Toolbar/ToolbarSeparator.js +1 -0
  206. package/dist/components/Toolbar/ToolbarToggle.js +1 -0
  207. package/dist/components/Tooltip/Tooltip.js +46 -42
  208. package/dist/components/Tour/Tour.js +76 -65
  209. package/dist/components/Transfer/TransferCore.js +31 -17
  210. package/dist/components/Tree/SortableTree.js +151 -0
  211. package/dist/components/Tree/Tree.js +163 -154
  212. package/dist/components/Tree/TreeItem.js +52 -39
  213. package/dist/components/Tree/index.js +2 -1
  214. package/dist/components/Tree/sortable-tree-styles.js +7 -0
  215. package/dist/components/Tree/sortable-tree-utils.js +36 -0
  216. package/dist/components/TreeSelect/TreeSelect.js +44 -34
  217. package/dist/components/Typography/Typography.js +3 -0
  218. package/dist/components/Upload/Upload.js +12 -11
  219. package/dist/components/Upload/UploadCore.js +92 -65
  220. package/dist/components/Upload/UploadList.js +177 -105
  221. package/dist/components/VirtualList/VirtualList.js +229 -124
  222. package/dist/components/Watermark/Watermark.js +8 -6
  223. package/dist/css/accordion.css +1 -1
  224. package/dist/css/alert.css +1 -1
  225. package/dist/css/async-section.css +1 -1
  226. package/dist/css/banner.css +1 -1
  227. package/dist/css/bottom-sheet.css +1 -1
  228. package/dist/css/button.css +2 -2
  229. package/dist/css/calendar.css +1 -1
  230. package/dist/css/carousel.css +1 -1
  231. package/dist/css/chat-message.css +1 -1
  232. package/dist/css/checkbox.css +1 -1
  233. package/dist/css/color-picker.css +2 -0
  234. package/dist/css/combobox.css +2 -2
  235. package/dist/css/context-menu.css +1 -1
  236. package/dist/css/dialog.css +1 -1
  237. package/dist/css/drawer.css +1 -1
  238. package/dist/css/dropdown-menu.css +7 -2
  239. package/dist/css/form.css +1 -1
  240. package/dist/css/grid.css +2 -1
  241. package/dist/css/hover-card.css +1 -1
  242. package/dist/css/input.css +1 -1
  243. package/dist/css/menu.css +9 -4
  244. package/dist/css/pagination.css +1 -1
  245. package/dist/css/popover.css +1 -1
  246. package/dist/css/progress.css +1 -1
  247. package/dist/css/radio.css +1 -1
  248. package/dist/css/rating.css +1 -1
  249. package/dist/css/segmented.css +1 -1
  250. package/dist/css/skeleton.css +1 -1
  251. package/dist/css/slider.css +1 -1
  252. package/dist/css/spinner.css +1 -1
  253. package/dist/css/stepper.css +1 -1
  254. package/dist/css/streaming-text.css +1 -1
  255. package/dist/css/switch.css +1 -1
  256. package/dist/css/tabs.css +1 -1
  257. package/dist/css/textarea.css +1 -1
  258. package/dist/css/thinking-indicator.css +1 -1
  259. package/dist/css/time-picker.css +1 -0
  260. package/dist/css/toast.css +1 -1
  261. package/dist/css/toggle.css +1 -1
  262. package/dist/css/tokens.css +1 -1
  263. package/dist/css/tooltip.css +1 -1
  264. package/dist/css/tree.css +2 -1
  265. package/dist/css/upload.css +1 -1
  266. package/dist/css/virtual-list.css +1 -1
  267. package/dist/css-manifest.json +22 -0
  268. package/dist/dates/adapter.js +13 -0
  269. package/dist/dates/gregory.js +44 -0
  270. package/dist/dates/islamic.js +87 -0
  271. package/dist/dates/registry.js +13 -0
  272. package/dist/dates/timezone.js +29 -0
  273. package/dist/design-tokens/cyan-dark.json +355 -0
  274. package/dist/design-tokens/cyan-light.json +355 -0
  275. package/dist/design-tokens/orange-dark.json +355 -0
  276. package/dist/design-tokens/orange-light.json +355 -0
  277. package/dist/design-tokens/rose-dark.json +355 -0
  278. package/dist/design-tokens/rose-light.json +355 -0
  279. package/dist/design-tokens/teal-dark.json +355 -0
  280. package/dist/design-tokens/teal-light.json +355 -0
  281. package/dist/design-tokens/violet-dark.json +355 -0
  282. package/dist/design-tokens/violet-light.json +355 -0
  283. package/dist/form/FormItem.js +71 -63
  284. package/dist/form/FormList.js +6 -6
  285. package/dist/form/form-item-styles.js +7 -0
  286. package/dist/haze-ui.css +63 -48
  287. package/dist/index.js +249 -232
  288. package/dist/mcp-docs.json +1011 -82
  289. package/dist/registry.json +17 -17
  290. package/dist/tokens/index.js +7 -7
  291. package/dist/tokens/motion.js +9 -2
  292. package/dist/tokens/palette.js +244 -84
  293. package/dist/tokens/registry.js +18 -22
  294. package/dist/types/components/Button/Button.d.ts +1 -1
  295. package/dist/types/components/Calendar/Calendar.d.ts +39 -14
  296. package/dist/types/components/Calendar/date.d.ts +51 -0
  297. package/dist/types/components/Calendar/index.d.ts +1 -1
  298. package/dist/types/components/Carousel/Carousel.d.ts +5 -1
  299. package/dist/types/components/Carousel/CarouselSlide.d.ts +3 -3
  300. package/dist/types/components/Chart/Chart.d.ts +13 -6
  301. package/dist/types/components/Chart/chart-elements.d.ts +27 -6
  302. package/dist/types/components/ChatMessage/ChatMessage.d.ts +10 -1
  303. package/dist/types/components/ColorPicker/ColorPicker.d.ts +44 -5
  304. package/dist/types/components/ColorPicker/ColorPickerPanel.d.ts +28 -0
  305. package/dist/types/components/ColorPicker/color-math.d.ts +63 -0
  306. package/dist/types/components/ColorPicker/color-picker-styles.d.ts +50 -0
  307. package/dist/types/components/ConfigProvider/ConfigContext.d.ts +67 -0
  308. package/dist/types/components/ConfigProvider/ConfigProvider.d.ts +25 -0
  309. package/dist/types/components/ConfigProvider/index.d.ts +4 -0
  310. package/dist/types/components/ConfigProvider/useConfigDefaults.d.ts +28 -0
  311. package/dist/types/components/Datepicker/Datepicker.d.ts +23 -10
  312. package/dist/types/components/Datepicker/DatepickerCore.d.ts +40 -10
  313. package/dist/types/components/Datepicker/datetime.d.ts +33 -11
  314. package/dist/types/components/DropdownMenu/DropdownMenu.d.ts +12 -2
  315. package/dist/types/components/DropdownMenu/DropdownMenuCheckboxItem.d.ts +26 -0
  316. package/dist/types/components/DropdownMenu/DropdownMenuGroup.d.ts +16 -0
  317. package/dist/types/components/DropdownMenu/DropdownMenuItem.d.ts +7 -1
  318. package/dist/types/components/DropdownMenu/DropdownMenuRadioGroup.d.ts +21 -0
  319. package/dist/types/components/DropdownMenu/DropdownMenuRadioItem.d.ts +22 -0
  320. package/dist/types/components/DropdownMenu/dropdown-menu-item-styles.d.ts +29 -0
  321. package/dist/types/components/DropdownMenu/index.d.ts +9 -1
  322. package/dist/types/components/Fullscreen/Fullscreen.d.ts +1 -0
  323. package/dist/types/components/Grid/Grid.d.ts +8 -1
  324. package/dist/types/components/Grid/GridItem.d.ts +24 -1
  325. package/dist/types/components/Grid/grid-item-styles.d.ts +57 -0
  326. package/dist/types/components/HoverCard/HoverCard.d.ts +1 -1
  327. package/dist/types/components/LocaleProvider/locale.d.ts +24 -0
  328. package/dist/types/components/Menu/Menu.d.ts +11 -2
  329. package/dist/types/components/Menu/MenuCheckboxItem.d.ts +25 -0
  330. package/dist/types/components/Menu/MenuGroup.d.ts +16 -0
  331. package/dist/types/components/Menu/MenuItem.d.ts +7 -1
  332. package/dist/types/components/Menu/MenuRadioGroup.d.ts +20 -0
  333. package/dist/types/components/Menu/MenuRadioItem.d.ts +22 -0
  334. package/dist/types/components/Menu/index.d.ts +9 -1
  335. package/dist/types/components/Menu/menu-item-styles.d.ts +28 -0
  336. package/dist/types/components/NavigationBar/NavLink.d.ts +1 -1
  337. package/dist/types/components/Pagination/Pagination.d.ts +17 -3
  338. package/dist/types/components/Sidebar/Sidebar.d.ts +1 -1
  339. package/dist/types/components/Slider/Slider.d.ts +24 -2
  340. package/dist/types/components/Slider/SliderCore.d.ts +41 -3
  341. package/dist/types/components/StreamingText/StreamingText.d.ts +8 -1
  342. package/dist/types/components/TimePicker/TimePicker.d.ts +36 -4
  343. package/dist/types/components/TimePicker/TimePickerPanel.d.ts +26 -0
  344. package/dist/types/components/TimePicker/index.d.ts +1 -0
  345. package/dist/types/components/TimePicker/time-picker-styles.d.ts +30 -0
  346. package/dist/types/components/TimePicker/time.d.ts +49 -0
  347. package/dist/types/components/Toast/Toast.d.ts +19 -6
  348. package/dist/types/components/Toast/ToastContainer.d.ts +1 -1
  349. package/dist/types/components/Toast/ToastContext.d.ts +22 -2
  350. package/dist/types/components/Toast/index.d.ts +1 -1
  351. package/dist/types/components/Toast/toast.d.ts +20 -14
  352. package/dist/types/components/Toast/useToast.d.ts +14 -4
  353. package/dist/types/components/Tooltip/Tooltip.d.ts +1 -1
  354. package/dist/types/components/Tree/SortableTree.d.ts +38 -0
  355. package/dist/types/components/Tree/Tree.d.ts +1 -1
  356. package/dist/types/components/Tree/index.d.ts +2 -0
  357. package/dist/types/components/Tree/sortable-tree-styles.d.ts +36 -0
  358. package/dist/types/components/Tree/sortable-tree-utils.d.ts +40 -0
  359. package/dist/types/components/Upload/Upload.d.ts +17 -10
  360. package/dist/types/components/Upload/UploadCore.d.ts +26 -12
  361. package/dist/types/components/Upload/UploadList.d.ts +10 -7
  362. package/dist/types/components/Upload/index.d.ts +1 -1
  363. package/dist/types/components/Upload/types.d.ts +33 -7
  364. package/dist/types/components/VirtualList/VirtualList.d.ts +79 -26
  365. package/dist/types/components/VirtualList/index.d.ts +1 -1
  366. package/dist/types/dates/adapter.d.ts +74 -0
  367. package/dist/types/dates/gregory.d.ts +10 -0
  368. package/dist/types/dates/index.d.ts +6 -0
  369. package/dist/types/dates/islamic.d.ts +17 -0
  370. package/dist/types/dates/registry.d.ts +13 -0
  371. package/dist/types/dates/timezone.d.ts +36 -0
  372. package/dist/types/form/FormItem.d.ts +31 -1
  373. package/dist/types/form/form-item-styles.d.ts +24 -0
  374. package/dist/types/index.d.ts +19 -11
  375. package/dist/types/tokens/index.d.ts +4 -2
  376. package/dist/types/tokens/motion.d.ts +16 -0
  377. package/dist/types/tokens/palette.d.ts +59 -2
  378. package/dist/types/utils/menuItems.d.ts +126 -0
  379. package/dist/types/utils/menuRadio.d.ts +21 -0
  380. package/dist/utils/floating.js +45 -44
  381. package/dist/utils/menuItems.js +55 -0
  382. package/dist/utils/menuKeyboard.js +31 -31
  383. package/dist/utils/menuRadio.js +28 -0
  384. package/dist/utils/sortable-shared.js +3 -3
  385. package/dist/utils/sortable.js +12 -11
  386. package/package.json +18 -9
package/README.md CHANGED
@@ -35,6 +35,24 @@ English | [简体中文](./README-zh_CN.md)
35
35
 
36
36
  ## Getting Started
37
37
 
38
+ ### Quickstart via create-haze-ui
39
+
40
+ Scaffold a ready-to-run app with the official templates — the CLI has zero
41
+ runtime dependencies and needs no network access beyond dependency install:
42
+
43
+ ```sh
44
+ pnpm create haze-ui my-app # vite template (default)
45
+ pnpm create haze-ui my-app --template nextjs # or: npm create haze-ui@latest my-app --
46
+ ```
47
+
48
+ The **vite** template is a React 19 + Vite + TypeScript single-page demo
49
+ (`Button` / `Input` / `Dialog` / `Toast`) with the theme classes mounted on
50
+ the page root; the **nextjs** template is a Next.js 15 App Router starter
51
+ whose home page renders the RSC-safe static subset (`Badge` / `Card` /
52
+ `Typography`) as a server component, with a client island for the
53
+ interactive pieces. Prefer wiring an existing project by hand? Continue
54
+ with Installation below.
55
+
38
56
  ### Installation
39
57
 
40
58
  ```sh
@@ -458,6 +476,46 @@ not wrapped.
458
476
  }
459
477
  ```
460
478
 
479
+ ## Brand themes: presets, runtime generation, CLI
480
+
481
+ Five preset brand themes ship as complete theme classes — `violetTheme`,
482
+ `tealTheme`, `cyanTheme`, `orangeTheme`, `roseTheme` — each a drop-in
483
+ replacement for `lightTheme`/`darkTheme` with primary/info/focus-ring
484
+ rerouted to the brand's scale.
485
+
486
+ **Runtime custom brands.** `createBrandTheme` (from `haze-ui` or
487
+ `haze-ui/tokens`) runs the exact preset pipeline from your own seed hex:
488
+
489
+ ```ts
490
+ import { createBrandTheme } from 'haze-ui/tokens';
491
+
492
+ const brand = createBrandTheme({
493
+ name: 'acme', // → --haze-acme-1…12 (lowercase kebab; not gray/green/amber/red)
494
+ light: '#0066ff', // light-mode primary seed (scale step 9)
495
+ dark: '#0a3d99', // optional — derived from light (oklch l +0.2) when omitted
496
+ overrides: { light: { 10: '#0052cc' } }, // optional extra anchors
497
+ });
498
+ // brand.light / brand.dark: bare declaration blocks — wrap in classes once:
499
+ // styleEl.textContent = `.acme-light { ${brand.light} }\n.acme-dark { ${brand.dark} }`;
500
+ ```
501
+
502
+ The blocks are theme *replacements* (never stack on `lightTheme`), and you
503
+ own contrast: pick a light seed dark enough for white text — the presets'
504
+ step-9 anchors sit near Tailwind's 600/700 range for that reason.
505
+
506
+ **CLI.** Zero Node dependencies, identical output:
507
+
508
+ ```bash
509
+ npx haze-ui-theme --primary '#0066ff' [--dark '#0a3d99'] [--name brand] [--out brand.css]
510
+ ```
511
+
512
+ **W3C design-token archives.** Every preset is also exported per mode as
513
+ W3C DTF JSON:
514
+
515
+ ```js
516
+ import violetLight from 'haze-ui/design-tokens/violet/light.json';
517
+ ```
518
+
461
519
  ## Component-level tokens
462
520
 
463
521
  Global `--haze-*` tokens theme the whole system; **component-level tokens**
package/cli/theme.mjs ADDED
@@ -0,0 +1,446 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * haze-ui-theme — generate a complete haze-ui brand theme CSS file from one
4
+ * or two seed hexes, no Node dependencies.
5
+ *
6
+ * node cli/theme.mjs --primary '#0066ff' [--dark '#0a3d99'] [--name brand] [--out brand.css]
7
+ * npx haze-ui-theme --primary '#7c3aed' --name acme
8
+ *
9
+ * The emitted classes (.haze-{name}-light / .haze-{name}-dark) are theme
10
+ * REPLACEMENTS for lightTheme/darkTheme — apply one per subtree, never stack
11
+ * on top of the default theme classes.
12
+ *
13
+ * The color math below is a dependency-free port of src/lib/tokens/oklch.ts
14
+ * + the scale/semantic pipeline of src/lib/tokens/palette.ts (the library
15
+ * source cannot be imported here: this file must also run from an
16
+ * as-yet-unbuilt checkout, and dist/ is not guaranteed to exist). Drift is
17
+ * pinned by src/lib/tokens/brand-theme.test.ts, which asserts this module's
18
+ * output is byte-identical to createBrandTheme() for every preset seed set.
19
+ */
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // OKLCH math — ported from src/lib/tokens/oklch.ts
23
+ // ---------------------------------------------------------------------------
24
+
25
+ const SRGB_LINEAR_CUTOFF = 0.04045;
26
+ const LINEAR_SRGB_CUTOFF = 0.0031308;
27
+ const GAMUT_EPSILON = 1e-5;
28
+
29
+ const srgbToLinear = (channel) =>
30
+ channel <= SRGB_LINEAR_CUTOFF ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);
31
+
32
+ const linearToSrgb = (channel) =>
33
+ channel <= LINEAR_SRGB_CUTOFF ? 12.92 * channel : 1.055 * Math.pow(channel, 1 / 2.4) - 0.055;
34
+
35
+ function linearRgbToOklab({r, g, b}) {
36
+ const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
37
+ const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
38
+ const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
39
+ return {
40
+ L: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
41
+ a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
42
+ b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
43
+ };
44
+ }
45
+
46
+ function oklabToLinearRgb({L, a, b}) {
47
+ const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
48
+ const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
49
+ const s_ = L - 0.0894841775 * a - 1.291485548 * b;
50
+ const l = l_ * l_ * l_;
51
+ const m = m_ * m_ * m_;
52
+ const s = s_ * s_ * s_;
53
+ return {
54
+ r: 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
55
+ g: -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
56
+ b: -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,
57
+ };
58
+ }
59
+
60
+ const lchToLab = ({l, c, h}) => {
61
+ const hue = (h * Math.PI) / 180;
62
+ return {L: l, a: c * Math.cos(hue), b: c * Math.sin(hue)};
63
+ };
64
+
65
+ const labToLch = ({L, a, b}) => {
66
+ const hue = (Math.atan2(b, a) * 180) / Math.PI;
67
+ return {l: L, c: Math.sqrt(a * a + b * b), h: hue < 0 ? hue + 360 : hue};
68
+ };
69
+
70
+ const inGamut = (rgb) =>
71
+ rgb.r >= -GAMUT_EPSILON && rgb.r <= 1 + GAMUT_EPSILON &&
72
+ rgb.g >= -GAMUT_EPSILON && rgb.g <= 1 + GAMUT_EPSILON &&
73
+ rgb.b >= -GAMUT_EPSILON && rgb.b <= 1 + GAMUT_EPSILON;
74
+
75
+ /** Reduce chroma until the color fits the sRGB gamut, preserving lightness and hue exactly. */
76
+ function clampChroma(color) {
77
+ const l = Math.min(1, Math.max(0, color.l));
78
+ const hue = (color.h * Math.PI) / 180;
79
+ let low = 0;
80
+ let high = Math.max(color.c, 0);
81
+ for (let i = 0; i < 20; i++) {
82
+ const mid = (low + high) / 2;
83
+ if (inGamut(oklabToLinearRgb({L: l, a: mid * Math.cos(hue), b: mid * Math.sin(hue)}))) {
84
+ low = mid;
85
+ } else {
86
+ high = mid;
87
+ }
88
+ }
89
+ return color.alpha === undefined ? {l, c: low, h: color.h} : {l, c: low, h: color.h, alpha: color.alpha};
90
+ }
91
+
92
+ /** Parse `#rgb`, `#rgba`, `#rrggbb` or `#rrggbbaa` into OKLCH. */
93
+ function parseHex(hex) {
94
+ const match = /^#([0-9a-f]{3,8})$/i.exec(hex.trim());
95
+ const digits = match?.[1];
96
+ if (digits === undefined || (digits.length !== 3 && digits.length !== 4 && digits.length !== 6 && digits.length !== 8)) {
97
+ throw new Error(`Invalid hex color: ${hex}`);
98
+ }
99
+ const expanded =
100
+ digits.length === 3 || digits.length === 4 ? digits.split('').map((d) => d + d).join('') : digits;
101
+ const alpha = expanded.length === 8 ? parseInt(expanded.slice(6, 8), 16) / 255 : undefined;
102
+ const lch = labToLch(
103
+ linearRgbToOklab({
104
+ r: srgbToLinear(parseInt(expanded.slice(0, 2), 16) / 255),
105
+ g: srgbToLinear(parseInt(expanded.slice(2, 4), 16) / 255),
106
+ b: srgbToLinear(parseInt(expanded.slice(4, 6), 16) / 255),
107
+ }),
108
+ );
109
+ return alpha === undefined ? lch : {...lch, alpha};
110
+ }
111
+
112
+ /** Format as a CSS `oklch()` string: l/c to 3 decimals, h to 1 decimal. */
113
+ const formatOklch = (color) =>
114
+ `oklch(${color.l.toFixed(3)} ${color.c.toFixed(3)} ${color.h.toFixed(1)})`;
115
+
116
+ // ---------------------------------------------------------------------------
117
+ // Palette pipeline — ported from src/lib/tokens/palette.ts
118
+ // ---------------------------------------------------------------------------
119
+
120
+ const MODES = ['light', 'dark'];
121
+
122
+ /** Gray seeds and the text-muted nudge — mirror of SEEDS.gray / TEXT_MUTED_ADJUST. */
123
+ const GRAY_SEEDS = {
124
+ light: {1: '#ffffff', 2: '#f7f8fa', 3: '#eef0f4', 4: '#e0e0e0', 9: '#8a8a8a', 11: '#4a4a4a', 12: '#1a1a1a'},
125
+ dark: {1: '#121212', 2: '#1e1e1e', 3: '#2a2a2a', 4: '#333333', 9: '#707070', 11: '#b0b0b0', 12: '#e8e8e8'},
126
+ };
127
+ /** Success/warning/danger seeds — mirror of SEEDS.green/amber/red (fixed in every theme). */
128
+ const STATUS_SEEDS = {
129
+ green: {light: {9: '#15803d'}, dark: {8: '#22c55e'}},
130
+ amber: {light: {9: '#f59e0b'}, dark: {8: '#fbbf24'}},
131
+ red: {light: {9: '#dc2626'}, dark: {8: '#ef4444'}},
132
+ };
133
+ const TEXT_MUTED_ADJUST = {light: -0.008, dark: 0.014};
134
+
135
+ const CHROMATIC_ENDPOINTS = {
136
+ light: {l1: 0.982, l12: 0.16, c1: 0.018, c12: 0.045},
137
+ dark: {l1: 0.155, l12: 0.982, c1: 0.03, c12: 0.012},
138
+ };
139
+
140
+ /** Piecewise-linear interpolation over sorted points (clamped at both ends). */
141
+ function interpolateAt(points, x) {
142
+ const first = points[0];
143
+ if (x <= first.x) return first.y;
144
+ for (let i = 1; i < points.length; i++) {
145
+ const point = points[i];
146
+ if (x <= point.x) {
147
+ const previous = points[i - 1];
148
+ const t = (x - previous.x) / (point.x - previous.x);
149
+ return previous.y + t * (point.y - previous.y);
150
+ }
151
+ }
152
+ return points[points.length - 1].y;
153
+ }
154
+
155
+ function formatSteps(luminancePoints, chromaAt, hueAt) {
156
+ const steps = [];
157
+ for (let step = 1; step <= 12; step++) {
158
+ steps.push(formatOklch(clampChroma({l: interpolateAt(luminancePoints, step), c: chromaAt(step), h: hueAt(step)})));
159
+ }
160
+ return steps;
161
+ }
162
+
163
+ function grayAnchors(seed, mode) {
164
+ return Object.entries(seed)
165
+ .map(([step, hex]) => {
166
+ const parsed = parseHex(hex);
167
+ const l = Number(step) === 9 ? parsed.l + TEXT_MUTED_ADJUST[mode] : parsed.l;
168
+ return {step: Number(step), color: {l, c: 0, h: 0}};
169
+ })
170
+ .sort((a, b) => a.step - b.step);
171
+ }
172
+
173
+ /** The fixed neutral scales — identical to the default themes' gray family. */
174
+ const GRAY_SCALE = Object.fromEntries(
175
+ MODES.map((mode) => [
176
+ mode,
177
+ formatSteps(grayAnchors(GRAY_SEEDS[mode], mode).map((a) => ({x: a.step, y: a.color.l})), () => 0, () => 0),
178
+ ]),
179
+ );
180
+
181
+ /** The fixed success/warning/danger scales — identical to the default themes'. */
182
+ const STATUS_SCALE = Object.fromEntries(
183
+ ['green', 'amber', 'red'].map((family) => [
184
+ family,
185
+ Object.fromEntries(
186
+ MODES.map((mode) => [
187
+ mode,
188
+ chromaticScaleFromAnchors(
189
+ Object.entries(STATUS_SEEDS[family][mode]).map(([step, hex]) => ({step: Number(step), color: parseHex(hex)})),
190
+ mode,
191
+ ),
192
+ ]),
193
+ ),
194
+ ]),
195
+ );
196
+
197
+ function chromaticScaleFromAnchors(anchors, mode) {
198
+ const endpoints = CHROMATIC_ENDPOINTS[mode];
199
+ const luminancePoints = [{x: 1, y: endpoints.l1}, ...anchors.map((a) => ({x: a.step, y: a.color.l})), {x: 12, y: endpoints.l12}];
200
+ const chromaPoints = [{x: 1, y: endpoints.c1}, ...anchors.map((a) => ({x: a.step, y: a.color.c})), {x: 12, y: endpoints.c12}];
201
+ const huePoints = [
202
+ {x: 1, y: anchors[0].color.h},
203
+ ...anchors.map((a) => ({x: a.step, y: a.color.h})),
204
+ {x: 12, y: anchors[anchors.length - 1].color.h},
205
+ ];
206
+ return formatSteps(luminancePoints, (step) => interpolateAt(chromaPoints, step), (step) => interpolateAt(huePoints, step));
207
+ }
208
+
209
+ // Semantic rerouting — mirror of DEFAULT_STATUS_FAMILY / STATUS_STEP / NEUTRAL_STEP.
210
+ const DEFAULT_STATUS_FAMILY = {primary: 'blue', success: 'green', warning: 'amber', danger: 'red', info: 'blue'};
211
+ const STATUS_STEP = {
212
+ light: {primary: 9, success: 9, warning: 9, danger: 9, info: 10},
213
+ dark: {primary: 9, success: 8, warning: 8, danger: 8, info: 8},
214
+ };
215
+ const NEUTRAL_STEP = {
216
+ bg: 1,
217
+ 'bg-subtle': 2,
218
+ 'bg-muted': 3,
219
+ text: 12,
220
+ 'text-secondary': 11,
221
+ 'text-muted': 9,
222
+ border: 4,
223
+ };
224
+
225
+ // Interaction-state parameters — mirror of DERIVED_PARAMS / FOCUS_RING_ALPHA.
226
+ const DERIVED_PARAMS = {
227
+ light: {hover: -0.045, active: -0.09, borderHover: -0.09, subtleL: 0.945, subtleC: 0.2},
228
+ dark: {hover: 0.05, active: 0.09, borderHover: 0.08, subtleL: 0.26, subtleC: 0.35},
229
+ };
230
+ const FOCUS_RING_ALPHA = 0.4;
231
+
232
+ const primitiveVar = (family, step) => `var(--haze-${family}-${step})`;
233
+ const lightnessCalc = (delta) => `calc(l ${delta < 0 ? '-' : '+'} ${Math.abs(delta)})`;
234
+
235
+ function derivedCss(mode, baseVar, kind) {
236
+ const params = DERIVED_PARAMS[mode];
237
+ switch (kind) {
238
+ case 'hover':
239
+ return `oklch(from ${baseVar} ${lightnessCalc(params.hover)} c h)`;
240
+ case 'active':
241
+ return `oklch(from ${baseVar} ${lightnessCalc(params.active)} c h)`;
242
+ case 'subtle':
243
+ return `oklch(from ${baseVar} ${params.subtleL} calc(c * ${params.subtleC}) h)`;
244
+ case 'border-hover':
245
+ return `oklch(from ${baseVar} ${lightnessCalc(params.borderHover)} c h)`;
246
+ case 'focus-ring':
247
+ return `oklch(from ${baseVar} l c h / ${FOCUS_RING_ALPHA})`;
248
+ }
249
+ }
250
+
251
+ /**
252
+ * The full declaration block one mode of a brand theme carries: primitive
253
+ * scales first (gray/{name}/green/amber/red), then the semantic aliases
254
+ * with primary/info/focus-ring rerouted to the brand family.
255
+ */
256
+ function themeDeclarations(mode, name, brandScale) {
257
+ const primitives = [
258
+ ['gray', GRAY_SCALE[mode]],
259
+ [name, brandScale],
260
+ ['green', STATUS_SCALE.green[mode]],
261
+ ['amber', STATUS_SCALE.amber[mode]],
262
+ ['red', STATUS_SCALE.red[mode]],
263
+ ]
264
+ .map(([family, steps]) => steps.map((value, index) => `--haze-${family}-${index + 1}: ${value};`).join('\n'))
265
+ .join('\n');
266
+ const statusFamily = {...DEFAULT_STATUS_FAMILY, primary: name, info: name};
267
+ const lines = [];
268
+ const statusGroup = (key) => {
269
+ const base = `--haze-color-${key}`;
270
+ const family = statusFamily[key];
271
+ lines.push(`${base}: ${primitiveVar(family, STATUS_STEP[mode][key])};`);
272
+ const baseVar = `var(${base})`;
273
+ lines.push(`${base}-hover: ${derivedCss(mode, baseVar, 'hover')};`);
274
+ lines.push(`${base}-active: ${derivedCss(mode, baseVar, 'active')};`);
275
+ lines.push(`${base}-subtle: ${derivedCss(mode, baseVar, 'subtle')};`);
276
+ };
277
+ const neutral = (key) => lines.push(`--haze-color-${key}: ${primitiveVar('gray', NEUTRAL_STEP[key])};`);
278
+ statusGroup('primary');
279
+ neutral('bg');
280
+ neutral('bg-subtle');
281
+ neutral('bg-muted');
282
+ neutral('text');
283
+ neutral('text-secondary');
284
+ neutral('text-muted');
285
+ lines.push(`--haze-color-text-inverse: ${mode === 'light' ? 'oklch(1 0 0)' : GRAY_SCALE.light[11]};`);
286
+ neutral('border');
287
+ lines.push(`--haze-color-border-hover: ${derivedCss(mode, 'var(--haze-color-border)', 'border-hover')};`);
288
+ statusGroup('success');
289
+ statusGroup('warning');
290
+ statusGroup('danger');
291
+ statusGroup('info');
292
+ lines.push(`--haze-color-focus-ring: ${derivedCss(mode, 'var(--haze-color-primary)', 'focus-ring')};`);
293
+ return `${primitives}\n\n${lines.join('\n')}`;
294
+ }
295
+
296
+ // ---------------------------------------------------------------------------
297
+ // createBrandTheme mirror — identical options/semantics to palette.ts
298
+ // ---------------------------------------------------------------------------
299
+
300
+ const NEUTRAL_FAMILIES = new Set(['gray', 'green', 'amber', 'red']);
301
+ const FAMILY_NAME_RE = /^[a-z][a-z0-9-]*$/;
302
+ const DERIVED_SEED_OFFSETS = {infoStep: -0.07, darkPrimary: 0.2};
303
+
304
+ const clampLightness = (l) => Math.min(1, Math.max(0, l));
305
+ const shiftLightness = (color, delta) => clampChroma({l: clampLightness(color.l + delta), c: color.c, h: color.h});
306
+
307
+ function mergeAnchors(base, seed) {
308
+ const byStep = new Map(base.map((anchor) => [anchor.step, anchor.color]));
309
+ for (const [step, hex] of Object.entries(seed ?? {})) {
310
+ if (Number(step) < 1 || Number(step) > 12) {
311
+ throw new Error(`Seed anchor step ${step} is outside the 1–12 scale`);
312
+ }
313
+ byStep.set(Number(step), parseHex(hex));
314
+ }
315
+ return [...byStep.entries()].map(([step, color]) => ({step, color})).sort((a, b) => a.step - b.step);
316
+ }
317
+
318
+ /**
319
+ * Build a complete brand theme at runtime — mirror of palette.ts's
320
+ * createBrandTheme (byte-identical output; enforced by brand-theme.test.ts).
321
+ *
322
+ * @param {{name?: string, light: string, dark?: string, overrides?: {light?: Record<number, string>, dark?: Record<number, string>}}} options
323
+ * @returns {{name: string, light: string, dark: string}} bare declaration blocks per mode
324
+ */
325
+ export function createBrandThemeCss({name = 'brand', light, dark, overrides} = {}) {
326
+ if (!FAMILY_NAME_RE.test(name)) {
327
+ throw new Error(`Invalid brand name "${name}" — use a lowercase kebab identifier (letters, digits, hyphens)`);
328
+ }
329
+ if (NEUTRAL_FAMILIES.has(name)) {
330
+ throw new Error(`Brand name "${name}" collides with a fixed neutral family (gray/green/amber/red)`);
331
+ }
332
+ const lightPrimary = parseHex(light);
333
+ const darkPrimary = dark === undefined ? shiftLightness(lightPrimary, DERIVED_SEED_OFFSETS.darkPrimary) : parseHex(dark);
334
+ const anchors = {
335
+ light: mergeAnchors(
336
+ [
337
+ {step: 9, color: lightPrimary},
338
+ {step: 10, color: shiftLightness(lightPrimary, DERIVED_SEED_OFFSETS.infoStep)},
339
+ ],
340
+ overrides?.light,
341
+ ),
342
+ dark: mergeAnchors(
343
+ [
344
+ {step: 9, color: darkPrimary},
345
+ {step: 8, color: shiftLightness(darkPrimary, DERIVED_SEED_OFFSETS.infoStep)},
346
+ ],
347
+ overrides?.dark,
348
+ ),
349
+ };
350
+ return {
351
+ name,
352
+ light: themeDeclarations('light', name, chromaticScaleFromAnchors(anchors.light, 'light')),
353
+ dark: themeDeclarations('dark', name, chromaticScaleFromAnchors(anchors.dark, 'dark')),
354
+ };
355
+ }
356
+
357
+ /** Wrap the two declaration blocks into a standalone stylesheet. */
358
+ export function renderStylesheet(theme, {lightSeed, darkSeed}) {
359
+ const header = [
360
+ `/* haze-ui brand theme "${theme.name}" — generated by haze-ui-theme.`,
361
+ ` light seed: ${lightSeed} · dark seed: ${darkSeed}`,
362
+ ' Apply ONE class per subtree as a replacement for lightTheme/darkTheme. */',
363
+ ].join('\n');
364
+ const block = (mode) => `.haze-${theme.name}-${mode} {\n${theme[mode]}\n}`;
365
+ return `${header}\n\n${block('light')}\n\n${block('dark')}\n`;
366
+ }
367
+
368
+ // ---------------------------------------------------------------------------
369
+ // CLI entry
370
+ // ---------------------------------------------------------------------------
371
+
372
+ import {writeFileSync} from 'node:fs';
373
+ import {pathToFileURL} from 'node:url';
374
+
375
+ const USAGE = `Usage: haze-ui-theme --primary <hex> [--dark <hex>] [--name <kebab>] [--out <file>]
376
+
377
+ --primary <hex> Light-mode primary seed, e.g. '#0066ff' (required).
378
+ --dark <hex> Dark-mode primary seed. Omit to derive it from --primary
379
+ (OKLCH lightness +0.2, chroma/hue preserved).
380
+ --name <kebab> Brand family name for the custom properties (default:
381
+ 'brand'). Becomes --haze-<name>-1…12; may not be
382
+ gray/green/amber/red.
383
+ --out <file> Write the stylesheet to <file> instead of stdout.
384
+
385
+ Outputs .haze-<name>-light / .haze-<name>-dark classes carrying the complete
386
+ token set (primitive scales + semantic aliases + relative-color interaction
387
+ states) — use them as replacements for lightTheme/darkTheme.`;
388
+
389
+ function parseArgs(argv) {
390
+ const options = {primary: undefined, dark: undefined, name: 'brand', out: undefined};
391
+ for (let i = 0; i < argv.length; i++) {
392
+ const arg = argv[i];
393
+ const flag = arg.includes('=') ? arg.slice(0, arg.indexOf('=')) : arg;
394
+ const inline = arg.includes('=') ? arg.slice(arg.indexOf('=') + 1) : undefined;
395
+ const value = inline ?? argv[++i];
396
+ if (flag === '--help' || flag === '-h') {
397
+ options.help = true;
398
+ } else if (flag === '--primary') {
399
+ options.primary = value;
400
+ } else if (flag === '--dark') {
401
+ options.dark = value;
402
+ } else if (flag === '--name') {
403
+ options.name = value;
404
+ } else if (flag === '--out') {
405
+ options.out = value;
406
+ } else {
407
+ throw new Error(`Unknown argument: ${arg}\n\n${USAGE}`);
408
+ }
409
+ if (value === undefined && !options.help) {
410
+ throw new Error(`Missing value for ${flag}\n\n${USAGE}`);
411
+ }
412
+ }
413
+ return options;
414
+ }
415
+
416
+ function main(argv) {
417
+ const options = parseArgs(argv);
418
+ if (options.help) {
419
+ process.stdout.write(`${USAGE}\n`);
420
+ return 0;
421
+ }
422
+ if (options.primary === undefined) {
423
+ process.stderr.write(`haze-ui-theme: --primary is required\n\n${USAGE}\n`);
424
+ return 1;
425
+ }
426
+ let theme;
427
+ try {
428
+ theme = createBrandThemeCss({name: options.name, light: options.primary, dark: options.dark});
429
+ } catch (error) {
430
+ process.stderr.write(`haze-ui-theme: ${error instanceof Error ? error.message : error}\n`);
431
+ return 1;
432
+ }
433
+ const css = renderStylesheet(theme, {lightSeed: options.primary, darkSeed: options.dark ?? 'derived (oklch l +0.2)'});
434
+ if (options.out === undefined) {
435
+ process.stdout.write(css);
436
+ return 0;
437
+ }
438
+ writeFileSync(options.out, css);
439
+ process.stdout.write(`haze-ui-theme: wrote ${options.out} (.haze-${options.name}-light / .haze-${options.name}-dark)\n`);
440
+ return 0;
441
+ }
442
+
443
+ // Run as a script; importable as a module when executed by the parity test.
444
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
445
+ process.exit(main(process.argv.slice(2)));
446
+ }
@@ -7,6 +7,7 @@ import { jsx as t } from "react/jsx-runtime";
7
7
  var n = "haze-Accordion__base";
8
8
  function r({ className: r, children: i }) {
9
9
  return /* @__PURE__ */ t("div", {
10
+ "data-slot": "accordion",
10
11
  className: e([n, r]),
11
12
  children: i
12
13
  });
@@ -7,12 +7,15 @@ import { jsx as t, jsxs as n } from "react/jsx-runtime";
7
7
  var r = "haze-AccordionItem__item", i = "haze-AccordionItem__summary", a = "haze-AccordionItem__content";
8
8
  function o({ title: o, className: s, children: c }) {
9
9
  return /* @__PURE__ */ n("details", {
10
+ "data-slot": "accordion-item",
10
11
  name: "accordion",
11
12
  className: e([r, s]),
12
13
  children: [/* @__PURE__ */ t("summary", {
14
+ "data-slot": "header",
13
15
  className: i,
14
16
  children: o
15
17
  }), /* @__PURE__ */ t("div", {
18
+ "data-slot": "content",
16
19
  className: a,
17
20
  children: c
18
21
  })]
@@ -8,6 +8,7 @@ var n = "haze-Affix__affix", r = "haze-Affix__posTop", i = "haze-Affix__posBotto
8
8
  function a({ position: a = "top", offset: o = 0, children: s, className: c, style: l }) {
9
9
  let u = a === "top" ? r : i;
10
10
  return /* @__PURE__ */ t("div", {
11
+ "data-slot": "affix",
11
12
  style: {
12
13
  ...a === "top" ? { top: o } : { bottom: o },
13
14
  ...l
@@ -16,16 +16,19 @@ function l({ visible: l, onClose: u, variant: d = "info", closable: f = !1, clas
16
16
  let [h, g] = i(l, !0), _ = t("alert");
17
17
  return h ? /* @__PURE__ */ r("div", {
18
18
  role: "alert",
19
+ "data-slot": "alert",
19
20
  className: e([
20
21
  a,
21
22
  o[d],
22
23
  p
23
24
  ]),
24
25
  children: [/* @__PURE__ */ n("div", {
26
+ "data-slot": "content",
25
27
  className: s,
26
28
  children: m
27
29
  }), f && /* @__PURE__ */ n("button", {
28
30
  type: "button",
31
+ "data-slot": "close",
29
32
  className: c,
30
33
  "aria-label": _.close,
31
34
  onClick: () => {
@@ -2,8 +2,8 @@
2
2
  "use client";
3
3
  import { classnames as e } from "../../utils/classnames.js";
4
4
  /* empty css */
5
- import { jsx as t } from "react/jsx-runtime";
6
- import { useEffect as n } from "react";
5
+ import { useEffect as t } from "react";
6
+ import { jsx as n } from "react/jsx-runtime";
7
7
  import { useControl as r } from "react-use-control";
8
8
  //#region src/lib/components/Anchor/Anchor.tsx
9
9
  var i = "haze-Anchor__nav", a = "haze-Anchor__list", o = "haze-Anchor__link", s = "haze-Anchor__linkActive";
@@ -21,7 +21,7 @@ function c({ items: c, activeId: l, onClick: u, offsetTop: d = 0, bounds: f = 5,
21
21
  behavior: "smooth"
22
22
  });
23
23
  };
24
- return n(() => {
24
+ return t(() => {
25
25
  if (typeof IntersectionObserver > "u") return;
26
26
  let e = /* @__PURE__ */ new Set(), t = p?.() ?? window, n = new IntersectionObserver((t) => {
27
27
  for (let n of t) n.isIntersecting ? e.add(n.target.id) : e.delete(n.target.id);
@@ -41,7 +41,7 @@ function c({ items: c, activeId: l, onClick: u, offsetTop: d = 0, bounds: f = 5,
41
41
  d,
42
42
  p,
43
43
  _
44
- ]), n(() => {
44
+ ]), t(() => {
45
45
  if (typeof IntersectionObserver < "u") return;
46
46
  let e = p?.() ?? window, t = e instanceof HTMLElement ? e : window, n = e instanceof HTMLElement ? e.getBoundingClientRect().top : 0, r = () => {
47
47
  let e;
@@ -57,20 +57,26 @@ function c({ items: c, activeId: l, onClick: u, offsetTop: d = 0, bounds: f = 5,
57
57
  f,
58
58
  p,
59
59
  _
60
- ]), /* @__PURE__ */ t("nav", {
60
+ ]), /* @__PURE__ */ n("nav", {
61
+ "data-slot": "anchor",
61
62
  ...h,
62
63
  className: e([i, m]),
63
- children: t("ul", {
64
+ children: n("ul", {
65
+ "data-slot": "list",
64
66
  className: e([a]),
65
- children: c.map((n) => /* @__PURE__ */ t("li", { children: /* @__PURE__ */ t("a", {
66
- href: `#${n.id}`,
67
- "aria-current": g === n.id ? "true" : void 0,
68
- onClick: (e) => {
69
- e.preventDefault(), _(n.id), u?.(n.id), v(n.id);
70
- },
71
- className: e([o, g === n.id && s]),
72
- children: n.label
73
- }) }, n.id))
67
+ children: c.map((t) => /* @__PURE__ */ n("li", {
68
+ "data-slot": "item",
69
+ children: /* @__PURE__ */ n("a", {
70
+ "data-slot": "link",
71
+ href: `#${t.id}`,
72
+ "aria-current": g === t.id ? "true" : void 0,
73
+ onClick: (e) => {
74
+ e.preventDefault(), _(t.id), u?.(t.id), v(t.id);
75
+ },
76
+ className: e([o, g === t.id && s]),
77
+ children: t.label
78
+ })
79
+ }, t.id))
74
80
  })
75
81
  });
76
82
  }
@@ -9,6 +9,7 @@ var i = "haze-AppShell__shell", a = "haze-AppShell__withSidebar", o = "haze-AppS
9
9
  function u({ header: u, sidebar: d, footer: f, sidebarCollapsed: p, sidebarWidth: m = "calc(var(--haze-space-16) * 4)", className: h, style: g, children: _, ...v }) {
10
10
  let [y] = r(p, !1);
11
11
  return /* @__PURE__ */ n("div", {
12
+ "data-slot": "app-shell",
12
13
  style: {
13
14
  "--haze-appshell-sidebar-width": m,
14
15
  ...g
@@ -21,19 +22,23 @@ function u({ header: u, sidebar: d, footer: f, sidebarCollapsed: p, sidebarWidth
21
22
  ]),
22
23
  children: [
23
24
  u != null && /* @__PURE__ */ t("header", {
25
+ "data-slot": "header",
24
26
  className: e(o),
25
27
  children: u
26
28
  }),
27
29
  d != null && /* @__PURE__ */ t("aside", {
30
+ "data-slot": "aside",
28
31
  "data-state": y ? "collapsed" : "expanded",
29
32
  className: e(s),
30
33
  children: d
31
34
  }),
32
35
  /* @__PURE__ */ t("main", {
36
+ "data-slot": "main",
33
37
  className: e(c),
34
38
  children: _
35
39
  }),
36
40
  f != null && /* @__PURE__ */ t("footer", {
41
+ "data-slot": "footer",
37
42
  className: e(l),
38
43
  children: f
39
44
  })