@dsh-workbench/shared 0.3.4 → 0.3.6
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/dist/api/blocker-table.d.ts +13 -0
- package/dist/api/blocker-table.js +13 -0
- package/dist/api/blocker.d.ts +6 -0
- package/dist/api/context-ref.d.ts +31 -0
- package/dist/api/context-ref.js +28 -0
- package/dist/api/dsh-client.d.ts +99 -0
- package/dist/api/dsh.d.ts +55 -3
- package/dist/api/facts.d.ts +42 -0
- package/dist/api/facts.js +33 -0
- package/dist/api/host-write.d.ts +18 -0
- package/dist/api/host-write.js +12 -0
- package/dist/api/long-task.d.ts +66 -1
- package/dist/api/long-task.js +59 -0
- package/dist/api/unit-board.d.ts +25 -0
- package/dist/api/unit-board.js +16 -0
- package/dist/api/unit-declaration.d.ts +36 -0
- package/dist/api/unit-declaration.js +24 -0
- package/dist/api/unit.d.ts +32 -0
- package/dist/api/unit.js +5 -0
- package/dist/api/workbench-client.d.ts +25 -0
- package/dist/api/workbench-client.js +13 -0
- package/dist/api/workbench-contract.d.ts +12 -0
- package/dist/components/Activity.d.ts +33 -0
- package/dist/components/Activity.js +24 -0
- package/dist/components/ApprovalDetail.d.ts +12 -0
- package/dist/components/ApprovalDetail.js +9 -0
- package/dist/components/ApprovalPlan.d.ts +14 -0
- package/dist/components/ApprovalPlan.js +8 -0
- package/dist/components/Card.d.ts +13 -0
- package/dist/components/Card.js +10 -0
- package/dist/components/CardAnchor.d.ts +14 -0
- package/dist/components/CardAnchor.js +11 -0
- package/dist/components/CardBoundary.d.ts +20 -0
- package/dist/components/CardBoundary.js +14 -0
- package/dist/components/CardHead.d.ts +13 -0
- package/dist/components/CardHead.js +10 -0
- package/dist/components/ChoiceGroup.d.ts +24 -0
- package/dist/components/ChoiceGroup.js +12 -0
- package/dist/components/Field.d.ts +10 -0
- package/dist/components/Field.js +7 -0
- package/dist/components/Form.css +6 -0
- package/dist/components/Form.d.ts +20 -0
- package/dist/components/Form.js +58 -0
- package/dist/components/FormActions.d.ts +14 -0
- package/dist/components/FormActions.js +5 -0
- package/dist/components/FormNodes.d.ts +103 -0
- package/dist/components/FormNodes.js +153 -0
- package/dist/components/FormRows.css +31 -0
- package/dist/components/FormRows.d.ts +20 -0
- package/dist/components/FormRows.js +14 -0
- package/dist/components/FormTypes.d.ts +59 -0
- package/dist/components/FormTypes.js +1 -0
- package/dist/components/Link.d.ts +12 -0
- package/dist/components/Link.js +9 -0
- package/dist/components/LongTaskRow.css +52 -0
- package/dist/components/LongTaskRow.d.ts +35 -0
- package/dist/components/LongTaskRow.js +45 -4
- package/dist/components/Note.d.ts +11 -0
- package/dist/components/Note.js +8 -0
- package/dist/components/ResourceStates.d.ts +25 -0
- package/dist/components/ResourceStates.js +22 -0
- package/dist/components/Rows.d.ts +17 -0
- package/dist/components/Rows.js +11 -0
- package/dist/components/SaveBar.d.ts +12 -0
- package/dist/components/SaveBar.js +9 -0
- package/dist/components/SelectField.d.ts +26 -0
- package/dist/components/SelectField.js +22 -0
- package/dist/components/SelectFieldNodes.d.ts +24 -0
- package/dist/components/SelectFieldNodes.js +24 -0
- package/dist/components/SettingsSection.d.ts +11 -0
- package/dist/components/SettingsSection.js +8 -0
- package/dist/components/Spinner.d.ts +9 -0
- package/dist/components/Spinner.js +6 -0
- package/dist/components/Stack.d.ts +8 -0
- package/dist/components/Stack.js +5 -0
- package/dist/components/StateBlock.d.ts +13 -0
- package/dist/components/StateBlock.js +10 -0
- package/dist/components/TextField.d.ts +8 -0
- package/dist/components/TextField.js +5 -0
- package/dist/components/board-module.d.ts +30 -0
- package/dist/components/icons.d.ts +38 -0
- package/dist/components/icons.js +35 -0
- package/dist/config/constants.d.ts +42 -0
- package/dist/config/constants.js +42 -0
- package/dist/config/storage.d.ts +4 -0
- package/dist/config/storage.js +4 -0
- package/dist/host/long-task.d.ts +7 -0
- package/dist/host/long-task.js +31 -5
- package/dist/host/tool-approval.d.ts +1 -0
- package/dist/host/unit-face.d.ts +6 -1
- package/dist/i18n/en.d.ts +1 -0
- package/dist/i18n/en.js +10 -8
- package/dist/i18n/index.d.ts +13 -9
- package/dist/i18n/index.js +1 -0
- package/dist/i18n/merge.d.ts +5 -0
- package/dist/i18n/merge.js +2 -0
- package/dist/i18n/zh.d.ts +11 -8
- package/dist/i18n/zh.js +10 -8
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/lib/blocker-action.d.ts +22 -0
- package/dist/lib/blocker-action.js +13 -0
- package/dist/lib/board-fact.d.ts +27 -0
- package/dist/lib/board-fact.js +18 -0
- package/dist/lib/busy.d.ts +10 -0
- package/dist/lib/busy.js +7 -0
- package/dist/lib/diy-debug.d.ts +42 -2
- package/dist/lib/diy-debug.js +19 -1
- package/dist/lib/diy-record.d.ts +41 -0
- package/dist/lib/diy-record.js +17 -0
- package/dist/lib/form-problem.d.ts +10 -0
- package/dist/lib/form-problem.js +10 -0
- package/dist/lib/panel-state.d.ts +60 -0
- package/dist/lib/panel-state.js +30 -0
- package/dist/lib/react.d.ts +39 -0
- package/dist/lib/react.js +36 -0
- package/dist/lib/text.d.ts +22 -0
- package/dist/lib/text.js +22 -0
- package/dist/lib/ui.d.ts +50 -0
- package/dist/lib/ui.js +41 -0
- package/package.json +1 -1
- package/src/api/__tests__/long-task.test.ts +41 -1
- package/src/api/blocker-table.ts +13 -0
- package/src/api/blocker.ts +6 -0
- package/src/api/context-ref.ts +31 -0
- package/src/api/dsh-client.ts +99 -0
- package/src/api/dsh.ts +56 -1
- package/src/api/facts.ts +42 -0
- package/src/api/host-write.ts +18 -0
- package/src/api/long-task.ts +79 -1
- package/src/api/unit-board.ts +25 -0
- package/src/api/unit-declaration.ts +36 -0
- package/src/api/unit.ts +32 -0
- package/src/api/workbench-client.ts +25 -0
- package/src/api/workbench-contract.ts +12 -0
- package/src/components/Activity.tsx +33 -0
- package/src/components/ApprovalDetail.tsx +12 -0
- package/src/components/ApprovalPlan.tsx +14 -0
- package/src/components/Card.tsx +13 -0
- package/src/components/CardAnchor.tsx +14 -0
- package/src/components/CardBoundary.tsx +20 -0
- package/src/components/CardHead.tsx +13 -0
- package/src/components/ChoiceGroup.tsx +24 -0
- package/src/components/Field.tsx +10 -0
- package/src/components/Form.css +6 -0
- package/src/components/Form.test.tsx +475 -0
- package/src/components/Form.tsx +78 -0
- package/src/components/FormActions.tsx +14 -0
- package/src/components/FormNodes.tsx +193 -0
- package/src/components/FormRows.css +31 -0
- package/src/components/FormRows.test.tsx +71 -1
- package/src/components/FormRows.tsx +20 -0
- package/src/components/FormTypes.ts +65 -0
- package/src/components/FormWiring.test.tsx +88 -0
- package/src/components/Link.tsx +12 -0
- package/src/components/LongTaskRow.css +52 -0
- package/src/components/LongTaskRow.tsx +76 -2
- package/src/components/Note.tsx +11 -0
- package/src/components/ResourceStates.tsx +25 -0
- package/src/components/Rows.tsx +17 -0
- package/src/components/SaveBar.tsx +12 -0
- package/src/components/SelectField.tsx +26 -0
- package/src/components/SelectFieldNodes.tsx +24 -0
- package/src/components/SettingsSection.tsx +11 -0
- package/src/components/Spinner.tsx +9 -0
- package/src/components/Stack.tsx +8 -0
- package/src/components/StateBlock.tsx +13 -0
- package/src/components/TextField.tsx +8 -0
- package/src/components/__tests__/long-task-row.test.ts +115 -0
- package/src/components/board-module.ts +30 -0
- package/src/components/icons.tsx +38 -0
- package/src/config/constants.ts +43 -0
- package/src/config/storage.ts +4 -0
- package/src/host/__tests__/long-task.test.ts +264 -0
- package/src/host/long-task.ts +43 -7
- package/src/host/tool-approval.ts +1 -0
- package/src/host/unit-face.ts +7 -1
- package/src/i18n/en.ts +11 -8
- package/src/i18n/index.ts +3 -0
- package/src/i18n/merge.ts +5 -0
- package/src/i18n/zh.ts +11 -8
- package/src/index.ts +6 -2
- package/src/lib/blocker-action.ts +22 -0
- package/src/lib/board-fact.ts +27 -0
- package/src/lib/busy.ts +10 -0
- package/src/lib/diy-debug.test.ts +2 -1
- package/src/lib/diy-debug.ts +44 -3
- package/src/lib/diy-record.ts +41 -0
- package/src/lib/form-problem.ts +10 -0
- package/src/lib/panel-state.ts +60 -0
- package/src/lib/react.ts +39 -0
- package/src/lib/text.ts +22 -0
- package/src/lib/ui.ts +50 -0
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import type { ReactNode } from '../lib/react.js';
|
|
2
2
|
import './Note.css';
|
|
3
|
+
/**
|
|
4
|
+
* `Note` 的契约:语气、标签名与读屏角色。
|
|
5
|
+
*/
|
|
3
6
|
export interface NoteProps {
|
|
4
7
|
readonly tone?: 'muted' | 'problem';
|
|
5
8
|
readonly as?: 'p' | 'span';
|
|
6
9
|
readonly role?: 'alert' | 'status';
|
|
7
10
|
readonly children?: ReactNode | undefined;
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 一句话说明或一句报错:卡片里的提示条用它,不承载交互。
|
|
14
|
+
* @param props.tone - `problem` 是报错色;默认 `muted`,普通说明色。
|
|
15
|
+
* @param props.as - `span` 是跟在别的行里,`p`(默认)独占一段。
|
|
16
|
+
* @param props.role - 读屏角色:变化中的提示给 `status`、报错给 `alert`;不给不设。
|
|
17
|
+
* @param props.children - 那句话本身。
|
|
18
|
+
* @returns 一个 `span` 或 `p`。
|
|
19
|
+
*/
|
|
9
20
|
export declare function Note({ tone, as, role, children }: NoteProps): JSX.Element;
|
package/dist/components/Note.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import './Note.css';
|
|
3
|
+
/**
|
|
4
|
+
* 一句话说明或一句报错:卡片里的提示条用它,不承载交互。
|
|
5
|
+
* @param props.tone - `problem` 是报错色;默认 `muted`,普通说明色。
|
|
6
|
+
* @param props.as - `span` 是跟在别的行里,`p`(默认)独占一段。
|
|
7
|
+
* @param props.role - 读屏角色:变化中的提示给 `status`、报错给 `alert`;不给不设。
|
|
8
|
+
* @param props.children - 那句话本身。
|
|
9
|
+
* @returns 一个 `span` 或 `p`。
|
|
10
|
+
*/
|
|
3
11
|
export function Note({ tone = 'muted', as, role, children }) {
|
|
4
12
|
const className = tone === 'problem' ? 'wb-problem' : 'wb-note';
|
|
5
13
|
return as === 'span' ? (h("span", { className: className, role: role }, children)) : (h("p", { className: className, role: role }, children));
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import './ResourceStates.css';
|
|
3
|
+
/**
|
|
4
|
+
* 骨架屏:读数期间已经知道大概形状时用它(连形状都不知道就用 `CenteredState` 那句"正在读")。
|
|
5
|
+
* @param props.rows - 画几行骨架(默认 4);整块 `aria-hidden`,不读给读屏。
|
|
6
|
+
* @returns 一叠占位条。
|
|
7
|
+
*/
|
|
3
8
|
export declare function SkeletonRows({ rows }: {
|
|
4
9
|
rows?: number;
|
|
5
10
|
}): JSX.Element;
|
|
11
|
+
/**
|
|
12
|
+
* `CenteredState` 的契约:图标、标题、说明、明细与动作。
|
|
13
|
+
*/
|
|
6
14
|
export interface CenteredStateProps {
|
|
7
15
|
icon: ReactNode;
|
|
8
16
|
title: ReactNode;
|
|
@@ -11,7 +19,24 @@ export interface CenteredStateProps {
|
|
|
11
19
|
action?: ReactNode;
|
|
12
20
|
compact?: boolean;
|
|
13
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* 居中一屏:要他先选一个 / 正在读 / 读不到时用它占住卡片版面。
|
|
24
|
+
* @param props.icon - 标题上方那枚图标;给 `null` 就只留标题(加载与报错常见)。
|
|
25
|
+
* @param props.title - 正中那行大字。
|
|
26
|
+
* @param props.hint - 标题下的一行说明。
|
|
27
|
+
* @param props.detail - 更细的一行(如原始错误码与那句话);"读不到"时把错误放这里,绝不显示 0。
|
|
28
|
+
* @param props.action - 底部动作(如"重试");不给不画。
|
|
29
|
+
* @param props.compact - 紧凑档(默认 false),卡里空间小的时候给 true。
|
|
30
|
+
* @returns 一个 `role="status"` 的居中块。
|
|
31
|
+
*/
|
|
14
32
|
export declare function CenteredState({ icon, title, hint, detail, action, compact }: CenteredStateProps): JSX.Element;
|
|
33
|
+
/**
|
|
34
|
+
* 就绪但空:它只是 `CenteredState` 的简写,标题就是那句空态文案。
|
|
35
|
+
* @param props.text - 空态那句话。
|
|
36
|
+
* @param props.icon - 标题上方的图标;默认 `null`,不画图标。
|
|
37
|
+
* @param props.compact - 紧凑档,默认 false。
|
|
38
|
+
* @returns 一个居中块。
|
|
39
|
+
*/
|
|
15
40
|
export declare function EmptyState({ text, icon, compact }: {
|
|
16
41
|
text: string;
|
|
17
42
|
icon?: ReactNode;
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import './ResourceStates.css';
|
|
3
|
+
/**
|
|
4
|
+
* 骨架屏:读数期间已经知道大概形状时用它(连形状都不知道就用 `CenteredState` 那句"正在读")。
|
|
5
|
+
* @param props.rows - 画几行骨架(默认 4);整块 `aria-hidden`,不读给读屏。
|
|
6
|
+
* @returns 一叠占位条。
|
|
7
|
+
*/
|
|
3
8
|
export function SkeletonRows({ rows = 4 }) {
|
|
4
9
|
return (h("div", { className: "wb-skeleton", "aria-hidden": "true" }, Array.from({ length: rows }, (_, index) => (h("span", { key: index, className: "wb-skeletonRow" },
|
|
5
10
|
h("span", { className: "wb-skeletonBar wb-skeletonBarTitle" }),
|
|
6
11
|
h("span", { className: "wb-skeletonBar wb-skeletonBarMeta" }))))));
|
|
7
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* 居中一屏:要他先选一个 / 正在读 / 读不到时用它占住卡片版面。
|
|
15
|
+
* @param props.icon - 标题上方那枚图标;给 `null` 就只留标题(加载与报错常见)。
|
|
16
|
+
* @param props.title - 正中那行大字。
|
|
17
|
+
* @param props.hint - 标题下的一行说明。
|
|
18
|
+
* @param props.detail - 更细的一行(如原始错误码与那句话);"读不到"时把错误放这里,绝不显示 0。
|
|
19
|
+
* @param props.action - 底部动作(如"重试");不给不画。
|
|
20
|
+
* @param props.compact - 紧凑档(默认 false),卡里空间小的时候给 true。
|
|
21
|
+
* @returns 一个 `role="status"` 的居中块。
|
|
22
|
+
*/
|
|
8
23
|
export function CenteredState({ icon, title, hint, detail, action, compact = false }) {
|
|
9
24
|
return (h("div", { className: compact ? 'wb-centered wb-centeredCompact' : 'wb-centered', role: "status" },
|
|
10
25
|
icon === null ? null : (h("span", { className: "wb-centeredHero", "aria-hidden": "true" }, icon)),
|
|
@@ -13,6 +28,13 @@ export function CenteredState({ icon, title, hint, detail, action, compact = fal
|
|
|
13
28
|
detail === undefined ? null : h("div", { className: "wb-centeredDetail" }, detail),
|
|
14
29
|
action === undefined ? null : h("div", { className: "wb-centeredAction" }, action)));
|
|
15
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* 就绪但空:它只是 `CenteredState` 的简写,标题就是那句空态文案。
|
|
33
|
+
* @param props.text - 空态那句话。
|
|
34
|
+
* @param props.icon - 标题上方的图标;默认 `null`,不画图标。
|
|
35
|
+
* @param props.compact - 紧凑档,默认 false。
|
|
36
|
+
* @returns 一个居中块。
|
|
37
|
+
*/
|
|
16
38
|
export function EmptyState({ text, icon = null, compact = false }) {
|
|
17
39
|
return h(CenteredState, { icon: icon, title: text, compact: compact });
|
|
18
40
|
}
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import type { ReactNode } from '../lib/react.js';
|
|
2
2
|
import './Rows.css';
|
|
3
|
+
/**
|
|
4
|
+
* `Rows` 的契约:一组键值行的容器。
|
|
5
|
+
*/
|
|
3
6
|
export interface RowsProps {
|
|
4
7
|
readonly children?: ReactNode | undefined;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* 键值行的容器:分隔线、行距与两端对齐在它和 `Row` 里,别自己写 `ul` / `li` 拼。
|
|
11
|
+
* @param props.children - 一串 `Row`。
|
|
12
|
+
* @returns 竖排的 div。
|
|
13
|
+
*/
|
|
6
14
|
export declare function Rows({ children }: RowsProps): JSX.Element;
|
|
15
|
+
/**
|
|
16
|
+
* `Row` 的契约:左边名字 + 右边值。
|
|
17
|
+
*/
|
|
7
18
|
export interface RowProps {
|
|
8
19
|
readonly label: ReactNode;
|
|
9
20
|
readonly value: ReactNode;
|
|
10
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* 一行键值:左边名字、右边值;要成对说明一项数据就用它,别自己写两栏。
|
|
24
|
+
* @param props.label - 左边那格(键)。
|
|
25
|
+
* @param props.value - 右边那格(值),可以是数字、时间或一小段节点。
|
|
26
|
+
* @returns 一行两格。
|
|
27
|
+
*/
|
|
11
28
|
export declare function Row({ label, value }: RowProps): JSX.Element;
|
package/dist/components/Rows.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import './Rows.css';
|
|
3
|
+
/**
|
|
4
|
+
* 键值行的容器:分隔线、行距与两端对齐在它和 `Row` 里,别自己写 `ul` / `li` 拼。
|
|
5
|
+
* @param props.children - 一串 `Row`。
|
|
6
|
+
* @returns 竖排的 div。
|
|
7
|
+
*/
|
|
3
8
|
export function Rows({ children }) {
|
|
4
9
|
return h("div", { className: "wb-rows" }, children);
|
|
5
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* 一行键值:左边名字、右边值;要成对说明一项数据就用它,别自己写两栏。
|
|
13
|
+
* @param props.label - 左边那格(键)。
|
|
14
|
+
* @param props.value - 右边那格(值),可以是数字、时间或一小段节点。
|
|
15
|
+
* @returns 一行两格。
|
|
16
|
+
*/
|
|
6
17
|
export function Row({ label, value }) {
|
|
7
18
|
return (h("div", { className: "wb-row" },
|
|
8
19
|
h("span", { className: "wb-rowKey" }, label),
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SaveBar` 的契约:忙碌态、三句文案与两个回调。
|
|
3
|
+
*/
|
|
1
4
|
export interface SaveBarProps {
|
|
2
5
|
readonly busy: boolean;
|
|
3
6
|
readonly disabled?: boolean | undefined;
|
|
@@ -9,4 +12,13 @@ export interface SaveBarProps {
|
|
|
9
12
|
readonly onCancel: () => void;
|
|
10
13
|
readonly onSave: () => void;
|
|
11
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* 设置面底下那条"取消 / 保存":就是 `FormActions` 的两颗固定动作,顺序与间距不归调用点。
|
|
17
|
+
* @param props.busy - 保存中:两颗钮一起禁用,保存那颗换成 `saving` 文案并带转圈。
|
|
18
|
+
* @param props.disabled - 再额外禁掉保存钮(如没改动可存);默认不禁,取消钮不受它管。
|
|
19
|
+
* @param props.labels - 三句文案:`cancel` / `save` / `saving`。
|
|
20
|
+
* @param props.onCancel - 点取消。
|
|
21
|
+
* @param props.onSave - 点保存。
|
|
22
|
+
* @returns 一组按钮。
|
|
23
|
+
*/
|
|
12
24
|
export declare function SaveBar({ busy, disabled, labels, onCancel, onSave }: SaveBarProps): JSX.Element;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import { FormActions } from './FormActions.js';
|
|
3
|
+
/**
|
|
4
|
+
* 设置面底下那条"取消 / 保存":就是 `FormActions` 的两颗固定动作,顺序与间距不归调用点。
|
|
5
|
+
* @param props.busy - 保存中:两颗钮一起禁用,保存那颗换成 `saving` 文案并带转圈。
|
|
6
|
+
* @param props.disabled - 再额外禁掉保存钮(如没改动可存);默认不禁,取消钮不受它管。
|
|
7
|
+
* @param props.labels - 三句文案:`cancel` / `save` / `saving`。
|
|
8
|
+
* @param props.onCancel - 点取消。
|
|
9
|
+
* @param props.onSave - 点保存。
|
|
10
|
+
* @returns 一组按钮。
|
|
11
|
+
*/
|
|
3
12
|
export function SaveBar({ busy, disabled, labels, onCancel, onSave }) {
|
|
4
13
|
const actions = [
|
|
5
14
|
{ key: 'cancel', label: labels.cancel, kind: 'default', onClick: onCancel, disabled: busy },
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { MenuEntry } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
3
|
import './SelectField.css';
|
|
4
|
+
/** 一个候选项:值、人看的标签,可带搜索词、图标、分组与禁用标记。 */
|
|
4
5
|
export interface SelectFieldOption {
|
|
5
6
|
readonly value: string;
|
|
6
7
|
readonly label: ReactNode;
|
|
@@ -9,14 +10,17 @@ export interface SelectFieldOption {
|
|
|
9
10
|
readonly group?: string | undefined;
|
|
10
11
|
readonly disabled?: boolean | undefined;
|
|
11
12
|
}
|
|
13
|
+
/** 名单读不到时的退路:值 + 变更回调,`SelectField` 会由下拉改成手填输入框。 */
|
|
12
14
|
export interface SelectFieldFallback {
|
|
13
15
|
readonly value: string;
|
|
14
16
|
readonly onChange: (next: string) => void;
|
|
15
17
|
}
|
|
18
|
+
/** 列表底部固定那一条(如"添加工作区"):文案 + 可选图标。 */
|
|
16
19
|
export interface SelectFieldFooter {
|
|
17
20
|
readonly label: ReactNode;
|
|
18
21
|
readonly icon?: ReactNode | undefined;
|
|
19
22
|
}
|
|
23
|
+
/** `SelectField` 的契约:值、候选、变更回调,外加搜索 / 分组 / 加载 / 空态 / 页脚那一整套开关。 */
|
|
20
24
|
export interface SelectFieldProps {
|
|
21
25
|
readonly value: string;
|
|
22
26
|
readonly options: readonly SelectFieldOption[];
|
|
@@ -51,10 +55,32 @@ export interface SelectFieldProps {
|
|
|
51
55
|
readonly className?: string | undefined;
|
|
52
56
|
readonly menuClassName?: string | undefined;
|
|
53
57
|
}
|
|
58
|
+
/** 算候选项用来匹配搜索的文本:有 `searchText` 就用它,否则取字符串标签;标签不是字符串又没给它是空串(这项搜不到)。 */
|
|
54
59
|
export declare function searchTextOf(option: SelectFieldOption): string;
|
|
60
|
+
/** 默认匹配:查询去空白折成小写后看它是不是 `searchTextOf` 的子串;查询为空或纯空白时一律命中(留在列表里)。 */
|
|
55
61
|
export declare function defaultSelectFilter(option: SelectFieldOption, query: string): boolean;
|
|
62
|
+
/** 按查询过滤候选 —— 组件与模块自己算列表都用它,好让同一份口径管两处:`filter` 不给就用 `defaultSelectFilter`,顺序不变。 */
|
|
56
63
|
export declare function filterSelectOptions(options: readonly SelectFieldOption[], query: string, filter?: (option: SelectFieldOption, query: string) => boolean): readonly SelectFieldOption[];
|
|
64
|
+
/** 把键盘游标换算成当前该高亮那项的 value:游标 `null`(还没动过键盘)或列表为空时没有高亮;太大的游标收到最后一项,负游标取不到项也回 `null`。 */
|
|
57
65
|
export declare function selectCursorValue(shown: readonly SelectFieldOption[], cursor: number | null): string | null;
|
|
66
|
+
/** 按上下键移动游标(两头环绕):还没选过时向下取第一项、向上取最后一项;列表为空回 `null`(一步都动不了)。`step` 1 向下、-1 向上。 */
|
|
58
67
|
export declare function stepSelectCursor(shown: readonly SelectFieldOption[], cursor: number | null, step: 1 | -1): number | null;
|
|
68
|
+
/** 把候选排成 `Menu` 要的条目表:按 `group` 插分组标题;一项都没有时退回 `emptyText` 那一行(不给就是空表)。`revealId` 是开列表时要滚进可视区的那个 value。 */
|
|
59
69
|
export declare function selectEntries(shown: readonly SelectFieldOption[], emptyText: string | undefined, revealId?: string | undefined): readonly MenuEntry[];
|
|
70
|
+
/**
|
|
71
|
+
* 下拉选择:默认是跟 `TextField` 一套的常规下拉框(不是原生 `<select>`),无边框那种给 `variant: 'ghost'`。
|
|
72
|
+
* `open` 不给就内部自己管(两种接法下 `onOpenChange` 都会通知),`loading` 把触发器换成转圈 + `loadingText`(默认 `…`),
|
|
73
|
+
* `selection` 选选中行标记(`fill` 整行底色 / `check` 行尾勾),`footer` 是列表底部那一条(点它走 `onFooter`,不改当前值)。
|
|
74
|
+
* @param props.value - 当前值;在 `options` 里找不到就按"没选"画 `placeholder`。
|
|
75
|
+
* @param props.options - 全量候选;空数组且给了 `fallback` 时改画手填输入框。
|
|
76
|
+
* @param props.onChange - 选中一项后的回调,回的是那一项的 `value`。
|
|
77
|
+
* @param props.label - 没进 `FormRow` 时的标签兜底;进了那一行就别再给它和 `hint`,否则会多一个标签。
|
|
78
|
+
* @param props.renderValue - 自己渲染触发器上那份当前值;不给就用候选项的 `label`。
|
|
79
|
+
* @param props.placeholder - 没选中时那句话;不给是 `—`。
|
|
80
|
+
* @param props.search - 是否可搜(默认 true);`false` 时不画搜索框、也不自动聚焦。
|
|
81
|
+
* @param props.filter - 自定义匹配;不给用 `defaultSelectFilter`(空白查询一律命中)。
|
|
82
|
+
* @param props.emptyText - 无匹配时的文案,或按查询生成文案的函数(能说"没有匹配 X 的项")。
|
|
83
|
+
* @param props.fallback - 退路:`options` 为空时改成手填(`value` + `onChange`)。
|
|
84
|
+
* @returns 触发器,以及打开时的搜索框与列表。
|
|
85
|
+
*/
|
|
60
86
|
export declare function SelectField(props: SelectFieldProps): ReactNode;
|
|
@@ -70,25 +70,30 @@ function framed(label, hint, className, control) {
|
|
|
70
70
|
: (h(Field, { label: label, hint: hint }, control));
|
|
71
71
|
return className === undefined ? inner : h("div", { className: className }, inner);
|
|
72
72
|
}
|
|
73
|
+
/** 算候选项用来匹配搜索的文本:有 `searchText` 就用它,否则取字符串标签;标签不是字符串又没给它是空串(这项搜不到)。 */
|
|
73
74
|
export function searchTextOf(option) {
|
|
74
75
|
if (option.searchText !== undefined)
|
|
75
76
|
return option.searchText;
|
|
76
77
|
return typeof option.label === 'string' ? option.label : '';
|
|
77
78
|
}
|
|
79
|
+
/** 默认匹配:查询去空白折成小写后看它是不是 `searchTextOf` 的子串;查询为空或纯空白时一律命中(留在列表里)。 */
|
|
78
80
|
export function defaultSelectFilter(option, query) {
|
|
79
81
|
const needle = query.trim().toLowerCase();
|
|
80
82
|
if (needle === '')
|
|
81
83
|
return true;
|
|
82
84
|
return searchTextOf(option).toLowerCase().includes(needle);
|
|
83
85
|
}
|
|
86
|
+
/** 按查询过滤候选 —— 组件与模块自己算列表都用它,好让同一份口径管两处:`filter` 不给就用 `defaultSelectFilter`,顺序不变。 */
|
|
84
87
|
export function filterSelectOptions(options, query, filter = defaultSelectFilter) {
|
|
85
88
|
return options.filter((option) => filter(option, query));
|
|
86
89
|
}
|
|
90
|
+
/** 把键盘游标换算成当前该高亮那项的 value:游标 `null`(还没动过键盘)或列表为空时没有高亮;太大的游标收到最后一项,负游标取不到项也回 `null`。 */
|
|
87
91
|
export function selectCursorValue(shown, cursor) {
|
|
88
92
|
if (cursor === null || shown.length === 0)
|
|
89
93
|
return null;
|
|
90
94
|
return shown[Math.min(cursor, shown.length - 1)]?.value ?? null;
|
|
91
95
|
}
|
|
96
|
+
/** 按上下键移动游标(两头环绕):还没选过时向下取第一项、向上取最后一项;列表为空回 `null`(一步都动不了)。`step` 1 向下、-1 向上。 */
|
|
92
97
|
export function stepSelectCursor(shown, cursor, step) {
|
|
93
98
|
if (shown.length === 0)
|
|
94
99
|
return null;
|
|
@@ -96,6 +101,7 @@ export function stepSelectCursor(shown, cursor, step) {
|
|
|
96
101
|
return step === 1 ? 0 : shown.length - 1;
|
|
97
102
|
return (cursor + step + shown.length) % shown.length;
|
|
98
103
|
}
|
|
104
|
+
/** 把候选排成 `Menu` 要的条目表:按 `group` 插分组标题;一项都没有时退回 `emptyText` 那一行(不给就是空表)。`revealId` 是开列表时要滚进可视区的那个 value。 */
|
|
99
105
|
export function selectEntries(shown, emptyText, revealId) {
|
|
100
106
|
if (shown.length === 0) {
|
|
101
107
|
return emptyText === undefined ? [] : [{ type: 'label', id: EMPTY_ID, text: emptyText }];
|
|
@@ -170,6 +176,22 @@ function useSelectState(props) {
|
|
|
170
176
|
empty: typeof emptyText === 'function' ? emptyText(query) : emptyText,
|
|
171
177
|
};
|
|
172
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* 下拉选择:默认是跟 `TextField` 一套的常规下拉框(不是原生 `<select>`),无边框那种给 `variant: 'ghost'`。
|
|
181
|
+
* `open` 不给就内部自己管(两种接法下 `onOpenChange` 都会通知),`loading` 把触发器换成转圈 + `loadingText`(默认 `…`),
|
|
182
|
+
* `selection` 选选中行标记(`fill` 整行底色 / `check` 行尾勾),`footer` 是列表底部那一条(点它走 `onFooter`,不改当前值)。
|
|
183
|
+
* @param props.value - 当前值;在 `options` 里找不到就按"没选"画 `placeholder`。
|
|
184
|
+
* @param props.options - 全量候选;空数组且给了 `fallback` 时改画手填输入框。
|
|
185
|
+
* @param props.onChange - 选中一项后的回调,回的是那一项的 `value`。
|
|
186
|
+
* @param props.label - 没进 `FormRow` 时的标签兜底;进了那一行就别再给它和 `hint`,否则会多一个标签。
|
|
187
|
+
* @param props.renderValue - 自己渲染触发器上那份当前值;不给就用候选项的 `label`。
|
|
188
|
+
* @param props.placeholder - 没选中时那句话;不给是 `—`。
|
|
189
|
+
* @param props.search - 是否可搜(默认 true);`false` 时不画搜索框、也不自动聚焦。
|
|
190
|
+
* @param props.filter - 自定义匹配;不给用 `defaultSelectFilter`(空白查询一律命中)。
|
|
191
|
+
* @param props.emptyText - 无匹配时的文案,或按查询生成文案的函数(能说"没有匹配 X 的项")。
|
|
192
|
+
* @param props.fallback - 退路:`options` 为空时改成手填(`value` + `onChange`)。
|
|
193
|
+
* @returns 触发器,以及打开时的搜索框与列表。
|
|
194
|
+
*/
|
|
173
195
|
export function SelectField(props) {
|
|
174
196
|
const { value, options, onChange, label, hint, icon, renderValue, placeholder, search = true, searchLabel, searchPlaceholder, footer, onFooter, disabled = false, invalid = false, loading = false, loadingText, fallback, selection = 'fill', variant = 'boxed', iconOnly = false, revealId, ariaLabel, title, id, name, className, menuClassName, } = props;
|
|
175
197
|
const state = useSelectState(props);
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 下拉触发器那颗按钮:图标 + 当前值 + 箭头,交给 `Menu` 当 anchor;宽窄两档共用一个形状。
|
|
4
|
+
* @param args.id - 触发器 id。
|
|
5
|
+
* @param args.className - 触发器类名(已含 variant 与 iconOnly 的档)。
|
|
6
|
+
* @param args.disabled - 是否禁用。
|
|
7
|
+
* @param args.invalid - 置真写 `aria-invalid`。
|
|
8
|
+
* @param args.open - 列表是否开着,写进 `aria-expanded`。
|
|
9
|
+
* @param args.ariaLabel - 读屏名。
|
|
10
|
+
* @param args.title - 原生提示。
|
|
11
|
+
* @param args.icon - 值左边那枚图标;不给不占位。
|
|
12
|
+
* @param args.value - 已渲染好的当前值节点(文本或占位)。
|
|
13
|
+
* @param args.iconOnly - 只画图标(窄栏那颗切换钮),值与箭头都不画。
|
|
14
|
+
* @param args.onOpen - 点它做什么,通常是把列表打开。
|
|
15
|
+
* @returns 一颗 `<button>`。
|
|
16
|
+
*/
|
|
2
17
|
export declare function selectTriggerNode(args: {
|
|
3
18
|
readonly id: string | undefined;
|
|
4
19
|
readonly className: string;
|
|
@@ -12,6 +27,15 @@ export declare function selectTriggerNode(args: {
|
|
|
12
27
|
readonly iconOnly: boolean;
|
|
13
28
|
readonly onOpen: () => void;
|
|
14
29
|
}): ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* 名单还没读到时的触发器:禁用 + `aria-busy` 的按钮,`SelectField` 在 `loading` 那档画它。
|
|
32
|
+
* @param args.id - 触发器 id。
|
|
33
|
+
* @param args.className - 触发器类名;它后面会接上 loading 那档的类。
|
|
34
|
+
* @param args.invalid - 置真写 `aria-invalid`。
|
|
35
|
+
* @param args.ariaLabel - 读屏名。
|
|
36
|
+
* @param args.loadingText - 占位文案;不给就是 `…`。
|
|
37
|
+
* @returns 一颗禁用且 `aria-busy` 的按钮。
|
|
38
|
+
*/
|
|
15
39
|
export declare function selectLoadingNode(args: {
|
|
16
40
|
readonly id: string | undefined;
|
|
17
41
|
readonly className: string;
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { Fragment, h } from '../lib/react.js';
|
|
2
2
|
import { IconChevronDownOutlineRegular, TextShimmer, } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
3
|
import { Spinner } from './Spinner.js';
|
|
4
|
+
/**
|
|
5
|
+
* 下拉触发器那颗按钮:图标 + 当前值 + 箭头,交给 `Menu` 当 anchor;宽窄两档共用一个形状。
|
|
6
|
+
* @param args.id - 触发器 id。
|
|
7
|
+
* @param args.className - 触发器类名(已含 variant 与 iconOnly 的档)。
|
|
8
|
+
* @param args.disabled - 是否禁用。
|
|
9
|
+
* @param args.invalid - 置真写 `aria-invalid`。
|
|
10
|
+
* @param args.open - 列表是否开着,写进 `aria-expanded`。
|
|
11
|
+
* @param args.ariaLabel - 读屏名。
|
|
12
|
+
* @param args.title - 原生提示。
|
|
13
|
+
* @param args.icon - 值左边那枚图标;不给不占位。
|
|
14
|
+
* @param args.value - 已渲染好的当前值节点(文本或占位)。
|
|
15
|
+
* @param args.iconOnly - 只画图标(窄栏那颗切换钮),值与箭头都不画。
|
|
16
|
+
* @param args.onOpen - 点它做什么,通常是把列表打开。
|
|
17
|
+
* @returns 一颗 `<button>`。
|
|
18
|
+
*/
|
|
4
19
|
export function selectTriggerNode(args) {
|
|
5
20
|
return (h("button", { type: "button", id: args.id, className: args.className, disabled: args.disabled, "aria-haspopup": "listbox", "aria-expanded": args.open, "aria-invalid": args.invalid || undefined, "aria-label": args.ariaLabel, title: args.title, onClick: args.onOpen }, args.iconOnly ? (h("span", { className: "wb-selectIcon" }, args.icon)) : (h(Fragment, null,
|
|
6
21
|
args.icon === undefined ? null : h("span", { className: "wb-selectIcon" }, args.icon),
|
|
@@ -8,6 +23,15 @@ export function selectTriggerNode(args) {
|
|
|
8
23
|
h("span", { className: "wb-selectChevron" },
|
|
9
24
|
h(IconChevronDownOutlineRegular, { size: 14 }))))));
|
|
10
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* 名单还没读到时的触发器:禁用 + `aria-busy` 的按钮,`SelectField` 在 `loading` 那档画它。
|
|
28
|
+
* @param args.id - 触发器 id。
|
|
29
|
+
* @param args.className - 触发器类名;它后面会接上 loading 那档的类。
|
|
30
|
+
* @param args.invalid - 置真写 `aria-invalid`。
|
|
31
|
+
* @param args.ariaLabel - 读屏名。
|
|
32
|
+
* @param args.loadingText - 占位文案;不给就是 `…`。
|
|
33
|
+
* @returns 一颗禁用且 `aria-busy` 的按钮。
|
|
34
|
+
*/
|
|
11
35
|
export function selectLoadingNode(args) {
|
|
12
36
|
return (h("button", { type: "button", id: args.id, className: `${args.className} wb-selectLoading`, disabled: true, "aria-busy": "true", "aria-invalid": args.invalid || undefined, "aria-label": args.ariaLabel, title: args.loadingText },
|
|
13
37
|
h("span", { className: "wb-selectValue" },
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import type { ReactNode } from '../lib/react.js';
|
|
2
2
|
import './SettingsSection.css';
|
|
3
|
+
/**
|
|
4
|
+
* `SettingsSection` 的契约:一节的读屏名、标题、右上动作与内容。
|
|
5
|
+
*/
|
|
3
6
|
export interface SettingsSectionProps {
|
|
4
7
|
readonly label: string;
|
|
5
8
|
readonly title: ReactNode;
|
|
6
9
|
readonly action?: ReactNode | undefined;
|
|
7
10
|
readonly children?: ReactNode | undefined;
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 设置面里的一节:标题 + 右上那颗动作 + 一节内容,把一屏设置分组。
|
|
14
|
+
* @param props.label - 只给读屏的组名(`aria-label`),不是标题。
|
|
15
|
+
* @param props.title - 人看的标题。
|
|
16
|
+
* @param props.action - 标题右侧的动作(如"添加");不给不占位。
|
|
17
|
+
* @param props.children - 这一节的内容。
|
|
18
|
+
* @returns 一个 `role="group"` 的 section。
|
|
19
|
+
*/
|
|
9
20
|
export declare function SettingsSection({ label, title, action, children }: SettingsSectionProps): JSX.Element;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import './SettingsSection.css';
|
|
3
|
+
/**
|
|
4
|
+
* 设置面里的一节:标题 + 右上那颗动作 + 一节内容,把一屏设置分组。
|
|
5
|
+
* @param props.label - 只给读屏的组名(`aria-label`),不是标题。
|
|
6
|
+
* @param props.title - 人看的标题。
|
|
7
|
+
* @param props.action - 标题右侧的动作(如"添加");不给不占位。
|
|
8
|
+
* @param props.children - 这一节的内容。
|
|
9
|
+
* @returns 一个 `role="group"` 的 section。
|
|
10
|
+
*/
|
|
3
11
|
export function SettingsSection({ label, title, action, children }) {
|
|
4
12
|
return (h("section", { className: "wb-settings", role: "group", "aria-label": label },
|
|
5
13
|
h("header", { className: "wb-settingsHead" },
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import './Spinner.css';
|
|
2
|
+
/**
|
|
3
|
+
* `Spinner` 的契约:直径像素与可选的读屏标签。
|
|
4
|
+
*/
|
|
2
5
|
export interface SpinnerProps {
|
|
3
6
|
readonly size?: number;
|
|
4
7
|
readonly label?: string | undefined;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* 转圈:加载态一律用它(`FormActions` 与 `ChoiceGroup` 内部也是它),别自己写动画。
|
|
11
|
+
* @param props.size - 直径像素(默认 14,与 dsh 紧凑控件同高)。
|
|
12
|
+
* @param props.label - 给了才读屏可见(`role="status"`);不给整颗 `aria-hidden`,此时旁边必须有文字。
|
|
13
|
+
* @returns 一枚 `StateDot state="ongoing"`,自身不带文字。
|
|
14
|
+
*/
|
|
6
15
|
export declare function Spinner({ size, label }: SpinnerProps): JSX.Element;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
2
2
|
import { h } from '../lib/react.js';
|
|
3
3
|
import './Spinner.css';
|
|
4
|
+
/**
|
|
5
|
+
* 转圈:加载态一律用它(`FormActions` 与 `ChoiceGroup` 内部也是它),别自己写动画。
|
|
6
|
+
* @param props.size - 直径像素(默认 14,与 dsh 紧凑控件同高)。
|
|
7
|
+
* @param props.label - 给了才读屏可见(`role="status"`);不给整颗 `aria-hidden`,此时旁边必须有文字。
|
|
8
|
+
* @returns 一枚 `StateDot state="ongoing"`,自身不带文字。
|
|
9
|
+
*/
|
|
4
10
|
export function Spinner({ size = 14, label }) {
|
|
5
11
|
return (h("span", { className: "wb-spinner", ...(label === undefined ? { 'aria-hidden': true } : { role: 'status', 'aria-label': label }) },
|
|
6
12
|
h(StateDot, { state: "ongoing", size: size })));
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { ReactNode } from '../lib/react.js';
|
|
2
2
|
import './Stack.css';
|
|
3
|
+
/**
|
|
4
|
+
* `Stack` 的契约:只带一个竖排内容槽。
|
|
5
|
+
*/
|
|
3
6
|
export interface StackProps {
|
|
4
7
|
readonly children?: ReactNode | undefined;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* 竖排容器:把相邻内容按统一间距摞起来,懒得自己分组时的默认外包装。
|
|
11
|
+
* @param props.children - 要竖排的内容;不给就渲染一个空容器。
|
|
12
|
+
* @returns 竖排的 div。
|
|
13
|
+
*/
|
|
6
14
|
export declare function Stack({ children }: StackProps): JSX.Element;
|
package/dist/components/Stack.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import './Stack.css';
|
|
3
|
+
/**
|
|
4
|
+
* 竖排容器:把相邻内容按统一间距摞起来,懒得自己分组时的默认外包装。
|
|
5
|
+
* @param props.children - 要竖排的内容;不给就渲染一个空容器。
|
|
6
|
+
* @returns 竖排的 div。
|
|
7
|
+
*/
|
|
3
8
|
export function Stack({ children }) {
|
|
4
9
|
return h("div", { className: "wb-stack" }, children);
|
|
5
10
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ReactNode } from '../lib/react.js';
|
|
2
2
|
import './StateBlock.css';
|
|
3
|
+
/**
|
|
4
|
+
* `StateBlock` 的契约:标题、状态点、提示、正文与行尾动作。
|
|
5
|
+
*/
|
|
3
6
|
export interface StateBlockProps {
|
|
4
7
|
readonly title?: ReactNode | undefined;
|
|
5
8
|
readonly dot?: ReactNode | undefined;
|
|
@@ -8,4 +11,14 @@ export interface StateBlockProps {
|
|
|
8
11
|
readonly resolving?: ReactNode | undefined;
|
|
9
12
|
readonly children?: ReactNode | undefined;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 有内容那一段:一个标题 + 一行提示 + 正文,卡里已经读到东西时用它开头。
|
|
16
|
+
* @param props.title - 标题那行;它与 `dot` 都不给时整行不画。
|
|
17
|
+
* @param props.dot - 标题前那枚状态点。
|
|
18
|
+
* @param props.hint - 标题下那行小字(如"3 条 · 刚刚");不给不画。
|
|
19
|
+
* @param props.resolving - "正在读"那行,读数期间挂上去;不给不画。
|
|
20
|
+
* @param props.actions - 底部动作区;给了才画那一条。
|
|
21
|
+
* @param props.children - 正文。
|
|
22
|
+
* @returns 一个 div。
|
|
23
|
+
*/
|
|
11
24
|
export declare function StateBlock({ title, dot, hint, actions, resolving, children }: StateBlockProps): JSX.Element;
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { h } from '../lib/react.js';
|
|
2
2
|
import './StateBlock.css';
|
|
3
|
+
/**
|
|
4
|
+
* 有内容那一段:一个标题 + 一行提示 + 正文,卡里已经读到东西时用它开头。
|
|
5
|
+
* @param props.title - 标题那行;它与 `dot` 都不给时整行不画。
|
|
6
|
+
* @param props.dot - 标题前那枚状态点。
|
|
7
|
+
* @param props.hint - 标题下那行小字(如"3 条 · 刚刚");不给不画。
|
|
8
|
+
* @param props.resolving - "正在读"那行,读数期间挂上去;不给不画。
|
|
9
|
+
* @param props.actions - 底部动作区;给了才画那一条。
|
|
10
|
+
* @param props.children - 正文。
|
|
11
|
+
* @returns 一个 div。
|
|
12
|
+
*/
|
|
3
13
|
export function StateBlock({ title, dot, hint, actions, resolving, children }) {
|
|
4
14
|
return (h("div", { className: "wb-stateBlock" },
|
|
5
15
|
title === undefined && dot === undefined ? null : (h("p", { className: "wb-stateBlockTitle" },
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { InputHTMLAttributes } from 'react';
|
|
2
2
|
import './TextField.css';
|
|
3
|
+
/**
|
|
4
|
+
* `TextField` 的契约:原生 input 属性,外加一个标红开关。
|
|
5
|
+
*/
|
|
3
6
|
export interface TextFieldProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
4
7
|
readonly invalid?: boolean;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* 单行文本输入:设置面与筛选框都用它,`invalid` 之外的属性全部透传给原生 `<input>`。
|
|
11
|
+
* @param props.invalid - 置真标红并写 `aria-invalid`(默认 false);错在哪一句归 `FormRow.problem`。
|
|
12
|
+
* @returns 输入框元素;`className` 是追加在基础类名之后,而不是替换它。
|
|
13
|
+
*/
|
|
6
14
|
export declare function TextField({ invalid, className, ...rest }: TextFieldProps): JSX.Element;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import './TextField.css';
|
|
2
2
|
import { h } from '../lib/react.js';
|
|
3
|
+
/**
|
|
4
|
+
* 单行文本输入:设置面与筛选框都用它,`invalid` 之外的属性全部透传给原生 `<input>`。
|
|
5
|
+
* @param props.invalid - 置真标红并写 `aria-invalid`(默认 false);错在哪一句归 `FormRow.problem`。
|
|
6
|
+
* @returns 输入框元素;`className` 是追加在基础类名之后,而不是替换它。
|
|
7
|
+
*/
|
|
3
8
|
export function TextField({ invalid = false, className, ...rest }) {
|
|
4
9
|
return (h("input", { ...rest, className: className === undefined ? 'wb-textField' : `wb-textField ${className}`, "aria-invalid": invalid || undefined }));
|
|
5
10
|
}
|