haze-ui 1.25.0 → 1.27.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/README.md +492 -10
  2. package/dist/components/Accordion/Accordion.js +1 -0
  3. package/dist/components/Accordion/AccordionItem.js +1 -0
  4. package/dist/components/Accordion/index.js +1 -0
  5. package/dist/components/Affix/Affix.js +1 -0
  6. package/dist/components/Affix/index.js +1 -0
  7. package/dist/components/Alert/Alert.js +1 -0
  8. package/dist/components/Alert/index.js +1 -0
  9. package/dist/components/Anchor/Anchor.js +78 -0
  10. package/dist/components/Anchor/index.js +3 -0
  11. package/dist/components/AppShell/AppShell.js +44 -0
  12. package/dist/components/AppShell/index.js +3 -0
  13. package/dist/components/ApprovalCard/ApprovalCard.js +1 -0
  14. package/dist/components/ApprovalCard/index.js +1 -0
  15. package/dist/components/AsyncSection/AsyncSection.js +1 -0
  16. package/dist/components/AsyncSection/index.js +1 -0
  17. package/dist/components/Avatar/Avatar.js +1 -0
  18. package/dist/components/Avatar/index.js +1 -0
  19. package/dist/components/AvatarGroup/AvatarGroup.js +1 -0
  20. package/dist/components/AvatarGroup/index.js +1 -0
  21. package/dist/components/BackToTop/BackToTop.js +1 -0
  22. package/dist/components/BackToTop/index.js +1 -0
  23. package/dist/components/Badge/Badge.js +5 -16
  24. package/dist/components/Badge/badge-styles.js +15 -0
  25. package/dist/components/Badge/index.js +3 -2
  26. package/dist/components/Banner/Banner.js +1 -0
  27. package/dist/components/Banner/index.js +1 -0
  28. package/dist/components/BottomSheet/BottomSheet.js +134 -22
  29. package/dist/components/BottomSheet/index.js +1 -0
  30. package/dist/components/Breadcrumb/Breadcrumb.js +1 -0
  31. package/dist/components/Breadcrumb/BreadcrumbItem.js +1 -0
  32. package/dist/components/Breadcrumb/index.js +1 -0
  33. package/dist/components/Button/Button.js +1 -0
  34. package/dist/components/Button/ButtonLink.js +1 -0
  35. package/dist/components/Button/index.js +5 -3
  36. package/dist/components/Button/styles.js +1 -0
  37. package/dist/components/Calendar/Calendar.js +453 -105
  38. package/dist/components/Calendar/date.js +87 -0
  39. package/dist/components/Calendar/index.js +1 -0
  40. package/dist/components/Carousel/Carousel.js +65 -41
  41. package/dist/components/Carousel/CarouselSlide.js +1 -0
  42. package/dist/components/Carousel/index.js +1 -0
  43. package/dist/components/Cascader/Cascader.js +186 -137
  44. package/dist/components/Cascader/index.js +1 -0
  45. package/dist/components/Chart/Chart.js +31 -0
  46. package/dist/components/Chart/chart-elements.js +88 -0
  47. package/dist/components/Chart/index.js +3 -0
  48. package/dist/components/ChatContainer/ChatContainer.js +37 -16
  49. package/dist/components/ChatContainer/index.js +1 -0
  50. package/dist/components/ChatInput/ChatInput.js +50 -29
  51. package/dist/components/ChatInput/index.js +1 -0
  52. package/dist/components/ChatMessage/ChatMessage.js +77 -29
  53. package/dist/components/ChatMessage/index.js +1 -0
  54. package/dist/components/Checkbox/Checkbox.js +7 -5
  55. package/dist/components/Checkbox/CheckboxCore.js +7 -5
  56. package/dist/components/Checkbox/index.js +1 -0
  57. package/dist/components/Chip/Chip.js +1 -0
  58. package/dist/components/Chip/index.js +1 -0
  59. package/dist/components/Collapsible/Collapsible.js +24 -10
  60. package/dist/components/Collapsible/index.js +1 -0
  61. package/dist/components/ColorPicker/ColorPicker.js +6 -4
  62. package/dist/components/ColorPicker/ColorPickerCore.js +6 -4
  63. package/dist/components/ColorPicker/index.js +1 -0
  64. package/dist/components/Combobox/Combobox.js +196 -69
  65. package/dist/components/Combobox/ComboboxGroup.js +23 -0
  66. package/dist/components/Combobox/ComboboxOption.js +10 -5
  67. package/dist/components/Combobox/index.js +5 -3
  68. package/dist/components/Command/Command.js +103 -59
  69. package/dist/components/Command/CommandDialog.js +48 -0
  70. package/dist/components/Command/command-filter.js +16 -0
  71. package/dist/components/Command/index.js +4 -2
  72. package/dist/components/ConfirmDialog/ConfirmDialog.js +4 -3
  73. package/dist/components/ConfirmDialog/index.js +1 -0
  74. package/dist/components/ContextMenu/ContextMenu.js +1 -0
  75. package/dist/components/ContextMenu/ContextMenuContent.js +5 -4
  76. package/dist/components/ContextMenu/ContextMenuContext.js +1 -0
  77. package/dist/components/ContextMenu/ContextMenuItem.js +1 -0
  78. package/dist/components/ContextMenu/ContextMenuSeparator.js +1 -0
  79. package/dist/components/ContextMenu/ContextMenuTrigger.js +1 -0
  80. package/dist/components/ContextMenu/index.js +1 -0
  81. package/dist/components/ConversationList/ConversationItem.js +1 -0
  82. package/dist/components/ConversationList/ConversationList.js +1 -0
  83. package/dist/components/ConversationList/index.js +1 -0
  84. package/dist/components/DataTable/CellEditor.js +38 -0
  85. package/dist/components/DataTable/DataTable.js +415 -125
  86. package/dist/components/DataTable/features.js +25 -0
  87. package/dist/components/DataTable/index.js +3 -1
  88. package/dist/components/DataTable/summary.js +17 -0
  89. package/dist/components/DateRangePicker/DateRangePicker.js +11 -7
  90. package/dist/components/DateRangePicker/DateRangePickerCore.js +60 -27
  91. package/dist/components/DateRangePicker/index.js +1 -0
  92. package/dist/components/Datepicker/Datepicker.js +17 -12
  93. package/dist/components/Datepicker/DatepickerCore.js +51 -37
  94. package/dist/components/Datepicker/index.js +1 -0
  95. package/dist/components/Dialog/Dialog.js +57 -32
  96. package/dist/components/Dialog/index.js +1 -0
  97. package/dist/components/DiffViewer/DiffViewer.js +1 -0
  98. package/dist/components/DiffViewer/index.js +1 -0
  99. package/dist/components/Disclosure/Disclosure.js +1 -0
  100. package/dist/components/Disclosure/index.js +1 -0
  101. package/dist/components/Drawer/Drawer.js +50 -29
  102. package/dist/components/Drawer/index.js +1 -0
  103. package/dist/components/DropdownMenu/DropdownMenu.js +39 -26
  104. package/dist/components/DropdownMenu/DropdownMenuContent.js +1 -0
  105. package/dist/components/DropdownMenu/DropdownMenuContext.js +1 -0
  106. package/dist/components/DropdownMenu/DropdownMenuItem.js +1 -0
  107. package/dist/components/DropdownMenu/DropdownMenuSeparator.js +1 -0
  108. package/dist/components/DropdownMenu/DropdownMenuSub.js +23 -0
  109. package/dist/components/DropdownMenu/DropdownMenuSubContent.js +24 -0
  110. package/dist/components/DropdownMenu/DropdownMenuSubTrigger.js +30 -0
  111. package/dist/components/DropdownMenu/DropdownMenuTrigger.js +1 -0
  112. package/dist/components/DropdownMenu/index.js +5 -1
  113. package/dist/components/Empty/Empty.js +1 -0
  114. package/dist/components/Empty/index.js +1 -0
  115. package/dist/components/FileInput/FileInput.js +1 -0
  116. package/dist/components/FileInput/index.js +1 -0
  117. package/dist/components/Fullscreen/Fullscreen.js +29 -0
  118. package/dist/components/Fullscreen/index.js +3 -0
  119. package/dist/components/HoverCard/HoverCard.js +1 -0
  120. package/dist/components/HoverCard/index.js +1 -0
  121. package/dist/components/Image/Image.js +38 -19
  122. package/dist/components/Image/ImagePreview.js +233 -0
  123. package/dist/components/Image/index.js +1 -0
  124. package/dist/components/InlineEdit/InlineEdit.js +1 -0
  125. package/dist/components/InlineEdit/index.js +1 -0
  126. package/dist/components/Input/Input.js +7 -5
  127. package/dist/components/Input/InputCore.js +4 -2
  128. package/dist/components/Input/index.js +1 -0
  129. package/dist/components/List/List.js +1 -0
  130. package/dist/components/List/ListItem.js +1 -0
  131. package/dist/components/List/index.js +1 -0
  132. package/dist/components/LocaleProvider/LocaleContext.js +1 -0
  133. package/dist/components/LocaleProvider/LocaleProvider.js +17 -13
  134. package/dist/components/LocaleProvider/index.js +6 -3
  135. package/dist/components/LocaleProvider/locale.js +65 -3
  136. package/dist/components/LocaleProvider/strings.js +15 -0
  137. package/dist/components/LocaleProvider/useStrings.js +18 -8
  138. package/dist/components/LocaleProvider/zh-cn.js +184 -0
  139. package/dist/components/LogViewer/LogViewer.js +1 -0
  140. package/dist/components/LogViewer/index.js +1 -0
  141. package/dist/components/MarkdownRenderer/MarkdownRenderer.js +1 -0
  142. package/dist/components/MarkdownRenderer/index.js +1 -0
  143. package/dist/components/MarkdownRenderer/markdown-blocks.js +1 -0
  144. package/dist/components/Mentions/Mentions.js +18 -0
  145. package/dist/components/Mentions/MentionsCore.js +117 -0
  146. package/dist/components/Mentions/index.js +4 -0
  147. package/dist/components/Menu/Menu.js +6 -5
  148. package/dist/components/Menu/MenuDivider.js +1 -0
  149. package/dist/components/Menu/MenuItem.js +1 -0
  150. package/dist/components/Menu/MenuSub.js +23 -0
  151. package/dist/components/Menu/MenuSubContent.js +24 -0
  152. package/dist/components/Menu/MenuSubTrigger.js +30 -0
  153. package/dist/components/Menu/index.js +5 -1
  154. package/dist/components/ModelPicker/ModelPicker.js +1 -0
  155. package/dist/components/ModelPicker/index.js +1 -0
  156. package/dist/components/NavigationBar/NavLink.js +1 -0
  157. package/dist/components/NavigationBar/NavigationBar.js +1 -0
  158. package/dist/components/NavigationBar/index.js +1 -0
  159. package/dist/components/NumberInput/NumberInput.js +7 -5
  160. package/dist/components/NumberInput/NumberInputCore.js +10 -8
  161. package/dist/components/NumberInput/index.js +1 -0
  162. package/dist/components/OTPInput/OTPInput.js +6 -4
  163. package/dist/components/OTPInput/OTPInputCore.js +35 -33
  164. package/dist/components/OTPInput/index.js +1 -0
  165. package/dist/components/Pagination/Pagination.js +1 -0
  166. package/dist/components/Pagination/index.js +1 -0
  167. package/dist/components/PasswordInput/PasswordInput.js +6 -4
  168. package/dist/components/PasswordInput/PasswordInputCore.js +9 -7
  169. package/dist/components/PasswordInput/index.js +1 -0
  170. package/dist/components/Popover/Popover.js +44 -31
  171. package/dist/components/Popover/index.js +1 -0
  172. package/dist/components/Progress/Progress.js +1 -0
  173. package/dist/components/Progress/index.js +1 -0
  174. package/dist/components/PromptInput/PromptInput.js +213 -0
  175. package/dist/components/PromptInput/index.js +3 -0
  176. package/dist/components/Radio/Radio.js +8 -6
  177. package/dist/components/Radio/RadioContext.js +1 -0
  178. package/dist/components/Radio/RadioGroup.js +6 -4
  179. package/dist/components/Radio/RadioGroupCore.js +24 -14
  180. package/dist/components/Radio/index.js +1 -0
  181. package/dist/components/Rating/Rating.js +6 -4
  182. package/dist/components/Rating/RatingCore.js +63 -28
  183. package/dist/components/Rating/index.js +1 -0
  184. package/dist/components/Resizable/Resizable.js +1 -0
  185. package/dist/components/Resizable/index.js +2 -1
  186. package/dist/components/ScrollArea/ScrollArea.js +1 -0
  187. package/dist/components/ScrollArea/index.js +1 -0
  188. package/dist/components/Segmented/Segmented.js +6 -4
  189. package/dist/components/Segmented/SegmentedCore.js +23 -18
  190. package/dist/components/Segmented/index.js +1 -0
  191. package/dist/components/Select/Option.js +1 -0
  192. package/dist/components/Select/OptionGroup.js +12 -0
  193. package/dist/components/Select/Select.js +20 -9
  194. package/dist/components/Select/SelectCore.js +74 -13
  195. package/dist/components/Select/SelectFloating.js +248 -0
  196. package/dist/components/Select/index.js +6 -4
  197. package/dist/components/Select/select-options.js +57 -0
  198. package/dist/components/Sidebar/Sidebar.js +10 -9
  199. package/dist/components/Sidebar/index.js +1 -0
  200. package/dist/components/Slider/Slider.js +17 -8
  201. package/dist/components/Slider/SliderCore.js +76 -12
  202. package/dist/components/Slider/index.js +1 -0
  203. package/dist/components/Spinner/Spinner.js +1 -0
  204. package/dist/components/Spinner/index.js +1 -0
  205. package/dist/components/StepTimeline/StepTimeline.js +1 -0
  206. package/dist/components/StepTimeline/index.js +1 -0
  207. package/dist/components/Stepper/Step.js +1 -0
  208. package/dist/components/Stepper/Stepper.js +1 -0
  209. package/dist/components/Stepper/StepperContext.js +1 -0
  210. package/dist/components/Stepper/index.js +1 -0
  211. package/dist/components/StreamingText/StreamingText.js +1 -0
  212. package/dist/components/StreamingText/index.js +1 -0
  213. package/dist/components/SwipeAction/SwipeAction.js +1 -0
  214. package/dist/components/SwipeAction/index.js +1 -0
  215. package/dist/components/Switch/Switch.js +7 -5
  216. package/dist/components/Switch/SwitchCore.js +4 -2
  217. package/dist/components/Switch/index.js +1 -0
  218. package/dist/components/Table/Table.js +1 -0
  219. package/dist/components/Table/TableBody.js +1 -0
  220. package/dist/components/Table/TableCell.js +1 -0
  221. package/dist/components/Table/TableHead.js +1 -0
  222. package/dist/components/Table/TableRow.js +1 -0
  223. package/dist/components/Table/index.js +1 -0
  224. package/dist/components/Tabs/Tab.js +8 -4
  225. package/dist/components/Tabs/TabList.js +39 -7
  226. package/dist/components/Tabs/TabPanel.js +5 -3
  227. package/dist/components/Tabs/Tabs.js +12 -6
  228. package/dist/components/Tabs/TabsContext.js +1 -0
  229. package/dist/components/Tabs/index.js +1 -0
  230. package/dist/components/Tag/Tag.js +1 -0
  231. package/dist/components/Tag/index.js +1 -0
  232. package/dist/components/TagGroup/TagGroup.js +20 -7
  233. package/dist/components/TagGroup/TagGroupItem.js +18 -11
  234. package/dist/components/TagGroup/index.js +1 -0
  235. package/dist/components/TagInput/TagInput.js +11 -8
  236. package/dist/components/TagInput/TagInputCore.js +95 -57
  237. package/dist/components/TagInput/index.js +1 -0
  238. package/dist/components/Textarea/Textarea.js +7 -5
  239. package/dist/components/Textarea/TextareaCore.js +4 -2
  240. package/dist/components/Textarea/index.js +1 -0
  241. package/dist/components/ThinkingIndicator/ThinkingIndicator.js +1 -0
  242. package/dist/components/ThinkingIndicator/index.js +1 -0
  243. package/dist/components/TimePicker/TimePicker.js +7 -5
  244. package/dist/components/TimePicker/TimePickerCore.js +4 -2
  245. package/dist/components/TimePicker/index.js +1 -0
  246. package/dist/components/Timeline/Timeline.js +1 -0
  247. package/dist/components/Timeline/index.js +1 -0
  248. package/dist/components/Toast/Toast.js +38 -31
  249. package/dist/components/Toast/ToastContainer.js +68 -47
  250. package/dist/components/Toast/ToastContext.js +24 -4
  251. package/dist/components/Toast/index.js +1 -0
  252. package/dist/components/Toast/toast2.js +64 -28
  253. package/dist/components/Toast/useToast.js +10 -7
  254. package/dist/components/Toggle/Toggle.js +20 -0
  255. package/dist/components/Toggle/ToggleCore.js +31 -0
  256. package/dist/components/Toggle/index.js +4 -0
  257. package/dist/components/TokenCounter/TokenCounter.js +1 -0
  258. package/dist/components/TokenCounter/index.js +1 -0
  259. package/dist/components/ToolCallCard/ToolCallCard.js +1 -0
  260. package/dist/components/ToolCallCard/index.js +1 -0
  261. package/dist/components/Toolbar/Toolbar.js +34 -32
  262. package/dist/components/Toolbar/ToolbarButton.js +1 -0
  263. package/dist/components/Toolbar/ToolbarContext.js +1 -0
  264. package/dist/components/Toolbar/ToolbarSeparator.js +1 -0
  265. package/dist/components/Toolbar/ToolbarToggle.js +31 -0
  266. package/dist/components/Toolbar/index.js +3 -1
  267. package/dist/components/Tooltip/Tooltip.js +2 -1
  268. package/dist/components/Tooltip/index.js +1 -0
  269. package/dist/components/Tour/Tour.js +58 -53
  270. package/dist/components/Tour/index.js +1 -0
  271. package/dist/components/Transfer/Transfer.js +1 -0
  272. package/dist/components/Transfer/TransferCore.js +1 -0
  273. package/dist/components/Transfer/index.js +1 -0
  274. package/dist/components/Tree/Tree.js +200 -77
  275. package/dist/components/Tree/TreeItem.js +18 -15
  276. package/dist/components/Tree/index.js +1 -0
  277. package/dist/components/Tree/utils.js +27 -10
  278. package/dist/components/Upload/Upload.js +22 -8
  279. package/dist/components/Upload/UploadCore.js +225 -37
  280. package/dist/components/Upload/UploadList.js +172 -0
  281. package/dist/components/Upload/index.js +1 -0
  282. package/dist/components/Upload/xhr-upload.js +22 -0
  283. package/dist/components/VirtualList/VirtualList.js +85 -56
  284. package/dist/components/VirtualList/index.js +1 -0
  285. package/dist/components/Watermark/Watermark.js +55 -0
  286. package/dist/components/Watermark/index.js +3 -0
  287. package/dist/css/accordion.css +1 -1
  288. package/dist/css/alert.css +1 -1
  289. package/dist/css/anchor.css +2 -0
  290. package/dist/css/app-shell.css +2 -0
  291. package/dist/css/approval-card.css +1 -1
  292. package/dist/css/async-section.css +1 -1
  293. package/dist/css/back-to-top.css +1 -1
  294. package/dist/css/badge.css +1 -1
  295. package/dist/css/bottom-sheet.css +1 -1
  296. package/dist/css/breadcrumb.css +1 -1
  297. package/dist/css/button.css +1 -1
  298. package/dist/css/calendar.css +1 -1
  299. package/dist/css/carousel.css +1 -1
  300. package/dist/css/cascader.css +1 -1
  301. package/dist/css/chart.css +2 -0
  302. package/dist/css/chat-container.css +1 -1
  303. package/dist/css/chat-input.css +1 -1
  304. package/dist/css/chat-message.css +1 -1
  305. package/dist/css/checkbox.css +1 -1
  306. package/dist/css/chip.css +1 -1
  307. package/dist/css/color-picker.css +1 -1
  308. package/dist/css/combobox.css +3 -2
  309. package/dist/css/command.css +2 -1
  310. package/dist/css/context-menu.css +2 -2
  311. package/dist/css/conversation-list.css +1 -1
  312. package/dist/css/data-table.css +2 -1
  313. package/dist/css/date-range-picker.css +1 -1
  314. package/dist/css/datepicker.css +2 -2
  315. package/dist/css/dialog.css +1 -1
  316. package/dist/css/disclosure.css +1 -1
  317. package/dist/css/dropdown-menu.css +5 -2
  318. package/dist/css/file-input.css +1 -1
  319. package/dist/css/image.css +2 -1
  320. package/dist/css/inline-edit.css +1 -1
  321. package/dist/css/input.css +1 -1
  322. package/dist/css/log-viewer.css +1 -1
  323. package/dist/css/mentions.css +2 -0
  324. package/dist/css/menu.css +5 -2
  325. package/dist/css/model-picker.css +1 -1
  326. package/dist/css/navigation-bar.css +1 -1
  327. package/dist/css/number-input.css +1 -1
  328. package/dist/css/otp-input.css +1 -1
  329. package/dist/css/pagination.css +1 -1
  330. package/dist/css/password-input.css +1 -1
  331. package/dist/css/popover.css +1 -1
  332. package/dist/css/progress.css +1 -1
  333. package/dist/css/prompt-input.css +2 -0
  334. package/dist/css/radio.css +1 -1
  335. package/dist/css/rating.css +1 -1
  336. package/dist/css/resizable.css +1 -1
  337. package/dist/css/segmented.css +1 -1
  338. package/dist/css/select.css +3 -1
  339. package/dist/css/slider.css +1 -1
  340. package/dist/css/stepper.css +1 -1
  341. package/dist/css/swipe-action.css +1 -1
  342. package/dist/css/switch.css +1 -1
  343. package/dist/css/tabs.css +1 -1
  344. package/dist/css/tag-group.css +2 -0
  345. package/dist/css/tag-input.css +3 -1
  346. package/dist/css/tag.css +1 -1
  347. package/dist/css/textarea.css +1 -1
  348. package/dist/css/time-picker.css +1 -1
  349. package/dist/css/toggle.css +2 -0
  350. package/dist/css/token-counter.css +1 -1
  351. package/dist/css/tokens.css +1 -1
  352. package/dist/css/toolbar.css +1 -0
  353. package/dist/css/tooltip.css +1 -1
  354. package/dist/css/tree.css +2 -2
  355. package/dist/css/upload.css +2 -1
  356. package/dist/css/watermark.css +2 -0
  357. package/dist/css-manifest.json +70 -2
  358. package/dist/form/FormItem.js +56 -50
  359. package/dist/form/FormList.js +79 -0
  360. package/dist/form/index.js +6 -1
  361. package/dist/form/standard-schema.js +16 -0
  362. package/dist/haze-ui.css +92 -67
  363. package/dist/headless/index.js +7 -0
  364. package/dist/hooks/useClickOutside.js +24 -0
  365. package/dist/hooks/useClipboard.js +30 -0
  366. package/dist/hooks/useDebouncedCallback.js +17 -0
  367. package/dist/hooks/useDebouncedValue.js +12 -0
  368. package/dist/hooks/useFullscreen.js +42 -0
  369. package/dist/hooks/useHotkeys.js +77 -0
  370. package/dist/hooks/useInView.js +27 -0
  371. package/dist/hooks/useLocalStorage.js +8 -0
  372. package/dist/hooks/useMediaQuery.js +14 -0
  373. package/dist/hooks/usePrefersReducedMotion.js +9 -0
  374. package/dist/hooks/usePrevious.js +11 -0
  375. package/dist/hooks/useSessionStorage.js +8 -0
  376. package/dist/hooks/useStorageState.js +80 -0
  377. package/dist/hooks/useTitle.js +1 -0
  378. package/dist/index.js +206 -163
  379. package/dist/registry.json +2259 -91
  380. package/dist/tokens/registry.js +17 -27
  381. package/dist/types/components/Anchor/Anchor.d.ts +25 -0
  382. package/dist/types/components/Anchor/index.d.ts +2 -0
  383. package/dist/types/components/AppShell/AppShell.d.ts +17 -0
  384. package/dist/types/components/AppShell/index.d.ts +2 -0
  385. package/dist/types/components/Badge/badge-styles.d.ts +21 -0
  386. package/dist/types/components/Badge/index.d.ts +1 -0
  387. package/dist/types/components/BottomSheet/BottomSheet.d.ts +52 -3
  388. package/dist/types/components/BottomSheet/index.d.ts +1 -1
  389. package/dist/types/components/Button/Button.d.ts +7 -0
  390. package/dist/types/components/Button/ButtonLink.d.ts +3 -0
  391. package/dist/types/components/Button/index.d.ts +1 -0
  392. package/dist/types/components/Button/styles.d.ts +17 -0
  393. package/dist/types/components/Calendar/Calendar.d.ts +71 -7
  394. package/dist/types/components/Calendar/date.d.ts +131 -0
  395. package/dist/types/components/Calendar/index.d.ts +1 -1
  396. package/dist/types/components/Cascader/Cascader.d.ts +29 -3
  397. package/dist/types/components/Chart/Chart.d.ts +29 -0
  398. package/dist/types/components/Chart/chart-elements.d.ts +52 -0
  399. package/dist/types/components/Chart/index.d.ts +2 -0
  400. package/dist/types/components/ChatContainer/ChatContainer.d.ts +18 -3
  401. package/dist/types/components/ChatInput/ChatInput.d.ts +11 -1
  402. package/dist/types/components/ChatMessage/ChatMessage.d.ts +13 -1
  403. package/dist/types/components/Checkbox/Checkbox.d.ts +6 -2
  404. package/dist/types/components/Checkbox/CheckboxCore.d.ts +4 -2
  405. package/dist/types/components/Collapsible/Collapsible.d.ts +24 -2
  406. package/dist/types/components/Collapsible/index.d.ts +1 -1
  407. package/dist/types/components/ColorPicker/ColorPicker.d.ts +7 -1
  408. package/dist/types/components/ColorPicker/ColorPickerCore.d.ts +7 -1
  409. package/dist/types/components/Combobox/Combobox.d.ts +101 -7
  410. package/dist/types/components/Combobox/ComboboxGroup.d.ts +22 -0
  411. package/dist/types/components/Combobox/ComboboxOption.d.ts +19 -2
  412. package/dist/types/components/Combobox/index.d.ts +3 -1
  413. package/dist/types/components/Command/Command.d.ts +70 -6
  414. package/dist/types/components/Command/CommandDialog.d.ts +36 -0
  415. package/dist/types/components/Command/command-filter.d.ts +34 -0
  416. package/dist/types/components/Command/index.d.ts +4 -2
  417. package/dist/types/components/DataTable/CellEditor.d.ts +24 -0
  418. package/dist/types/components/DataTable/DataTable.d.ts +184 -26
  419. package/dist/types/components/DataTable/features.d.ts +118 -0
  420. package/dist/types/components/DataTable/index.d.ts +2 -1
  421. package/dist/types/components/DataTable/summary.d.ts +19 -0
  422. package/dist/types/components/DateRangePicker/DateRangePicker.d.ts +15 -1
  423. package/dist/types/components/DateRangePicker/DateRangePickerCore.d.ts +26 -2
  424. package/dist/types/components/DateRangePicker/index.d.ts +1 -1
  425. package/dist/types/components/Datepicker/Datepicker.d.ts +17 -1
  426. package/dist/types/components/Datepicker/DatepickerCore.d.ts +24 -2
  427. package/dist/types/components/Datepicker/index.d.ts +1 -1
  428. package/dist/types/components/Dialog/Dialog.d.ts +68 -3
  429. package/dist/types/components/Dialog/index.d.ts +1 -1
  430. package/dist/types/components/Drawer/Drawer.d.ts +33 -3
  431. package/dist/types/components/Drawer/index.d.ts +1 -1
  432. package/dist/types/components/DropdownMenu/DropdownMenu.d.ts +23 -3
  433. package/dist/types/components/DropdownMenu/DropdownMenuSub.d.ts +18 -0
  434. package/dist/types/components/DropdownMenu/DropdownMenuSubContent.d.ts +13 -0
  435. package/dist/types/components/DropdownMenu/DropdownMenuSubTrigger.d.ts +14 -0
  436. package/dist/types/components/DropdownMenu/index.d.ts +7 -1
  437. package/dist/types/components/Fullscreen/Fullscreen.d.ts +34 -0
  438. package/dist/types/components/Fullscreen/index.d.ts +3 -0
  439. package/dist/types/components/Image/Image.d.ts +20 -5
  440. package/dist/types/components/Image/ImagePreview.d.ts +13 -0
  441. package/dist/types/components/Image/index.d.ts +1 -1
  442. package/dist/types/components/Input/Input.d.ts +5 -2
  443. package/dist/types/components/Input/InputCore.d.ts +4 -2
  444. package/dist/types/components/LocaleProvider/LocaleContext.d.ts +10 -1
  445. package/dist/types/components/LocaleProvider/LocaleProvider.d.ts +17 -3
  446. package/dist/types/components/LocaleProvider/index.d.ts +4 -1
  447. package/dist/types/components/LocaleProvider/locale.d.ts +63 -1
  448. package/dist/types/components/LocaleProvider/strings.d.ts +28 -0
  449. package/dist/types/components/LocaleProvider/useStrings.d.ts +5 -4
  450. package/dist/types/components/LocaleProvider/zh-cn.d.ts +13 -0
  451. package/dist/types/components/Mentions/Mentions.d.ts +20 -0
  452. package/dist/types/components/Mentions/MentionsCore.d.ts +23 -0
  453. package/dist/types/components/Mentions/index.d.ts +4 -0
  454. package/dist/types/components/Menu/MenuSub.d.ts +18 -0
  455. package/dist/types/components/Menu/MenuSubContent.d.ts +12 -0
  456. package/dist/types/components/Menu/MenuSubTrigger.d.ts +14 -0
  457. package/dist/types/components/Menu/index.d.ts +6 -0
  458. package/dist/types/components/NumberInput/NumberInput.d.ts +5 -2
  459. package/dist/types/components/NumberInput/NumberInputCore.d.ts +4 -2
  460. package/dist/types/components/OTPInput/OTPInput.d.ts +5 -1
  461. package/dist/types/components/OTPInput/OTPInputCore.d.ts +4 -1
  462. package/dist/types/components/PasswordInput/PasswordInput.d.ts +5 -1
  463. package/dist/types/components/PasswordInput/PasswordInputCore.d.ts +4 -1
  464. package/dist/types/components/Popover/Popover.d.ts +41 -3
  465. package/dist/types/components/Popover/index.d.ts +1 -1
  466. package/dist/types/components/PromptInput/PromptInput.d.ts +46 -0
  467. package/dist/types/components/PromptInput/index.d.ts +2 -0
  468. package/dist/types/components/Radio/Radio.d.ts +5 -2
  469. package/dist/types/components/Radio/RadioGroup.d.ts +8 -2
  470. package/dist/types/components/Radio/RadioGroupCore.d.ts +7 -2
  471. package/dist/types/components/Rating/Rating.d.ts +8 -1
  472. package/dist/types/components/Rating/RatingCore.d.ts +7 -1
  473. package/dist/types/components/Resizable/index.d.ts +2 -0
  474. package/dist/types/components/Segmented/Segmented.d.ts +8 -1
  475. package/dist/types/components/Segmented/SegmentedCore.d.ts +7 -2
  476. package/dist/types/components/Select/OptionGroup.d.ts +16 -0
  477. package/dist/types/components/Select/Select.d.ts +66 -4
  478. package/dist/types/components/Select/SelectCore.d.ts +70 -6
  479. package/dist/types/components/Select/SelectFloating.d.ts +83 -0
  480. package/dist/types/components/Select/index.d.ts +2 -0
  481. package/dist/types/components/Select/select-options.d.ts +53 -0
  482. package/dist/types/components/Slider/Slider.d.ts +29 -4
  483. package/dist/types/components/Slider/SliderCore.d.ts +35 -6
  484. package/dist/types/components/Switch/Switch.d.ts +5 -2
  485. package/dist/types/components/Switch/SwitchCore.d.ts +4 -2
  486. package/dist/types/components/Tabs/TabList.d.ts +7 -0
  487. package/dist/types/components/Tabs/Tabs.d.ts +8 -1
  488. package/dist/types/components/Tabs/TabsContext.d.ts +20 -0
  489. package/dist/types/components/Tabs/index.d.ts +1 -0
  490. package/dist/types/components/TagGroup/TagGroup.d.ts +13 -1
  491. package/dist/types/components/TagInput/TagInput.d.ts +12 -1
  492. package/dist/types/components/TagInput/TagInputCore.d.ts +11 -1
  493. package/dist/types/components/Textarea/Textarea.d.ts +5 -2
  494. package/dist/types/components/Textarea/TextareaCore.d.ts +4 -2
  495. package/dist/types/components/TimePicker/TimePicker.d.ts +5 -2
  496. package/dist/types/components/TimePicker/TimePickerCore.d.ts +4 -2
  497. package/dist/types/components/Toast/Toast.d.ts +31 -2
  498. package/dist/types/components/Toast/ToastContainer.d.ts +11 -1
  499. package/dist/types/components/Toast/ToastContext.d.ts +44 -3
  500. package/dist/types/components/Toast/index.d.ts +1 -1
  501. package/dist/types/components/Toast/toast.d.ts +35 -4
  502. package/dist/types/components/Toast/useToast.d.ts +16 -4
  503. package/dist/types/components/Toggle/Toggle.d.ts +19 -0
  504. package/dist/types/components/Toggle/ToggleCore.d.ts +23 -0
  505. package/dist/types/components/Toggle/index.d.ts +4 -0
  506. package/dist/types/components/Toolbar/ToolbarToggle.d.ts +19 -0
  507. package/dist/types/components/Toolbar/index.d.ts +2 -0
  508. package/dist/types/components/Tour/Tour.d.ts +3 -3
  509. package/dist/types/components/Tree/Tree.d.ts +3 -3
  510. package/dist/types/components/Tree/TreeItem.d.ts +6 -1
  511. package/dist/types/components/Tree/types.d.ts +26 -0
  512. package/dist/types/components/Tree/utils.d.ts +32 -0
  513. package/dist/types/components/Upload/Upload.d.ts +38 -3
  514. package/dist/types/components/Upload/UploadCore.d.ts +75 -4
  515. package/dist/types/components/Upload/UploadList.d.ts +12 -0
  516. package/dist/types/components/Upload/index.d.ts +1 -0
  517. package/dist/types/components/Upload/types.d.ts +60 -0
  518. package/dist/types/components/Upload/xhr-upload.d.ts +20 -0
  519. package/dist/types/components/VirtualList/VirtualList.d.ts +16 -1
  520. package/dist/types/components/Watermark/Watermark.d.ts +32 -0
  521. package/dist/types/components/Watermark/index.d.ts +2 -0
  522. package/dist/types/form/FormItem.d.ts +33 -8
  523. package/dist/types/form/FormList.d.ts +113 -0
  524. package/dist/types/form/index.d.ts +26 -0
  525. package/dist/types/form/standard-schema.d.ts +30 -0
  526. package/dist/types/headless/index.d.ts +182 -0
  527. package/dist/types/hooks/index.d.ts +17 -0
  528. package/dist/types/hooks/useClickOutside.d.ts +46 -0
  529. package/dist/types/hooks/useClipboard.d.ts +31 -0
  530. package/dist/types/hooks/useDebouncedCallback.d.ts +21 -0
  531. package/dist/types/hooks/useDebouncedValue.d.ts +20 -0
  532. package/dist/types/hooks/useFullscreen.d.ts +33 -0
  533. package/dist/types/hooks/useHotkeys.d.ts +53 -0
  534. package/dist/types/hooks/useInView.d.ts +32 -0
  535. package/dist/types/hooks/useLocalStorage.d.ts +33 -0
  536. package/dist/types/hooks/useMediaQuery.d.ts +20 -0
  537. package/dist/types/hooks/usePrefersReducedMotion.d.ts +14 -0
  538. package/dist/types/hooks/usePrevious.d.ts +18 -0
  539. package/dist/types/hooks/useSessionStorage.d.ts +26 -0
  540. package/dist/types/hooks/useStorageState.d.ts +12 -0
  541. package/dist/types/index.d.ts +60 -32
  542. package/dist/types/utils/collision.d.ts +39 -1
  543. package/dist/types/utils/direction.d.ts +22 -0
  544. package/dist/types/utils/floating.d.ts +32 -4
  545. package/dist/types/utils/focus-scope.d.ts +2 -1
  546. package/dist/types/utils/focus.d.ts +2 -1
  547. package/dist/types/utils/menuKeyboard.d.ts +19 -4
  548. package/dist/types/utils/refs.d.ts +16 -0
  549. package/dist/types/utils/sortable-shared.d.ts +42 -0
  550. package/dist/types/utils/sortable.d.ts +36 -0
  551. package/dist/types/utils/submenu.d.ts +63 -0
  552. package/dist/types/utils/view-transition.d.ts +28 -0
  553. package/dist/utils/collision.js +38 -26
  554. package/dist/utils/direction.js +34 -0
  555. package/dist/utils/floating.js +164 -143
  556. package/dist/utils/focus-scope.js +1 -0
  557. package/dist/utils/focus.js +1 -0
  558. package/dist/utils/menuKeyboard.js +60 -46
  559. package/dist/utils/presence.js +1 -0
  560. package/dist/utils/refs.js +9 -0
  561. package/dist/utils/sortable-shared.js +24 -0
  562. package/dist/utils/sortable.js +46 -0
  563. package/dist/utils/submenu.js +104 -0
  564. package/dist/utils/view-transition.js +26 -0
  565. package/package.json +119 -24
package/README.md CHANGED
@@ -5,14 +5,25 @@
5
5
  English | [简体中文](./README-zh_CN.md)
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/haze-ui)](https://www.npmjs.com/package/haze-ui)
8
+ [![downloads](https://img.shields.io/npm/dm/haze-ui.svg)](https://www.npmjs.com/package/haze-ui)
8
9
  [![CI](https://github.com/wmzy/haze-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/wmzy/haze-ui/actions/workflows/ci.yml)
9
10
 
10
11
  ## Features
11
12
 
12
13
  - Integrated [react use control](https://github.com/wmzy/react-use-control) provides component internal states
14
+ - Built for React 19+ (`ref` as a prop, `ControlOrValue<T>` state protocol) — no React 18 compatibility layer
13
15
  - Keep strict, provide lightweight, composable, and easily extendable components
14
16
  - Support themes customization
15
17
  - Support Tree-shaking
18
+ - RTL by construction: CSS logical properties, mirrored horizontal-key
19
+ semantics (Tabs, Rating, Slider, Carousel, Calendar, menus, …) and
20
+ mirrored floating placements under `dir="rtl"`
21
+ - RSC-aware dist: interactive modules carry `'use client'`; 36 static,
22
+ hook-free modules (tokens, Badge, Card, Typography, …) ship without it
23
+ so they render as React Server Components
24
+ - Tested like a product: 120+ unit test files, axe accessibility cases in
25
+ every component test suite, ~50 Playwright e2e scenarios across
26
+ Chromium/Firefox/WebKit, and pixel-locked visual baselines
16
27
 
17
28
  ## Why npm-distributed (not copy-paste)
18
29
 
@@ -32,6 +43,117 @@ npm i haze-ui
32
43
  pnpm add haze-ui
33
44
  ```
34
45
 
46
+ ### Install via shadcn CLI (GitHub registry)
47
+
48
+ The repository is also a [shadcn registry](https://ui.shadcn.com/docs/registry/github),
49
+ so the shadcn CLI installs any component directly from GitHub — no manual
50
+ npm setup:
51
+
52
+ ```sh
53
+ pnpm dlx shadcn@latest add wmzy/haze-ui/button
54
+ pnpm dlx shadcn@latest add wmzy/haze-ui/dialog wmzy/haze-ui/tabs
55
+ pnpm dlx shadcn@latest add wmzy/haze-ui/base # everything at once
56
+ pnpm dlx shadcn@latest list wmzy/haze-ui # browse all items
57
+ ```
58
+
59
+ The `base` item (type `registry:base`) is the one-command path: it
60
+ installs the theme-token activation plus a wrapper for every component in
61
+ a single `shadcn add` — the 107 component items are pulled in through
62
+ `registryDependencies` (full `wmzy/haze-ui/<item>` addresses, since plain
63
+ names would resolve against the official shadcn registry).
64
+
65
+ Every **styled** export is covered (107 component items — one per CSS
66
+ family, so compound components like `tabs` arrive as `Tabs`/`TabList`/
67
+ `Tab`/`TabPanel` together). What lands in your project is a thin
68
+ **wrapper** file under `components/ui/haze/` that re-exports the
69
+ component from `haze-ui` and imports its stylesheet — not vendored
70
+ source. The wrapper is your customization layer (fork it, wrap it,
71
+ restyle it), while `haze-ui` itself is installed as a normal npm
72
+ dependency and keeps updating through your package manager. Common items:
73
+ `button`, `input`, `select`, `dialog`, `tabs`, `toast`, `sidebar`,
74
+ `form`, `data-table`, `chart`, `chat-message`, plus `tokens` (the theme
75
+ classes) and `haze-tokens` (a token onboarding guide doc). Each item also
76
+ carries `docs` (markdown usage — description, install command, theme
77
+ activation — printed by `shadcn view`) and `categories` (kebab-case tags
78
+ — `form`, `overlay`, `data-display`, `agent`, … — used by registry
79
+ search/filter tooling). See [registry/README.md](./registry/README.md)
80
+ for the full picture.
81
+
82
+ ### React 19+ by design
83
+
84
+ The peer range is `react: ^19.0.0` on purpose — haze-ui is built on
85
+ modern React rather than carrying a compatibility layer for 18:
86
+
87
+ - **`ref` as a prop.** React 19 passes `ref` to function components
88
+ directly, so components that expose refs accept one prop instead of a
89
+ `forwardRef` wrapper layer.
90
+ - **A modern-platform baseline.** Floating panels (Popover, DropdownMenu,
91
+ Tooltip, ContextMenu, Combobox, Datepicker) choose between three tiers
92
+ by feature detection — native `popover` + CSS anchor positioning,
93
+ `popover` alone, or a JS fallback — with the newest platform features
94
+ as the primary path, not an enhancement layered on top.
95
+ - **`ControlOrValue<T>`** — the `Control<T> | T` state protocol — is
96
+ designed for modern React semantics throughout.
97
+
98
+ On React 18? Upgrade first. haze-ui ships no React 18 compatibility
99
+ layer, and none is planned.
100
+
101
+ #### Migrating from React 18
102
+
103
+ Once the app itself is on React 19, run through the haze-ui-relevant
104
+ checklist:
105
+
106
+ - **`ref` is a prop.** React 19 passes `ref` to function components
107
+ directly — drop any `forwardRef` wrapper you had around haze components
108
+ and pass `ref` like any other prop.
109
+ - **No `defaultValue` dual track.** Stateful components speak
110
+ `ControlOrValue<T>` (`checked?: Control<T> | boolean`): one prop covers
111
+ controlled *and* uncontrolled usage, so there is no
112
+ `defaultChecked`/`defaultValue` pair to migrate. Where you used to pass
113
+ `defaultValue`, pass the plain value (uncontrolled) or switch to
114
+ controlled with `onChange`.
115
+ - **Floating panels assume the modern-platform baseline.** Popover,
116
+ DropdownMenu, Tooltip, ContextMenu, Combobox and Datepicker
117
+ feature-detect between native `popover` + CSS anchor positioning,
118
+ `popover` alone, or a JS fallback — no polyfills to carry over from
119
+ your React 18 setup, but the floor from [Browser support](#browser-support)
120
+ applies.
121
+ - **Colors are OKLCH with runtime-derived interaction states.** Requires
122
+ Chrome/Edge 119+, Safari 16.4+ or Firefox 128+; no HSL/hex fallbacks
123
+ are shipped.
124
+ - **`'use client'` is pre-injected on interactive modules.** Every
125
+ stateful module in `dist/` starts with the directive; the static,
126
+ hook-free set (tokens and presentational components) ships without it
127
+ so those render as React Server Components (see
128
+ [Server Components](#server-components-nextjs-app-router)).
129
+
130
+ ### Dependencies
131
+
132
+ haze-ui ships two runtime dependencies — `react-use-control`, the engine
133
+ behind `ControlOrValue<T>`, and `react-f0rm` (^1.3), the form engine
134
+ behind `FormItem`/`FormList` (the same author's headless form store).
135
+ Five integrations remain optional peers, installed only when you use the
136
+ components that need them:
137
+
138
+ ```sh
139
+ npm i @tanstack/react-table # DataTable (peer range ^9.2.4)
140
+ npm i recharts # Chart (peer range ^3.10.1)
141
+ npm i @dnd-kit/core @dnd-kit/sortable \
142
+ @dnd-kit/utilities # TagInput/TagGroup sortable
143
+ # (^6.3.1 / ^10.0.0 / ^3.2.2)
144
+ ```
145
+
146
+ Everything else — `Button`, `Input`, `Dialog`, `Select`, … — runs with
147
+ nothing beyond `react` and the two runtime dependencies. The dist is ESM
148
+ with `preserveModules` and side-effect-free JS, so bundlers (Next.js,
149
+ Vite, webpack, Turbopack, Rollup) tree-shake the unused re-export chains
150
+ and never resolve peers you haven't installed: `import { Button } from
151
+ 'haze-ui'` works without `@tanstack/react-table`. Only bundler-less
152
+ consumers (bare Node ESM importing the barrel, which links the module
153
+ graph eagerly) must install the optional peers; the
154
+ `haze-ui/components/DataTable` and `haze-ui/components/Chart` subpaths
155
+ bypass the barrel entirely.
156
+
35
157
  ### Browser support
36
158
 
37
159
  Since v1.13, haze-ui colors are generated in **OKLCH**, with interaction
@@ -83,6 +205,47 @@ included); `noCss` lists pure-logic exports with no css of their own.
83
205
  Bundler plugins and codemods should read this manifest instead of
84
206
  re-deriving file names — the mapping changes in lockstep with the build.
85
207
 
208
+ ### Server Components (Next.js App Router)
209
+
210
+ Interactive modules in `dist/` carry the `'use client'` directive,
211
+ injected at build time — the same convention Radix, Base UI and React
212
+ Aria ship. In an App Router project you import haze-ui straight from
213
+ your client components; there is no need for a wrapper module that
214
+ re-exports the library under its own `'use client'` banner:
215
+
216
+ ```jsx
217
+ // any client component — import straight from the package
218
+ import { Button } from 'haze-ui';
219
+
220
+ export function Actions() {
221
+ return <Button>Start</Button>;
222
+ }
223
+ ```
224
+
225
+ **A static subset renders as React Server Components.** Modules with no
226
+ hooks and no DOM access ship *without* the directive, so they can be
227
+ imported directly into server components and cost zero client JS:
228
+
229
+ - tokens: everything on the `haze-ui/tokens` subpath (`lightTheme`,
230
+ `darkTheme`, `spacing`, `typography`, `TOKEN_REGISTRY`, OKLCH utils)
231
+ - components: `AspectRatio`, `Badge`, `Card`, `CodeBlock`, `Container`,
232
+ `Divider`, `Flex`, `Grid`/`GridItem`, `Icon`, `Kbd`, `Skeleton`,
233
+ `Stat`/`StatGroup`, `Typography` (`Title`/`Text`/`Paragraph`)
234
+
235
+ Import them from the subpath (`import { Badge } from
236
+ 'haze-ui/components/Badge'`) or the barrel — in an RSC module the
237
+ bundler resolves the module itself, not the client-marked barrel shell.
238
+ The emitted markup carries the usual Linaria class names, so CSS loading
239
+ is unchanged (`haze-ui/styles.css` or the `css/*` subpaths). The safe
240
+ list lives in `scripts/rsc-safe.mjs` and is enforced by
241
+ `src/lib/dist-esm-contract.test.ts` (including a transitive-closure
242
+ check: every static import inside a safe module must itself be safe) —
243
+ new components only join the list when they stay hook-free.
244
+
245
+ CSS loading is unchanged from the two modes above — `haze-ui/styles.css`
246
+ in the root layout, or the `haze-ui/css/*` subpaths. A runnable Next.js
247
+ 15 project lives in [`examples/nextjs`](./examples/nextjs).
248
+
86
249
  ## ButtonLink: a real anchor with the Button skin
87
250
 
88
251
  Navigation that must look like a button should still *be* a link —
@@ -160,6 +323,116 @@ function SettingsView() {
160
323
  }
161
324
  ```
162
325
 
326
+ ## Anchor: scroll-spy navigation
327
+
328
+ Sticky anchor navigation with an IntersectionObserver scroll-spy (a
329
+ scroll-listener fallback covers engines without IO). Pass `items`, and
330
+ the highlighted section is a controllable state like everything else —
331
+ `activeId?: ControlOrValue<string>`. Clicks scroll the container
332
+ (`getContainer` defaults to the window) with an `offsetTop` adjustment,
333
+ and the active link carries `aria-current="true"`.
334
+
335
+ ```jsx
336
+ import 'haze-ui/css/tokens.css';
337
+ import 'haze-ui/css/anchor.css';
338
+ import { Anchor } from 'haze-ui';
339
+
340
+ <Anchor items={[{ id: 'intro', label: 'Intro' }, { id: 'api', label: 'API' }]} />;
341
+ ```
342
+
343
+ ## Watermark: tiled canvas watermark
344
+
345
+ A canvas-tiled watermark layer: text rows (`content: string | string[]`)
346
+ rendered onto an off-screen tile (rotated, `gap`-spaced,
347
+ device-pixel-ratio aware) and repeated as a background over the
348
+ container — or the whole viewport with `fullscreen`. Default color
349
+ follows the theme's `--haze-color-text-muted`; the layer is
350
+ `pointer-events: none` and `aria-hidden`, and engines without a canvas
351
+ 2d context degrade to no watermark rather than crashing.
352
+
353
+ ```jsx
354
+ <Watermark content="CONFIDENTIAL" rotate={-22}>
355
+ <Report />
356
+ </Watermark>
357
+ ```
358
+
359
+ ## Fullscreen: wrap-mode fullscreen binding
360
+
361
+ `useFullscreen(target?)` returns `[isFullscreen, toggle, handle]` — the
362
+ Fullscreen API wired to `ControlOrValue` semantics: `Fullscreen`
363
+ wraps a single trigger child (its `onClick` is preserved and composed)
364
+ and exposes `fullscreen?: ControlOrValue<boolean>`, so browser-side
365
+ exits (Esc, OS gestures) write back through the control and fire
366
+ `onChange` exactly once.
367
+
368
+ ```jsx
369
+ const [fs, setFs, fsCtrl] = useControl(undefined, false);
370
+ <Fullscreen fullscreen={fsCtrl} onChange={setFs}>
371
+ <Button>Enter focus mode</Button>
372
+ </Fullscreen>
373
+ ```
374
+
375
+ ## Utility hooks
376
+
377
+ All hooks ship on the main barrel (no separate import path) and follow
378
+ the same conventions as the components: `ControlOrValue` where state is
379
+ user-controllable, SSR/jsdom-safe when the underlying API is missing.
380
+
381
+ | Hook | Returns | Notes |
382
+ | --- | --- | --- |
383
+ | `useClipboard(resetMs?)` | `{ copied, copy }` | `copied` resets after `resetMs` |
384
+ | `useDebouncedCallback(fn, delayMs)` | debounced `fn` | Stable identity across renders |
385
+ | `useDebouncedValue(value, delayMs)` | `T` | Trails the input by `delayMs` |
386
+ | `useFullscreen(target?)` | `[isFullscreen, toggle, handle]` | See section above |
387
+ | `useHotkeys(map, options?)` | — | `'mod+s'`-style specs (`mod` normalizes to ⌘ on macOS, Ctrl elsewhere); skips events from editable targets unless `allowInInput`; `hotkey(...keys)` builds specs type-safely |
388
+ | `useInView(options?)` | `[refCallback, inView]` | IntersectionObserver; `once` freezes after the first hit; `false` forever when the API is missing (SSR) |
389
+ | `useLocalStorage(key, control?, initial?)` | `[value, setValue]` | `ControlOrValue` semantics, cross-tab `storage` sync, corrupt JSON self-heals to `initial` |
390
+ | `useSessionStorage(key, control?, initial?)` | `[value, setValue]` | Same kernel, `sessionStorage` scope |
391
+ | `useMediaQuery(query)` | `boolean` | Reactive `matchMedia`; `false` when missing |
392
+ | `usePrefersReducedMotion()` | `boolean` | Token-aware animation gating |
393
+ | `useTitle(title)` | — | Document title while mounted |
394
+ | `useToast()` | toast API | Requires a `ToastContainer` ancestor |
395
+
396
+ ## Sortable tags and chips (optional dnd-kit peers)
397
+
398
+ `TagInput` and `TagGroup` accept `sortable?: boolean` — opt-in drag
399
+ reordering powered by `@dnd-kit/core` / `@dnd-kit/sortable` /
400
+ `@dnd-kit/utilities` (optional peers, same tree-shaking contract as
401
+ recharts and TanStack Table). `TagInput` writes the new array through
402
+ `onChange`; `TagGroup` reports `onReorder(nextOrder)` (the new
403
+ arrangement of original child indexes) and leaves re-rendering to the
404
+ parent. Sorting is keyboard-complete: focus a tag, `Space` to lift,
405
+ arrows to move, `Space` to drop, `Escape` to cancel.
406
+
407
+ ## Imperative overlay handles
408
+
409
+ `Dialog`, `Drawer`, `BottomSheet`, `Popover` and `DropdownMenu` accept a
410
+ `ref` (React 19 style — no `forwardRef`) exposing
411
+ `{ open(), close(), focusTrigger() }`. The methods drive the same state
412
+ outset as user interaction — `Dialog`'s `close()` goes through the
413
+ native `close` event path so `onClose` and focus restoration fire
414
+ exactly once — and they honor controlled mode, writing through the
415
+ control.
416
+
417
+ ```tsx
418
+ const dialog = useRef<DialogHandle>(null);
419
+ <Dialog ref={dialog} …>…</Dialog>;
420
+ <button onClick={() => dialog.current?.open()}>Show</button>;
421
+ ```
422
+
423
+ ## View Transitions on modals (opt-in)
424
+
425
+ `Dialog`, `Drawer` and `BottomSheet` accept `viewTransition?: boolean`
426
+ (default `false`). When enabled, their open/close state flips are wrapped
427
+ in `document.startViewTransition(() => flushSync(...))` — the synchronous
428
+ DOM-update pattern React requires — so modals animate through the native
429
+ View Transitions API alongside their regular enter/exit animations. The
430
+ transition itself degrades to a plain state flip when the engine lacks
431
+ `startViewTransition` or the user prefers reduced motion; transition
432
+ appearance is yours to style via `::view-transition-*`. Controlled
433
+ consumers' own flips happen outside the component and are intentionally
434
+ not wrapped.
435
+
163
436
  ## Design tokens export (Figma)
164
437
 
165
438
  `toDesignTokens()` converts the token registry into a [W3C Design Tokens](https://tr.designtokens.org/) JSON file — grouped by category (`color` / `font` / `spacing` / `dimension` / `shadow`), each token carrying a W3C `$type` and the source CSS variable in `$extensions['haze-ui.css-var']`, with `$value` being the resolved value of the chosen theme (`light` by default). The Theme Editor ships a one-click entry: the **Export W3C tokens (.json)** button in the toolbar downloads the file for the mode currently being edited, live edits included. The exported file can be imported directly into Figma Tokens / Tokens Studio.
@@ -183,6 +456,168 @@ function SettingsView() {
183
456
  }
184
457
  ```
185
458
 
459
+ ## Component-level tokens
460
+
461
+ Global `--haze-*` tokens theme the whole system; **component-level tokens**
462
+ theme one component family without touching anything else. They are plain
463
+ CSS custom properties consumed through a fallback chain baked into the
464
+ component's own stylesheet:
465
+
466
+ ```css
467
+ /* inside haze-ui/css/button.css */
468
+ height: var(--haze-button-height-md, auto);
469
+ ```
470
+
471
+ The library never defines these variables — nothing to register, no
472
+ runtime. When you set one on `:root` or any ancestor of the component, your
473
+ value wins; when you don't, the built-in fallback applies and the component
474
+ looks exactly as shipped. Scoping is ordinary CSS inheritance: set the
475
+ variable on a wrapper element to retheme only that subtree.
476
+
477
+ `Button`/`ButtonLink` (pilot — they share one skin, so both change
478
+ together; `Toggle` and the Toolbar items wearing the same skin follow
479
+ along):
480
+
481
+ | Token | Fallback (default look) |
482
+ | ---------------------------------- | ----------------------- |
483
+ | `--haze-button-height-sm/md/lg` | `auto` (content-driven) |
484
+ | `--haze-button-font-size-sm/md` | `var(--haze-text-sm)` |
485
+ | `--haze-button-font-size-lg` | `var(--haze-text-base)` |
486
+ | `--haze-button-radius` | `var(--haze-radius-md)` |
487
+
488
+ `Dialog`:
489
+
490
+ | Token | Fallback (default look) |
491
+ | -------------------------------- | ------------------------ |
492
+ | `--haze-dialog-width` | `480px` (on `max-width`) |
493
+ | `--haze-dialog-radius` | `var(--haze-radius-xl)` |
494
+ | `--haze-dialog-padding` | `var(--haze-space-6)` |
495
+ | `--haze-dialog-title-gap` | `var(--haze-space-4)` |
496
+ | `--haze-dialog-title-font-size` | `var(--haze-text-lg)` |
497
+
498
+ ```css
499
+ /* app-wide denser buttons; every other component keeps its sizing */
500
+ :root {
501
+ --haze-button-height-md: 32px;
502
+ }
503
+
504
+ /* only dialogs inside this subtree get wider */
505
+ .wide-dialogs {
506
+ --haze-dialog-width: 720px;
507
+ }
508
+ ```
509
+
510
+ `COMPONENT_TOKENS` (exported from `haze-ui` and `haze-ui/tokens`) lists
511
+ each component's component-level tokens alongside the global tokens it
512
+ consumes.
513
+
514
+ ## AI-friendly distribution
515
+
516
+ **llms.txt** — a markdown overview of the whole library (the `ControlOrValue<T>`
517
+ state protocol, both CSS loading modes, all 107 components grouped with one-line
518
+ purposes, the token system, the floating-overlay tiers, form integration) written
519
+ for AI coding tools and crawlers. It lives at the repo root
520
+ ([llms.txt](./llms.txt)) and, on the docs site, at
521
+ <https://wmzy.github.io/haze-ui/llms.txt> (`build:demo` copies it into `dist/`).
522
+
523
+ **registry.json** — an agent-installable registry shipped as the
524
+ `haze-ui/registry.json` npm artifact (regenerated by
525
+ `scripts/generate-registry.mjs` on every build), also reachable at
526
+ <https://unpkg.com/haze-ui/registry.json>. Point any registry-aware
527
+ tooling at it — the shadcn CLI works:
528
+
529
+ ```sh
530
+ pnpm dlx shadcn@latest add https://unpkg.com/haze-ui/registry.json
531
+ ```
532
+
533
+ Every item is a **wrapper file, not vendored source**: it re-exports the
534
+ component from the published haze-ui npm package and imports its
535
+ stylesheet, so `haze-ui` stays a normal npm dependency that keeps
536
+ updating underneath — the shadcn CLI is only the distribution channel.
537
+ That is the point: AI coding agents (and anyone who wants a fast setup
538
+ while keeping the npm update path) get working imports in one step,
539
+ without the copy-paste expectation of owning pasted source. When you
540
+ want different styles or behavior, fork the generated wrapper file — it
541
+ is your customization layer, not a source drop. Coverage: **every styled
542
+ export** (107 css families / 185 components), generated from the build's
543
+ own css manifest. The same items are also installable straight from this
544
+ GitHub repository — see
545
+ [Install via shadcn CLI (GitHub registry)](#install-via-shadcn-cli-github-registry).
546
+
547
+ ## AI runtime integration (Vercel AI SDK `useChat`)
548
+
549
+ haze-ui ships the agent chat surface as **presentational** components —
550
+ `ChatContainer` (scrolling), `ChatMessage` (bubbles), `StreamingText`
551
+ (typewriter reveal), `ToolCallCard` (tool input/output), `ThinkingIndicator`
552
+ (waiting dots), `ChatInput` (composer) — with no opinion about where
553
+ messages come from. The Vercel AI SDK's `useChat` is the stateful half: it
554
+ owns `messages` (a `UIMessage[]` of typed `parts`), `status`
555
+ (`submitted | streaming | ready | error`) and the `sendMessage`/`stop`
556
+ pair. One small adapter bridges them — pure functions over duck-typed
557
+ shapes, so the `ai` package never enters your dependency tree through
558
+ haze-ui:
559
+
560
+ ```tsx
561
+ import { useChat } from '@ai-sdk/react';
562
+ import { DefaultChatTransport } from 'ai';
563
+ import { Button, ChatContainer, ChatInput } from 'haze-ui';
564
+
565
+ import { useHazeChat } from './ai-chat-adapter'; // the recipe module
566
+
567
+ function SupportChat() {
568
+ const chat = useChat({ transport: new DefaultChatTransport({ api: '/api/chat' }) });
569
+ const { messages, busy, send, stop } = useHazeChat(chat);
570
+
571
+ return (
572
+ <div>
573
+ <ChatContainer>{messages}</ChatContainer>
574
+ <ChatInput disabled={busy} onSend={send} />
575
+ {busy && <Button variant='outline' onClick={stop}>Stop</Button>}
576
+ </div>
577
+ );
578
+ }
579
+ ```
580
+
581
+ The mapping rules: text parts → `ChatMessage` bubbles (`StreamingText`
582
+ typewriter while a part streams), reasoning → `ThinkingIndicator` then a
583
+ collapsible transcript, `tool-*` parts → `ToolCallCard` driven by v5
584
+ `states` (with v4 `tool-call`/`tool-result` pairs folded into one card by
585
+ `toolCallId`), sources → links; `status: submitted` → thinking dots before
586
+ the first token, `error` → a system bubble with the transport error. The
587
+ whole thing is one small, unit-tested module that never throws on odd
588
+ payloads — unknown part types are skipped, so future SDK parts degrade
589
+ instead of crashing.
590
+
591
+ The full recipe — live runnable demo (same adapter over a mock streaming
592
+ source, no network), the complete adapter source, the `useHazeChat` hook,
593
+ per-part mapping table and known limits (attachments, branching, voice out
594
+ of scope; `StreamingText` restart-on-grow caveat for char-by-char
595
+ transports) — lives on the docs site:
596
+ **<https://wmzy.github.io/haze-ui/recipes>**.
597
+
598
+ ## Headless primitives
599
+
600
+ The behavior layer the styled components are built on ships as its own
601
+ subpath: `haze-ui/headless`. Component authors assembling their own panels
602
+ get the same primitives Popover, DropdownMenu and Tooltip use internally —
603
+ with the same version, no re-implementation:
604
+
605
+ - `useFloating` — the three-tier floating engine (native `popover` + CSS
606
+ anchor positioning → `popover` alone → JS fallback), plus
607
+ `placeFloatingPanel`, `useFloatingPosition` and the placement/panel types
608
+ - `Presence` — mount/unmount with exit animations
609
+ - `useFocusScope` / `isTabbable` / `getTabbables` — focus trapping and
610
+ tab-order queries
611
+ - `computeFloatingPosition` — the flip/shift collision math as a pure
612
+ function
613
+
614
+ ```jsx
615
+ import { useFloating, Presence } from 'haze-ui/headless';
616
+ ```
617
+
618
+ Stable public API — same semver commitment as the component library:
619
+ breaking changes land only on a major version.
620
+
186
621
  ## react-f0rm Integration
187
622
 
188
623
  react-f0rm owns form field state, and its headless `useField` hook is
@@ -194,6 +629,25 @@ pair with zero adapters, and `FormItem` wraps the hook's state in label,
194
629
  error and aria wiring. The sugar components (`Input`, `Select`, ...)
195
630
  keep their `ControlOrValue<T>` (`Control<T> | T`) API for standalone use outside forms.
196
631
 
632
+ Beyond `FormItem`, the `haze-ui` barrel re-exports the whole form layer
633
+ so consumers never import react-f0rm directly: `FormList` (array fields
634
+ over `useFieldArray` — append/prepend/insert/remove/swap/move with
635
+ stable row keys), `FormProvider`/`useFormContext` (`FormItem`/`FormList`
636
+ fall back to context when the `form` prop is omitted), the imperative
637
+ APIs (`setValue`, `getValue`, `reset`, `trigger`, `setFocus`,
638
+ `setServerErrors`, `useWatch`, ...), and schema resolvers:
639
+
640
+ ```jsx
641
+ import { FormItem, FormList, zodResolver, standardSchemaResolver } from 'haze-ui';
642
+ ```
643
+
644
+ `zodResolver` adapts any zod schema (v4) as a field validator;
645
+ `standardSchemaResolver` adapts any Standard Schema v1 implementation
646
+ (zod, valibot, arktype, ...) the same way. Field controls forward refs
647
+ to their focusable element and `FormItem` wires f0rm's `focusRef`
648
+ channel, so `setFocus(form, 'name')` and a failed submit's
649
+ first-error auto-focus land on the real input.
650
+
197
651
  ### useField: field → {value, onChange}
198
652
 
199
653
  ```jsx
@@ -457,13 +911,34 @@ display, `validate`-only).
457
911
 
458
912
  ## Accessibility & RTL
459
913
 
914
+ Accessibility is a baseline, not an opt-in: every component's test suite
915
+ includes axe checks, and the token sheet ships a global
916
+ `@media (prefers-reduced-motion: reduce)` block that collapses every
917
+ animation duration token to `0ms` — motion-sensitive users get instant
918
+ state changes with no per-component wiring.
919
+
460
920
  haze-ui supports RTL via CSS logical properties wherever a side is
461
921
  semantic (the *start/end* of reading flow), not just decorative. Set
462
922
  `dir="rtl"` (or `direction: rtl`) on an ancestor and those sides mirror
463
- automatically — no component props change. A regression smoke test
464
- (`src/lib/rtl.test.tsx`) renders Progress, Alert, Badge, Tag and Dialog
465
- in a `dir="rtl"` subtree asserting rendering, axe cleanliness and
466
- unchanged aria contracts.
923
+ automatically — no component props change. The same goes for keyboard
924
+ semantics: horizontal arrow keys invert their meaning in RTL (Tabs,
925
+ Rating, Slider, Carousel, Calendar, Toolbar, Cascader, Tour and
926
+ horizontal menus), and floating placements are logical — a panel with
927
+ `placement="bottom"` in an RTL document lands on the mirrored inline
928
+ side without passing a mirrored placement. `src/lib/rtl.test.tsx` is a
929
+ four-layer contract suite (rendering + axe, keyboard mirroring, floating
930
+ mirroring, and a CSS-codemod guard with an explicit exemption list),
931
+ backed by `e2e/rtl.spec.ts` cross-engine checks.
932
+
933
+ `LocaleProvider` takes an optional `direction` prop (`'ltr' | 'rtl'`,
934
+ explicit wins over derivation from the locale — Arabic, Hebrew, Farsi
935
+ and friends are derived automatically) and feeds `useDirection()`, the
936
+ hook components use internally. `getDirection(el)` (DOM resolution with
937
+ `[dir]` fallback) and `localeDirection(locale)` are exported from the
938
+ barrel alongside it, plus `createStrings(base, overrides)` — a
939
+ `DeepPartial<HazeStrings>` deep-merge for deriving locale packs without
940
+ forking a whole string table (see the *Adding a locale* recipe on the
941
+ docs site).
467
942
 
468
943
  ### Direction-responsive by construction (no physical CSS)
469
944
 
@@ -503,12 +978,13 @@ Checkbox's rotated checkmark, Radio's centered dot, Affix's symmetric
503
978
  ### Partial support: known gaps
504
979
 
505
980
  - **Floating panels (Popover, DropdownMenu, Tooltip, ContextMenu,
506
- Combobox, Datepicker)** — placements are physical sides
507
- (`'left'`/`'right'`/`'bottom-end'`, …). The CSS anchor-positioning
508
- `position-area` grid keywords and the JS collision math
509
- (`utils/collision.ts`, viewport coordinates) are physical; migrating to
510
- logical `position-area` keywords is a tracked future change. In RTL the
511
- panels position identically to LTR.
981
+ Combobox, Datepicker)** — *fixed*: `FloatingPlacement` is logical now.
982
+ Tier 1 uses logical `position-area` values (`span-inline-end
983
+ block-end`, …) where engines accept them and falls back to
984
+ dir-switched physical classes; the tier-2 JS math
985
+ (`utils/collision.ts` `computeFloatingPosition(..., { dir })`)
986
+ mirrors the x-axis. In RTL the panels open on the mirrored side
987
+ automatically.
512
988
  - **Input adornments** — `SelectCore` / `ModelPicker` chevrons
513
989
  (`background-position: right …` + `padding-right`) and
514
990
  `PasswordInputCore`'s absolute reveal button sit on the physical right
@@ -573,6 +1049,12 @@ import 'haze-ui/css/button.css';
573
1049
  No — haze-ui is ESM-only (`"type": "module"`). Use a bundler or runtime
574
1050
  with ESM support (Vite, webpack 5, Next.js, Node ≥ 18, …).
575
1051
 
1052
+ ### Does haze-ui support React 18?
1053
+
1054
+ No — the peer range is `react@^19.0.0` by design (see
1055
+ [React 19+ by design](#react-19-by-design)). Upgrade to React 19 first;
1056
+ haze-ui ships no React 18 compatibility layer.
1057
+
576
1058
  ### How do I detect (or degrade) the relative-color syntax?
577
1059
 
578
1060
  Since v1.13, theme interaction states are derived with CSS relative
@@ -1,4 +1,5 @@
1
1
 
2
+ "use client";
2
3
  import { classnames as e } from "../../utils/classnames.js";
3
4
  /* empty css */
4
5
  import { jsx as t } from "react/jsx-runtime";
@@ -1,4 +1,5 @@
1
1
 
2
+ "use client";
2
3
  import { classnames as e } from "../../utils/classnames.js";
3
4
  /* empty css */
4
5
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import e from "./Accordion.js";
2
3
  import t from "./AccordionItem.js";
3
4
  export { e as Accordion, t as AccordionItem };
@@ -1,4 +1,5 @@
1
1
 
2
+ "use client";
2
3
  import { classnames as e } from "../../utils/classnames.js";
3
4
  /* empty css */
4
5
  import { jsx as t } from "react/jsx-runtime";
@@ -1,2 +1,3 @@
1
+ "use client";
1
2
  import e from "./Affix.js";
2
3
  export { e as Affix };
@@ -1,4 +1,5 @@
1
1
 
2
+ "use client";
2
3
  import { classnames as e } from "../../utils/classnames.js";
3
4
  import { useStrings as t } from "../LocaleProvider/useStrings.js";
4
5
  /* empty css */
@@ -1,2 +1,3 @@
1
+ "use client";
1
2
  import e from "./Alert.js";
2
3
  export { e as Alert };