@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
@@ -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;
@@ -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
  }
@@ -3,9 +3,15 @@ import type { SessionsSnapshot, Translate, WorkspaceSnapshot, WorkspaceView } fr
3
3
  import type { UnitManifest } from '../api/unit.js';
4
4
  import type { CapabilityPayload } from '../api/workbench-contract.js';
5
5
  import type { Dictionaries } from '../i18n/index.js';
6
+ /**
7
+ * 面板要跳去的一格:只用 `kind` 说去哪,具体负载由各 unit 自己约定。
8
+ */
6
9
  export interface PanelStep {
7
10
  readonly kind: string;
8
11
  }
12
+ /**
13
+ * 交给面板渲染的宿主世界:工作区与会话快照、装着的 unit、面板开关、能力表与当前选中。
14
+ */
9
15
  export interface SuiteWorld {
10
16
  readonly workspaces: WorkspaceSnapshot;
11
17
  readonly sessions: SessionsSnapshot;
@@ -19,6 +25,9 @@ export interface SuiteWorld {
19
25
  readonly workspace: WorkspaceView | null;
20
26
  };
21
27
  }
28
+ /**
29
+ * 面板视图的统一 prop:一份世界快照 + 刷新令牌 + 四个通知回调 + 翻译函数。
30
+ */
22
31
  export interface BoardModuleProps {
23
32
  readonly world: SuiteWorld;
24
33
  readonly refreshToken: number;
@@ -28,14 +37,23 @@ export interface BoardModuleProps {
28
37
  readonly onSummary: (summary: ModuleSummary) => void;
29
38
  readonly t: Translate;
30
39
  }
40
+ /**
41
+ * 一张卡报给宿主的摘要:此刻在不在刷新、上次读到是哪个时刻。
42
+ */
31
43
  export interface ModuleSummary {
32
44
  readonly refreshing: boolean;
33
45
  readonly at: number | null;
34
46
  }
47
+ /**
48
+ * unit 的一个子步骤:标题文案键 + 渲染这件视图的组件。
49
+ */
35
50
  export interface UnitStep {
36
51
  readonly titleKey: string;
37
52
  readonly View: (props: BoardModuleProps) => ReactNode;
38
53
  }
54
+ /**
55
+ * 一个面板单元的注册面:id、标题键、排序、视图,可带一组子步骤。
56
+ */
39
57
  export interface BoardModule {
40
58
  readonly id: string;
41
59
  readonly titleKey: string;
@@ -43,6 +61,9 @@ export interface BoardModule {
43
61
  readonly View: (props: BoardModuleProps) => ReactNode;
44
62
  readonly steps?: Readonly<Record<string, UnitStep>>;
45
63
  }
64
+ /**
65
+ * 模块在浏览器侧交出来的那份面:卡片、子步骤、自己的字典,以及审批渲染。
66
+ */
46
67
  export interface UnitClientFace {
47
68
  readonly unit: string;
48
69
  readonly card?: (props: BoardModuleProps) => ReactNode;
@@ -56,13 +77,22 @@ export interface UnitClientFace {
56
77
  }) => ReactNode;
57
78
  } | undefined;
58
79
  }
80
+ /**
81
+ * 带着自己 manifest 的模块面(外壳按 unit 认领时用)。
82
+ */
59
83
  export interface UnitOwnedClientFace extends UnitClientFace {
60
84
  readonly manifest: UnitManifest;
61
85
  }
86
+ /**
87
+ * 一次审批要看的输入:工具名,与它这次收到的参数。
88
+ */
62
89
  export interface ApprovalInput {
63
90
  readonly tool: string;
64
91
  readonly args: Readonly<Record<string, unknown>>;
65
92
  }
93
+ /**
94
+ * 模块注册进外壳的那个口:注册一份面(拿回注销函数)、列出已装 unit。
95
+ */
66
96
  export interface UnitClientApi {
67
97
  registerUnit(face: UnitClientFace): () => void;
68
98
  manifests(): readonly UnitManifest[];
@@ -1,10 +1,48 @@
1
+ /**
2
+ * 自绘图标的契约:只给边长像素。
3
+ */
1
4
  export interface IconProps {
2
5
  size?: number;
3
6
  }
7
+ /**
8
+ * 会话图标:一枚对话气泡,dsh 的图标表里没有,留给我们自己用;默认 16px。
9
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
10
+ * @returns 一枚 `aria-hidden` 的 svg。
11
+ */
4
12
  export declare function IconConversation({ size }: IconProps): JSX.Element;
13
+ /**
14
+ * 品牌标:侧栏顶上那枚工作台方块标;默认 24px(它是品牌物,别拿它当通用图标)。
15
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
16
+ * @returns 一枚 `aria-hidden` 的 svg。
17
+ */
5
18
  export declare function IconBrandMark({ size }: IconProps): JSX.Element;
19
+ /**
20
+ * opencli 的标:包类型那一格用它;颜色写死的品牌物,不跟主题走。默认 16px。
21
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
22
+ * @returns 一枚 `aria-hidden` 的 svg。
23
+ */
6
24
  export declare function IconOpencli({ size }: IconProps): JSX.Element;
25
+ /**
26
+ * npm 的标:包类型那一格用它;保留品牌红,不跟主题走。默认 16px。
27
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
28
+ * @returns 一枚 `aria-hidden` 的 svg。
29
+ */
7
30
  export declare function IconNpm({ size }: IconProps): JSX.Element;
31
+ /**
32
+ * 四宫格:"模块"这个概念的通用单色图标(侧栏、面板那颗钮、市场节的标题);默认 16px。
33
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
34
+ * @returns 一枚 `aria-hidden` 的 svg。
35
+ */
8
36
  export declare function IconModules({ size }: IconProps): JSX.Element;
37
+ /**
38
+ * 模块类型标:渐变方块 + 白四宫格,用在"这是个模块"的行首;品牌物,颜色不跟主题走。默认 16px。
39
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
40
+ * @returns 一枚 `aria-hidden` 的 svg。
41
+ */
9
42
  export declare function IconModuleMark({ size }: IconProps): JSX.Element;
43
+ /**
44
+ * 面板 / 卡片那类的图标:整屏与柱状那种形状,给"面板"这一档用;默认 16px。
45
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
46
+ * @returns 一枚 `aria-hidden` 的 svg。
47
+ */
10
48
  export declare function IconPanelScreen({ size }: IconProps): JSX.Element;
@@ -2,15 +2,30 @@ import { h } from '../lib/react.js';
2
2
  function Shell({ size, strokeWidth = 1, viewBox = '0 0 16 16', children, }) {
3
3
  return (h("svg", { width: size, height: size, viewBox: viewBox, fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", strokeWidth: strokeWidth, style: { display: 'block' } }, children));
4
4
  }
5
+ /**
6
+ * 会话图标:一枚对话气泡,dsh 的图标表里没有,留给我们自己用;默认 16px。
7
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
8
+ * @returns 一枚 `aria-hidden` 的 svg。
9
+ */
5
10
  export function IconConversation({ size = 16 }) {
6
11
  return (h(Shell, { size: size, strokeWidth: 1.3 },
7
12
  h("path", { d: "M2.5 7.2c0-2.3 2.1-4.2 4.8-4.2h1.4c2.7 0 4.8 1.9 4.8 4.2s-2.1 4.2-4.8 4.2H7.5l-3.2 2v-2.3c-1.1-.8-1.8-2-1.8-3.9Z", stroke: "currentColor", strokeLinejoin: "round" })));
8
13
  }
14
+ /**
15
+ * 品牌标:侧栏顶上那枚工作台方块标;默认 24px(它是品牌物,别拿它当通用图标)。
16
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
17
+ * @returns 一枚 `aria-hidden` 的 svg。
18
+ */
9
19
  export function IconBrandMark({ size = 24 }) {
10
20
  return (h(Shell, { size: size, strokeWidth: 1.6, viewBox: "0 0 24 24" },
11
21
  h("rect", { x: 3, y: 3, width: 18, height: 18, rx: 5, stroke: "currentColor" }),
12
22
  h("path", { d: "M8 9.5h8M8 12.5h8M8 15.5h5", stroke: "currentColor", strokeLinecap: "round" })));
13
23
  }
24
+ /**
25
+ * opencli 的标:包类型那一格用它;颜色写死的品牌物,不跟主题走。默认 16px。
26
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
27
+ * @returns 一枚 `aria-hidden` 的 svg。
28
+ */
14
29
  export function IconOpencli({ size = 16 }) {
15
30
  return (h(Shell, { size: size, viewBox: "0 0 64 64" },
16
31
  h("defs", null,
@@ -21,10 +36,20 @@ export function IconOpencli({ size = 16 }) {
21
36
  h("rect", { width: 64, height: 64, rx: 14, fill: "#0a0a0f" }),
22
37
  h("text", { x: "50%", y: "54%", dominantBaseline: "middle", textAnchor: "middle", fontFamily: "monospace", fontWeight: 700, fontSize: 28, fill: "url(#opencli-mark)" }, ">_")));
23
38
  }
39
+ /**
40
+ * npm 的标:包类型那一格用它;保留品牌红,不跟主题走。默认 16px。
41
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
42
+ * @returns 一枚 `aria-hidden` 的 svg。
43
+ */
24
44
  export function IconNpm({ size = 16 }) {
25
45
  return (h(Shell, { size: size, viewBox: "0 0 1024 1024" },
26
46
  h("path", { d: "M64 337.76h896v298.72H512v49.792H312.896v-49.824H64z m49.792 248.928h99.552v-149.376h49.76v149.344h49.792v-199.104H113.792z m248.896-199.136v248.928h99.552v-49.792h99.552v-199.136z m99.552 49.792H512v99.584h-49.792z m149.344-49.792v199.136h99.552v-149.376h49.792v149.344h49.792v-149.344h49.792v149.344h49.792v-199.104z", fill: "#CB3837" })));
27
47
  }
48
+ /**
49
+ * 四宫格:"模块"这个概念的通用单色图标(侧栏、面板那颗钮、市场节的标题);默认 16px。
50
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
51
+ * @returns 一枚 `aria-hidden` 的 svg。
52
+ */
28
53
  export function IconModules({ size = 16 }) {
29
54
  return (h("svg", { width: size, height: size, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" },
30
55
  h("rect", { x: "2.5", y: "2.5", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
@@ -32,6 +57,11 @@ export function IconModules({ size = 16 }) {
32
57
  h("rect", { x: "2.5", y: "8.9", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" }),
33
58
  h("rect", { x: "8.9", y: "8.9", width: "4.6", height: "4.6", rx: "1.2", stroke: "currentColor", strokeWidth: "1.2" })));
34
59
  }
60
+ /**
61
+ * 模块类型标:渐变方块 + 白四宫格,用在"这是个模块"的行首;品牌物,颜色不跟主题走。默认 16px。
62
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
63
+ * @returns 一枚 `aria-hidden` 的 svg。
64
+ */
35
65
  export function IconModuleMark({ size = 16 }) {
36
66
  return (h(Shell, { size: size, viewBox: "0 0 24 24" },
37
67
  h("defs", null,
@@ -45,6 +75,11 @@ export function IconModuleMark({ size = 16 }) {
45
75
  h("rect", { x: "4.6", y: "13.2", width: "6.2", height: "6.2", rx: "1.9", fill: "#ffffff", fillOpacity: 0.78 }),
46
76
  h("rect", { x: "13.2", y: "13.2", width: "6.2", height: "6.2", rx: "1.9", fill: "#ffffff" })));
47
77
  }
78
+ /**
79
+ * 面板 / 卡片那类的图标:整屏与柱状那种形状,给"面板"这一档用;默认 16px。
80
+ * @param props.size - 边长像素,同时给 `width` 与 `height`。
81
+ * @returns 一枚 `aria-hidden` 的 svg。
82
+ */
48
83
  export function IconPanelScreen({ size = 16 }) {
49
84
  return (h("svg", { width: size, height: size, viewBox: "0 0 1024 1024", fill: "currentColor", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", style: { display: 'block', overflow: 'hidden' } },
50
85
  h("path", { d: "M939 112c17.673 0 32 14.327 32 32v554.667c0 17.673-14.327 32-32 32l-394.5-0.001v96c0 3.74-0.642 7.331-1.82 10.668H768.4c17.673 0 32 14.326 32 32 0 17.496-14.042 31.712-31.47 31.995l-0.53 0.004H256.6c-17.673 0-32-14.327-32-32 0-17.496 14.042-31.713 31.47-31.995l0.53-0.005h225.721a31.923 31.923 0 0 1-1.817-10.137l-0.004-0.53v-96H86c-17.496 0-31.713-14.041-31.996-31.47l-0.004-0.53V144c0-17.673 14.327-32 32-32z m-32 64H118v490.666h789V176zM341.9 432c17.496 0 31.713 14.042 31.996 31.47l0.004 0.53v85.333c0 17.673-14.327 32-32 32-17.496 0-31.713-14.041-31.996-31.47l-0.004-0.53V464c0-17.673 14.327-32 32-32z m170.6-85.333c17.496 0 31.713 14.041 31.996 31.47l0.004 0.53v170.666c0 17.673-14.327 32-32 32-17.496 0-31.713-14.041-31.996-31.47l-0.004-0.53V378.667c0-17.673 14.327-32 32-32z m170.6-85.334c17.496 0 31.713 14.042 31.996 31.471l0.004 0.53v256c0 17.672-14.327 32-32 32-17.496 0-31.713-14.042-31.996-31.471l-0.004-0.53v-256c0-17.673 14.327-32 32-32z" })));