@rainbow-oh/yee-c 0.6.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/cjs/Button/style/index.less +5 -4
  2. package/dist/cjs/Drawer/drawer.js +1 -1
  3. package/dist/cjs/Drawer/interface.d.ts +1 -1
  4. package/dist/cjs/Drawer/style/index.less +1 -0
  5. package/dist/cjs/Form/form-store.d.ts +2 -1
  6. package/dist/cjs/Form/form-store.js +32 -17
  7. package/dist/cjs/List/demo/virtual.d.ts +3 -0
  8. package/dist/cjs/List/demo/virtual.js +53 -0
  9. package/dist/cjs/List/hooks/useListKeyboard.d.ts +28 -0
  10. package/dist/cjs/List/hooks/useListKeyboard.js +188 -0
  11. package/dist/cjs/List/interface.d.ts +29 -2
  12. package/dist/cjs/List/list.js +141 -21
  13. package/dist/cjs/List/style/index.less +24 -0
  14. package/dist/cjs/Select/demo/columns.d.ts +3 -0
  15. package/dist/cjs/Select/demo/columns.js +62 -0
  16. package/dist/cjs/Select/hooks/useSelectKeyboard.d.ts +13 -1
  17. package/dist/cjs/Select/hooks/useSelectKeyboard.js +81 -10
  18. package/dist/cjs/Select/interface.d.ts +30 -3
  19. package/dist/cjs/Select/option.js +4 -3
  20. package/dist/cjs/Select/options.js +90 -8
  21. package/dist/cjs/Select/select.js +32 -8
  22. package/dist/cjs/Select/style/index.less +14 -0
  23. package/dist/cjs/Selector/interface.d.ts +4 -0
  24. package/dist/cjs/Selector/selector.js +5 -3
  25. package/dist/cjs/Table/hooks/useColumns.js +1 -1
  26. package/dist/cjs/Table/interface.d.ts +1 -1
  27. package/dist/cjs/Table/style/index.less +35 -11
  28. package/dist/cjs/Table/table.js +57 -7
  29. package/dist/cjs/Table/tbody/cell.js +1 -1
  30. package/dist/cjs/Table/util/header.d.ts +3 -1
  31. package/dist/cjs/Table/util/header.js +30 -3
  32. package/dist/cjs/Tree/demo/draggable.js +2 -0
  33. package/dist/cjs/Tree/interface.d.ts +46 -23
  34. package/dist/cjs/Tree/tree-node.d.ts +1 -1
  35. package/dist/cjs/Tree/tree-node.js +30 -23
  36. package/dist/cjs/Tree/tree.d.ts +13 -12
  37. package/dist/cjs/Tree/tree.js +452 -227
  38. package/dist/cjs/Tree/utils/tree-tools.d.ts +43 -10
  39. package/dist/cjs/Tree/utils/tree-tools.js +129 -91
  40. package/dist/cjs/locale/context.d.ts +5 -4
  41. package/dist/cjs/locale/context.js +15 -8
  42. package/dist/cjs/locale/interface.d.ts +20 -0
  43. package/dist/cjs/locale/util.d.ts +3 -3
  44. package/dist/cjs/style/color.css +3 -0
  45. package/dist/cjs/style/size.css +2 -1
  46. package/dist/cjs/style/themes.css +1 -1
  47. package/dist/cjs/style/variables.css +6 -2
  48. package/dist/cjs/utils/isEqual.js +5 -7
  49. package/dist/cjs/version.d.ts +1 -1
  50. package/dist/cjs/version.js +1 -1
  51. package/dist/esm/Button/style/index.less +5 -4
  52. package/dist/esm/Drawer/drawer.js +2 -1
  53. package/dist/esm/Drawer/interface.d.ts +1 -1
  54. package/dist/esm/Drawer/style/index.less +1 -0
  55. package/dist/esm/Form/form-store.d.ts +2 -1
  56. package/dist/esm/Form/form-store.js +40 -19
  57. package/dist/esm/List/demo/virtual.d.ts +3 -0
  58. package/dist/esm/List/demo/virtual.js +22 -0
  59. package/dist/esm/List/hooks/useListKeyboard.d.ts +28 -0
  60. package/dist/esm/List/hooks/useListKeyboard.js +173 -0
  61. package/dist/esm/List/interface.d.ts +29 -2
  62. package/dist/esm/List/list.js +171 -14
  63. package/dist/esm/List/style/index.less +24 -0
  64. package/dist/esm/Select/demo/columns.d.ts +3 -0
  65. package/dist/esm/Select/demo/columns.js +36 -0
  66. package/dist/esm/Select/hooks/useSelectKeyboard.d.ts +13 -1
  67. package/dist/esm/Select/hooks/useSelectKeyboard.js +91 -14
  68. package/dist/esm/Select/interface.d.ts +30 -3
  69. package/dist/esm/Select/option.js +6 -2
  70. package/dist/esm/Select/options.js +114 -32
  71. package/dist/esm/Select/select.js +40 -11
  72. package/dist/esm/Select/style/index.less +14 -0
  73. package/dist/esm/Selector/interface.d.ts +4 -0
  74. package/dist/esm/Selector/selector.js +10 -4
  75. package/dist/esm/Table/hooks/useColumns.js +1 -1
  76. package/dist/esm/Table/interface.d.ts +1 -1
  77. package/dist/esm/Table/style/index.less +35 -11
  78. package/dist/esm/Table/table.js +54 -2
  79. package/dist/esm/Table/tbody/cell.js +1 -1
  80. package/dist/esm/Table/util/header.d.ts +3 -1
  81. package/dist/esm/Table/util/header.js +30 -2
  82. package/dist/esm/Tree/demo/draggable.js +2 -0
  83. package/dist/esm/Tree/interface.d.ts +46 -23
  84. package/dist/esm/Tree/tree-node.d.ts +1 -1
  85. package/dist/esm/Tree/tree-node.js +26 -31
  86. package/dist/esm/Tree/tree.d.ts +13 -12
  87. package/dist/esm/Tree/tree.js +572 -163
  88. package/dist/esm/Tree/utils/tree-tools.d.ts +43 -10
  89. package/dist/esm/Tree/utils/tree-tools.js +219 -104
  90. package/dist/esm/locale/context.d.ts +5 -4
  91. package/dist/esm/locale/context.js +25 -9
  92. package/dist/esm/locale/interface.d.ts +20 -0
  93. package/dist/esm/locale/util.d.ts +3 -3
  94. package/dist/esm/style/color.css +3 -0
  95. package/dist/esm/style/size.css +2 -1
  96. package/dist/esm/style/themes.css +1 -1
  97. package/dist/esm/style/variables.css +6 -2
  98. package/dist/esm/utils/isEqual.js +5 -7
  99. package/dist/esm/version.d.ts +1 -1
  100. package/dist/esm/version.js +1 -1
  101. package/dist/umd/yee-c.min.css +4 -4
  102. package/dist/umd/yee-c.min.js +1 -1
  103. package/package.json +1 -1
  104. package/src/Button/style/index.less +5 -4
  105. package/src/Drawer/drawer.tsx +1 -1
  106. package/src/Drawer/interface.ts +1 -0
  107. package/src/Drawer/style/index.less +1 -0
  108. package/src/Form/form-store.ts +42 -15
  109. package/src/List/demo/virtual.tsx +20 -0
  110. package/src/List/hooks/useListKeyboard.ts +235 -0
  111. package/src/List/index.en-US.md +6 -0
  112. package/src/List/index.zh-CN.md +6 -0
  113. package/src/List/interface.ts +29 -2
  114. package/src/List/list.tsx +157 -19
  115. package/src/List/style/index.less +24 -0
  116. package/src/Select/demo/columns.tsx +35 -0
  117. package/src/Select/hooks/useSelectKeyboard.ts +112 -15
  118. package/src/Select/index.en-US.md +4 -0
  119. package/src/Select/index.zh-CN.md +4 -0
  120. package/src/Select/interface.ts +31 -4
  121. package/src/Select/option.tsx +9 -3
  122. package/src/Select/options.tsx +119 -26
  123. package/src/Select/select.tsx +41 -8
  124. package/src/Select/style/index.less +14 -0
  125. package/src/Selector/interface.ts +4 -0
  126. package/src/Selector/selector.tsx +8 -3
  127. package/src/Table/hooks/useColumns.ts +1 -1
  128. package/src/Table/interface.ts +1 -1
  129. package/src/Table/style/index.less +35 -11
  130. package/src/Table/table.tsx +60 -1
  131. package/src/Table/tbody/cell.tsx +1 -1
  132. package/src/Table/util/header.ts +48 -2
  133. package/src/Tree/demo/draggable.tsx +2 -0
  134. package/src/Tree/interface.ts +46 -23
  135. package/src/Tree/tree-node.tsx +26 -29
  136. package/src/Tree/tree.tsx +573 -274
  137. package/src/Tree/utils/tree-tools.ts +231 -125
  138. package/src/locale/_README.md +22 -13
  139. package/src/locale/context.tsx +33 -16
  140. package/src/locale/interface.ts +24 -0
  141. package/src/locale/util.ts +6 -6
  142. package/src/style/color.css +3 -0
  143. package/src/style/size.css +2 -1
  144. package/src/utils/isEqual.ts +5 -7
  145. package/src/version.ts +1 -1
@@ -1,4 +1,4 @@
1
- var _excluded = ["prefixCls", "options", "placement", "mode", "value", "defaultValue", "optionFilterProp", "disabled", "onChange", "onFilter", "virtual", "itemHeight", "listHeight", "orphanClassName", "orphanStyle"];
1
+ var _excluded = ["prefixCls", "options", "placement", "mode", "value", "defaultValue", "optionFilterProp", "disabled", "onChange", "onFilter", "virtual", "itemHeight", "listHeight", "columns", "popupWidth", "looseMatch", "orphanClassName", "orphanStyle"];
2
2
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
3
3
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
4
4
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -22,6 +22,24 @@ import mergeContextToProps from "../utils/mergeContextToProps";
22
22
  import useSelectKeyboard from "./hooks/useSelectKeyboard";
23
23
  import Options from "./options";
24
24
  import "./style/index.less";
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Value comparison utilities (module-level for stable references)
28
+ // ---------------------------------------------------------------------------
29
+
30
+ /** Compare two values: loose mode uses String() conversion, strict uses ===. */
31
+ function matchValue(a, b, loose) {
32
+ if (loose) return String(a) === String(b);
33
+ return a === b;
34
+ }
35
+
36
+ /** Check if a value exists in a keys array with optional loose matching. */
37
+ function keysIncludes(keys, val, loose) {
38
+ if (loose) return keys.some(function (k) {
39
+ return String(k) === String(val);
40
+ });
41
+ return keys.includes(val);
42
+ }
25
43
  var Select = function Select(baseprops) {
26
44
  var _useContext = useContext(GlobalContext),
27
45
  select = _useContext.select;
@@ -43,6 +61,11 @@ var Select = function Select(baseprops) {
43
61
  virtual = props.virtual,
44
62
  itemHeight = props.itemHeight,
45
63
  listHeight = props.listHeight,
64
+ _props$columns = props.columns,
65
+ columns = _props$columns === void 0 ? 1 : _props$columns,
66
+ popupWidth = props.popupWidth,
67
+ _props$looseMatch = props.looseMatch,
68
+ looseMatch = _props$looseMatch === void 0 ? false : _props$looseMatch,
46
69
  orphanClassName = props.orphanClassName,
47
70
  orphanStyle = props.orphanStyle,
48
71
  rest = _objectWithoutProperties(props, _excluded);
@@ -89,11 +112,9 @@ var Select = function Select(baseprops) {
89
112
  if (keys.length === 0) {
90
113
  return [];
91
114
  }
92
- // 按 keys 顺序回填,找不到的 key 构造 label=value 的兜底项(孤儿值),
93
- // 与 Selector 的显示保持一致,避免 onChange 第二参数丢值。
94
115
  return keys.map(function (key) {
95
116
  var opt = options.find(function (o) {
96
- return o.value === key;
117
+ return matchValue(o.value, key, looseMatch);
97
118
  });
98
119
  return opt !== null && opt !== void 0 ? opt : {
99
120
  value: key,
@@ -102,7 +123,7 @@ var Select = function Select(baseprops) {
102
123
  });
103
124
  }
104
125
  return (_options$find = options.find(function (opt) {
105
- return opt.value === keys;
126
+ return matchValue(opt.value, keys, looseMatch);
106
127
  })) !== null && _options$find !== void 0 ? _options$find : {
107
128
  value: keys,
108
129
  label: String(keys)
@@ -116,9 +137,9 @@ var Select = function Select(baseprops) {
116
137
  setSearchValue('');
117
138
  setOpen(false);
118
139
  } else {
119
- if (mergedValue.includes(key)) {
140
+ if (keysIncludes(mergedValue, key, looseMatch)) {
120
141
  keys = mergedValue.filter(function (k) {
121
- return k !== key;
142
+ return !matchValue(k, key, looseMatch);
122
143
  });
123
144
  } else {
124
145
  keys = [].concat(_toConsumableArray(mergedValue), [key]);
@@ -137,7 +158,7 @@ var Select = function Select(baseprops) {
137
158
  };
138
159
  var handleRemove = function handleRemove(option) {
139
160
  var keys = mergedValue.filter(function (k) {
140
- return k !== option.value;
161
+ return !matchValue(k, option.value, looseMatch);
141
162
  });
142
163
  var filteredOpts = getOptions(keys);
143
164
  setMergedValue(keys);
@@ -169,6 +190,8 @@ var Select = function Select(baseprops) {
169
190
  options: filteredOpts,
170
191
  open: open,
171
192
  selectedKeys: mergedValue,
193
+ columns: columns,
194
+ looseMatch: looseMatch,
172
195
  onSelect: handleSelect,
173
196
  onClose: function onClose() {
174
197
  return setOpen(false);
@@ -191,12 +214,17 @@ var Select = function Select(baseprops) {
191
214
  virtual: virtual,
192
215
  itemHeight: itemHeight,
193
216
  listHeight: listHeight,
194
- virtualApiRef: virtualApiRef
217
+ virtualApiRef: virtualApiRef,
218
+ columns: columns,
219
+ looseMatch: looseMatch
195
220
  });
196
221
  return /*#__PURE__*/React.createElement(Trigger, _extends({}, rest, {
197
222
  placement: placement,
198
223
  popup: popup,
199
- stretch: "width",
224
+ stretch: popupWidth ? undefined : 'width',
225
+ popupStyle: popupWidth ? {
226
+ width: popupWidth
227
+ } : undefined,
200
228
  open: disabled ? false : open,
201
229
  onOpenChange: handleOpenChange
202
230
  }), /*#__PURE__*/React.createElement(Selector, _extends({}, rest, {
@@ -211,7 +239,8 @@ var Select = function Select(baseprops) {
211
239
  onSearch: handleSearch,
212
240
  onKeyDown: onKeyDown,
213
241
  orphanClassName: orphanClassName,
214
- orphanStyle: orphanStyle
242
+ orphanStyle: orphanStyle,
243
+ looseMatch: looseMatch
215
244
  })));
216
245
  };
217
246
  export default Select;
@@ -54,6 +54,20 @@
54
54
  align-items: center;
55
55
  }
56
56
 
57
+ // Multi-column grid layout (non-virtual mode).
58
+ // The column count is driven by the CSS custom property --yee-select-columns
59
+ // set inline by the Options component.
60
+ &-popup-grid {
61
+ display: grid;
62
+ grid-template-columns: repeat(var(--yee-select-columns, 1), 1fr);
63
+ }
64
+
65
+ // Virtual multi-column: each row container is already a grid via inline style;
66
+ // options inside it should fill cells evenly and center vertically.
67
+ &-popup-grid-row {
68
+ align-items: center;
69
+ }
70
+
57
71
  &-empty {
58
72
  padding: var(--yee-select-option-padding);
59
73
  }
@@ -62,6 +62,10 @@ export interface PureSelectorProps {
62
62
  * Selected keys
63
63
  */
64
64
  selectedKeys: Array<string | number>;
65
+ /**
66
+ * Enable loose value matching (String comparison instead of strict equality)
67
+ */
68
+ looseMatch?: boolean;
65
69
  /**
66
70
  * Custom suffix
67
71
  */
@@ -1,5 +1,5 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- var _excluded = ["prefixCls", "mode", "className", "style", "optionLabelProp", "searchable", "disabled", "options", "selectedKeys", "orphanClassName", "orphanStyle", "allowClear", "placeholder", "closable", "suffix", "value", "open", "loading", "size", "onSearch", "onRemove", "onClear", "onOpenChange", "onKeyDown"],
2
+ var _excluded = ["prefixCls", "mode", "className", "style", "optionLabelProp", "searchable", "disabled", "options", "selectedKeys", "looseMatch", "orphanClassName", "orphanStyle", "allowClear", "placeholder", "closable", "suffix", "value", "open", "loading", "size", "onSearch", "onRemove", "onClear", "onOpenChange", "onKeyDown"],
3
3
  _excluded2 = ["_orphan"];
4
4
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
5
5
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -38,6 +38,8 @@ var Selector = /*#__PURE__*/React.forwardRef(function (props, ref) {
38
38
  _props$options = props.options,
39
39
  options = _props$options === void 0 ? [] : _props$options,
40
40
  selectedKeys = props.selectedKeys,
41
+ _props$looseMatch = props.looseMatch,
42
+ looseMatch = _props$looseMatch === void 0 ? false : _props$looseMatch,
41
43
  orphanClassName = props.orphanClassName,
42
44
  orphanStyle = props.orphanStyle,
43
45
  _props$allowClear = props.allowClear,
@@ -71,7 +73,9 @@ var Selector = /*#__PURE__*/React.forwardRef(function (props, ref) {
71
73
  }
72
74
  // 按 selectedKeys 顺序渲染;找不到的 key 作为孤儿值回退显示 value 本身
73
75
  return selectedKeys.map(function (key) {
74
- var opt = options.find(function (o) {
76
+ var opt = looseMatch ? options.find(function (o) {
77
+ return String(o.value) === String(key);
78
+ }) : options.find(function (o) {
75
79
  return o.value === key;
76
80
  });
77
81
  if (opt) {
@@ -87,7 +91,7 @@ var Selector = /*#__PURE__*/React.forwardRef(function (props, ref) {
87
91
  _orphan: true
88
92
  };
89
93
  });
90
- }, [options, selectedKeys, optionLabelProp]);
94
+ }, [options, selectedKeys, optionLabelProp, looseMatch]);
91
95
  var handleClick = function handleClick() {
92
96
  if (inputRef.current && !disabled) {
93
97
  inputRef.current.focus();
@@ -156,7 +160,9 @@ var Selector = /*#__PURE__*/React.forwardRef(function (props, ref) {
156
160
  });
157
161
  }
158
162
  var key = selectedKeys.length ? selectedKeys[0] : '';
159
- var opt = Array.isArray(options) ? options.find(function (opt) {
163
+ var opt = Array.isArray(options) ? looseMatch ? options.find(function (opt) {
164
+ return String(opt.value) === String(key);
165
+ }) : options.find(function (opt) {
160
166
  return opt.value === key;
161
167
  }) : null;
162
168
  // 孤儿值:key 非空但在 options 中找不到时,回退显示 value 本身
@@ -37,7 +37,7 @@ export default function useColumns(_ref) {
37
37
  var tree = injectSelectionExpand(base, rowSelection, expandable);
38
38
  var leaves = flattenLeafColumns(tree);
39
39
  var wraped = handleColumns(leaves);
40
- var rows = parseHeaderRows(tree);
40
+ var rows = parseHeaderRows(tree, wraped);
41
41
  return {
42
42
  wrapedColumns: wraped,
43
43
  headerRows: rows
@@ -498,7 +498,7 @@ export interface TableProps extends FooterProps, Omit<HeaderProps, 'pageData'>,
498
498
  /**
499
499
  * Row class name, unlike classNames, this prop can be set dynamically via a function
500
500
  */
501
- rowClassName?: (record: object) => string | undefined;
501
+ rowClassName?: (record: Record<string, any>) => string | undefined;
502
502
  /**
503
503
  * Row style, unlike styles, this prop can be set dynamically via a function
504
504
  */
@@ -49,6 +49,12 @@
49
49
  background-color: var(--yee-table-head-cell-split-line-color, #eee);
50
50
  }
51
51
  }
52
+
53
+ &-fixed-left,
54
+ &-fixed-right {
55
+ position: sticky;
56
+ z-index: 1;
57
+ }
52
58
  }
53
59
 
54
60
  &-cell {
@@ -84,6 +90,16 @@
84
90
  &-wrapper {
85
91
  overflow: auto;
86
92
  width: 100%;
93
+
94
+ &-scroll-left @{pls}-cell-fixed-left-last {
95
+ box-shadow: 6px 0 6px -4px
96
+ var(--yee-table-fixed-left-after-bs-color);
97
+ }
98
+
99
+ &-scroll-right @{pls}-cell-fixed-right-first {
100
+ box-shadow: -6px 0 6px -4px
101
+ var(--yee-table-fixed-right-after-bs-color);
102
+ }
87
103
  }
88
104
 
89
105
  > table {
@@ -101,10 +117,18 @@
101
117
  }
102
118
  }
103
119
 
120
+ &-row {
121
+ background-color: var(--yee-table-row-bg-color);
122
+ }
123
+
104
124
  &-even-row {
105
125
  background-color: var(--yee-table-even-row-bg-color);
106
126
  }
107
127
 
128
+ &-odd-row {
129
+ background-color: var(--yee-table-odd-row-bg-color);
130
+ }
131
+
108
132
  &-column-sorters {
109
133
  display: inline-flex;
110
134
  align-items: center;
@@ -137,7 +161,7 @@
137
161
  &-fixed-left,
138
162
  &-fixed-right {
139
163
  position: sticky;
140
- background-color: inherit;
164
+ background-color: var(--yee-table-fixed-column-bg-color);
141
165
  }
142
166
  }
143
167
 
@@ -163,17 +187,17 @@
163
187
  }
164
188
  }
165
189
 
166
- &-odd-row {
167
- > @{pls}-cell {
168
- background-color: var(--yee-table-odd-row-bg-color);
169
- }
170
- }
190
+ // &-odd-row {
191
+ // > @{pls}-cell {
192
+ // background-color: var(--yee-table-odd-row-bg-color);
193
+ // }
194
+ // }
171
195
 
172
- &-even-row {
173
- > @{pls}-cell {
174
- background-color: var(--yee-table-even-row-bg-color);
175
- }
176
- }
196
+ // &-even-row {
197
+ // > @{pls}-cell {
198
+ // background-color: var(--yee-table-even-row-bg-color);
199
+ // }
200
+ // }
177
201
 
178
202
  &-footer {
179
203
  display: flex;
@@ -6,6 +6,12 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
6
6
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
7
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
8
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
9
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
10
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
11
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
12
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
13
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
14
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
9
15
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
10
16
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
11
17
  import clsx from 'clsx';
@@ -138,6 +144,30 @@ var Table = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
138
144
 
139
145
  // Track previous values to determine what action triggered onChange
140
146
  var prevSortersRef = useRef({});
147
+ var contentWrapperRef = useRef(null);
148
+ var contentRef = useRef(null);
149
+ var _React$useState = React.useState({
150
+ left: false,
151
+ right: false
152
+ }),
153
+ _React$useState2 = _slicedToArray(_React$useState, 2),
154
+ horizontalScroll = _React$useState2[0],
155
+ setHorizontalScroll = _React$useState2[1];
156
+ var updateHorizontalScroll = React.useCallback(function () {
157
+ var wrapper = contentWrapperRef.current;
158
+ var content = contentRef.current;
159
+ if (!wrapper || !content) return;
160
+ var scrollContainer = content.scrollWidth - content.clientWidth > 1 ? content : wrapper;
161
+ var maxScrollLeft = scrollContainer.scrollWidth - scrollContainer.clientWidth;
162
+ var hasHorizontalScroll = maxScrollLeft > 1;
163
+ var next = {
164
+ left: hasHorizontalScroll && scrollContainer.scrollLeft > 1,
165
+ right: hasHorizontalScroll && scrollContainer.scrollLeft < maxScrollLeft - 1
166
+ };
167
+ setHorizontalScroll(function (current) {
168
+ return current.left === next.left && current.right === next.right ? current : next;
169
+ });
170
+ }, []);
141
171
 
142
172
  // Wrap onFilter to trigger onChange
143
173
  var onFilter = React.useCallback(function () {
@@ -179,6 +209,24 @@ var Table = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
179
209
  return;
180
210
  }
181
211
  }, [sorters, current, pageSize, pageData, sortedData, onChange]);
212
+ useEffect(function () {
213
+ updateHorizontalScroll();
214
+ var wrapper = contentWrapperRef.current;
215
+ var content = contentRef.current;
216
+ if (!wrapper || !content) return undefined;
217
+ if (typeof ResizeObserver === 'undefined') {
218
+ window.addEventListener('resize', updateHorizontalScroll);
219
+ return function () {
220
+ return window.removeEventListener('resize', updateHorizontalScroll);
221
+ };
222
+ }
223
+ var resizeObserver = new ResizeObserver(updateHorizontalScroll);
224
+ resizeObserver.observe(wrapper);
225
+ resizeObserver.observe(content);
226
+ return function () {
227
+ return resizeObserver.disconnect();
228
+ };
229
+ }, [updateHorizontalScroll, wrapedColumns, pageData, scroll === null || scroll === void 0 ? void 0 : scroll.x]);
182
230
  var renderHeader = function renderHeader() {
183
231
  return /*#__PURE__*/React.createElement(Header, {
184
232
  prefixCls: prefixCls,
@@ -244,13 +292,17 @@ var Table = /*#__PURE__*/React.forwardRef(function (baseprops, ref) {
244
292
  columns: wrapedColumns
245
293
  }), renderTHeader(), renderTBody(), renderTFooter()));
246
294
  return /*#__PURE__*/React.createElement("div", {
247
- className: "".concat(prefixCls, "-content-wrapper")
295
+ ref: contentWrapperRef,
296
+ className: clsx("".concat(prefixCls, "-content-wrapper"), _defineProperty(_defineProperty({}, "".concat(prefixCls, "-content-wrapper-scroll-left"), horizontalScroll.left), "".concat(prefixCls, "-content-wrapper-scroll-right"), horizontalScroll.right)),
297
+ onScroll: updateHorizontalScroll
248
298
  }, /*#__PURE__*/React.createElement("div", {
299
+ ref: contentRef,
249
300
  className: clsx("".concat(prefixCls, "-content"), _defineProperty(_defineProperty({}, "".concat(prefixCls, "-").concat(size, "-size"), size), "".concat(prefixCls, "-fixed-header"), scroll === null || scroll === void 0 ? void 0 : scroll.y)),
250
301
  style: {
251
302
  height: scroll === null || scroll === void 0 ? void 0 : scroll.y,
252
303
  width: scroll === null || scroll === void 0 ? void 0 : scroll.x
253
- }
304
+ },
305
+ onScroll: updateHorizontalScroll
254
306
  }, table));
255
307
  };
256
308
  var renderFooter = function renderFooter() {
@@ -42,7 +42,7 @@ var TableCell = function TableCell(props) {
42
42
  var _children = renderChildren();
43
43
  var getTdProps = function getTdProps() {
44
44
  var title = render ? undefined : record[dataIndex || ''];
45
- var cls = clsx("".concat(prefixCls, "-cell"), _defineProperty(_defineProperty(_defineProperty({}, "".concat(prefixCls, "-cell-fixed-").concat(fixed), fixed), "".concat(prefixCls, "-cell-fixed-").concat(fixed, "-first"), isFixedRightFirst), "".concat(prefixCls, "-fixed-").concat(fixed, "-last"), isFixedLeftLast), className);
45
+ var cls = clsx("".concat(prefixCls, "-cell"), _defineProperty(_defineProperty(_defineProperty({}, "".concat(prefixCls, "-cell-fixed-").concat(fixed), fixed), "".concat(prefixCls, "-cell-fixed-").concat(fixed, "-first"), isFixedRightFirst), "".concat(prefixCls, "-cell-fixed-").concat(fixed, "-last"), isFixedLeftLast), className);
46
46
  var styles = _objectSpread(_objectSpread({}, style), {}, {
47
47
  width: width,
48
48
  maxWidth: width,
@@ -11,10 +11,12 @@ export declare function flattenLeafColumns(columns: WrapedColumnProps[], parentF
11
11
  *
12
12
  * - Pass 1 (DFS): place each column into the row matching its depth; a group's
13
13
  * colSpan equals the sum of its children's colSpans.
14
+ * - Fixed metadata from the resolved leaf columns is reused by leaf cells and
15
+ * aggregated for group cells whose descendants share the same fixed side.
14
16
  * - Pass 2: leaf cells (no sub-columns) get rowSpan = rowCount - rowIndex so
15
17
  * they stretch down to the last header row; group cells keep rowSpan = 1.
16
18
  */
17
- export declare function parseHeaderRows(rootColumns: WrapedColumnProps[]): HeaderCell[][];
19
+ export declare function parseHeaderRows(rootColumns: WrapedColumnProps[], resolvedLeafColumns?: WrapedColumnProps[]): HeaderCell[][];
18
20
  /**
19
21
  * Inject selection / expand columns into the top level of the column tree.
20
22
  * `index` is a 1-based position among the top-level columns.
@@ -34,24 +34,52 @@ export function flattenLeafColumns(columns, parentFixed) {
34
34
  *
35
35
  * - Pass 1 (DFS): place each column into the row matching its depth; a group's
36
36
  * colSpan equals the sum of its children's colSpans.
37
+ * - Fixed metadata from the resolved leaf columns is reused by leaf cells and
38
+ * aggregated for group cells whose descendants share the same fixed side.
37
39
  * - Pass 2: leaf cells (no sub-columns) get rowSpan = rowCount - rowIndex so
38
40
  * they stretch down to the last header row; group cells keep rowSpan = 1.
39
41
  */
40
42
  export function parseHeaderRows(rootColumns) {
43
+ var resolvedLeafColumns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : flattenLeafColumns(rootColumns);
41
44
  var rows = [];
45
+ var leafIndex = 0;
42
46
  var fillRowCells = function fillRowCells(columns, rowIndex) {
43
47
  rows[rowIndex] = rows[rowIndex] || [];
44
48
  var colSpanTotal = 0;
45
- columns.filter(Boolean).forEach(function (column) {
49
+ columns.filter(Boolean).forEach(function (sourceColumn) {
50
+ var column = sourceColumn;
51
+ var subColumns = sourceColumn.children;
52
+ var leafStartIndex = leafIndex;
46
53
  var cell = {
47
54
  column: column,
48
55
  colSpan: 1,
49
56
  rowSpan: 1
50
57
  };
51
- var subColumns = column.children;
52
58
  if (subColumns && subColumns.length > 0) {
59
+ var _groupLeaves$;
53
60
  cell.colSpan = fillRowCells(subColumns, rowIndex + 1);
54
61
  cell.hasSubColumns = true;
62
+ var groupLeaves = resolvedLeafColumns.slice(leafStartIndex, leafIndex);
63
+ var fixed = (_groupLeaves$ = groupLeaves[0]) === null || _groupLeaves$ === void 0 ? void 0 : _groupLeaves$.fixed;
64
+ var isFixedGroup = (fixed === 'left' || fixed === 'right') && groupLeaves.every(function (leaf) {
65
+ return leaf.fixed === fixed;
66
+ });
67
+ if (isFixedGroup) {
68
+ var _offsetLeaf$style;
69
+ var offsetLeaf = fixed === 'left' ? groupLeaves[0] : groupLeaves[groupLeaves.length - 1];
70
+ var boundaryLeaf = fixed === 'left' ? groupLeaves[groupLeaves.length - 1] : groupLeaves[0];
71
+ column = _objectSpread(_objectSpread({}, sourceColumn), {}, {
72
+ fixed: fixed,
73
+ style: _objectSpread(_objectSpread({}, sourceColumn.style), {}, _defineProperty({}, fixed, (_offsetLeaf$style = offsetLeaf.style) === null || _offsetLeaf$style === void 0 ? void 0 : _offsetLeaf$style[fixed])),
74
+ isFixedLeftLast: fixed === 'left' && boundaryLeaf.isFixedLeftLast,
75
+ isFixedRightFirst: fixed === 'right' && boundaryLeaf.isFixedRightFirst
76
+ });
77
+ cell.column = column;
78
+ }
79
+ } else {
80
+ column = resolvedLeafColumns[leafIndex] || sourceColumn;
81
+ cell.column = column;
82
+ leafIndex += 1;
55
83
  }
56
84
  rows[rowIndex].push(cell);
57
85
  colSpanTotal += cell.colSpan;
@@ -53,6 +53,8 @@ export default (function () {
53
53
  return moveTreeNode(prev, {
54
54
  dragKey: info.dragKey,
55
55
  dropKey: info.dropKey,
56
+ dragPath: info.dragPath,
57
+ dropPath: info.dropPath,
56
58
  position: info.position
57
59
  }, FIELD_NAMES);
58
60
  });
@@ -4,13 +4,14 @@ export type DragPosition = 'before' | 'after' | 'inside';
4
4
  export type { MoveInfo } from './utils/tree-tools';
5
5
  export type TreeNode<T> = {
6
6
  /**
7
- * uid
7
+ * Unique internal identifier built from key path joined by '\x00'.
8
+ * Guaranteed unique even when user-provided `key` values repeat across branches.
8
9
  */
9
10
  uid: string;
10
11
  /**
11
- * Unique key
12
- * */
13
- key: string;
12
+ * User-provided key (may not be globally unique)
13
+ */
14
+ key: string | number;
14
15
  /**
15
16
  * Display node text
16
17
  */
@@ -20,7 +21,7 @@ export type TreeNode<T> = {
20
21
  */
21
22
  title?: string;
22
23
  /**
23
- * Child nodes
24
+ * Child nodes (only present in raw tree; not used in flat list)
24
25
  */
25
26
  children?: Array<TreeNode<T>>;
26
27
  /**
@@ -28,16 +29,16 @@ export type TreeNode<T> = {
28
29
  */
29
30
  depth: number;
30
31
  /**
31
- * Parent node key
32
- * */
33
- pKey: string | null;
32
+ * Parent node uid (null for root nodes)
33
+ */
34
+ pUid: string | null;
34
35
  /**
35
36
  * Whether this is a leaf node
36
- * */
37
+ */
37
38
  isLeaf: boolean;
38
39
  /**
39
40
  * Whether this is the last node at its level
40
- * */
41
+ */
41
42
  isLast: boolean;
42
43
  /**
43
44
  * Whether disabled
@@ -48,17 +49,17 @@ export type TreeNode<T> = {
48
49
  */
49
50
  icon?: React.ReactNode | (() => React.ReactNode);
50
51
  /**
51
- * Ancestor keys
52
+ * Ancestor keys (user-provided keys, for building uid path)
52
53
  */
53
- path: string[];
54
+ path: Array<string | number>;
54
55
  /**
55
- * Whether to show connecting lines
56
+ * Whether to show connecting lines at given depth levels
56
57
  */
57
58
  lines: number[];
58
59
  /**
59
- * List of child node keys
60
+ * All descendant uids (collected bottom-up). Used for check/uncheck propagation.
60
61
  */
61
- childKeys?: Array<string | number>;
62
+ childUids?: Array<string>;
62
63
  /**
63
64
  * Original data
64
65
  */
@@ -66,6 +67,7 @@ export type TreeNode<T> = {
66
67
  };
67
68
  export interface TreeNodeProps<T> {
68
69
  node: TreeNode<T>;
70
+ style?: React.CSSProperties;
69
71
  }
70
72
  export interface TreeProps<T> {
71
73
  /**
@@ -89,11 +91,11 @@ export interface TreeProps<T> {
89
91
  */
90
92
  defaultExpandAll?: boolean;
91
93
  /**
92
- * Specify which tree nodes to expand by default
94
+ * Specify which tree nodes to expand by default (user keys)
93
95
  */
94
96
  defaultExpandedKeys?: string[];
95
97
  /**
96
- * Controlled expanded tree nodes
98
+ * Controlled expanded tree nodes (user keys)
97
99
  */
98
100
  expandedKeys?: string[];
99
101
  /**
@@ -124,6 +126,10 @@ export interface TreeProps<T> {
124
126
  dropNode: T;
125
127
  dragKey: string | number;
126
128
  dropKey: string | number;
129
+ /** Full key path from root to the dragged node (for non-unique key support) */
130
+ dragPath: Array<string | number>;
131
+ /** Full key path from root to the drop target (for non-unique key support) */
132
+ dropPath: Array<string | number>;
127
133
  position: DragPosition;
128
134
  /** Convenience flag: true when position is 'before' or 'after' */
129
135
  dropToGap: boolean;
@@ -164,22 +170,39 @@ export interface TreeProps<T> {
164
170
  loadData?: () => void;
165
171
  /**
166
172
  * Data source
167
- * */
173
+ */
168
174
  dataSource?: Array<T> | T;
169
175
  /**
170
- * Checked tree nodes (controlled)
176
+ * Enable virtual scrolling for large datasets.
177
+ * Requires `height` to be set.
178
+ * @default false
179
+ */
180
+ virtual?: boolean;
181
+ /**
182
+ * Height of the scrollable container in pixels.
183
+ * Required when `virtual` is true.
184
+ */
185
+ height?: number;
186
+ /**
187
+ * Fixed height of each tree node row in pixels.
188
+ * Used for virtual scroll calculation.
189
+ * @default 28
190
+ */
191
+ itemHeight?: number;
192
+ /**
193
+ * Checked tree nodes (controlled, user keys)
171
194
  */
172
195
  checkedKeys?: Array<string | number>;
173
196
  /**
174
- * Checked tree nodes (uncontrolled)
197
+ * Checked tree nodes (uncontrolled, user keys)
175
198
  */
176
199
  defaultCheckedKeys?: Array<string | number>;
177
200
  /**
178
- * Set selected tree nodes, set multiple to true for multi-select
201
+ * Set selected tree nodes, set multiple to true for multi-select (user keys)
179
202
  */
180
203
  selectedKeys?: Array<string | number>;
181
204
  /**
182
- * Set default selected tree nodes, set multiple to true for multi-select
205
+ * Set default selected tree nodes (user keys)
183
206
  */
184
207
  defaultSelectedKeys?: Array<string | number>;
185
208
  /**
@@ -204,6 +227,6 @@ export interface TreeProps<T> {
204
227
  onExpand?: (expandedKeys: Array<string | number>, params: {
205
228
  expanded: boolean;
206
229
  expandedNodes: T[];
207
- node: T[];
230
+ node: T;
208
231
  }) => void;
209
232
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import type { TreeNodeProps } from './interface';
3
3
  import './style/index.less';
4
- declare const Node: <T extends Record<string, unknown> = any>(props: TreeNodeProps<T>) => React.JSX.Element | null;
4
+ declare const Node: <T extends Record<string, unknown> = any>(props: TreeNodeProps<T>) => React.JSX.Element;
5
5
  export default Node;