@rainbow-oh/yee-c 0.8.16 → 0.8.18

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 (61) hide show
  1. package/dist/cjs/Select/demo/loading.d.ts +3 -0
  2. package/dist/cjs/Select/demo/loading.js +61 -0
  3. package/dist/cjs/Select/interface.d.ts +6 -1
  4. package/dist/cjs/Select/select.js +3 -0
  5. package/dist/cjs/Selector/selector.js +10 -1
  6. package/dist/cjs/TableSelect/interface.d.ts +5 -0
  7. package/dist/cjs/TableSelect/table-select.js +3 -0
  8. package/dist/cjs/Tree/interface.d.ts +16 -0
  9. package/dist/cjs/Tree/tree-node.js +7 -2
  10. package/dist/cjs/Tree/tree.d.ts +2 -1
  11. package/dist/cjs/Tree/tree.js +6 -2
  12. package/dist/cjs/Tree/utils/tree-tools.d.ts +1 -0
  13. package/dist/cjs/Tree/utils/tree-tools.js +3 -1
  14. package/dist/cjs/TreeSelect/interface.d.ts +5 -0
  15. package/dist/cjs/TreeSelect/tree-select.js +4 -1
  16. package/dist/cjs/style/themes.css +1 -1
  17. package/dist/cjs/style/variables.css +1 -1
  18. package/dist/cjs/version.d.ts +1 -1
  19. package/dist/cjs/version.js +1 -1
  20. package/dist/esm/Select/demo/loading.d.ts +3 -0
  21. package/dist/esm/Select/demo/loading.js +32 -0
  22. package/dist/esm/Select/interface.d.ts +6 -1
  23. package/dist/esm/Select/select.js +3 -1
  24. package/dist/esm/Selector/selector.js +5 -1
  25. package/dist/esm/TableSelect/interface.d.ts +5 -0
  26. package/dist/esm/TableSelect/table-select.js +3 -1
  27. package/dist/esm/Tree/interface.d.ts +16 -0
  28. package/dist/esm/Tree/tree-node.js +12 -2
  29. package/dist/esm/Tree/tree.d.ts +2 -1
  30. package/dist/esm/Tree/tree.js +15 -13
  31. package/dist/esm/Tree/utils/tree-tools.d.ts +1 -0
  32. package/dist/esm/Tree/utils/tree-tools.js +4 -1
  33. package/dist/esm/TreeSelect/interface.d.ts +5 -0
  34. package/dist/esm/TreeSelect/tree-select.js +3 -1
  35. package/dist/esm/style/themes.css +1 -1
  36. package/dist/esm/style/variables.css +1 -1
  37. package/dist/esm/version.d.ts +1 -1
  38. package/dist/esm/version.js +1 -1
  39. package/dist/umd/yee-c.min.js +1 -1
  40. package/package.json +1 -1
  41. package/src/Select/demo/loading.tsx +28 -0
  42. package/src/Select/index.en-US.md +2 -0
  43. package/src/Select/index.zh-CN.md +2 -0
  44. package/src/Select/interface.ts +10 -3
  45. package/src/Select/select.tsx +2 -0
  46. package/src/Selector/selector.tsx +10 -1
  47. package/src/TableSelect/index.en-US.md +1 -0
  48. package/src/TableSelect/index.zh-CN.md +1 -0
  49. package/src/TableSelect/interface.ts +5 -0
  50. package/src/TableSelect/table-select.tsx +2 -0
  51. package/src/Tree/index.en-US.md +20 -2
  52. package/src/Tree/index.zh-CN.md +20 -2
  53. package/src/Tree/interface.ts +16 -1
  54. package/src/Tree/tree-node.tsx +15 -2
  55. package/src/Tree/tree.tsx +6 -2
  56. package/src/Tree/utils/tree-tools.ts +4 -1
  57. package/src/TreeSelect/index.en-US.md +1 -0
  58. package/src/TreeSelect/index.zh-CN.md +1 -0
  59. package/src/TreeSelect/interface.ts +5 -0
  60. package/src/TreeSelect/tree-select.tsx +2 -0
  61. package/src/version.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rainbow-oh/yee-c",
3
- "version": "0.8.16",
3
+ "version": "0.8.18",
4
4
  "description": "yee basic components",
5
5
  "keywords": [
6
6
  "react",
@@ -0,0 +1,28 @@
1
+ import { Select, Space } from '@rainbow-oh/yee-c';
2
+ import React from 'react';
3
+
4
+ const options = [
5
+ { label: 'Apple', value: 'apple' },
6
+ { label: 'Banana', value: 'banana' },
7
+ { label: 'Orange', value: 'orange' },
8
+ ];
9
+
10
+ export default () => {
11
+ return (
12
+ <Space direction="vertical">
13
+ <Select
14
+ loading
15
+ options={options}
16
+ style={{ width: 200 }}
17
+ placeholder="Loading"
18
+ />
19
+ <Select
20
+ loading
21
+ disabled
22
+ defaultValue="apple"
23
+ options={options}
24
+ style={{ width: 200 }}
25
+ />
26
+ </Space>
27
+ );
28
+ };
@@ -17,6 +17,7 @@ Select component for choosing from a set of options.
17
17
  <code src="./demo/basic.tsx" title="Basic" description="Basic usage of Select"></code>
18
18
  <code src="./demo/size.tsx" title="Size" description="Different sizes of Select"></code>
19
19
  <code src="./demo/disabled.tsx" title="Disabled" description="Disabled Select"></code>
20
+ <code src="./demo/loading.tsx" title="Loading" description="Loading Select, optionally combined with disabled"></code>
20
21
  <code src="./demo/allowClear.tsx" title="Allow Clear" description="Allow clear selected value"></code>
21
22
  <code src="./demo/multiple.tsx" title="Multiple" description="Multiple selection mode"></code>
22
23
  <code src="./demo/search.tsx" title="Search" description="Searchable Select"></code>
@@ -39,6 +40,7 @@ Select component for choosing from a set of options.
39
40
  | defaultValue | `string \| number \| Array<string \| number>` | Default value | - |
40
41
  | value | `string \| number \| Array<string \| number>` | Controlled value | - |
41
42
  | disabled | `boolean` | Whether disabled | - |
43
+ | loading | `boolean` | Whether data is loading; displays a spinner in the selector suffix | `false` |
42
44
  | placeholder | `string` | Placeholder text | - |
43
45
  | placement | `'top' \| 'bottom' \| 'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight'` | Dropdown position | - |
44
46
  | searchable | `boolean` | Whether searchable | - |
@@ -17,6 +17,7 @@ toc: 'content'
17
17
  <code src="./demo/basic.tsx" title="基础用法" description="Select的基础用法"></code>
18
18
  <code src="./demo/size.tsx" title="尺寸" description="不同尺寸的Select"></code>
19
19
  <code src="./demo/disabled.tsx" title="禁用" description="禁用的Select"></code>
20
+ <code src="./demo/loading.tsx" title="加载中" description="加载中的 Select,可与 disabled 组合使用"></code>
20
21
  <code src="./demo/allowClear.tsx" title="可清除" description="可清除已选值"></code>
21
22
  <code src="./demo/multiple.tsx" title="多选" description="多选模式"></code>
22
23
  <code src="./demo/search.tsx" title="可搜索" description="可搜索的Select"></code>
@@ -39,6 +40,7 @@ toc: 'content'
39
40
  | defaultValue | `string \| number \| Array<string \| number>` | 默认值 | - |
40
41
  | value | `string \| number \| Array<string \| number>` | 受控值 | - |
41
42
  | disabled | `boolean` | 是否禁用 | - |
43
+ | loading | `boolean` | 是否处于加载状态,加载时选择框后缀显示加载图标 | `false` |
42
44
  | placeholder | `string` | 选择框默认文本 | - |
43
45
  | placement | `'top' \| 'bottom' \| 'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight'` | 下拉框弹出位置 | - |
44
46
  | searchable | `boolean` | 是否可搜索 | - |
@@ -1,7 +1,6 @@
1
- import type { TriggerProps } from '../Trigger';
2
1
  import type { SelectorProps } from '../Selector';
2
+ import type { TriggerProps } from '../Trigger';
3
3
  import type { DataAttributeProps } from '../utils/types';
4
-
5
4
  export type Option = {
6
5
  /**
7
6
  * Whether disabled
@@ -26,7 +25,10 @@ export type Option = {
26
25
  };
27
26
 
28
27
  export interface SelectProps
29
- extends DataAttributeProps, Pick<SelectorProps, 'size'>, Omit<TriggerProps, 'popup' | 'children'> {
28
+ extends
29
+ DataAttributeProps,
30
+ Pick<SelectorProps, 'size'>,
31
+ Omit<TriggerProps, 'popup' | 'children'> {
30
32
  /**
31
33
  * Custom class name prefix
32
34
  * */
@@ -60,6 +62,11 @@ export interface SelectProps
60
62
  * Whether disabled
61
63
  */
62
64
  disabled?: boolean;
65
+ /**
66
+ * Whether data is loading
67
+ * @default false
68
+ */
69
+ loading?: boolean;
63
70
  /**
64
71
  * Placeholder text for the select box
65
72
  */
@@ -51,6 +51,7 @@ const Select = (baseprops: SelectProps) => {
51
51
  defaultValue,
52
52
  optionFilterProp = 'label',
53
53
  disabled,
54
+ loading,
54
55
  onChange,
55
56
  onFilter,
56
57
  virtual,
@@ -233,6 +234,7 @@ const Select = (baseprops: SelectProps) => {
233
234
  value={searchValue}
234
235
  options={options}
235
236
  disabled={disabled}
237
+ loading={loading}
236
238
  selectedKeys={mergedValue}
237
239
  onOpenChange={handleOpenChange}
238
240
  onClear={handleClear}
@@ -224,7 +224,16 @@ const Selector = React.forwardRef(
224
224
  return (
225
225
  <span className={`${prefixCls}-arrow`}>
226
226
  {loading ? (
227
- <Spin size="small" />
227
+ <Spin
228
+ variant="ring"
229
+ size="small"
230
+ style={
231
+ {
232
+ '--m-indicator-dot-bg-color':
233
+ 'var(--yee-text-color-secondary)',
234
+ } as React.CSSProperties
235
+ }
236
+ />
228
237
  ) : suffix ? (
229
238
  typeof suffix === 'function' ? (
230
239
  suffix()
@@ -43,6 +43,7 @@ A component for selecting one or more options from table data, combining feature
43
43
  | value | `SelectionKeyType \| SelectionKeyType[]` | Controlled value | - |
44
44
  | defaultValue | `SelectionKeyType \| SelectionKeyType[]` | Default value | - |
45
45
  | disabled | `boolean` | Whether disabled | - |
46
+ | loading | `boolean` | Whether data is loading; displays a gray loading indicator | `false` |
46
47
  | placement | `'bottomLeft' \| 'topLeft'` | Popup placement | `'bottomLeft'` |
47
48
  | searchable | `boolean` | Whether searchable | `true` |
48
49
  | searchOnInput | `boolean` | Whether to search while typing | `true` |
@@ -43,6 +43,7 @@ toc: 'content'
43
43
  | value | `SelectionKeyType \| SelectionKeyType[]` | 受控值 | - |
44
44
  | defaultValue | `SelectionKeyType \| SelectionKeyType[]` | 默认值 | - |
45
45
  | disabled | `boolean` | 是否禁用 | - |
46
+ | loading | `boolean` | 是否处于加载状态,加载时显示灰色加载图标 | `false` |
46
47
  | placement | `'bottomLeft' \| 'topLeft'` | 弹出层位置 | `'bottomLeft'` |
47
48
  | searchable | `boolean` | 是否可搜索 | `true` |
48
49
  | searchOnInput | `boolean` | 是否边输入边搜索 | `true` |
@@ -131,6 +131,11 @@ export interface TableSelectProps
131
131
  * Whether disabled
132
132
  */
133
133
  disabled?: boolean;
134
+ /**
135
+ * Whether data is loading
136
+ * @default false
137
+ */
138
+ loading?: boolean;
134
139
  /**
135
140
  * Input direction (for special scenarios)
136
141
  */
@@ -37,6 +37,7 @@ const TableSelect = (baseprops: TableSelectProps) => {
37
37
  defaultValue,
38
38
  placement = 'bottomLeft',
39
39
  disabled,
40
+ loading,
40
41
  rowSelection,
41
42
  dataSource,
42
43
  rowKey = 'id',
@@ -175,6 +176,7 @@ const TableSelect = (baseprops: TableSelectProps) => {
175
176
  options: selectorOptions,
176
177
  open: open,
177
178
  disabled: disabled,
179
+ loading: loading,
178
180
  value: searchValue,
179
181
  selectedKeys: mergedValue,
180
182
  onSearch: handleSearch,
@@ -44,7 +44,8 @@ Tree is a hierarchical data display component.
44
44
  | icon | `React.ReactNode \| ((props: TreeProps<T>) => React.ReactNode)` | Icon before title (requires showIcon) | - |
45
45
  | switcherIcon | `[React.ReactNode, React.ReactNode]` | Expand/collapse switcher icons | - |
46
46
  | multiple | `boolean` | Whether tree node supports multiple selection | `false` |
47
- | fieldNames | `{ key?: keyof T; label?: keyof T; children?: keyof T }` | Custom key, label, children fields | - |
47
+ | fieldNames | `{ key?: keyof T; label?: keyof T; children?: keyof T; extra?: keyof T }` | Custom key, label, children, extra fields | - |
48
+ | labelRender | `(node: TreeNode<T>) => React.ReactNode` | Custom label render function. When provided, takes full control of the label area; the node's `extra` will NOT be appended automatically (access it via `node.extra` in your render function) | - |
48
49
  | loadData | `() => void` | Async load data | - |
49
50
  | dataSource | `Array<T> \| T` | Data source | - |
50
51
  | checkedKeys | `Array<string \| number>` | Checked tree nodes (controlled) | - |
@@ -53,4 +54,21 @@ Tree is a hierarchical data display component.
53
54
  | defaultSelectedKeys | `Array<string \| number>` | Default selected tree nodes | - |
54
55
  | onCheck | `(checkedKeys: Array<string \| number>, params: { checked: boolean; checkedNodes: T[]; node: T }) => void` | Callback when checkbox is checked | - |
55
56
  | onSelect | `(selectedKeys: Array<string \| number>, params: { selected: boolean; selectedNodes: T[]; node: T }) => void` | Callback when tree node is clicked | - |
56
- | onExpand | `(expandedKeys: Array<string \| number>, params: { expanded: boolean; expandedNodes: T[]; node: T[] }) => void` | Callback when expand/collapse | - |
57
+ | onExpand | `(expandedKeys: Array<string \| number>, params: { expanded: boolean; expandedNodes: T[]; node: T[] }) => void` | Callback when expand/collapse | - |
58
+
59
+ ### Data Node Fields
60
+
61
+ | Property | Type | Description |
62
+ | --- | --- | --- |
63
+ | key | `string \| number` | Unique node identifier |
64
+ | label | `string` | Display text |
65
+ | children | `Array<T>` | Child nodes |
66
+ | extra | `React.ReactNode \| ((node: T) => React.ReactNode)` | Extra content rendered after the label (e.g. tags, badges, action buttons). When `labelRender` is provided, extra is NOT rendered automatically — access it via `node.extra` in your render function |
67
+ | disabled | `boolean` | Whether disabled |
68
+ | icon | `React.ReactNode \| (() => React.ReactNode)` | Custom icon |
69
+
70
+ ### Relationship between extra and labelRender
71
+
72
+ - **`extra` only**: Automatically appended after the default label text. Ideal for simple tags, badges, etc.
73
+ - **`labelRender` only**: Full custom rendering of the node label area.
74
+ - **Both present**: `labelRender` takes priority; extra is NOT automatically appended. To use extra in your custom render, access it via the callback parameter `node.extra`.
@@ -44,7 +44,8 @@ toc: 'content'
44
44
  | icon | `React.ReactNode \| ((props: TreeProps<T>) => React.ReactNode)` | 标题前的图标,需设置showIcon为true | - |
45
45
  | switcherIcon | `[React.ReactNode, React.ReactNode]` | 展开收起按钮图标 | - |
46
46
  | multiple | `boolean` | 树节点数据是否支持多选 | `false` |
47
- | fieldNames | `{ key?: keyof T; label?: keyof T; children?: keyof T }` | 自定义节点key, label, children字段 | - |
47
+ | fieldNames | `{ key?: keyof T; label?: keyof T; children?: keyof T; extra?: keyof T }` | 自定义节点key, label, children, extra字段 | - |
48
+ | labelRender | `(node: TreeNode<T>) => React.ReactNode` | 自定义节点标签渲染函数。提供后将完全接管 label 区域的渲染,此时节点的 `extra` 不会自动追加(可通过 `node.extra` 自行渲染) | - |
48
49
  | loadData | `() => void` | 异步加载数据 | - |
49
50
  | dataSource | `Array<T> \| T` | 数据源 | - |
50
51
  | checkedKeys | `Array<string \| number>` | 选中复选框的树节点,受控 | - |
@@ -53,4 +54,21 @@ toc: 'content'
53
54
  | defaultSelectedKeys | `Array<string \| number>` | 设置默认选中的树节点,多选需设置 multiple 为 true | - |
54
55
  | onCheck | `(checkedKeys: Array<string \| number>, params: { checked: boolean; checkedNodes: T[]; node: T }) => void` | 复选框选中的回调 | - |
55
56
  | onSelect | `(selectedKeys: Array<string \| number>, params: { selected: boolean; selectedNodes: T[]; node: T }) => void` | 点击树节点的回调 | - |
56
- | onExpand | `(expandedKeys: Array<string \| number>, params: { expanded: boolean; expandedNodes: T[]; node: T[] }) => void` | 展开收起的回调 | - |
57
+ | onExpand | `(expandedKeys: Array<string \| number>, params: { expanded: boolean; expandedNodes: T[]; node: T[] }) => void` | 展开收起的回调 | - |
58
+
59
+ ### 数据节点字段
60
+
61
+ | 属性名 | 类型 | 描述 |
62
+ | --- | --- | --- |
63
+ | key | `string \| number` | 节点唯一标识 |
64
+ | label | `string` | 节点显示文本 |
65
+ | children | `Array<T>` | 子节点 |
66
+ | extra | `React.ReactNode \| ((node: T) => React.ReactNode)` | 节点标签后的附加内容(如标签、徽标、操作按钮)。当 `labelRender` 存在时不会自动渲染,需在 `labelRender` 中通过 `node.extra` 自行处理 |
67
+ | disabled | `boolean` | 是否禁用 |
68
+ | icon | `React.ReactNode \| (() => React.ReactNode)` | 自定义图标 |
69
+
70
+ ### extra 与 labelRender 的关系
71
+
72
+ - **仅使用 `extra`**:在默认 label 文本后自动追加 extra 内容,适合简单的标签、徽标等场景
73
+ - **仅使用 `labelRender`**:完全自定义节点标签区域的渲染
74
+ - **同时存在时**:`labelRender` 优先级更高,extra 不会自动追加。如需在自定义渲染中使用 extra,可通过回调参数 `node.extra` 取得原始值自行渲染
@@ -64,6 +64,13 @@ export type TreeNode<T> = {
64
64
  * All descendant uids (collected bottom-up). Used for check/uncheck propagation.
65
65
  */
66
66
  childUids?: Array<string>;
67
+ /**
68
+ * Extra content rendered after the label (e.g. tags, badges, action buttons).
69
+ * Only takes effect when `labelRender` is NOT provided at the Tree level.
70
+ * When `labelRender` is present, access this value via `node.extra` in your
71
+ * custom render function.
72
+ */
73
+ extra?: React.ReactNode | ((node: T) => React.ReactNode);
67
74
  /**
68
75
  * Original data
69
76
  */
@@ -162,10 +169,18 @@ export interface TreeProps<T> extends DataAttributeProps {
162
169
  * @default false
163
170
  */
164
171
  multiple?: boolean;
172
+ /**
173
+ * Custom render function for node label.
174
+ * When provided, takes full control of the label area rendering.
175
+ * The node's `extra` will NOT be appended automatically in this case;
176
+ * access it via `node.extra` if you need it in your custom render.
177
+ * The original `label` string is still used for `title` attribute fallback.
178
+ */
179
+ labelRender?: (node: TreeNode<T>) => React.ReactNode;
165
180
  /**
166
181
  * Customize node key, title, children field names
167
182
  */
168
- fieldNames?: { key?: keyof T; label?: keyof T; children?: keyof T };
183
+ fieldNames?: { key?: keyof T; label?: keyof T; children?: keyof T; extra?: keyof T };
169
184
  /**
170
185
  * Asynchronous data loading
171
186
  */
@@ -21,6 +21,7 @@ const Node = <T extends Record<string, unknown> = any>(
21
21
  disabled,
22
22
  depth,
23
23
  icon,
24
+ extra,
24
25
  original,
25
26
  lines,
26
27
  } = node;
@@ -35,6 +36,7 @@ const Node = <T extends Record<string, unknown> = any>(
35
36
  indeterminateUids,
36
37
  expandedUids,
37
38
  switcherIcon,
39
+ labelRender,
38
40
  draggable,
39
41
  draggingUid,
40
42
  dropState,
@@ -105,6 +107,14 @@ const Node = <T extends Record<string, unknown> = any>(
105
107
  const _icon =
106
108
  typeof mergedIcon === 'function' ? mergedIcon(original) : mergedIcon;
107
109
 
110
+ // labelRender takes full control of the label content when provided
111
+ const content = labelRender ? labelRender(node) : label;
112
+
113
+ // extra: appended after the label content (only when labelRender is NOT used)
114
+ const _extra = !labelRender && extra
115
+ ? (typeof extra === 'function' ? extra(original) : extra)
116
+ : null;
117
+
108
118
  return (
109
119
  <Button
110
120
  className={clsx(`${prefixCls}-node-label`, {
@@ -116,7 +126,10 @@ const Node = <T extends Record<string, unknown> = any>(
116
126
  icon={showIcon ? _icon : undefined}
117
127
  onClick={disabled ? undefined : () => onSelect(uid)}
118
128
  >
119
- {label}
129
+ {content}
130
+ {_extra && (
131
+ <span className={`${prefixCls}-node-extra`}>{_extra}</span>
132
+ )}
120
133
  </Button>
121
134
  );
122
135
  };
@@ -139,7 +152,7 @@ const Node = <T extends Record<string, unknown> = any>(
139
152
  <span
140
153
  aria-hidden="true"
141
154
  className={`${prefixCls}-node-indent`}
142
- key={index}
155
+ key={`node-empty-${index}`}
143
156
  ></span>
144
157
  ));
145
158
  };
package/src/Tree/tree.tsx CHANGED
@@ -35,6 +35,7 @@ export const TreeContext = createContext<{
35
35
  icon?: React.ReactNode | ((props: any) => React.ReactNode);
36
36
  showLine?: boolean;
37
37
  switcherIcon?: [React.ReactNode, React.ReactNode];
38
+ labelRender?: (node: TreeNode<any>) => React.ReactNode;
38
39
  selectedUids: Set<string>;
39
40
  checkedUids: Set<string>;
40
41
  indeterminateUids: Set<string>;
@@ -203,6 +204,7 @@ const Tree = <T extends Record<string, unknown> = any>(
203
204
  onSelect,
204
205
  onCheck,
205
206
  onExpand,
207
+ labelRender,
206
208
  virtual = false,
207
209
  height,
208
210
  itemHeight = 28,
@@ -553,6 +555,7 @@ const Tree = <T extends Record<string, unknown> = any>(
553
555
  icon,
554
556
  showLine,
555
557
  switcherIcon,
558
+ labelRender,
556
559
  selectedUids: selectedUidSet,
557
560
  checkedUids: checkedUidSet,
558
561
  indeterminateUids: indeterminateUidSet,
@@ -575,6 +578,7 @@ const Tree = <T extends Record<string, unknown> = any>(
575
578
  icon,
576
579
  showLine,
577
580
  switcherIcon,
581
+ labelRender,
578
582
  selectedUidSet,
579
583
  checkedUidSet,
580
584
  indeterminateUidSet,
@@ -687,7 +691,7 @@ const Tree = <T extends Record<string, unknown> = any>(
687
691
  >
688
692
  <TreeContext.Provider value={contextValue}>
689
693
  <AnimatePresence initial={false}>
690
- {segments.map((segment) => {
694
+ {segments.map((segment, index) => {
691
695
  if (segment.type === 'node') {
692
696
  return (
693
697
  <TreeNodeComp node={segment.node} key={segment.node.uid} />
@@ -698,7 +702,7 @@ const Tree = <T extends Record<string, unknown> = any>(
698
702
  // source and cancels the drag before dragOver/drop can fire.
699
703
  return (
700
704
  <motion.div
701
- key={segment.pUid + '\x01children'}
705
+ key={segment.pUid + index + '\x01children'}
702
706
  initial={{ height: 0, opacity: 0 }}
703
707
  animate={{ height: 'auto', opacity: 1 }}
704
708
  exit={{ height: 0, opacity: 0 }}
@@ -181,6 +181,7 @@ export function tree2array<T extends Record<string, unknown>>(
181
181
  key: keyof T;
182
182
  label: keyof T;
183
183
  children: keyof T;
184
+ extra?: keyof T;
184
185
  },
185
186
  ): [TreeNode<T>[], Map<string, TreeNode<T>>] {
186
187
  if (!tree || (Array.isArray(tree) && tree.length === 0))
@@ -190,7 +191,7 @@ export function tree2array<T extends Record<string, unknown>>(
190
191
  const res: TreeNode<T>[] = [];
191
192
  const map = new Map<string, TreeNode<T>>();
192
193
 
193
- const { key, label, children } = fieldNames;
194
+ const { key, label, children, extra } = fieldNames;
194
195
 
195
196
  /**
196
197
  * Walk returns the list of descendant uids so the parent can collect them
@@ -216,6 +217,7 @@ export function tree2array<T extends Record<string, unknown>>(
216
217
  const rawKey = node[key] as string | number;
217
218
  const _label = node[label];
218
219
  const _children = node[children] as T[] | undefined;
220
+ const _extra = extra ? node[extra] : node.extra;
219
221
  const nextPath = [...path, rawKey];
220
222
  const uid = pUid ? `${pUid}\x00${String(rawKey)}` : String(rawKey);
221
223
 
@@ -227,6 +229,7 @@ export function tree2array<T extends Record<string, unknown>>(
227
229
  key: rawKey,
228
230
  label: _label as string,
229
231
  title: node.title as string | undefined,
232
+ extra: _extra as React.ReactNode | ((node: T) => React.ReactNode) | undefined,
230
233
  path,
231
234
  pUid,
232
235
  depth,
@@ -37,6 +37,7 @@ Tree selection control.
37
37
  | defaultValue | `string \| number \| Array<string \| number>` | Default selected value | - |
38
38
  | value | `string \| number \| Array<string \| number>` | Selected value (controlled) | - |
39
39
  | disabled | `boolean` | Disable the component | - |
40
+ | loading | `boolean` | Whether data is loading; displays a gray loading indicator | `false` |
40
41
  | placeholder | `string` | Placeholder text | - |
41
42
  | placement | `'top' \| 'bottom' \| 'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight'` | Dropdown placement | `'bottomLeft'` |
42
43
  | searchable | `boolean` | Enable search functionality | `true` |
@@ -37,6 +37,7 @@ toc: 'content'
37
37
  | defaultValue | `string \| number \| Array<string \| number>` | 默认值 | - |
38
38
  | value | `string \| number \| Array<string \| number>` | 受控值 | - |
39
39
  | disabled | `boolean` | 是否禁用 | - |
40
+ | loading | `boolean` | 是否处于加载状态,加载时显示灰色加载图标 | `false` |
40
41
  | placeholder | `string` | 选择框默认文本 | - |
41
42
  | placement | `'top' \| 'bottom' \| 'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight'` | 下拉框弹出位置 | `'bottomLeft'` |
42
43
  | searchable | `boolean` | 是否可搜索 | `true` |
@@ -37,6 +37,11 @@ export interface TreeSelectProps<T = any>
37
37
  * Whether disabled
38
38
  */
39
39
  disabled?: boolean;
40
+ /**
41
+ * Whether data is loading
42
+ * @default false
43
+ */
44
+ loading?: boolean;
40
45
  /**
41
46
  * Placeholder text for the select box
42
47
  */
@@ -32,6 +32,7 @@ const TreeSelect = <T extends Record<string, unknown> = any>(
32
32
  defaultValue,
33
33
  checkable = false,
34
34
  multiple = false, // eslint-disable-line @typescript-eslint/no-unused-vars
35
+ loading,
35
36
  optionLabelProp = 'label',
36
37
  onChange,
37
38
  onFilter,
@@ -242,6 +243,7 @@ const TreeSelect = <T extends Record<string, unknown> = any>(
242
243
  mode={mode}
243
244
  value={searchValue}
244
245
  options={selectedOptions}
246
+ loading={loading}
245
247
  selectedKeys={mergedValue}
246
248
  onOpenChange={handleOpenChange}
247
249
  onClear={handleClear}
package/src/version.ts CHANGED
@@ -4,7 +4,7 @@ declare global {
4
4
  }
5
5
  }
6
6
 
7
- export const version = "0.8.16";
7
+ export const version = "0.8.18";
8
8
 
9
9
  if (typeof window !== 'undefined') {
10
10
  window.__yee_c_version__ = version;