haze-ui 1.20.0 → 1.22.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 CHANGED
@@ -49,6 +49,25 @@ Component CSS files are kebab-case versions of the component name
49
49
  cover that component's rules — tokens (themes, spacing, typography)
50
50
  always come from `haze-ui/css/tokens.css`.
51
51
 
52
+ Don't hardcode that kebab-case rule in tooling: sub-components and cores
53
+ share their directory's family file (`InputCore` → `input.css`,
54
+ `ButtonLink` → `button.css`, `Title`/`Text` → `typography.css`). The
55
+ authoritative export → css-file mapping ships as data:
56
+ `haze-ui/css-manifest.json`, generated at build time by
57
+ `scripts/split-css.mjs` from the actual CSS output (never hand-edited):
58
+
59
+ ```json
60
+ {
61
+ "families": { "Button": "button", "ButtonLink": "button", "InputCore": "input", "useToast": "toast" },
62
+ "noCss": ["COMPONENT_TOKENS", "TOKEN_REGISTRY", "useControl", "useTitle"]
63
+ }
64
+ ```
65
+
66
+ `families` covers every named export that has styles (family absorption
67
+ included); `noCss` lists pure-logic exports with no css of their own.
68
+ Bundler plugins and codemods should read this manifest instead of
69
+ re-deriving file names — the mapping changes in lockstep with the build.
70
+
52
71
  ## ButtonLink: a real anchor with the Button skin
53
72
 
54
73
  Navigation that must look like a button should still *be* a link —
@@ -106,6 +125,26 @@ import { AsyncSection } from 'haze-ui';
106
125
  </AsyncSection>
107
126
  ```
108
127
 
128
+ ## useTitle: view-level document.title
129
+
130
+ `useTitle(title)` sets `document.title` while the view is mounted and
131
+ restores the pre-entry title (the static `<title>` from the host page) on
132
+ unmount. Two timing pitfalls are baked into the implementation: the write
133
+ and the restore are two separate effects (a single `[title]` effect would
134
+ restore the *previous round's* title, not the entry default, on every prop
135
+ change), and the entry snapshot is taken at effect time, not render time —
136
+ a route swap is one commit, so at render time the old view's cleanup has
137
+ not run yet and `document.title` still holds the previous page.
138
+
139
+ ```jsx
140
+ import { useTitle } from 'haze-ui';
141
+
142
+ function SettingsView() {
143
+ useTitle('Settings');
144
+ // ...
145
+ }
146
+ ```
147
+
109
148
  ## react-f0rm Integration
110
149
 
111
150
  react-f0rm owns form field state, and its headless `useField` hook is
@@ -0,0 +1,167 @@
1
+ {
2
+ "families": {
3
+ "Accordion": "accordion",
4
+ "AccordionItem": "accordion",
5
+ "Affix": "affix",
6
+ "Alert": "alert",
7
+ "ApprovalCard": "approval-card",
8
+ "AspectRatio": "aspect-ratio",
9
+ "AsyncSection": "async-section",
10
+ "Avatar": "avatar",
11
+ "BackToTop": "back-to-top",
12
+ "Badge": "badge",
13
+ "Banner": "banner",
14
+ "BottomSheet": "bottom-sheet",
15
+ "Breadcrumb": "breadcrumb",
16
+ "BreadcrumbItem": "breadcrumb",
17
+ "Button": "button",
18
+ "ButtonLink": "button",
19
+ "Card": "card",
20
+ "Carousel": "carousel",
21
+ "CarouselSlide": "carousel",
22
+ "ChatContainer": "chat-container",
23
+ "ChatInput": "chat-input",
24
+ "ChatMessage": "chat-message",
25
+ "Checkbox": "checkbox",
26
+ "CheckboxCore": "checkbox",
27
+ "Chip": "chip",
28
+ "CodeBlock": "code-block",
29
+ "Collapsible": "collapsible",
30
+ "CollapsibleContent": "collapsible",
31
+ "CollapsibleTrigger": "collapsible",
32
+ "ColorPicker": "color-picker",
33
+ "ColorPickerCore": "color-picker",
34
+ "Combobox": "combobox",
35
+ "Command": "command",
36
+ "CommandInput": "command",
37
+ "CommandItem": "command",
38
+ "CommandList": "command",
39
+ "ConfirmDialog": "confirm-dialog",
40
+ "Container": "container",
41
+ "ContextMenu": "context-menu",
42
+ "ContextMenuContent": "context-menu",
43
+ "ContextMenuItem": "context-menu",
44
+ "ContextMenuSeparator": "context-menu",
45
+ "ContextMenuTrigger": "context-menu",
46
+ "ConversationItem": "conversation-list",
47
+ "ConversationList": "conversation-list",
48
+ "DateRangePicker": "date-range-picker",
49
+ "DateRangePickerCore": "date-range-picker",
50
+ "Datepicker": "datepicker",
51
+ "DatepickerCore": "datepicker",
52
+ "Dialog": "dialog",
53
+ "DiffViewer": "diff-viewer",
54
+ "Disclosure": "disclosure",
55
+ "Divider": "divider",
56
+ "Drawer": "drawer",
57
+ "DropdownMenu": "dropdown-menu",
58
+ "DropdownMenuContent": "dropdown-menu",
59
+ "DropdownMenuItem": "dropdown-menu",
60
+ "DropdownMenuSeparator": "dropdown-menu",
61
+ "DropdownMenuTrigger": "dropdown-menu",
62
+ "Empty": "empty",
63
+ "FileInput": "file-input",
64
+ "Flex": "flex",
65
+ "FormItem": "form",
66
+ "Grid": "grid",
67
+ "GridItem": "grid",
68
+ "Icon": "icon",
69
+ "Image": "image",
70
+ "InlineEdit": "inline-edit",
71
+ "Input": "input",
72
+ "InputCore": "input",
73
+ "List": "list",
74
+ "ListItem": "list",
75
+ "LogViewer": "log-viewer",
76
+ "MarkdownRenderer": "markdown-renderer",
77
+ "Menu": "menu",
78
+ "MenuDivider": "menu",
79
+ "MenuItem": "menu",
80
+ "ModelPicker": "model-picker",
81
+ "NavLink": "navigation-bar",
82
+ "NavigationBar": "navigation-bar",
83
+ "NumberInput": "number-input",
84
+ "NumberInputCore": "number-input",
85
+ "OTPInput": "otp-input",
86
+ "OTPInputCore": "otp-input",
87
+ "Option": "select",
88
+ "Pagination": "pagination",
89
+ "Paragraph": "typography",
90
+ "PasswordInput": "password-input",
91
+ "PasswordInputCore": "password-input",
92
+ "Popover": "popover",
93
+ "Progress": "progress",
94
+ "Radio": "radio",
95
+ "RadioGroup": "radio",
96
+ "RadioGroupCore": "radio",
97
+ "Rating": "rating",
98
+ "RatingCore": "rating",
99
+ "ResizableGroup": "resizable",
100
+ "ResizableHandle": "resizable",
101
+ "ResizablePanel": "resizable",
102
+ "ScrollArea": "scroll-area",
103
+ "Segmented": "segmented",
104
+ "SegmentedCore": "segmented",
105
+ "Select": "select",
106
+ "SelectCore": "select",
107
+ "Skeleton": "skeleton",
108
+ "Slider": "slider",
109
+ "SliderCore": "slider",
110
+ "Spinner": "spinner",
111
+ "Stat": "stat",
112
+ "StatGroup": "stat",
113
+ "Step": "stepper",
114
+ "StepTimeline": "step-timeline",
115
+ "StepTimelineItem": "step-timeline",
116
+ "Stepper": "stepper",
117
+ "StreamingText": "streaming-text",
118
+ "SwipeAction": "swipe-action",
119
+ "Switch": "switch",
120
+ "SwitchCore": "switch",
121
+ "Tab": "tabs",
122
+ "TabList": "tabs",
123
+ "TabPanel": "tabs",
124
+ "Table": "table",
125
+ "TableBody": "table",
126
+ "TableCell": "table",
127
+ "TableHead": "table",
128
+ "TableRow": "table",
129
+ "Tabs": "tabs",
130
+ "Tag": "tag",
131
+ "TagGroup": "tag-group",
132
+ "TagGroupItem": "tag-group",
133
+ "TagInput": "tag-input",
134
+ "TagInputCore": "tag-input",
135
+ "Text": "typography",
136
+ "Textarea": "textarea",
137
+ "TextareaCore": "textarea",
138
+ "ThinkingIndicator": "thinking-indicator",
139
+ "TimePicker": "time-picker",
140
+ "TimePickerCore": "time-picker",
141
+ "Timeline": "timeline",
142
+ "TimelineItem": "timeline",
143
+ "Title": "typography",
144
+ "Toast": "toast",
145
+ "ToastContainer": "toast",
146
+ "TokenCounter": "token-counter",
147
+ "ToolCallCard": "tool-call-card",
148
+ "Tooltip": "tooltip",
149
+ "Transfer": "transfer",
150
+ "TransferCore": "transfer",
151
+ "Tree": "tree",
152
+ "Upload": "upload",
153
+ "UploadCore": "upload",
154
+ "VirtualList": "virtual-list",
155
+ "darkTheme": "tokens",
156
+ "lightTheme": "tokens",
157
+ "spacing": "tokens",
158
+ "typography": "tokens",
159
+ "useToast": "toast"
160
+ },
161
+ "noCss": [
162
+ "COMPONENT_TOKENS",
163
+ "TOKEN_REGISTRY",
164
+ "useControl",
165
+ "useTitle"
166
+ ]
167
+ }
@@ -0,0 +1,12 @@
1
+ import { useEffect as e, useRef as t } from "react";
2
+ //#region src/lib/hooks/useTitle.ts
3
+ function n(n) {
4
+ let r = t(null);
5
+ e(() => {
6
+ r.current === null && (r.current = document.title), document.title = n;
7
+ }, [n]), e(() => () => {
8
+ r.current !== null && (document.title = r.current);
9
+ }, []);
10
+ }
11
+ //#endregion
12
+ export { n as useTitle };
package/dist/index.js CHANGED
@@ -142,6 +142,7 @@ import Kt from "./components/ConversationList/ConversationItem.js";
142
142
  import qt from "./components/DiffViewer/DiffViewer.js";
143
143
  import Jt from "./components/LogViewer/LogViewer.js";
144
144
  import Yt from "./components/AsyncSection/AsyncSection.js";
145
- import Xt from "./form/FormItem.js";
146
- import { useControl as Zt } from "react-use-control";
147
- export { N as Accordion, P as AccordionItem, St as Affix, F as Alert, Ht as ApprovalCard, Dt as AspectRatio, Yt as AsyncSection, I as Avatar, xt as BackToTop, _ as Badge, wt as Banner, jt as BottomSheet, H as Breadcrumb, U as BreadcrumbItem, o as Button, s as ButtonLink, i as COMPONENT_TOKENS, x as Card, ce as Carousel, le as CarouselSlide, Pt as ChatContainer, Ft as ChatInput, Nt as ChatMessage, m as Checkbox, p as CheckboxCore, Xe as Chip, Et as CodeBlock, Ae as Collapsible, je as CollapsibleContent, Me as CollapsibleTrigger, Re as ColorPicker, Le as ColorPickerCore, ne as Combobox, Ce as Command, we as CommandInput, Te as CommandItem, Ee as CommandList, Tt as ConfirmDialog, Ct as Container, mt as ContextMenu, gt as ContextMenuContent, _t as ContextMenuItem, vt as ContextMenuSeparator, ht as ContextMenuTrigger, Kt as ConversationItem, Gt as ConversationList, tt as DateRangePicker, et as DateRangePickerCore, de as Datepicker, ue as DatepickerCore, v as Dialog, qt as DiffViewer, W as Disclosure, pe as Divider, be as Drawer, lt as DropdownMenu, dt as DropdownMenuContent, ft as DropdownMenuItem, pt as DropdownMenuSeparator, ut as DropdownMenuTrigger, he as Empty, X as FileInput, V as Flex, Xt as FormItem, ve as Grid, ye as GridItem, z as Icon, B as Image, ct as InlineEdit, l as Input, c as InputCore, ee as List, te as ListItem, Jt as LogViewer, Lt as MarkdownRenderer, G as Menu, q as MenuDivider, K as MenuItem, Wt as ModelPicker, bt as NavLink, yt as NavigationBar, Y as NumberInput, J as NumberInputCore, rt as OTPInput, nt as OTPInputCore, f as Option, _e as Pagination, Ue as Paragraph, at as PasswordInput, it as PasswordInputCore, b as Popover, ge as Progress, S as Radio, w as RadioGroup, C as RadioGroupCore, Be as Rating, ze as RatingCore, De as ResizableGroup, Oe as ResizableHandle, ke as ResizablePanel, Ze as ScrollArea, Ye as Segmented, Je as SegmentedCore, d as Select, u as SelectCore, R as Skeleton, O as Slider, D as SliderCore, me as Spinner, Ke as Stat, qe as StatGroup, Se as Step, Bt as StepTimeline, Vt as StepTimelineItem, xe as Stepper, It as StreamingText, Mt as SwipeAction, g as Switch, h as SwitchCore, a as TOKEN_REGISTRY, j as Tab, A as TabList, M as TabPanel, re as Table, ae as TableBody, se as TableCell, ie as TableHead, oe as TableRow, k as Tabs, L as Tag, kt as TagGroup, At as TagGroupItem, st as TagInput, ot as TagInputCore, We as Text, E as Textarea, T as TextareaCore, zt as ThinkingIndicator, $e as TimePicker, Qe as TimePickerCore, Ve as Timeline, He as TimelineItem, Ge as Title, Z as Toast, Q as ToastContainer, Ut as TokenCounter, Rt as ToolCallCard, y as Tooltip, Pe as Transfer, Ne as TransferCore, fe as Tree, Ie as Upload, Fe as UploadCore, Ot as VirtualList, e as darkTheme, t as lightTheme, n as spacing, r as typography, Zt as useControl, $ as useToast };
145
+ import { useTitle as Xt } from "./hooks/useTitle.js";
146
+ import Zt from "./form/FormItem.js";
147
+ import { useControl as Qt } from "react-use-control";
148
+ export { N as Accordion, P as AccordionItem, St as Affix, F as Alert, Ht as ApprovalCard, Dt as AspectRatio, Yt as AsyncSection, I as Avatar, xt as BackToTop, _ as Badge, wt as Banner, jt as BottomSheet, H as Breadcrumb, U as BreadcrumbItem, o as Button, s as ButtonLink, i as COMPONENT_TOKENS, x as Card, ce as Carousel, le as CarouselSlide, Pt as ChatContainer, Ft as ChatInput, Nt as ChatMessage, m as Checkbox, p as CheckboxCore, Xe as Chip, Et as CodeBlock, Ae as Collapsible, je as CollapsibleContent, Me as CollapsibleTrigger, Re as ColorPicker, Le as ColorPickerCore, ne as Combobox, Ce as Command, we as CommandInput, Te as CommandItem, Ee as CommandList, Tt as ConfirmDialog, Ct as Container, mt as ContextMenu, gt as ContextMenuContent, _t as ContextMenuItem, vt as ContextMenuSeparator, ht as ContextMenuTrigger, Kt as ConversationItem, Gt as ConversationList, tt as DateRangePicker, et as DateRangePickerCore, de as Datepicker, ue as DatepickerCore, v as Dialog, qt as DiffViewer, W as Disclosure, pe as Divider, be as Drawer, lt as DropdownMenu, dt as DropdownMenuContent, ft as DropdownMenuItem, pt as DropdownMenuSeparator, ut as DropdownMenuTrigger, he as Empty, X as FileInput, V as Flex, Zt as FormItem, ve as Grid, ye as GridItem, z as Icon, B as Image, ct as InlineEdit, l as Input, c as InputCore, ee as List, te as ListItem, Jt as LogViewer, Lt as MarkdownRenderer, G as Menu, q as MenuDivider, K as MenuItem, Wt as ModelPicker, bt as NavLink, yt as NavigationBar, Y as NumberInput, J as NumberInputCore, rt as OTPInput, nt as OTPInputCore, f as Option, _e as Pagination, Ue as Paragraph, at as PasswordInput, it as PasswordInputCore, b as Popover, ge as Progress, S as Radio, w as RadioGroup, C as RadioGroupCore, Be as Rating, ze as RatingCore, De as ResizableGroup, Oe as ResizableHandle, ke as ResizablePanel, Ze as ScrollArea, Ye as Segmented, Je as SegmentedCore, d as Select, u as SelectCore, R as Skeleton, O as Slider, D as SliderCore, me as Spinner, Ke as Stat, qe as StatGroup, Se as Step, Bt as StepTimeline, Vt as StepTimelineItem, xe as Stepper, It as StreamingText, Mt as SwipeAction, g as Switch, h as SwitchCore, a as TOKEN_REGISTRY, j as Tab, A as TabList, M as TabPanel, re as Table, ae as TableBody, se as TableCell, ie as TableHead, oe as TableRow, k as Tabs, L as Tag, kt as TagGroup, At as TagGroupItem, st as TagInput, ot as TagInputCore, We as Text, E as Textarea, T as TextareaCore, zt as ThinkingIndicator, $e as TimePicker, Qe as TimePickerCore, Ve as Timeline, He as TimelineItem, Ge as Title, Z as Toast, Q as ToastContainer, Ut as TokenCounter, Rt as ToolCallCard, y as Tooltip, Pe as Transfer, Ne as TransferCore, fe as Tree, Ie as Upload, Fe as UploadCore, Ot as VirtualList, e as darkTheme, t as lightTheme, n as spacing, r as typography, Qt as useControl, Xt as useTitle, $ as useToast };
@@ -0,0 +1 @@
1
+ export { useTitle } from './useTitle';
@@ -0,0 +1 @@
1
+ export declare function useTitle(title: string): void;
@@ -183,6 +183,7 @@ export { LogViewer } from './components/LogViewer';
183
183
  export type { LogViewerProps, LogEntry, LogLevel } from './components/LogViewer';
184
184
  export { AsyncSection } from './components/AsyncSection';
185
185
  export type { AsyncSectionProps } from './components/AsyncSection';
186
+ export { useTitle } from './hooks';
186
187
  export { FormItem } from './form';
187
188
  export type { FieldValidator, FormItemAsProps, FormItemBinding, FormItemOwnProps, FormItemProps, FormItemRawElement, FormItemRawElementBinding, FormInstance, PathValueOf, } from './form';
188
189
  export { useControl } from 'react-use-control';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haze-ui",
3
- "version": "1.20.0",
3
+ "version": "1.22.0",
4
4
  "type": "module",
5
5
  "description": "A React UI component library powered by react-use-control and Linaria",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,8 @@
28
28
  "default": "./dist/tokens/index.js"
29
29
  },
30
30
  "./styles.css": "./dist/haze-ui.css",
31
- "./css/*": "./dist/css/*"
31
+ "./css/*": "./dist/css/*",
32
+ "./css-manifest.json": "./dist/css-manifest.json"
32
33
  },
33
34
  "files": [
34
35
  "dist"