haze-ui 1.19.1 → 1.21.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 +41 -0
- package/dist/components/AsyncSection/AsyncSection.js +62 -0
- package/dist/components/AsyncSection/index.js +2 -0
- package/dist/css/async-section.css +2 -0
- package/dist/haze-ui.css +1 -0
- package/dist/hooks/useTitle.js +12 -0
- package/dist/index.js +5 -3
- package/dist/types/components/AsyncSection/AsyncSection.d.ts +22 -0
- package/dist/types/components/AsyncSection/index.d.ts +2 -0
- package/dist/types/hooks/index.d.ts +1 -0
- package/dist/types/hooks/useTitle.d.ts +1 -0
- package/dist/types/index.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,6 +85,47 @@ Both components share one skin (a styles module), so a theme tweak to
|
|
|
85
85
|
`Button` re-skins `ButtonLink` in lockstep. CSS: `haze-ui/css/button.css`
|
|
86
86
|
covers both.
|
|
87
87
|
|
|
88
|
+
## AsyncSection: loading / error / content in one place
|
|
89
|
+
|
|
90
|
+
`AsyncSection` collapses the three states every async view hand-rolls into
|
|
91
|
+
one component: `loading` renders the spinner placeholder, a non-null
|
|
92
|
+
`error` renders an alert box with an optional `Retry` button (an `Error`
|
|
93
|
+
instance contributes its `message`; `errorText` overrides), and otherwise
|
|
94
|
+
the children render. `loading` wins when both are set — the retry path
|
|
95
|
+
(loading again before the old error clears) shows the placeholder, not
|
|
96
|
+
the stale error. All copy is configurable; the retry button only renders
|
|
97
|
+
when `onRetry` is provided.
|
|
98
|
+
|
|
99
|
+
```jsx
|
|
100
|
+
import 'haze-ui/css/tokens.css';
|
|
101
|
+
import 'haze-ui/css/async-section.css';
|
|
102
|
+
import { AsyncSection } from 'haze-ui';
|
|
103
|
+
|
|
104
|
+
<AsyncSection loading={loading} error={error} onRetry={refetch}>
|
|
105
|
+
{data}
|
|
106
|
+
</AsyncSection>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## useTitle: view-level document.title
|
|
110
|
+
|
|
111
|
+
`useTitle(title)` sets `document.title` while the view is mounted and
|
|
112
|
+
restores the pre-entry title (the static `<title>` from the host page) on
|
|
113
|
+
unmount. Two timing pitfalls are baked into the implementation: the write
|
|
114
|
+
and the restore are two separate effects (a single `[title]` effect would
|
|
115
|
+
restore the *previous round's* title, not the entry default, on every prop
|
|
116
|
+
change), and the entry snapshot is taken at effect time, not render time —
|
|
117
|
+
a route swap is one commit, so at render time the old view's cleanup has
|
|
118
|
+
not run yet and `document.title` still holds the previous page.
|
|
119
|
+
|
|
120
|
+
```jsx
|
|
121
|
+
import { useTitle } from 'haze-ui';
|
|
122
|
+
|
|
123
|
+
function SettingsView() {
|
|
124
|
+
useTitle('Settings');
|
|
125
|
+
// ...
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
88
129
|
## react-f0rm Integration
|
|
89
130
|
|
|
90
131
|
react-f0rm owns form field state, and its headless `useField` hook is
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
import { classnames as e } from "../../utils/classnames.js";
|
|
3
|
+
/* empty css */
|
|
4
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
5
|
+
//#region src/lib/components/AsyncSection/AsyncSection.tsx
|
|
6
|
+
var r = "haze-AsyncSection__base", i = "haze-AsyncSection__placeholder", a = "haze-AsyncSection__spin", o = "haze-AsyncSection__errorBox", s = "haze-AsyncSection__errorMessage", c = "haze-AsyncSection__retryButton";
|
|
7
|
+
function l({ loading: l = !1, error: u, onRetry: d, loadingText: f = "Loading…", errorText: p, retryText: m = "Retry", className: h, children: g }) {
|
|
8
|
+
if (l) return /* @__PURE__ */ t("section", {
|
|
9
|
+
"aria-busy": "true",
|
|
10
|
+
className: e([r, h]),
|
|
11
|
+
children: n("div", {
|
|
12
|
+
role: "status",
|
|
13
|
+
className: e([i]),
|
|
14
|
+
children: [/* @__PURE__ */ t("span", {
|
|
15
|
+
"aria-hidden": "true",
|
|
16
|
+
className: e([a]),
|
|
17
|
+
children: /* @__PURE__ */ n("svg", {
|
|
18
|
+
viewBox: "0 0 24 24",
|
|
19
|
+
fill: "none",
|
|
20
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
21
|
+
children: [/* @__PURE__ */ t("circle", {
|
|
22
|
+
cx: "12",
|
|
23
|
+
cy: "12",
|
|
24
|
+
r: "10",
|
|
25
|
+
stroke: "var(--haze-color-border)",
|
|
26
|
+
strokeWidth: "3"
|
|
27
|
+
}), /* @__PURE__ */ t("path", {
|
|
28
|
+
d: "M12 2a10 10 0 0 1 10 10",
|
|
29
|
+
stroke: "var(--haze-color-primary)",
|
|
30
|
+
strokeWidth: "3",
|
|
31
|
+
strokeLinecap: "round"
|
|
32
|
+
})]
|
|
33
|
+
})
|
|
34
|
+
}), f]
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
if (u != null) {
|
|
38
|
+
let i = p ?? (u instanceof Error && u.message ? u.message : void 0) ?? "Something went wrong";
|
|
39
|
+
return /* @__PURE__ */ t("section", {
|
|
40
|
+
className: e([r, h]),
|
|
41
|
+
children: n("div", {
|
|
42
|
+
role: "alert",
|
|
43
|
+
className: e([o]),
|
|
44
|
+
children: [/* @__PURE__ */ t("p", {
|
|
45
|
+
className: e([s]),
|
|
46
|
+
children: i
|
|
47
|
+
}), d && /* @__PURE__ */ t("button", {
|
|
48
|
+
type: "button",
|
|
49
|
+
onClick: d,
|
|
50
|
+
className: e([c]),
|
|
51
|
+
children: m
|
|
52
|
+
})]
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return /* @__PURE__ */ t("section", {
|
|
57
|
+
className: e([r, h]),
|
|
58
|
+
children: g
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { l as default };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/* haze-ui async-section — generated by scripts/split-css.mjs, do not edit */
|
|
2
|
+
.haze-AsyncSection__base{font-family:var(--haze-font-sans);color:var(--haze-color-text)}.haze-AsyncSection__placeholder{align-items:center;gap:var(--haze-space-3);padding:var(--haze-space-8) var(--haze-space-4);color:var(--haze-color-text-muted);font-size:var(--haze-text-sm);flex-direction:column;display:flex}.haze-AsyncSection__spin{width:24px;height:24px;animation:.8s linear infinite spin-haze-AsyncSection__spin;display:inline-flex}@keyframes spin-haze-AsyncSection__spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.haze-AsyncSection__errorBox{-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;gap:var(--haze-space-4);padding:var(--haze-space-3) var(--haze-space-4);border-radius:var(--haze-radius-md);background:color-mix(in srgb, var(--haze-color-danger) 10%, transparent);border:1px solid color-mix(in srgb, var(--haze-color-danger) 25%, transparent);font-size:var(--haze-text-sm);line-height:var(--haze-leading-normal);flex-direction:column;display:flex}.haze-AsyncSection__errorMessage{color:var(--haze-color-danger);margin:0}.haze-AsyncSection__retryButton{align-items:center;gap:var(--haze-space-2);padding:var(--haze-space-1) var(--haze-space-3);border:1px solid var(--haze-color-border);border-radius:var(--haze-radius-md);color:var(--haze-color-text);font-family:var(--haze-font-sans);font-size:var(--haze-text-sm);font-weight:var(--haze-weight-medium);line-height:var(--haze-leading-tight);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;transition:background .15s,border-color .15s;display:inline-flex}.haze-AsyncSection__retryButton:hover{border-color:var(--haze-color-border-hover);background:var(--haze-color-bg-subtle)}.haze-AsyncSection__retryButton:focus-visible{box-shadow:0 0 0 3px var(--haze-color-focus-ring);outline:none}
|
package/dist/haze-ui.css
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
.haze-Alert__base{-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;gap:var(--haze-space-3);padding:var(--haze-space-3) var(--haze-space-4);border-radius:var(--haze-radius-md);font-family:var(--haze-font-sans);font-size:var(--haze-text-sm);line-height:var(--haze-leading-normal);display:flex}.haze-Alert__info{background:color-mix(in srgb, var(--haze-color-info) 10%, transparent);color:var(--haze-color-info);border:1px solid color-mix(in srgb, var(--haze-color-info) 25%, transparent)}.haze-Alert__success{background:color-mix(in srgb, var(--haze-color-success) 10%, transparent);color:var(--haze-color-success);border:1px solid color-mix(in srgb, var(--haze-color-success) 25%, transparent)}.haze-Alert__warning{background:color-mix(in srgb, var(--haze-color-warning) 10%, transparent);color:var(--haze-color-warning);border:1px solid color-mix(in srgb, var(--haze-color-warning) 25%, transparent)}.haze-Alert__danger{background:color-mix(in srgb, var(--haze-color-danger) 10%, transparent);color:var(--haze-color-danger);border:1px solid color-mix(in srgb, var(--haze-color-danger) 25%, transparent)}.haze-Alert__contentStyle{flex:1}.haze-Alert__closeBtn{appearance:none;color:inherit;cursor:pointer;font-size:var(--haze-text-lg);opacity:.6;background:0 0;border:none;padding:0;line-height:1;transition:opacity .15s}.haze-Alert__closeBtn:hover{opacity:1}.haze-Alert__closeBtn:focus-visible{box-shadow:0 0 0 3px var(--haze-color-focus-ring);border-radius:var(--haze-radius-sm);outline:none}
|
|
8
8
|
.haze-ApprovalCard__card{border:1px solid var(--haze-color-warning,#eab308);border-radius:var(--haze-radius-md);font-family:var(--haze-font-sans);background:var(--haze-color-bg);overflow:hidden}.haze-ApprovalCard__header{padding:var(--haze-space-3) var(--haze-space-4);background:var(--haze-color-warning-light,#fef9c3);font-size:var(--haze-text-sm);font-weight:var(--haze-weight-medium);color:var(--haze-color-text)}.haze-ApprovalCard__body{padding:var(--haze-space-3) var(--haze-space-4)}.haze-ApprovalCard__desc{font-size:var(--haze-text-sm);color:var(--haze-color-text-muted);margin-bottom:var(--haze-space-3)}.haze-ApprovalCard__content{margin-bottom:var(--haze-space-3)}.haze-ApprovalCard__actions{gap:var(--haze-space-2);padding:var(--haze-space-3) var(--haze-space-4);border-top:1px solid var(--haze-color-border);display:flex}.haze-ApprovalCard__btn{padding:var(--haze-space-2) var(--haze-space-4);border-radius:var(--haze-radius-md);font-size:var(--haze-text-sm);font-family:var(--haze-font-sans);font-weight:var(--haze-weight-medium);cursor:pointer;flex:1;transition:background .15s}.haze-ApprovalCard__denyBtn{background:var(--haze-color-bg);border:1px solid var(--haze-color-border);color:var(--haze-color-text)}.haze-ApprovalCard__denyBtn:hover{background:var(--haze-color-muted)}.haze-ApprovalCard__approveBtn{background:var(--haze-color-primary);border:1px solid var(--haze-color-primary);color:var(--haze-color-bg)}.haze-ApprovalCard__approveBtn:hover{opacity:.9}
|
|
9
9
|
.haze-AspectRatio__wrapper{width:100%;position:relative}.haze-AspectRatio__inner{justify-content:center;align-items:center;display:flex;position:absolute;inset:0;overflow:hidden}
|
|
10
|
+
.haze-AsyncSection__base{font-family:var(--haze-font-sans);color:var(--haze-color-text)}.haze-AsyncSection__placeholder{align-items:center;gap:var(--haze-space-3);padding:var(--haze-space-8) var(--haze-space-4);color:var(--haze-color-text-muted);font-size:var(--haze-text-sm);flex-direction:column;display:flex}.haze-AsyncSection__spin{width:24px;height:24px;animation:.8s linear infinite spin-haze-AsyncSection__spin;display:inline-flex}@keyframes spin-haze-AsyncSection__spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.haze-AsyncSection__errorBox{-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;gap:var(--haze-space-4);padding:var(--haze-space-3) var(--haze-space-4);border-radius:var(--haze-radius-md);background:color-mix(in srgb, var(--haze-color-danger) 10%, transparent);border:1px solid color-mix(in srgb, var(--haze-color-danger) 25%, transparent);font-size:var(--haze-text-sm);line-height:var(--haze-leading-normal);flex-direction:column;display:flex}.haze-AsyncSection__errorMessage{color:var(--haze-color-danger);margin:0}.haze-AsyncSection__retryButton{align-items:center;gap:var(--haze-space-2);padding:var(--haze-space-1) var(--haze-space-3);border:1px solid var(--haze-color-border);border-radius:var(--haze-radius-md);color:var(--haze-color-text);font-family:var(--haze-font-sans);font-size:var(--haze-text-sm);font-weight:var(--haze-weight-medium);line-height:var(--haze-leading-tight);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;transition:background .15s,border-color .15s;display:inline-flex}.haze-AsyncSection__retryButton:hover{border-color:var(--haze-color-border-hover);background:var(--haze-color-bg-subtle)}.haze-AsyncSection__retryButton:focus-visible{box-shadow:0 0 0 3px var(--haze-color-focus-ring);outline:none}
|
|
10
11
|
.haze-Avatar__base{border-radius:var(--haze-radius-full);background:var(--haze-color-bg-muted);color:var(--haze-color-text-secondary);font-family:var(--haze-font-sans);font-weight:var(--haze-weight-medium);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;overflow:hidden}.haze-Avatar__sm{width:32px;height:32px;font-size:var(--haze-text-xs)}.haze-Avatar__md{width:40px;height:40px;font-size:var(--haze-text-sm)}.haze-Avatar__lg{width:56px;height:56px;font-size:var(--haze-text-lg)}.haze-Avatar__imgStyle{object-fit:cover;width:100%;height:100%}
|
|
11
12
|
.haze-BackToTop__button{bottom:calc(var(--haze-space-6) + env(safe-area-inset-bottom));right:calc(var(--haze-space-6) + env(safe-area-inset-right));border-radius:var(--haze-radius-full);background:var(--haze-color-primary);width:2.5rem;height:2.5rem;color:var(--haze-color-bg);cursor:pointer;box-shadow:var(--haze-shadow-lg);font-size:var(--haze-text-lg);-webkit-transition:opacity .2s,-webkit-transform .2s;border:none;justify-content:center;align-items:center;transition:opacity .2s,transform .2s;display:flex;position:fixed}.haze-BackToTop__button:hover{transform:translateY(-2px)}.haze-BackToTop__hidden{opacity:0;pointer-events:none;transform:translateY(1rem)}
|
|
12
13
|
.haze-Badge__base{border-radius:var(--haze-radius-full);font-family:var(--haze-font-sans);font-weight:var(--haze-weight-medium);line-height:var(--haze-leading-tight);white-space:nowrap;align-items:center;display:inline-flex}.haze-Badge__default{background:var(--haze-color-bg-muted);color:var(--haze-color-text-secondary)}.haze-Badge__success{background:color-mix(in srgb, var(--haze-color-success) 15%, transparent);color:var(--haze-color-success)}.haze-Badge__warning{background:color-mix(in srgb, var(--haze-color-warning) 15%, transparent);color:var(--haze-color-warning)}.haze-Badge__danger{background:color-mix(in srgb, var(--haze-color-danger) 15%, transparent);color:var(--haze-color-danger)}.haze-Badge__info{background:color-mix(in srgb, var(--haze-color-info) 15%, transparent);color:var(--haze-color-info)}.haze-Badge__sm{padding:var(--haze-space-0) var(--haze-space-2);font-size:var(--haze-text-xs)}.haze-Badge__md{padding:var(--haze-space-1) var(--haze-space-3);font-size:var(--haze-text-sm)}
|
|
@@ -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
|
@@ -141,6 +141,8 @@ import Gt from "./components/ConversationList/ConversationList.js";
|
|
|
141
141
|
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
|
-
import Yt from "./
|
|
145
|
-
import {
|
|
146
|
-
|
|
144
|
+
import Yt from "./components/AsyncSection/AsyncSection.js";
|
|
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,22 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
type AsyncSectionProps = {
|
|
3
|
+
/**
|
|
4
|
+
* 为真时渲染加载占位(Spinner + loadingText)。优先级最高:错误未
|
|
5
|
+
* 清除时点重试(loading 与 error 同时为真)显示的是加载态。
|
|
6
|
+
*/
|
|
7
|
+
loading?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* 非空值(null/undefined 之外)时渲染错误态(Alert 样式框 + Retry)。
|
|
10
|
+
* Error 实例自动取 message 作为文案,其余值落在通用兜底文案上。
|
|
11
|
+
*/
|
|
12
|
+
error?: unknown;
|
|
13
|
+
/** Retry 按钮回调;不传时不渲染按钮,只显示错误信息。 */
|
|
14
|
+
onRetry?: () => void;
|
|
15
|
+
loadingText?: string;
|
|
16
|
+
errorText?: string;
|
|
17
|
+
retryText?: string;
|
|
18
|
+
className?: string;
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
};
|
|
21
|
+
export default function AsyncSection({ loading, error, onRetry, loadingText, errorText, retryText, className, children, }: AsyncSectionProps): import("react").JSX.Element;
|
|
22
|
+
export type { AsyncSectionProps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useTitle } from './useTitle';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useTitle(title: string): void;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -181,6 +181,9 @@ export { DiffViewer } from './components/DiffViewer';
|
|
|
181
181
|
export type { DiffViewerProps, DiffLine } from './components/DiffViewer';
|
|
182
182
|
export { LogViewer } from './components/LogViewer';
|
|
183
183
|
export type { LogViewerProps, LogEntry, LogLevel } from './components/LogViewer';
|
|
184
|
+
export { AsyncSection } from './components/AsyncSection';
|
|
185
|
+
export type { AsyncSectionProps } from './components/AsyncSection';
|
|
186
|
+
export { useTitle } from './hooks';
|
|
184
187
|
export { FormItem } from './form';
|
|
185
188
|
export type { FieldValidator, FormItemAsProps, FormItemBinding, FormItemOwnProps, FormItemProps, FormItemRawElement, FormItemRawElementBinding, FormInstance, PathValueOf, } from './form';
|
|
186
189
|
export { useControl } from 'react-use-control';
|