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.
- package/README.md +492 -10
- package/dist/components/Accordion/Accordion.js +1 -0
- package/dist/components/Accordion/AccordionItem.js +1 -0
- package/dist/components/Accordion/index.js +1 -0
- package/dist/components/Affix/Affix.js +1 -0
- package/dist/components/Affix/index.js +1 -0
- package/dist/components/Alert/Alert.js +1 -0
- package/dist/components/Alert/index.js +1 -0
- package/dist/components/Anchor/Anchor.js +78 -0
- package/dist/components/Anchor/index.js +3 -0
- package/dist/components/AppShell/AppShell.js +44 -0
- package/dist/components/AppShell/index.js +3 -0
- package/dist/components/ApprovalCard/ApprovalCard.js +1 -0
- package/dist/components/ApprovalCard/index.js +1 -0
- package/dist/components/AsyncSection/AsyncSection.js +1 -0
- package/dist/components/AsyncSection/index.js +1 -0
- package/dist/components/Avatar/Avatar.js +1 -0
- package/dist/components/Avatar/index.js +1 -0
- package/dist/components/AvatarGroup/AvatarGroup.js +1 -0
- package/dist/components/AvatarGroup/index.js +1 -0
- package/dist/components/BackToTop/BackToTop.js +1 -0
- package/dist/components/BackToTop/index.js +1 -0
- package/dist/components/Badge/Badge.js +5 -16
- package/dist/components/Badge/badge-styles.js +15 -0
- package/dist/components/Badge/index.js +3 -2
- package/dist/components/Banner/Banner.js +1 -0
- package/dist/components/Banner/index.js +1 -0
- package/dist/components/BottomSheet/BottomSheet.js +134 -22
- package/dist/components/BottomSheet/index.js +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.js +1 -0
- package/dist/components/Breadcrumb/BreadcrumbItem.js +1 -0
- package/dist/components/Breadcrumb/index.js +1 -0
- package/dist/components/Button/Button.js +1 -0
- package/dist/components/Button/ButtonLink.js +1 -0
- package/dist/components/Button/index.js +5 -3
- package/dist/components/Button/styles.js +1 -0
- package/dist/components/Calendar/Calendar.js +453 -105
- package/dist/components/Calendar/date.js +87 -0
- package/dist/components/Calendar/index.js +1 -0
- package/dist/components/Carousel/Carousel.js +65 -41
- package/dist/components/Carousel/CarouselSlide.js +1 -0
- package/dist/components/Carousel/index.js +1 -0
- package/dist/components/Cascader/Cascader.js +186 -137
- package/dist/components/Cascader/index.js +1 -0
- package/dist/components/Chart/Chart.js +31 -0
- package/dist/components/Chart/chart-elements.js +88 -0
- package/dist/components/Chart/index.js +3 -0
- package/dist/components/ChatContainer/ChatContainer.js +37 -16
- package/dist/components/ChatContainer/index.js +1 -0
- package/dist/components/ChatInput/ChatInput.js +50 -29
- package/dist/components/ChatInput/index.js +1 -0
- package/dist/components/ChatMessage/ChatMessage.js +77 -29
- package/dist/components/ChatMessage/index.js +1 -0
- package/dist/components/Checkbox/Checkbox.js +7 -5
- package/dist/components/Checkbox/CheckboxCore.js +7 -5
- package/dist/components/Checkbox/index.js +1 -0
- package/dist/components/Chip/Chip.js +1 -0
- package/dist/components/Chip/index.js +1 -0
- package/dist/components/Collapsible/Collapsible.js +24 -10
- package/dist/components/Collapsible/index.js +1 -0
- package/dist/components/ColorPicker/ColorPicker.js +6 -4
- package/dist/components/ColorPicker/ColorPickerCore.js +6 -4
- package/dist/components/ColorPicker/index.js +1 -0
- package/dist/components/Combobox/Combobox.js +196 -69
- package/dist/components/Combobox/ComboboxGroup.js +23 -0
- package/dist/components/Combobox/ComboboxOption.js +10 -5
- package/dist/components/Combobox/index.js +5 -3
- package/dist/components/Command/Command.js +103 -59
- package/dist/components/Command/CommandDialog.js +48 -0
- package/dist/components/Command/command-filter.js +16 -0
- package/dist/components/Command/index.js +4 -2
- package/dist/components/ConfirmDialog/ConfirmDialog.js +4 -3
- package/dist/components/ConfirmDialog/index.js +1 -0
- package/dist/components/ContextMenu/ContextMenu.js +1 -0
- package/dist/components/ContextMenu/ContextMenuContent.js +5 -4
- package/dist/components/ContextMenu/ContextMenuContext.js +1 -0
- package/dist/components/ContextMenu/ContextMenuItem.js +1 -0
- package/dist/components/ContextMenu/ContextMenuSeparator.js +1 -0
- package/dist/components/ContextMenu/ContextMenuTrigger.js +1 -0
- package/dist/components/ContextMenu/index.js +1 -0
- package/dist/components/ConversationList/ConversationItem.js +1 -0
- package/dist/components/ConversationList/ConversationList.js +1 -0
- package/dist/components/ConversationList/index.js +1 -0
- package/dist/components/DataTable/CellEditor.js +38 -0
- package/dist/components/DataTable/DataTable.js +415 -125
- package/dist/components/DataTable/features.js +25 -0
- package/dist/components/DataTable/index.js +3 -1
- package/dist/components/DataTable/summary.js +17 -0
- package/dist/components/DateRangePicker/DateRangePicker.js +11 -7
- package/dist/components/DateRangePicker/DateRangePickerCore.js +60 -27
- package/dist/components/DateRangePicker/index.js +1 -0
- package/dist/components/Datepicker/Datepicker.js +17 -12
- package/dist/components/Datepicker/DatepickerCore.js +51 -37
- package/dist/components/Datepicker/index.js +1 -0
- package/dist/components/Dialog/Dialog.js +57 -32
- package/dist/components/Dialog/index.js +1 -0
- package/dist/components/DiffViewer/DiffViewer.js +1 -0
- package/dist/components/DiffViewer/index.js +1 -0
- package/dist/components/Disclosure/Disclosure.js +1 -0
- package/dist/components/Disclosure/index.js +1 -0
- package/dist/components/Drawer/Drawer.js +50 -29
- package/dist/components/Drawer/index.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.js +39 -26
- package/dist/components/DropdownMenu/DropdownMenuContent.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenuContext.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenuItem.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenuSeparator.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenuSub.js +23 -0
- package/dist/components/DropdownMenu/DropdownMenuSubContent.js +24 -0
- package/dist/components/DropdownMenu/DropdownMenuSubTrigger.js +30 -0
- package/dist/components/DropdownMenu/DropdownMenuTrigger.js +1 -0
- package/dist/components/DropdownMenu/index.js +5 -1
- package/dist/components/Empty/Empty.js +1 -0
- package/dist/components/Empty/index.js +1 -0
- package/dist/components/FileInput/FileInput.js +1 -0
- package/dist/components/FileInput/index.js +1 -0
- package/dist/components/Fullscreen/Fullscreen.js +29 -0
- package/dist/components/Fullscreen/index.js +3 -0
- package/dist/components/HoverCard/HoverCard.js +1 -0
- package/dist/components/HoverCard/index.js +1 -0
- package/dist/components/Image/Image.js +38 -19
- package/dist/components/Image/ImagePreview.js +233 -0
- package/dist/components/Image/index.js +1 -0
- package/dist/components/InlineEdit/InlineEdit.js +1 -0
- package/dist/components/InlineEdit/index.js +1 -0
- package/dist/components/Input/Input.js +7 -5
- package/dist/components/Input/InputCore.js +4 -2
- package/dist/components/Input/index.js +1 -0
- package/dist/components/List/List.js +1 -0
- package/dist/components/List/ListItem.js +1 -0
- package/dist/components/List/index.js +1 -0
- package/dist/components/LocaleProvider/LocaleContext.js +1 -0
- package/dist/components/LocaleProvider/LocaleProvider.js +17 -13
- package/dist/components/LocaleProvider/index.js +6 -3
- package/dist/components/LocaleProvider/locale.js +65 -3
- package/dist/components/LocaleProvider/strings.js +15 -0
- package/dist/components/LocaleProvider/useStrings.js +18 -8
- package/dist/components/LocaleProvider/zh-cn.js +184 -0
- package/dist/components/LogViewer/LogViewer.js +1 -0
- package/dist/components/LogViewer/index.js +1 -0
- package/dist/components/MarkdownRenderer/MarkdownRenderer.js +1 -0
- package/dist/components/MarkdownRenderer/index.js +1 -0
- package/dist/components/MarkdownRenderer/markdown-blocks.js +1 -0
- package/dist/components/Mentions/Mentions.js +18 -0
- package/dist/components/Mentions/MentionsCore.js +117 -0
- package/dist/components/Mentions/index.js +4 -0
- package/dist/components/Menu/Menu.js +6 -5
- package/dist/components/Menu/MenuDivider.js +1 -0
- package/dist/components/Menu/MenuItem.js +1 -0
- package/dist/components/Menu/MenuSub.js +23 -0
- package/dist/components/Menu/MenuSubContent.js +24 -0
- package/dist/components/Menu/MenuSubTrigger.js +30 -0
- package/dist/components/Menu/index.js +5 -1
- package/dist/components/ModelPicker/ModelPicker.js +1 -0
- package/dist/components/ModelPicker/index.js +1 -0
- package/dist/components/NavigationBar/NavLink.js +1 -0
- package/dist/components/NavigationBar/NavigationBar.js +1 -0
- package/dist/components/NavigationBar/index.js +1 -0
- package/dist/components/NumberInput/NumberInput.js +7 -5
- package/dist/components/NumberInput/NumberInputCore.js +10 -8
- package/dist/components/NumberInput/index.js +1 -0
- package/dist/components/OTPInput/OTPInput.js +6 -4
- package/dist/components/OTPInput/OTPInputCore.js +35 -33
- package/dist/components/OTPInput/index.js +1 -0
- package/dist/components/Pagination/Pagination.js +1 -0
- package/dist/components/Pagination/index.js +1 -0
- package/dist/components/PasswordInput/PasswordInput.js +6 -4
- package/dist/components/PasswordInput/PasswordInputCore.js +9 -7
- package/dist/components/PasswordInput/index.js +1 -0
- package/dist/components/Popover/Popover.js +44 -31
- package/dist/components/Popover/index.js +1 -0
- package/dist/components/Progress/Progress.js +1 -0
- package/dist/components/Progress/index.js +1 -0
- package/dist/components/PromptInput/PromptInput.js +213 -0
- package/dist/components/PromptInput/index.js +3 -0
- package/dist/components/Radio/Radio.js +8 -6
- package/dist/components/Radio/RadioContext.js +1 -0
- package/dist/components/Radio/RadioGroup.js +6 -4
- package/dist/components/Radio/RadioGroupCore.js +24 -14
- package/dist/components/Radio/index.js +1 -0
- package/dist/components/Rating/Rating.js +6 -4
- package/dist/components/Rating/RatingCore.js +63 -28
- package/dist/components/Rating/index.js +1 -0
- package/dist/components/Resizable/Resizable.js +1 -0
- package/dist/components/Resizable/index.js +2 -1
- package/dist/components/ScrollArea/ScrollArea.js +1 -0
- package/dist/components/ScrollArea/index.js +1 -0
- package/dist/components/Segmented/Segmented.js +6 -4
- package/dist/components/Segmented/SegmentedCore.js +23 -18
- package/dist/components/Segmented/index.js +1 -0
- package/dist/components/Select/Option.js +1 -0
- package/dist/components/Select/OptionGroup.js +12 -0
- package/dist/components/Select/Select.js +20 -9
- package/dist/components/Select/SelectCore.js +74 -13
- package/dist/components/Select/SelectFloating.js +248 -0
- package/dist/components/Select/index.js +6 -4
- package/dist/components/Select/select-options.js +57 -0
- package/dist/components/Sidebar/Sidebar.js +10 -9
- package/dist/components/Sidebar/index.js +1 -0
- package/dist/components/Slider/Slider.js +17 -8
- package/dist/components/Slider/SliderCore.js +76 -12
- package/dist/components/Slider/index.js +1 -0
- package/dist/components/Spinner/Spinner.js +1 -0
- package/dist/components/Spinner/index.js +1 -0
- package/dist/components/StepTimeline/StepTimeline.js +1 -0
- package/dist/components/StepTimeline/index.js +1 -0
- package/dist/components/Stepper/Step.js +1 -0
- package/dist/components/Stepper/Stepper.js +1 -0
- package/dist/components/Stepper/StepperContext.js +1 -0
- package/dist/components/Stepper/index.js +1 -0
- package/dist/components/StreamingText/StreamingText.js +1 -0
- package/dist/components/StreamingText/index.js +1 -0
- package/dist/components/SwipeAction/SwipeAction.js +1 -0
- package/dist/components/SwipeAction/index.js +1 -0
- package/dist/components/Switch/Switch.js +7 -5
- package/dist/components/Switch/SwitchCore.js +4 -2
- package/dist/components/Switch/index.js +1 -0
- package/dist/components/Table/Table.js +1 -0
- package/dist/components/Table/TableBody.js +1 -0
- package/dist/components/Table/TableCell.js +1 -0
- package/dist/components/Table/TableHead.js +1 -0
- package/dist/components/Table/TableRow.js +1 -0
- package/dist/components/Table/index.js +1 -0
- package/dist/components/Tabs/Tab.js +8 -4
- package/dist/components/Tabs/TabList.js +39 -7
- package/dist/components/Tabs/TabPanel.js +5 -3
- package/dist/components/Tabs/Tabs.js +12 -6
- package/dist/components/Tabs/TabsContext.js +1 -0
- package/dist/components/Tabs/index.js +1 -0
- package/dist/components/Tag/Tag.js +1 -0
- package/dist/components/Tag/index.js +1 -0
- package/dist/components/TagGroup/TagGroup.js +20 -7
- package/dist/components/TagGroup/TagGroupItem.js +18 -11
- package/dist/components/TagGroup/index.js +1 -0
- package/dist/components/TagInput/TagInput.js +11 -8
- package/dist/components/TagInput/TagInputCore.js +95 -57
- package/dist/components/TagInput/index.js +1 -0
- package/dist/components/Textarea/Textarea.js +7 -5
- package/dist/components/Textarea/TextareaCore.js +4 -2
- package/dist/components/Textarea/index.js +1 -0
- package/dist/components/ThinkingIndicator/ThinkingIndicator.js +1 -0
- package/dist/components/ThinkingIndicator/index.js +1 -0
- package/dist/components/TimePicker/TimePicker.js +7 -5
- package/dist/components/TimePicker/TimePickerCore.js +4 -2
- package/dist/components/TimePicker/index.js +1 -0
- package/dist/components/Timeline/Timeline.js +1 -0
- package/dist/components/Timeline/index.js +1 -0
- package/dist/components/Toast/Toast.js +38 -31
- package/dist/components/Toast/ToastContainer.js +68 -47
- package/dist/components/Toast/ToastContext.js +24 -4
- package/dist/components/Toast/index.js +1 -0
- package/dist/components/Toast/toast2.js +64 -28
- package/dist/components/Toast/useToast.js +10 -7
- package/dist/components/Toggle/Toggle.js +20 -0
- package/dist/components/Toggle/ToggleCore.js +31 -0
- package/dist/components/Toggle/index.js +4 -0
- package/dist/components/TokenCounter/TokenCounter.js +1 -0
- package/dist/components/TokenCounter/index.js +1 -0
- package/dist/components/ToolCallCard/ToolCallCard.js +1 -0
- package/dist/components/ToolCallCard/index.js +1 -0
- package/dist/components/Toolbar/Toolbar.js +34 -32
- package/dist/components/Toolbar/ToolbarButton.js +1 -0
- package/dist/components/Toolbar/ToolbarContext.js +1 -0
- package/dist/components/Toolbar/ToolbarSeparator.js +1 -0
- package/dist/components/Toolbar/ToolbarToggle.js +31 -0
- package/dist/components/Toolbar/index.js +3 -1
- package/dist/components/Tooltip/Tooltip.js +2 -1
- package/dist/components/Tooltip/index.js +1 -0
- package/dist/components/Tour/Tour.js +58 -53
- package/dist/components/Tour/index.js +1 -0
- package/dist/components/Transfer/Transfer.js +1 -0
- package/dist/components/Transfer/TransferCore.js +1 -0
- package/dist/components/Transfer/index.js +1 -0
- package/dist/components/Tree/Tree.js +200 -77
- package/dist/components/Tree/TreeItem.js +18 -15
- package/dist/components/Tree/index.js +1 -0
- package/dist/components/Tree/utils.js +27 -10
- package/dist/components/Upload/Upload.js +22 -8
- package/dist/components/Upload/UploadCore.js +225 -37
- package/dist/components/Upload/UploadList.js +172 -0
- package/dist/components/Upload/index.js +1 -0
- package/dist/components/Upload/xhr-upload.js +22 -0
- package/dist/components/VirtualList/VirtualList.js +85 -56
- package/dist/components/VirtualList/index.js +1 -0
- package/dist/components/Watermark/Watermark.js +55 -0
- package/dist/components/Watermark/index.js +3 -0
- package/dist/css/accordion.css +1 -1
- package/dist/css/alert.css +1 -1
- package/dist/css/anchor.css +2 -0
- package/dist/css/app-shell.css +2 -0
- package/dist/css/approval-card.css +1 -1
- package/dist/css/async-section.css +1 -1
- package/dist/css/back-to-top.css +1 -1
- package/dist/css/badge.css +1 -1
- package/dist/css/bottom-sheet.css +1 -1
- package/dist/css/breadcrumb.css +1 -1
- package/dist/css/button.css +1 -1
- package/dist/css/calendar.css +1 -1
- package/dist/css/carousel.css +1 -1
- package/dist/css/cascader.css +1 -1
- package/dist/css/chart.css +2 -0
- package/dist/css/chat-container.css +1 -1
- package/dist/css/chat-input.css +1 -1
- package/dist/css/chat-message.css +1 -1
- package/dist/css/checkbox.css +1 -1
- package/dist/css/chip.css +1 -1
- package/dist/css/color-picker.css +1 -1
- package/dist/css/combobox.css +3 -2
- package/dist/css/command.css +2 -1
- package/dist/css/context-menu.css +2 -2
- package/dist/css/conversation-list.css +1 -1
- package/dist/css/data-table.css +2 -1
- package/dist/css/date-range-picker.css +1 -1
- package/dist/css/datepicker.css +2 -2
- package/dist/css/dialog.css +1 -1
- package/dist/css/disclosure.css +1 -1
- package/dist/css/dropdown-menu.css +5 -2
- package/dist/css/file-input.css +1 -1
- package/dist/css/image.css +2 -1
- package/dist/css/inline-edit.css +1 -1
- package/dist/css/input.css +1 -1
- package/dist/css/log-viewer.css +1 -1
- package/dist/css/mentions.css +2 -0
- package/dist/css/menu.css +5 -2
- package/dist/css/model-picker.css +1 -1
- package/dist/css/navigation-bar.css +1 -1
- package/dist/css/number-input.css +1 -1
- package/dist/css/otp-input.css +1 -1
- package/dist/css/pagination.css +1 -1
- package/dist/css/password-input.css +1 -1
- package/dist/css/popover.css +1 -1
- package/dist/css/progress.css +1 -1
- package/dist/css/prompt-input.css +2 -0
- package/dist/css/radio.css +1 -1
- package/dist/css/rating.css +1 -1
- package/dist/css/resizable.css +1 -1
- package/dist/css/segmented.css +1 -1
- package/dist/css/select.css +3 -1
- package/dist/css/slider.css +1 -1
- package/dist/css/stepper.css +1 -1
- package/dist/css/swipe-action.css +1 -1
- package/dist/css/switch.css +1 -1
- package/dist/css/tabs.css +1 -1
- package/dist/css/tag-group.css +2 -0
- package/dist/css/tag-input.css +3 -1
- package/dist/css/tag.css +1 -1
- package/dist/css/textarea.css +1 -1
- package/dist/css/time-picker.css +1 -1
- package/dist/css/toggle.css +2 -0
- package/dist/css/token-counter.css +1 -1
- package/dist/css/tokens.css +1 -1
- package/dist/css/toolbar.css +1 -0
- package/dist/css/tooltip.css +1 -1
- package/dist/css/tree.css +2 -2
- package/dist/css/upload.css +2 -1
- package/dist/css/watermark.css +2 -0
- package/dist/css-manifest.json +70 -2
- package/dist/form/FormItem.js +56 -50
- package/dist/form/FormList.js +79 -0
- package/dist/form/index.js +6 -1
- package/dist/form/standard-schema.js +16 -0
- package/dist/haze-ui.css +92 -67
- package/dist/headless/index.js +7 -0
- package/dist/hooks/useClickOutside.js +24 -0
- package/dist/hooks/useClipboard.js +30 -0
- package/dist/hooks/useDebouncedCallback.js +17 -0
- package/dist/hooks/useDebouncedValue.js +12 -0
- package/dist/hooks/useFullscreen.js +42 -0
- package/dist/hooks/useHotkeys.js +77 -0
- package/dist/hooks/useInView.js +27 -0
- package/dist/hooks/useLocalStorage.js +8 -0
- package/dist/hooks/useMediaQuery.js +14 -0
- package/dist/hooks/usePrefersReducedMotion.js +9 -0
- package/dist/hooks/usePrevious.js +11 -0
- package/dist/hooks/useSessionStorage.js +8 -0
- package/dist/hooks/useStorageState.js +80 -0
- package/dist/hooks/useTitle.js +1 -0
- package/dist/index.js +206 -163
- package/dist/registry.json +2259 -91
- package/dist/tokens/registry.js +17 -27
- package/dist/types/components/Anchor/Anchor.d.ts +25 -0
- package/dist/types/components/Anchor/index.d.ts +2 -0
- package/dist/types/components/AppShell/AppShell.d.ts +17 -0
- package/dist/types/components/AppShell/index.d.ts +2 -0
- package/dist/types/components/Badge/badge-styles.d.ts +21 -0
- package/dist/types/components/Badge/index.d.ts +1 -0
- package/dist/types/components/BottomSheet/BottomSheet.d.ts +52 -3
- package/dist/types/components/BottomSheet/index.d.ts +1 -1
- package/dist/types/components/Button/Button.d.ts +7 -0
- package/dist/types/components/Button/ButtonLink.d.ts +3 -0
- package/dist/types/components/Button/index.d.ts +1 -0
- package/dist/types/components/Button/styles.d.ts +17 -0
- package/dist/types/components/Calendar/Calendar.d.ts +71 -7
- package/dist/types/components/Calendar/date.d.ts +131 -0
- package/dist/types/components/Calendar/index.d.ts +1 -1
- package/dist/types/components/Cascader/Cascader.d.ts +29 -3
- package/dist/types/components/Chart/Chart.d.ts +29 -0
- package/dist/types/components/Chart/chart-elements.d.ts +52 -0
- package/dist/types/components/Chart/index.d.ts +2 -0
- package/dist/types/components/ChatContainer/ChatContainer.d.ts +18 -3
- package/dist/types/components/ChatInput/ChatInput.d.ts +11 -1
- package/dist/types/components/ChatMessage/ChatMessage.d.ts +13 -1
- package/dist/types/components/Checkbox/Checkbox.d.ts +6 -2
- package/dist/types/components/Checkbox/CheckboxCore.d.ts +4 -2
- package/dist/types/components/Collapsible/Collapsible.d.ts +24 -2
- package/dist/types/components/Collapsible/index.d.ts +1 -1
- package/dist/types/components/ColorPicker/ColorPicker.d.ts +7 -1
- package/dist/types/components/ColorPicker/ColorPickerCore.d.ts +7 -1
- package/dist/types/components/Combobox/Combobox.d.ts +101 -7
- package/dist/types/components/Combobox/ComboboxGroup.d.ts +22 -0
- package/dist/types/components/Combobox/ComboboxOption.d.ts +19 -2
- package/dist/types/components/Combobox/index.d.ts +3 -1
- package/dist/types/components/Command/Command.d.ts +70 -6
- package/dist/types/components/Command/CommandDialog.d.ts +36 -0
- package/dist/types/components/Command/command-filter.d.ts +34 -0
- package/dist/types/components/Command/index.d.ts +4 -2
- package/dist/types/components/DataTable/CellEditor.d.ts +24 -0
- package/dist/types/components/DataTable/DataTable.d.ts +184 -26
- package/dist/types/components/DataTable/features.d.ts +118 -0
- package/dist/types/components/DataTable/index.d.ts +2 -1
- package/dist/types/components/DataTable/summary.d.ts +19 -0
- package/dist/types/components/DateRangePicker/DateRangePicker.d.ts +15 -1
- package/dist/types/components/DateRangePicker/DateRangePickerCore.d.ts +26 -2
- package/dist/types/components/DateRangePicker/index.d.ts +1 -1
- package/dist/types/components/Datepicker/Datepicker.d.ts +17 -1
- package/dist/types/components/Datepicker/DatepickerCore.d.ts +24 -2
- package/dist/types/components/Datepicker/index.d.ts +1 -1
- package/dist/types/components/Dialog/Dialog.d.ts +68 -3
- package/dist/types/components/Dialog/index.d.ts +1 -1
- package/dist/types/components/Drawer/Drawer.d.ts +33 -3
- package/dist/types/components/Drawer/index.d.ts +1 -1
- package/dist/types/components/DropdownMenu/DropdownMenu.d.ts +23 -3
- package/dist/types/components/DropdownMenu/DropdownMenuSub.d.ts +18 -0
- package/dist/types/components/DropdownMenu/DropdownMenuSubContent.d.ts +13 -0
- package/dist/types/components/DropdownMenu/DropdownMenuSubTrigger.d.ts +14 -0
- package/dist/types/components/DropdownMenu/index.d.ts +7 -1
- package/dist/types/components/Fullscreen/Fullscreen.d.ts +34 -0
- package/dist/types/components/Fullscreen/index.d.ts +3 -0
- package/dist/types/components/Image/Image.d.ts +20 -5
- package/dist/types/components/Image/ImagePreview.d.ts +13 -0
- package/dist/types/components/Image/index.d.ts +1 -1
- package/dist/types/components/Input/Input.d.ts +5 -2
- package/dist/types/components/Input/InputCore.d.ts +4 -2
- package/dist/types/components/LocaleProvider/LocaleContext.d.ts +10 -1
- package/dist/types/components/LocaleProvider/LocaleProvider.d.ts +17 -3
- package/dist/types/components/LocaleProvider/index.d.ts +4 -1
- package/dist/types/components/LocaleProvider/locale.d.ts +63 -1
- package/dist/types/components/LocaleProvider/strings.d.ts +28 -0
- package/dist/types/components/LocaleProvider/useStrings.d.ts +5 -4
- package/dist/types/components/LocaleProvider/zh-cn.d.ts +13 -0
- package/dist/types/components/Mentions/Mentions.d.ts +20 -0
- package/dist/types/components/Mentions/MentionsCore.d.ts +23 -0
- package/dist/types/components/Mentions/index.d.ts +4 -0
- package/dist/types/components/Menu/MenuSub.d.ts +18 -0
- package/dist/types/components/Menu/MenuSubContent.d.ts +12 -0
- package/dist/types/components/Menu/MenuSubTrigger.d.ts +14 -0
- package/dist/types/components/Menu/index.d.ts +6 -0
- package/dist/types/components/NumberInput/NumberInput.d.ts +5 -2
- package/dist/types/components/NumberInput/NumberInputCore.d.ts +4 -2
- package/dist/types/components/OTPInput/OTPInput.d.ts +5 -1
- package/dist/types/components/OTPInput/OTPInputCore.d.ts +4 -1
- package/dist/types/components/PasswordInput/PasswordInput.d.ts +5 -1
- package/dist/types/components/PasswordInput/PasswordInputCore.d.ts +4 -1
- package/dist/types/components/Popover/Popover.d.ts +41 -3
- package/dist/types/components/Popover/index.d.ts +1 -1
- package/dist/types/components/PromptInput/PromptInput.d.ts +46 -0
- package/dist/types/components/PromptInput/index.d.ts +2 -0
- package/dist/types/components/Radio/Radio.d.ts +5 -2
- package/dist/types/components/Radio/RadioGroup.d.ts +8 -2
- package/dist/types/components/Radio/RadioGroupCore.d.ts +7 -2
- package/dist/types/components/Rating/Rating.d.ts +8 -1
- package/dist/types/components/Rating/RatingCore.d.ts +7 -1
- package/dist/types/components/Resizable/index.d.ts +2 -0
- package/dist/types/components/Segmented/Segmented.d.ts +8 -1
- package/dist/types/components/Segmented/SegmentedCore.d.ts +7 -2
- package/dist/types/components/Select/OptionGroup.d.ts +16 -0
- package/dist/types/components/Select/Select.d.ts +66 -4
- package/dist/types/components/Select/SelectCore.d.ts +70 -6
- package/dist/types/components/Select/SelectFloating.d.ts +83 -0
- package/dist/types/components/Select/index.d.ts +2 -0
- package/dist/types/components/Select/select-options.d.ts +53 -0
- package/dist/types/components/Slider/Slider.d.ts +29 -4
- package/dist/types/components/Slider/SliderCore.d.ts +35 -6
- package/dist/types/components/Switch/Switch.d.ts +5 -2
- package/dist/types/components/Switch/SwitchCore.d.ts +4 -2
- package/dist/types/components/Tabs/TabList.d.ts +7 -0
- package/dist/types/components/Tabs/Tabs.d.ts +8 -1
- package/dist/types/components/Tabs/TabsContext.d.ts +20 -0
- package/dist/types/components/Tabs/index.d.ts +1 -0
- package/dist/types/components/TagGroup/TagGroup.d.ts +13 -1
- package/dist/types/components/TagInput/TagInput.d.ts +12 -1
- package/dist/types/components/TagInput/TagInputCore.d.ts +11 -1
- package/dist/types/components/Textarea/Textarea.d.ts +5 -2
- package/dist/types/components/Textarea/TextareaCore.d.ts +4 -2
- package/dist/types/components/TimePicker/TimePicker.d.ts +5 -2
- package/dist/types/components/TimePicker/TimePickerCore.d.ts +4 -2
- package/dist/types/components/Toast/Toast.d.ts +31 -2
- package/dist/types/components/Toast/ToastContainer.d.ts +11 -1
- package/dist/types/components/Toast/ToastContext.d.ts +44 -3
- package/dist/types/components/Toast/index.d.ts +1 -1
- package/dist/types/components/Toast/toast.d.ts +35 -4
- package/dist/types/components/Toast/useToast.d.ts +16 -4
- package/dist/types/components/Toggle/Toggle.d.ts +19 -0
- package/dist/types/components/Toggle/ToggleCore.d.ts +23 -0
- package/dist/types/components/Toggle/index.d.ts +4 -0
- package/dist/types/components/Toolbar/ToolbarToggle.d.ts +19 -0
- package/dist/types/components/Toolbar/index.d.ts +2 -0
- package/dist/types/components/Tour/Tour.d.ts +3 -3
- package/dist/types/components/Tree/Tree.d.ts +3 -3
- package/dist/types/components/Tree/TreeItem.d.ts +6 -1
- package/dist/types/components/Tree/types.d.ts +26 -0
- package/dist/types/components/Tree/utils.d.ts +32 -0
- package/dist/types/components/Upload/Upload.d.ts +38 -3
- package/dist/types/components/Upload/UploadCore.d.ts +75 -4
- package/dist/types/components/Upload/UploadList.d.ts +12 -0
- package/dist/types/components/Upload/index.d.ts +1 -0
- package/dist/types/components/Upload/types.d.ts +60 -0
- package/dist/types/components/Upload/xhr-upload.d.ts +20 -0
- package/dist/types/components/VirtualList/VirtualList.d.ts +16 -1
- package/dist/types/components/Watermark/Watermark.d.ts +32 -0
- package/dist/types/components/Watermark/index.d.ts +2 -0
- package/dist/types/form/FormItem.d.ts +33 -8
- package/dist/types/form/FormList.d.ts +113 -0
- package/dist/types/form/index.d.ts +26 -0
- package/dist/types/form/standard-schema.d.ts +30 -0
- package/dist/types/headless/index.d.ts +182 -0
- package/dist/types/hooks/index.d.ts +17 -0
- package/dist/types/hooks/useClickOutside.d.ts +46 -0
- package/dist/types/hooks/useClipboard.d.ts +31 -0
- package/dist/types/hooks/useDebouncedCallback.d.ts +21 -0
- package/dist/types/hooks/useDebouncedValue.d.ts +20 -0
- package/dist/types/hooks/useFullscreen.d.ts +33 -0
- package/dist/types/hooks/useHotkeys.d.ts +53 -0
- package/dist/types/hooks/useInView.d.ts +32 -0
- package/dist/types/hooks/useLocalStorage.d.ts +33 -0
- package/dist/types/hooks/useMediaQuery.d.ts +20 -0
- package/dist/types/hooks/usePrefersReducedMotion.d.ts +14 -0
- package/dist/types/hooks/usePrevious.d.ts +18 -0
- package/dist/types/hooks/useSessionStorage.d.ts +26 -0
- package/dist/types/hooks/useStorageState.d.ts +12 -0
- package/dist/types/index.d.ts +60 -32
- package/dist/types/utils/collision.d.ts +39 -1
- package/dist/types/utils/direction.d.ts +22 -0
- package/dist/types/utils/floating.d.ts +32 -4
- package/dist/types/utils/focus-scope.d.ts +2 -1
- package/dist/types/utils/focus.d.ts +2 -1
- package/dist/types/utils/menuKeyboard.d.ts +19 -4
- package/dist/types/utils/refs.d.ts +16 -0
- package/dist/types/utils/sortable-shared.d.ts +42 -0
- package/dist/types/utils/sortable.d.ts +36 -0
- package/dist/types/utils/submenu.d.ts +63 -0
- package/dist/types/utils/view-transition.d.ts +28 -0
- package/dist/utils/collision.js +38 -26
- package/dist/utils/direction.js +34 -0
- package/dist/utils/floating.js +164 -143
- package/dist/utils/focus-scope.js +1 -0
- package/dist/utils/focus.js +1 -0
- package/dist/utils/menuKeyboard.js +60 -46
- package/dist/utils/presence.js +1 -0
- package/dist/utils/refs.js +9 -0
- package/dist/utils/sortable-shared.js +24 -0
- package/dist/utils/sortable.js +46 -0
- package/dist/utils/submenu.js +104 -0
- package/dist/utils/view-transition.js +26 -0
- package/package.json +119 -24
package/README.md
CHANGED
|
@@ -5,14 +5,25 @@
|
|
|
5
5
|
English | [简体中文](./README-zh_CN.md)
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/haze-ui)
|
|
8
|
+
[](https://www.npmjs.com/package/haze-ui)
|
|
8
9
|
[](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.
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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)** —
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
panels
|
|
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
|