@dsh-workbench/shared 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/dist/api/blocker-table.d.ts +13 -0
  2. package/dist/api/blocker-table.js +13 -0
  3. package/dist/api/blocker.d.ts +6 -0
  4. package/dist/api/context-ref.d.ts +31 -0
  5. package/dist/api/context-ref.js +28 -0
  6. package/dist/api/dsh-client.d.ts +99 -0
  7. package/dist/api/dsh.d.ts +55 -3
  8. package/dist/api/facts.d.ts +42 -0
  9. package/dist/api/facts.js +33 -0
  10. package/dist/api/host-write.d.ts +18 -0
  11. package/dist/api/host-write.js +12 -0
  12. package/dist/api/long-task.d.ts +36 -0
  13. package/dist/api/long-task.js +27 -0
  14. package/dist/api/unit-board.d.ts +25 -0
  15. package/dist/api/unit-board.js +16 -0
  16. package/dist/api/unit-declaration.d.ts +36 -0
  17. package/dist/api/unit-declaration.js +24 -0
  18. package/dist/api/unit.d.ts +32 -0
  19. package/dist/api/unit.js +5 -0
  20. package/dist/api/workbench-client.d.ts +25 -0
  21. package/dist/api/workbench-client.js +13 -0
  22. package/dist/api/workbench-contract.d.ts +12 -0
  23. package/dist/components/Activity.d.ts +33 -0
  24. package/dist/components/Activity.js +24 -0
  25. package/dist/components/ApprovalDetail.d.ts +12 -0
  26. package/dist/components/ApprovalDetail.js +9 -0
  27. package/dist/components/ApprovalPlan.d.ts +14 -0
  28. package/dist/components/ApprovalPlan.js +8 -0
  29. package/dist/components/Card.d.ts +13 -0
  30. package/dist/components/Card.js +10 -0
  31. package/dist/components/CardAnchor.d.ts +14 -0
  32. package/dist/components/CardAnchor.js +11 -0
  33. package/dist/components/CardBoundary.d.ts +20 -0
  34. package/dist/components/CardBoundary.js +14 -0
  35. package/dist/components/CardHead.d.ts +13 -0
  36. package/dist/components/CardHead.js +10 -0
  37. package/dist/components/ChoiceGroup.d.ts +24 -0
  38. package/dist/components/ChoiceGroup.js +12 -0
  39. package/dist/components/Field.d.ts +10 -0
  40. package/dist/components/Field.js +7 -0
  41. package/dist/components/Form.css +6 -0
  42. package/dist/components/Form.d.ts +20 -0
  43. package/dist/components/Form.js +58 -0
  44. package/dist/components/FormActions.d.ts +14 -0
  45. package/dist/components/FormActions.js +5 -0
  46. package/dist/components/FormNodes.d.ts +103 -0
  47. package/dist/components/FormNodes.js +153 -0
  48. package/dist/components/FormRows.d.ts +20 -0
  49. package/dist/components/FormRows.js +14 -0
  50. package/dist/components/FormTypes.d.ts +59 -0
  51. package/dist/components/FormTypes.js +1 -0
  52. package/dist/components/Link.d.ts +12 -0
  53. package/dist/components/Link.js +9 -0
  54. package/dist/components/LongTaskRow.d.ts +19 -0
  55. package/dist/components/LongTaskRow.js +13 -0
  56. package/dist/components/Note.d.ts +11 -0
  57. package/dist/components/Note.js +8 -0
  58. package/dist/components/ResourceStates.d.ts +25 -0
  59. package/dist/components/ResourceStates.js +22 -0
  60. package/dist/components/Rows.d.ts +17 -0
  61. package/dist/components/Rows.js +11 -0
  62. package/dist/components/SaveBar.d.ts +12 -0
  63. package/dist/components/SaveBar.js +9 -0
  64. package/dist/components/SelectField.d.ts +26 -0
  65. package/dist/components/SelectField.js +22 -0
  66. package/dist/components/SelectFieldNodes.d.ts +24 -0
  67. package/dist/components/SelectFieldNodes.js +24 -0
  68. package/dist/components/SettingsSection.d.ts +11 -0
  69. package/dist/components/SettingsSection.js +8 -0
  70. package/dist/components/Spinner.d.ts +9 -0
  71. package/dist/components/Spinner.js +6 -0
  72. package/dist/components/Stack.d.ts +8 -0
  73. package/dist/components/Stack.js +5 -0
  74. package/dist/components/StateBlock.d.ts +13 -0
  75. package/dist/components/StateBlock.js +10 -0
  76. package/dist/components/TextField.d.ts +8 -0
  77. package/dist/components/TextField.js +5 -0
  78. package/dist/components/board-module.d.ts +30 -0
  79. package/dist/components/icons.d.ts +38 -0
  80. package/dist/components/icons.js +35 -0
  81. package/dist/config/constants.d.ts +42 -0
  82. package/dist/config/constants.js +42 -0
  83. package/dist/config/storage.d.ts +4 -0
  84. package/dist/config/storage.js +4 -0
  85. package/dist/host/unit-face.d.ts +5 -1
  86. package/dist/i18n/en.d.ts +1 -0
  87. package/dist/i18n/en.js +8 -8
  88. package/dist/i18n/index.d.ts +11 -9
  89. package/dist/i18n/index.js +1 -0
  90. package/dist/i18n/merge.d.ts +5 -0
  91. package/dist/i18n/merge.js +2 -0
  92. package/dist/i18n/zh.d.ts +9 -8
  93. package/dist/i18n/zh.js +8 -8
  94. package/dist/index.d.ts +6 -2
  95. package/dist/index.js +6 -2
  96. package/dist/lib/blocker-action.d.ts +22 -0
  97. package/dist/lib/blocker-action.js +13 -0
  98. package/dist/lib/board-fact.d.ts +27 -0
  99. package/dist/lib/board-fact.js +18 -0
  100. package/dist/lib/busy.d.ts +10 -0
  101. package/dist/lib/busy.js +7 -0
  102. package/dist/lib/diy-debug.d.ts +42 -2
  103. package/dist/lib/diy-debug.js +19 -1
  104. package/dist/lib/diy-record.d.ts +41 -0
  105. package/dist/lib/diy-record.js +17 -0
  106. package/dist/lib/form-problem.d.ts +10 -0
  107. package/dist/lib/form-problem.js +10 -0
  108. package/dist/lib/panel-state.d.ts +60 -0
  109. package/dist/lib/panel-state.js +30 -0
  110. package/dist/lib/react.d.ts +39 -0
  111. package/dist/lib/react.js +36 -0
  112. package/dist/lib/text.d.ts +22 -0
  113. package/dist/lib/text.js +22 -0
  114. package/dist/lib/ui.d.ts +50 -0
  115. package/dist/lib/ui.js +41 -0
  116. package/package.json +1 -1
  117. package/src/api/blocker-table.ts +13 -0
  118. package/src/api/blocker.ts +6 -0
  119. package/src/api/context-ref.ts +31 -0
  120. package/src/api/dsh-client.ts +99 -0
  121. package/src/api/dsh.ts +56 -1
  122. package/src/api/facts.ts +42 -0
  123. package/src/api/host-write.ts +18 -0
  124. package/src/api/long-task.ts +36 -0
  125. package/src/api/unit-board.ts +25 -0
  126. package/src/api/unit-declaration.ts +36 -0
  127. package/src/api/unit.ts +32 -0
  128. package/src/api/workbench-client.ts +25 -0
  129. package/src/api/workbench-contract.ts +12 -0
  130. package/src/components/Activity.tsx +33 -0
  131. package/src/components/ApprovalDetail.tsx +12 -0
  132. package/src/components/ApprovalPlan.tsx +14 -0
  133. package/src/components/Card.tsx +13 -0
  134. package/src/components/CardAnchor.tsx +14 -0
  135. package/src/components/CardBoundary.tsx +20 -0
  136. package/src/components/CardHead.tsx +13 -0
  137. package/src/components/ChoiceGroup.tsx +24 -0
  138. package/src/components/Field.tsx +10 -0
  139. package/src/components/Form.css +6 -0
  140. package/src/components/Form.test.tsx +475 -0
  141. package/src/components/Form.tsx +78 -0
  142. package/src/components/FormActions.tsx +14 -0
  143. package/src/components/FormNodes.tsx +193 -0
  144. package/src/components/FormRows.tsx +20 -0
  145. package/src/components/FormTypes.ts +65 -0
  146. package/src/components/FormWiring.test.tsx +88 -0
  147. package/src/components/Link.tsx +12 -0
  148. package/src/components/LongTaskRow.tsx +19 -0
  149. package/src/components/Note.tsx +11 -0
  150. package/src/components/ResourceStates.tsx +25 -0
  151. package/src/components/Rows.tsx +17 -0
  152. package/src/components/SaveBar.tsx +12 -0
  153. package/src/components/SelectField.tsx +26 -0
  154. package/src/components/SelectFieldNodes.tsx +24 -0
  155. package/src/components/SettingsSection.tsx +11 -0
  156. package/src/components/Spinner.tsx +9 -0
  157. package/src/components/Stack.tsx +8 -0
  158. package/src/components/StateBlock.tsx +13 -0
  159. package/src/components/TextField.tsx +8 -0
  160. package/src/components/board-module.ts +30 -0
  161. package/src/components/icons.tsx +38 -0
  162. package/src/config/constants.ts +43 -0
  163. package/src/config/storage.ts +4 -0
  164. package/src/host/unit-face.ts +6 -1
  165. package/src/i18n/en.ts +8 -8
  166. package/src/i18n/index.ts +3 -0
  167. package/src/i18n/merge.ts +5 -0
  168. package/src/i18n/zh.ts +9 -8
  169. package/src/index.ts +6 -2
  170. package/src/lib/blocker-action.ts +22 -0
  171. package/src/lib/board-fact.ts +27 -0
  172. package/src/lib/busy.ts +10 -0
  173. package/src/lib/diy-debug.test.ts +2 -1
  174. package/src/lib/diy-debug.ts +44 -3
  175. package/src/lib/diy-record.ts +41 -0
  176. package/src/lib/form-problem.ts +10 -0
  177. package/src/lib/panel-state.ts +60 -0
  178. package/src/lib/react.ts +39 -0
  179. package/src/lib/text.ts +22 -0
  180. package/src/lib/ui.ts +50 -0
@@ -3,11 +3,20 @@ import { Button, Tooltip } from '@deepseek-ai/dsh-client-ui-primitives';
3
3
  import { h } from '../lib/react.js';
4
4
  import './Activity.css';
5
5
 
6
+ /**
7
+ * `ActivityBlock` 的契约:块头与块内容。
8
+ */
6
9
  export interface ActivityBlockProps {
7
10
  readonly head?: ReactNode | undefined;
8
11
  readonly children?: ReactNode | undefined;
9
12
  }
10
13
 
14
+ /**
15
+ * "它做过什么"那一块:上面一行块头、下面一列活动行,卡里放时间线就用它。
16
+ * @param props.head - 块头(如"最近 10 次");不给不画那一行。
17
+ * @param props.children - 块内容,通常是一串 `ActivityLine`。
18
+ * @returns 一个 div。
19
+ */
11
20
  export function ActivityBlock({ head, children }: ActivityBlockProps) {
12
21
  return (
13
22
  <div className="wb-activityBlock">
@@ -17,6 +26,9 @@ export function ActivityBlock({ head, children }: ActivityBlockProps) {
17
26
  );
18
27
  }
19
28
 
29
+ /**
30
+ * `ActivityLine` 的契约:状态点、正文、时间与行尾动作。
31
+ */
20
32
  export interface ActivityLineProps {
21
33
  readonly dot?: ReactNode | undefined;
22
34
  readonly text: ReactNode;
@@ -24,6 +36,14 @@ export interface ActivityLineProps {
24
36
  readonly actions?: ReactNode | undefined;
25
37
  }
26
38
 
39
+ /**
40
+ * 一条活动:状态点 + 正文 + 时间,行尾可挂动作;时间一律用它,别自己拼。
41
+ * @param props.dot - 行首那枚状态点;不给就只留正文。
42
+ * @param props.text - 这一条干了什么。
43
+ * @param props.at - 时间那一格(相对时间文本);不给不画。
44
+ * @param props.actions - 行尾动作,通常是一两颗 `ActivityAction`;不给不画。
45
+ * @returns 一行。
46
+ */
27
47
  export function ActivityLine({ dot, text, at, actions }: ActivityLineProps) {
28
48
  return (
29
49
  <div className="wb-activityLine">
@@ -35,6 +55,9 @@ export function ActivityLine({ dot, text, at, actions }: ActivityLineProps) {
35
55
  );
36
56
  }
37
57
 
58
+ /**
59
+ * `ActivityAction` 的契约:一颗图标钮、一个外链,或一个失败态。
60
+ */
38
61
  export interface ActivityActionProps {
39
62
  readonly label: string;
40
63
  readonly hint?: string | undefined;
@@ -44,6 +67,16 @@ export interface ActivityActionProps {
44
67
  readonly failed?: boolean | undefined;
45
68
  }
46
69
 
70
+ /**
71
+ * 活动行尾那颗动作:给 `href` 就是外链,否则是图标钮并带上 tooltip。
72
+ * @param props.label - 读屏名,也是 `hint` 不给时的 tooltip 文案。
73
+ * @param props.hint - tooltip 上那句更细的说明;不给退化成 `label`。
74
+ * @param props.icon - 那颗图标。
75
+ * @param props.href - 给了就渲染成新窗口外链;与 `onClick` 同时给时以它为准。
76
+ * @param props.onClick - 图标钮的点击回调。
77
+ * @param props.failed - 上一次动作失败了:钮换成危险色(默认 false)。
78
+ * @returns 一个 `<a>` 或一颗 `Button`。
79
+ */
47
80
  export function ActivityAction({ label, hint, icon, href, onClick, failed }: ActivityActionProps) {
48
81
  const tip = hint ?? label;
49
82
  if (href !== undefined) {
@@ -18,6 +18,9 @@ interface ChatSnapshot {
18
18
 
19
19
  type UseChat = <T>(selector: (snapshot: ChatSnapshot) => T) => T | undefined;
20
20
 
21
+ /**
22
+ * `ApprovalDetail` 的契约:调用 id、读会话快照的钩子、已装模块与兜底渲染。
23
+ */
21
24
  export interface ApprovalDetailProps {
22
25
  readonly callId?: string;
23
26
  readonly useChat?: UseChat;
@@ -45,6 +48,15 @@ function parseArgs(raw: string): Readonly<Record<string, unknown>> {
45
48
  }
46
49
  }
47
50
 
51
+ /**
52
+ * 审批屏的详情格:按工具名找到认领它的模块交给它渲染,没有模块认领就退回外壳那张表或一段原始命令。
53
+ * @param props.callId - 这次工具调用的 id;不给就直接走兜底(连调用都找不到)。
54
+ * @param props.useChat - 读会话快照的钩子(dsh 注入);不给就当作读不到调用。
55
+ * @param props.units - 已装模块的面,按各自的 `approval.tools` 认领这次调用。
56
+ * @param props.t - 翻译函数;不给就用返回 key 的直通实现。
57
+ * @param props.renderShell - 没有模块认领时外壳自己的渲染(那张表);不给且这次调用没带 `command` 时整格返回 `null`。
58
+ * @returns 认领方的渲染、外壳那张表,或一段可复制的命令。
59
+ */
48
60
  export function ApprovalDetail(props: ApprovalDetailProps) {
49
61
  const useChat = props.useChat ?? ((): undefined => undefined);
50
62
  const call = useChat((snapshot) => callOf(snapshot, props.callId));
@@ -2,11 +2,17 @@ import type { ReactNode } from '../lib/react.js';
2
2
  import { h } from '../lib/react.js';
3
3
  import './ApprovalPlan.css';
4
4
 
5
+ /**
6
+ * 审批详情里的一行:左边标签、右边值。
7
+ */
5
8
  export interface ApprovalPlanRow {
6
9
  readonly label: ReactNode;
7
10
  readonly value: ReactNode;
8
11
  }
9
12
 
13
+ /**
14
+ * `ApprovalPlan` 的契约:详情行,外加附注与警告两格。
15
+ */
10
16
  export interface ApprovalPlanProps {
11
17
  readonly rows: readonly ApprovalPlanRow[];
12
18
  readonly hint?: ReactNode | undefined;
@@ -14,6 +20,14 @@ export interface ApprovalPlanProps {
14
20
  readonly children?: ReactNode | undefined;
15
21
  }
16
22
 
23
+ /**
24
+ * 审批屏那张"这次要做什么"的表:一行一项,上面可给一句附注、下面可给一句警告。
25
+ * @param props.rows - 详情行,按给的顺序渲染;空数组时只剩附注与警告。
26
+ * @param props.hint - 表上面那句说明;不给不画。
27
+ * @param props.warn - 表下面那句警告;不给不画。
28
+ * @param props.children - 插在表与 `warn` 之间的补充内容。
29
+ * @returns 一个 div。
30
+ */
17
31
  export function ApprovalPlan({ rows, hint, warn, children }: ApprovalPlanProps) {
18
32
  return (
19
33
  <div className="wb-approvalPlan">
@@ -4,6 +4,9 @@ import { h } from '../lib/react.js';
4
4
  import { CardHead } from './CardHead.js';
5
5
  import './Card.css';
6
6
 
7
+ /**
8
+ * `Card` 的契约:标题、刷新、卡片体,以及可整块替换的卡头。
9
+ */
7
10
  export interface CardProps {
8
11
  readonly t: Translate;
9
12
  readonly title: string;
@@ -14,6 +17,16 @@ export interface CardProps {
14
17
  readonly children?: ReactNode | undefined;
15
18
  }
16
19
 
20
+ /**
21
+ * 一张卡的壳:卡头(标题 + 刷新钮)+ 卡片体,面板上每一格都是它。
22
+ * @param props.t - 卡头那两句文案(刷新 / 刷新中)的翻译函数。
23
+ * @param props.refreshing - 正在刷新:刷新钮随之禁用并转圈;接 `resource.phase === 'loading'`。
24
+ * @param props.onRefresh - 点刷新钮做什么,异步由调用点自己管。
25
+ * @param props.meta - 标题右侧那一小段补充(条数、时间);不给不占位。
26
+ * @param props.head - 整块替换卡头时给(如自带齿轮的 `CardHead`);不给用默认卡头。
27
+ * @param props.children - 卡片体。
28
+ * @returns 一个 `<section>`。
29
+ */
17
30
  export function Card({ t, title, refreshing, onRefresh, meta, head, children }: CardProps) {
18
31
  return (
19
32
  <section className="wb-card">
@@ -2,15 +2,29 @@ import type { ReactNode } from '../lib/react.js';
2
2
  import { h } from '../lib/react.js';
3
3
  import styles from './CardAnchor.module.css';
4
4
 
5
+ /**
6
+ * 由 unit id 拼出卡片锚点 id,外壳的截图、滚动与页面探针都按它找卡。
7
+ * @param unit - unit id;`null` 或空串(没有 unit 的卡)时返回 undefined,不生成锚点。
8
+ * @returns `wb-card-<unit>`,或 undefined。
9
+ */
5
10
  export function cardIdOf(unit: string | null): string | undefined {
6
11
  return unit === null || unit === '' ? undefined : `wb-card-${unit}`;
7
12
  }
8
13
 
14
+ /**
15
+ * `CardAnchor` 的契约:unit id 与它锚住的内容。
16
+ */
9
17
  export interface CardAnchorProps {
10
18
  readonly unit: string;
11
19
  readonly children?: ReactNode | undefined;
12
20
  }
13
21
 
22
+ /**
23
+ * 外壳自己盖的卡片锚点:套在卡外面给出 `id="wb-card-<unit>"`;模块别自己写,也别删。
24
+ * @param props.unit - 卡的 unit id,用来算锚点 id。
25
+ * @param props.children - 被锚住的卡片本体;锚点自己 `display: contents`,不占布局。
26
+ * @returns 带 id 的占位 div。
27
+ */
14
28
  export function CardAnchor({ unit, children }: CardAnchorProps) {
15
29
  return (
16
30
  <div id={cardIdOf(unit)} className={styles.anchor}>
@@ -4,6 +4,9 @@ import type { ReactNode } from '../lib/react.js';
4
4
  import { Component, h } from '../lib/react.js';
5
5
  import { Note } from './Note.js';
6
6
 
7
+ /**
8
+ * `CardBoundary` 的契约:被守的 unit、重来键与失败回调。
9
+ */
7
10
  export interface CardBoundaryProps {
8
11
  readonly unit: string;
9
12
  readonly resetKey: string;
@@ -12,15 +15,32 @@ export interface CardBoundaryProps {
12
15
  readonly children?: ReactNode | undefined;
13
16
  }
14
17
 
18
+ /**
19
+ * `CardBoundary` 的状态:这次渲染炸出来的那句话,没炸是 `null`。
20
+ */
15
21
  export interface CardBoundaryState {
16
22
  readonly reason: string | null;
17
23
  }
18
24
 
25
+ /**
26
+ * 把抛出来的任何东西收成一句人能看的失败原因,上报与展示都用它。
27
+ * @param error - 抛出来的值:`Error` 取 `message`,字符串原样,其余走 JSON。
28
+ * @returns 一句原因文本;`Error('')` 这种没带 message 的会回空串(调用点别把它当"一定有话")。
29
+ */
19
30
  export function errorReasonOf(error: unknown): string {
20
31
  if (error instanceof Error) return error.message;
21
32
  return typeof error === 'string' ? error : JSON.stringify(error) ?? String(error);
22
33
  }
23
34
 
35
+ /**
36
+ * 卡片级错误边界:一张卡渲染炸了只画一条报错 + 重试,不让整块面板跟着塌。
37
+ * @param props.unit - 出事的 unit id,写进报错文案并作为上报标识。
38
+ * @param props.resetKey - 重来键:它一变(如切了工作区)就自动清掉报错,把卡片重新渲染一遍。
39
+ * @param props.t - 报错那句与重试钮文案的翻译函数。
40
+ * @param props.onFailure - 失败时把原因报给宿主(面板状态要用);不给就只打一条 console。
41
+ * @param props.children - 正常时要渲染的卡片内容。
42
+ * @returns 正常时是 `children`,炸过且还没重来之前是一条报错。
43
+ */
24
44
  export class CardBoundary extends Component<CardBoundaryProps, CardBoundaryState> {
25
45
  override state: CardBoundaryState = { reason: null };
26
46
 
@@ -10,6 +10,9 @@ import {
10
10
  import { h } from '../lib/react.js';
11
11
  import './CardHead.css';
12
12
 
13
+ /**
14
+ * `CardHead` 的契约:标题、补充、刷新,外加齿轮与平台跳转两格。
15
+ */
13
16
  export interface CardHeadProps {
14
17
  readonly t: Translate;
15
18
  readonly title: string;
@@ -24,6 +27,16 @@ export interface CardHeadProps {
24
27
  readonly platformTitle?: string | undefined;
25
28
  }
26
29
 
30
+ /**
31
+ * 卡头:标题 + 补充 + 刷新钮(`Card` 内部就是它),要自己拼卡头或加齿轮 / 平台跳转时直接用。
32
+ * @param props.t - 刷新那两句文案(刷新 / 刷新中)的翻译函数。
33
+ * @param props.title - 卡标题;`props.meta` 是它右侧那一小段补充,不给不占位。
34
+ * @param props.refreshing - 正在刷新:刷新钮禁用并转圈。
35
+ * @param props.onRefresh - 点刷新钮做什么。
36
+ * @param props.gear - 齿轮钮的读屏名;`gearOpen` 控制它高亮、`onToggleGear` 是点击回调,三者一起给才画。
37
+ * @param props.platformHref - 整张卡对应系统的地址:给了就画那颗 ↗(新窗口),tooltip 用 `platformTitle`,缺了退化用 `platform`。
38
+ * @returns 一个 `<header>`。
39
+ */
27
40
  export function CardHead({
28
41
  t,
29
42
  title,
@@ -4,6 +4,9 @@ import { IconCheckOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives';
4
4
  import { Spinner } from './Spinner.js';
5
5
  import './ChoiceGroup.css';
6
6
 
7
+ /**
8
+ * 一个候选项:值、人看的标签,可带一行说明。
9
+ */
7
10
  export interface ChoiceGroupOption {
8
11
  readonly value: string;
9
12
  readonly label: ReactNode;
@@ -21,18 +24,27 @@ interface ChoiceGroupCommon {
21
24
  readonly emptyText?: ReactNode | undefined;
22
25
  }
23
26
 
27
+ /**
28
+ * 单选那一支的契约:`value` + `onChange(next)`;`multi` 不给或给 false。
29
+ */
24
30
  export interface ChoiceGroupSingleProps extends ChoiceGroupCommon {
25
31
  readonly multi?: false | undefined;
26
32
  readonly value: string;
27
33
  readonly onChange: (next: string) => void;
28
34
  }
29
35
 
36
+ /**
37
+ * 多选那一支的契约:`multi: true` + `values` + `onChange(next[])`。
38
+ */
30
39
  export interface ChoiceGroupMultiProps extends ChoiceGroupCommon {
31
40
  readonly multi: true;
32
41
  readonly values: readonly string[];
33
42
  readonly onChange: (next: readonly string[]) => void;
34
43
  }
35
44
 
45
+ /**
46
+ * `ChoiceGroup` 的契约:单选与多选两支的联合。
47
+ */
36
48
  export type ChoiceGroupProps = ChoiceGroupSingleProps | ChoiceGroupMultiProps;
37
49
 
38
50
  interface ChoiceRowState {
@@ -110,6 +122,18 @@ function ChoiceMenu(input: {
110
122
  );
111
123
  }
112
124
 
125
+ /**
126
+ * 一组单选或多选:候选少、要一眼看全时用它;候选多或要搜索就用 `SelectField`。
127
+ * @param props.multi - true 走多选那支(`values` / `onChange(string[])`);默认单选(`value` / `onChange(string)`)。
128
+ * @param props.label - 只给读屏的组名(`aria-label`)。
129
+ * @param props.name - 这一组 `input` 的共用 name。
130
+ * @param props.options - 候选项,按给的顺序排;空数组时画 `emptyText`(没给就什么都不画)。
131
+ * @param props.disabled - 禁掉整组(默认 false),不是单颗。
132
+ * @param props.variant - `boxed`(默认,带边框的选项格)或 `ghost`(无边框,跟着父容器走)。
133
+ * @param props.loading - 正在读候选:整组换成转圈,文案取 `loadingText`(不给是 `…`);默认 false。
134
+ * @param props.emptyText - 读到了但一个候选都没有时那句话;不给不画。
135
+ * @returns 一组 `radio` / `checkbox` 选项。
136
+ */
113
137
  export function ChoiceGroup(props: ChoiceGroupProps) {
114
138
  const common = {
115
139
  label: props.label,
@@ -2,12 +2,22 @@ import type { ReactNode } from '../lib/react.js';
2
2
  import { h } from '../lib/react.js';
3
3
  import './Field.css';
4
4
 
5
+ /**
6
+ * `Field` 的契约:一行"标签 + 控件 + 说明"的排布。
7
+ */
5
8
  export interface FieldProps {
6
9
  readonly label: ReactNode;
7
10
  readonly hint?: ReactNode | undefined;
8
11
  readonly children?: ReactNode | undefined;
9
12
  }
10
13
 
14
+ /**
15
+ * 标签 + 控件的排布:没进 `FormRow` 时用它兜住一个字段的标签与说明。
16
+ * @param props.label - 左侧标签,必给。
17
+ * @param props.hint - 控件下面那行说明;不给不画。
18
+ * @param props.children - 控件本体,落在标签与说明之间。
19
+ * @returns 一个 `<label>`,点标签会聚焦里面的控件。
20
+ */
11
21
  export function Field({ label, hint, children }: FieldProps) {
12
22
  return (
13
23
  <label className="wb-field">
@@ -0,0 +1,6 @@
1
+ .wb-form {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--wb-len-12);
5
+ width: 100%;
6
+ }