@douyinfe/semi-ui 2.3.0 → 2.4.1

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 (73) hide show
  1. package/datePicker/_story/RenderDate/index.js +13 -3
  2. package/datePicker/_story/RenderFullDate/index.js +36 -14
  3. package/datePicker/_story/RenderFullDate/index.scss +1 -1
  4. package/datePicker/_story/datePicker.stories.js +19 -11
  5. package/datePicker/_story/v2/PanelOpen.jsx +39 -0
  6. package/datePicker/_story/v2/index.js +2 -1
  7. package/datePicker/datePicker.tsx +1 -0
  8. package/dist/css/semi.css +34 -9
  9. package/dist/css/semi.min.css +1 -1
  10. package/dist/umd/semi-ui.js +92 -33
  11. package/dist/umd/semi-ui.js.map +1 -1
  12. package/dist/umd/semi-ui.min.js +1 -1
  13. package/dist/umd/semi-ui.min.js.map +1 -1
  14. package/dropdown/index.tsx +11 -3
  15. package/form/_story/demo.jsx +1 -0
  16. package/input/index.tsx +1 -0
  17. package/input/textarea.tsx +6 -4
  18. package/inputNumber/__test__/inputNumber.test.js +36 -8
  19. package/inputNumber/index.tsx +2 -1
  20. package/lib/cjs/datePicker/datePicker.js +12 -8
  21. package/lib/cjs/dropdown/index.d.ts +10 -3
  22. package/lib/cjs/input/index.js +2 -1
  23. package/lib/cjs/input/textarea.js +5 -3
  24. package/lib/cjs/inputNumber/index.js +3 -2
  25. package/lib/cjs/list/index.d.ts +4 -4
  26. package/lib/cjs/navigation/Item.js +1 -1
  27. package/lib/cjs/navigation/SubNav.js +1 -1
  28. package/lib/cjs/scrollList/scrollItem.d.ts +5 -1
  29. package/lib/cjs/scrollList/scrollItem.js +7 -0
  30. package/lib/cjs/select/index.js +1 -1
  31. package/lib/cjs/table/Table.js +9 -5
  32. package/lib/cjs/timePicker/TimePicker.d.ts +2 -0
  33. package/lib/cjs/timePicker/TimePicker.js +4 -4
  34. package/lib/cjs/timePicker/index.d.ts +1 -0
  35. package/lib/cjs/tree/treeNode.js +10 -1
  36. package/lib/cjs/treeSelect/index.js +11 -3
  37. package/lib/cjs/typography/util.js +0 -1
  38. package/lib/es/datePicker/datePicker.js +12 -8
  39. package/lib/es/dropdown/index.d.ts +10 -3
  40. package/lib/es/input/index.js +2 -1
  41. package/lib/es/input/textarea.js +5 -3
  42. package/lib/es/inputNumber/index.js +3 -2
  43. package/lib/es/list/index.d.ts +4 -4
  44. package/lib/es/navigation/Item.js +1 -1
  45. package/lib/es/navigation/SubNav.js +1 -1
  46. package/lib/es/scrollList/scrollItem.d.ts +5 -1
  47. package/lib/es/scrollList/scrollItem.js +7 -0
  48. package/lib/es/select/index.js +1 -1
  49. package/lib/es/table/Table.js +9 -5
  50. package/lib/es/timePicker/TimePicker.d.ts +2 -0
  51. package/lib/es/timePicker/TimePicker.js +4 -4
  52. package/lib/es/timePicker/index.d.ts +1 -0
  53. package/lib/es/tree/treeNode.js +9 -1
  54. package/lib/es/treeSelect/index.js +12 -4
  55. package/lib/es/typography/util.js +0 -1
  56. package/list/index.tsx +5 -5
  57. package/navigation/Item.tsx +1 -1
  58. package/navigation/SubNav.tsx +1 -1
  59. package/package.json +9 -8
  60. package/scrollList/scrollItem.tsx +10 -3
  61. package/select/index.tsx +6 -1
  62. package/table/Table.tsx +9 -6
  63. package/table/_story/table.stories.js +2 -0
  64. package/table/_story/v2/FixedColumnsChange/index.jsx +104 -0
  65. package/table/_story/v2/FixedZIndex/index.jsx +87 -0
  66. package/timePicker/TimePicker.tsx +4 -1
  67. package/timePicker/__test__/timePicker.test.js +42 -3
  68. package/timePicker/_story/timepicker.stories.js +18 -0
  69. package/tree/treeNode.tsx +9 -2
  70. package/treeSelect/__test__/treeSelect.test.js +157 -0
  71. package/treeSelect/index.tsx +21 -12
  72. package/typography/_story/typography.stories.js +8 -0
  73. package/typography/util.tsx +0 -1
@@ -241,19 +241,21 @@ class TextArea extends BaseComponent {
241
241
  minLength: stateMinLength
242
242
  } = this.state;
243
243
  const wrapperCls = cls(className, "".concat(prefixCls, "-textarea-wrapper"), {
244
- ["".concat(prefixCls, "-textarea-wrapper-disabled")]: disabled || readonly,
244
+ ["".concat(prefixCls, "-textarea-wrapper-disabled")]: disabled,
245
+ ["".concat(prefixCls, "-textarea-wrapper-readonly")]: readonly,
245
246
  [_concatInstanceProperty(_context = "".concat(prefixCls, "-textarea-wrapper-")).call(_context, validateStatus)]: Boolean(validateStatus),
246
247
  ["".concat(prefixCls, "-textarea-wrapper-focus")]: isFocus // [`${prefixCls}-textarea-wrapper-resize`]: !autosize && resize,
247
248
 
248
249
  }); // const ref = this.props.forwardRef || this.textAreaRef;
249
250
 
250
251
  const itemCls = cls("".concat(prefixCls, "-textarea"), {
251
- ["".concat(prefixCls, "-textarea-disabled")]: disabled || readonly,
252
+ ["".concat(prefixCls, "-textarea-disabled")]: disabled,
253
+ ["".concat(prefixCls, "-textarea-readonly")]: readonly,
252
254
  ["".concat(prefixCls, "-textarea-autosize")]: autosize,
253
255
  ["".concat(prefixCls, "-textarea-showClear")]: showClear
254
256
  });
255
257
 
256
- const itemProps = _Object$assign(_Object$assign({}, _omit(rest, 'insetLabel', 'getValueLength', 'onClear', 'showClear')), {
258
+ const itemProps = _Object$assign(_Object$assign({}, _omit(rest, 'insetLabel', 'insetLabelId', 'getValueLength', 'onClear', 'showClear')), {
257
259
  className: itemCls,
258
260
  disabled,
259
261
  readOnly: readonly,
@@ -412,9 +412,10 @@ class InputNumber extends BaseComponent {
412
412
  innerButtons,
413
413
  style,
414
414
  onNumberChange,
415
- keepFocus
415
+ keepFocus,
416
+ defaultValue
416
417
  } = _a,
417
- rest = __rest(_a, ["disabled", "className", "prefixCls", "min", "max", "step", "shiftStep", "precision", "formatter", "parser", "forwardedRef", "onUpClick", "onDownClick", "pressInterval", "pressTimeout", "suffix", "size", "hideButtons", "innerButtons", "style", "onNumberChange", "keepFocus"]);
418
+ rest = __rest(_a, ["disabled", "className", "prefixCls", "min", "max", "step", "shiftStep", "precision", "formatter", "parser", "forwardedRef", "onUpClick", "onDownClick", "pressInterval", "pressTimeout", "suffix", "size", "hideButtons", "innerButtons", "style", "onNumberChange", "keepFocus", "defaultValue"]);
418
419
 
419
420
  const {
420
421
  value,
@@ -5,7 +5,7 @@ import ListItem from './item';
5
5
  import { Grid } from './list-context';
6
6
  import BaseComponent from '../_base/baseComponent';
7
7
  export { ListItemProps } from './item';
8
- export interface ListProps {
8
+ export interface ListProps<T> {
9
9
  style?: React.CSSProperties;
10
10
  className?: string;
11
11
  bordered?: boolean;
@@ -15,15 +15,15 @@ export interface ListProps {
15
15
  size?: 'small' | 'large' | 'default';
16
16
  split?: boolean;
17
17
  emptyContent?: React.ReactNode;
18
- dataSource?: any[];
19
- renderItem?: (item: any, ind: number) => React.ReactNode;
18
+ dataSource?: T[];
19
+ renderItem?: (item: T, ind: number) => React.ReactNode;
20
20
  grid?: Grid;
21
21
  loading?: boolean;
22
22
  loadMore?: React.ReactNode;
23
23
  onClick?: React.MouseEventHandler<HTMLLIElement>;
24
24
  onRightClick?: React.MouseEventHandler<HTMLLIElement>;
25
25
  }
26
- declare class List extends BaseComponent<ListProps> {
26
+ declare class List<T = any> extends BaseComponent<ListProps<T>> {
27
27
  static Item: typeof ListItem;
28
28
  static propTypes: {
29
29
  style: PropTypes.Requireable<object>;
@@ -176,7 +176,7 @@ export default class NavItem extends BaseComponent {
176
176
  } else {
177
177
  let placeholderIcons = null;
178
178
 
179
- if (mode === strings.MODE_VERTICAL && !limitIndent) {
179
+ if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
180
180
  const iconAmount = icon && !indent ? level : level - 1;
181
181
  placeholderIcons = _times(iconAmount, () => this.renderIcon(null, strings.ICON_POS_RIGHT, false));
182
182
  }
@@ -200,7 +200,7 @@ export default class SubNav extends BaseComponent {
200
200
 
201
201
  let placeholderIcons = null;
202
202
 
203
- if (mode === strings.MODE_VERTICAL && !limitIndent) {
203
+ if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
204
204
  /* Different icons' amount means different indents.*/
205
205
  const iconAmount = icon && !indent ? level : level - 1;
206
206
  placeholderIcons = _times(iconAmount, index => this.renderIcon(null, strings.ICON_POS_RIGHT, false, undefined, index));
@@ -3,7 +3,10 @@ import BaseComponent from '../_base/baseComponent';
3
3
  import PropTypes from 'prop-types';
4
4
  import { Item, ScrollItemAdapter } from '@douyinfe/semi-foundation/lib/es/scrollList/itemFoundation';
5
5
  import { Motion } from '../_base/base';
6
- declare type DebounceSelectFn = (e: React.UIEvent, newSelectedNode: HTMLElement) => void;
6
+ interface DebounceSelectFn {
7
+ (e: React.UIEvent, newSelectedNode: HTMLElement): void;
8
+ cancel(): void;
9
+ }
7
10
  export interface ScrollItemProps<T extends Item> {
8
11
  mode?: string;
9
12
  cycled?: boolean;
@@ -52,6 +55,7 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
52
55
  debouncedSelect: DebounceSelectFn;
53
56
  constructor(props?: {});
54
57
  get adapter(): ScrollItemAdapter<ScrollItemProps<T>, ScrollItemState, T>;
58
+ componentWillUnmount(): void;
55
59
  componentDidMount(): void;
56
60
  componentDidUpdate(prevProps: ScrollItemProps<T>): void;
57
61
  _cacheNode: (name: string, node: Element) => Element;
@@ -429,6 +429,13 @@ export default class ScrollItem extends BaseComponent {
429
429
  });
430
430
  }
431
431
 
432
+ componentWillUnmount() {
433
+ if (this.props.cycled) {
434
+ this.throttledAdjustList.cancel();
435
+ this.debouncedSelect.cancel();
436
+ }
437
+ }
438
+
432
439
  componentDidMount() {
433
440
  this.foundation.init();
434
441
  const {
@@ -506,7 +506,7 @@ class Select extends BaseComponent {
506
506
  role: "button",
507
507
  "aria-label": "Use the input box to create an optional item",
508
508
  onClick: e => this.onSelect(option, optionIndex, e),
509
- key: new Date().valueOf()
509
+ key: option.key || option.label
510
510
  }, customCreateItem)
511
511
  );
512
512
  }
@@ -1238,15 +1238,18 @@ class Table extends BaseComponent {
1238
1238
  const _dataSource = [...dataSource];
1239
1239
  const filteredSortedDataSource = this.foundation.getFilteredSortedDataSource(_dataSource, stateQueries);
1240
1240
  this.foundation.setCachedFilteredSortedDataSource(filteredSortedDataSource);
1241
- states.dataSource = filteredSortedDataSource; // when dataSource has change, should reset currentPage
1242
-
1243
- states.pagination = _isObject(statePagination) ? _Object$assign(_Object$assign({}, statePagination), {
1244
- currentPage: _isObject(propsPagination) && propsPagination.currentPage ? propsPagination.currentPage : 1
1245
- }) : statePagination;
1241
+ states.dataSource = filteredSortedDataSource;
1246
1242
 
1247
1243
  if (this.props.groupBy) {
1248
1244
  states.groups = null;
1249
1245
  }
1246
+ } // when dataSource has change, should reset currentPage
1247
+
1248
+
1249
+ if (dataSource !== prevProps.dataSource) {
1250
+ states.pagination = _isObject(statePagination) ? _Object$assign(_Object$assign({}, statePagination), {
1251
+ currentPage: _isObject(propsPagination) && propsPagination.currentPage ? propsPagination.currentPage : 1
1252
+ }) : statePagination;
1250
1253
  }
1251
1254
 
1252
1255
  if (_Object$keys(states).length) {
@@ -1433,6 +1436,7 @@ class Table extends BaseComponent {
1433
1436
  return /*#__PURE__*/React.createElement("div", {
1434
1437
  ref: this.rootWrapRef,
1435
1438
  className: classnames(className, "".concat(prefixCls, "-wrapper")),
1439
+ "data-column-fixed": anyColumnFixed,
1436
1440
  style: wrapStyle,
1437
1441
  id: id
1438
1442
  }, /*#__PURE__*/React.createElement(TableContextProvider, _Object$assign({}, tableContextValue), /*#__PURE__*/React.createElement(Spin, {
@@ -69,6 +69,7 @@ export declare type TimePickerProps = {
69
69
  zIndex?: number | string;
70
70
  onBlur?: React.FocusEventHandler<HTMLInputElement>;
71
71
  onChange?: TimePickerAdapter['notifyChange'];
72
+ onChangeWithDateFirst?: boolean;
72
73
  onFocus?: React.FocusEventHandler<HTMLInputElement>;
73
74
  onOpenChange?: (open: boolean) => void;
74
75
  };
@@ -169,6 +170,7 @@ export default class TimePicker extends BaseComponent<TimePickerProps, TimePicke
169
170
  onFocus: (...args: any[]) => void;
170
171
  onBlur: (...args: any[]) => void;
171
172
  onChange: (...args: any[]) => void;
173
+ onChangeWithDateFirst: boolean;
172
174
  use12Hours: boolean;
173
175
  focusOnOpen: boolean;
174
176
  onKeyDown: (...args: any[]) => void;
@@ -149,9 +149,7 @@ export default class TimePicker extends BaseComponent {
149
149
  notifyOpenChange: function () {
150
150
  return _this2.props.onOpenChange(...arguments);
151
151
  },
152
- notifyChange: function () {
153
- return _this2.props.onChange && _this2.props.onChange(...arguments);
154
- },
152
+ notifyChange: (agr1, arg2) => this.props.onChange && this.props.onChange(agr1, arg2),
155
153
  notifyFocus: function () {
156
154
  return _this2.props.onFocus && _this2.props.onFocus(...arguments);
157
155
  },
@@ -298,6 +296,7 @@ export default class TimePicker extends BaseComponent {
298
296
  panelFooter,
299
297
  rangeSeparator,
300
298
  onOpenChange,
299
+ onChangeWithDateFirst,
301
300
  popupClassName: propPopupClassName,
302
301
  hideDisabledOptions,
303
302
  use12Hours,
@@ -309,7 +308,7 @@ export default class TimePicker extends BaseComponent {
309
308
  motion,
310
309
  autoAdjustOverflow
311
310
  } = _a,
312
- rest = __rest(_a, ["prefixCls", "placeholder", "disabled", "defaultValue", "className", "popupStyle", "size", "style", "locale", "localeCode", "zIndex", "getPopupContainer", "insetLabel", "insetLabelId", "inputStyle", "showClear", "panelHeader", "panelFooter", "rangeSeparator", "onOpenChange", "popupClassName", "hideDisabledOptions", "use12Hours", "minuteStep", "hourStep", "secondStep", "scrollItemProps", "triggerRender", "motion", "autoAdjustOverflow"]);
311
+ rest = __rest(_a, ["prefixCls", "placeholder", "disabled", "defaultValue", "className", "popupStyle", "size", "style", "locale", "localeCode", "zIndex", "getPopupContainer", "insetLabel", "insetLabelId", "inputStyle", "showClear", "panelHeader", "panelFooter", "rangeSeparator", "onOpenChange", "onChangeWithDateFirst", "popupClassName", "hideDisabledOptions", "use12Hours", "minuteStep", "hourStep", "secondStep", "scrollItemProps", "triggerRender", "motion", "autoAdjustOverflow"]);
313
312
 
314
313
  const format = this.foundation.getDefaultFormatIfNeed();
315
314
  const position = this.foundation.getPosition();
@@ -469,6 +468,7 @@ TimePicker.defaultProps = _Object$assign({
469
468
  onFocus: _noop,
470
469
  onBlur: _noop,
471
470
  onChange: _noop,
471
+ onChangeWithDateFirst: true,
472
472
  use12Hours: false,
473
473
  focusOnOpen: false,
474
474
  onKeyDown: _noop,
@@ -91,6 +91,7 @@ export default class LocaleTimePicker extends React.PureComponent<LocalePickerPr
91
91
  onFocus: (...args: any[]) => void;
92
92
  onBlur: (...args: any[]) => void;
93
93
  onChange: (...args: any[]) => void;
94
+ onChangeWithDateFirst: boolean;
94
95
  use12Hours: boolean;
95
96
  focusOnOpen: boolean;
96
97
  onKeyDown: (...args: any[]) => void;
@@ -1,3 +1,4 @@
1
+ import _isEmpty from "lodash/isEmpty";
1
2
  import _get from "lodash/get";
2
3
  import _isString from "lodash/isString";
3
4
  import _isFunction from "lodash/isFunction";
@@ -470,7 +471,14 @@ export default class TreeNode extends PureComponent {
470
471
  ref: this.setRef
471
472
  }, dragProps));
472
473
  } else {
473
- return customLabel;
474
+ if (_isEmpty(style)) {
475
+ return customLabel;
476
+ } else {
477
+ // In virtualization, props.style will contain location information
478
+ return /*#__PURE__*/React.cloneElement(customLabel, {
479
+ style: _Object$assign(_Object$assign({}, _get(customLabel, ['props', 'style'])), style)
480
+ });
481
+ }
474
482
  }
475
483
  }
476
484
 
@@ -17,7 +17,7 @@ import ReactDOM from 'react-dom';
17
17
  import cls from 'classnames';
18
18
  import PropTypes from 'prop-types';
19
19
  import TreeSelectFoundation from '@douyinfe/semi-foundation/lib/es/treeSelect/foundation';
20
- import { convertDataToEntities, flattenTreeData, calcExpandedKeysForValues, calcMotionKeys, findKeysForValues, calcCheckedKeys, calcExpandedKeys, getValueOrKey, normalizeKeyList, calcDisabledKeys, normalizeValue } from '@douyinfe/semi-foundation/lib/es/tree/treeUtil';
20
+ import { convertDataToEntities, flattenTreeData, calcExpandedKeysForValues, calcMotionKeys, findKeysForValues, calcCheckedKeys, calcExpandedKeys, getValueOrKey, normalizeKeyList, calcDisabledKeys, normalizeValue, updateKeys } from '@douyinfe/semi-foundation/lib/es/tree/treeUtil';
21
21
  import { cssClasses, strings } from '@douyinfe/semi-foundation/lib/es/treeSelect/constants';
22
22
  import { numbers as popoverNumbers } from '@douyinfe/semi-foundation/lib/es/popover/constants';
23
23
  import { FixedSizeList as VirtualList } from 'react-window';
@@ -896,7 +896,7 @@ class TreeSelect extends BaseComponent {
896
896
  } // if treeData keys changes, we won't show animation
897
897
 
898
898
 
899
- if (treeData && props.motion && !_isEqual(new _Set(_Object$keys(newState.keyEntities)), new _Set(_Object$keys(prevState.keyEntities)))) {
899
+ if (treeData && props.motion && !_isEqual(_Object$keys(newState.keyEntities), _Object$keys(prevState.keyEntities))) {
900
900
  if (prevProps && props.motion) {
901
901
  newState.motionKeys = new _Set([]);
902
902
  newState.motionType = null;
@@ -942,7 +942,11 @@ class TreeSelect extends BaseComponent {
942
942
  newState.selectedKeys = findKeysForValues(normalizeValue(props.defaultValue, withObject), valueEntities, isMultiple);
943
943
  } else if (treeData) {
944
944
  // If `treeData` changed, we also need check it
945
- newState.selectedKeys = findKeysForValues(normalizeValue(props.value, withObject) || '', valueEntities, isMultiple);
945
+ if (props.value) {
946
+ newState.selectedKeys = findKeysForValues(normalizeValue(props.value, withObject) || '', valueEntities, isMultiple);
947
+ } else {
948
+ newState.selectedKeys = updateKeys(prevState.selectedKeys, keyEntities);
949
+ }
946
950
  }
947
951
  } else {
948
952
  // checkedKeys: multiple mode controlled || data changed
@@ -954,7 +958,11 @@ class TreeSelect extends BaseComponent {
954
958
  checkedKeyValues = findKeysForValues(normalizeValue(props.defaultValue, withObject), valueEntities, isMultiple);
955
959
  } else if (treeData) {
956
960
  // If `treeData` changed, we also need check it
957
- checkedKeyValues = findKeysForValues(normalizeValue(props.value, withObject) || [], valueEntities, isMultiple);
961
+ if (props.value) {
962
+ checkedKeyValues = findKeysForValues(normalizeValue(props.value, withObject) || [], valueEntities, isMultiple);
963
+ } else {
964
+ checkedKeyValues = updateKeys(prevState.checkedKeys, keyEntities);
965
+ }
958
966
  }
959
967
 
960
968
  if (checkedKeyValues) {
@@ -62,7 +62,6 @@ const getRenderText = function (originEle, rows) {
62
62
  ellipsisContainer.style.zIndex = '-1000'; // clean up css overflow
63
63
 
64
64
  ellipsisContainer.style.textOverflow = 'clip';
65
- ellipsisContainer.style.whiteSpace = 'normal';
66
65
  ellipsisContainer.style.webkitLineClamp = 'none'; // Render fake container
67
66
 
68
67
  ReactDOM.render( /*#__PURE__*/React.createElement(React.Fragment, null), ellipsisContainer); // Check if ellipsis in measure div is height enough for content
package/list/index.tsx CHANGED
@@ -14,7 +14,7 @@ import BaseComponent from '../_base/baseComponent';
14
14
 
15
15
  export { ListItemProps } from './item';
16
16
 
17
- export interface ListProps {
17
+ export interface ListProps<T> {
18
18
  style?: React.CSSProperties;
19
19
  className?: string;
20
20
  bordered?: boolean;
@@ -24,8 +24,8 @@ export interface ListProps {
24
24
  size?: 'small' | 'large' | 'default';
25
25
  split?: boolean;
26
26
  emptyContent?: React.ReactNode;
27
- dataSource?: any[];
28
- renderItem?: (item: any, ind: number) => React.ReactNode;
27
+ dataSource?: T[];
28
+ renderItem?: (item: T, ind: number) => React.ReactNode;
29
29
  grid?: Grid;
30
30
  loading?: boolean;
31
31
  loadMore?: React.ReactNode;
@@ -35,7 +35,7 @@ export interface ListProps {
35
35
 
36
36
  const prefixCls = cssClasses.PREFIX;
37
37
 
38
- class List extends BaseComponent<ListProps> {
38
+ class List<T = any> extends BaseComponent<ListProps<T>> {
39
39
  static Item = ListItem;
40
40
 
41
41
  static propTypes = {
@@ -170,4 +170,4 @@ class List extends BaseComponent<ListProps> {
170
170
  }
171
171
  }
172
172
 
173
- export default List;
173
+ export default List;
@@ -195,7 +195,7 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
195
195
  itemChildren = children;
196
196
  } else {
197
197
  let placeholderIcons = null;
198
- if (mode === strings.MODE_VERTICAL && !limitIndent) {
198
+ if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
199
199
  const iconAmount = (icon && !indent) ? level : level - 1;
200
200
  placeholderIcons = times(iconAmount, () => this.renderIcon(null, strings.ICON_POS_RIGHT, false));
201
201
  }
@@ -237,7 +237,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
237
237
  }
238
238
 
239
239
  let placeholderIcons = null;
240
- if (mode === strings.MODE_VERTICAL && !limitIndent) {
240
+ if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
241
241
  /* Different icons' amount means different indents.*/
242
242
  const iconAmount = (icon && !indent) ? level : level - 1;
243
243
  placeholderIcons = times(iconAmount, index => this.renderIcon(null, strings.ICON_POS_RIGHT, false, undefined, index));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-ui",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "description": "",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/es/index.js",
@@ -14,11 +14,12 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@babel/runtime-corejs3": "^7.15.4",
17
- "@douyinfe/semi-animation-react": "2.3.0",
18
- "@douyinfe/semi-foundation": "2.3.0",
19
- "@douyinfe/semi-icons": "2.3.0",
20
- "@douyinfe/semi-illustrations": "2.3.0",
21
- "@douyinfe/semi-theme-default": "2.3.0",
17
+ "@douyinfe/semi-animation": "2.4.1",
18
+ "@douyinfe/semi-animation-react": "2.4.1",
19
+ "@douyinfe/semi-foundation": "2.4.1",
20
+ "@douyinfe/semi-icons": "2.4.1",
21
+ "@douyinfe/semi-illustrations": "2.4.1",
22
+ "@douyinfe/semi-theme-default": "2.4.1",
22
23
  "@types/react-window": "^1.8.2",
23
24
  "async-validator": "^3.5.0",
24
25
  "classnames": "^2.2.6",
@@ -68,13 +69,13 @@
68
69
  ],
69
70
  "author": "",
70
71
  "license": "MIT",
71
- "gitHead": "456b90e3f3501dd92e9d0b55bb9c8c86312837aa",
72
+ "gitHead": "c69c466ecd14aeeda847473e97dad2ec313f09fa",
72
73
  "devDependencies": {
73
74
  "@babel/plugin-proposal-decorators": "^7.15.8",
74
75
  "@babel/plugin-transform-runtime": "^7.15.8",
75
76
  "@babel/preset-env": "^7.15.8",
76
77
  "@babel/preset-react": "^7.14.5",
77
- "@douyinfe/semi-scss-compile": "2.3.0",
78
+ "@douyinfe/semi-scss-compile": "2.4.1",
78
79
  "@storybook/addon-knobs": "^6.3.1",
79
80
  "@types/lodash": "^4.14.176",
80
81
  "babel-loader": "^8.2.2",
@@ -13,8 +13,10 @@ import { Motion } from '../_base/base';
13
13
  const msPerFrame = 1000 / 60;
14
14
  const blankReg = /^\s*$/;
15
15
  const wheelMode = 'wheel';
16
-
17
- type DebounceSelectFn = (e: React.UIEvent, newSelectedNode: HTMLElement) => void;
16
+ interface DebounceSelectFn {
17
+ (e: React.UIEvent, newSelectedNode: HTMLElement): void;
18
+ cancel(): void
19
+ }
18
20
  export interface ScrollItemProps<T extends Item> {
19
21
  mode?: string;
20
22
  cycled?: boolean;
@@ -110,7 +112,12 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
110
112
  scrollToCenter: this.scrollToCenter,
111
113
  };
112
114
  }
113
-
115
+ componentWillUnmount(){
116
+ if (this.props.cycled) {
117
+ this.throttledAdjustList.cancel();
118
+ this.debouncedSelect.cancel();
119
+ }
120
+ }
114
121
  componentDidMount() {
115
122
  this.foundation.init();
116
123
 
package/select/index.tsx CHANGED
@@ -739,7 +739,12 @@ class Select extends BaseComponent<SelectProps, SelectState> {
739
739
 
740
740
  return (
741
741
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/interactive-supports-focus
742
- <div role="button" aria-label="Use the input box to create an optional item" onClick={e => this.onSelect(option, optionIndex, e)} key={new Date().valueOf()}>
742
+ <div
743
+ role="button"
744
+ aria-label="Use the input box to create an optional item"
745
+ onClick={e => this.onSelect(option, optionIndex, e)}
746
+ key={option.key || option.label}
747
+ >
743
748
  {customCreateItem}
744
749
  </div>
745
750
  );
package/table/Table.tsx CHANGED
@@ -534,7 +534,6 @@ class Table<RecordType extends Record<string, any>> extends BaseComponent<Normal
534
534
  this.foundation.initExpandedRowKeys({ groups: stateGroups });
535
535
  }
536
536
 
537
-
538
537
  /**
539
538
  * After dataSource is updated || (cachedColumns || cachedChildren updated)
540
539
  * 1. Cache filtered sorted data and a collection of data rows, stored in this
@@ -547,17 +546,20 @@ class Table<RecordType extends Record<string, any>> extends BaseComponent<Normal
547
546
  const filteredSortedDataSource = this.foundation.getFilteredSortedDataSource(_dataSource, stateQueries);
548
547
  this.foundation.setCachedFilteredSortedDataSource(filteredSortedDataSource);
549
548
  states.dataSource = filteredSortedDataSource;
550
- // when dataSource has change, should reset currentPage
551
- states.pagination = isObject(statePagination) ? {
552
- ...statePagination,
553
- currentPage: isObject(propsPagination) && propsPagination.currentPage ? propsPagination.currentPage : 1,
554
- } : statePagination;
555
549
 
556
550
  if (this.props.groupBy) {
557
551
  states.groups = null;
558
552
  }
559
553
  }
560
554
 
555
+ // when dataSource has change, should reset currentPage
556
+ if (dataSource !== prevProps.dataSource) {
557
+ states.pagination = isObject(statePagination) ? {
558
+ ...statePagination,
559
+ currentPage: isObject(propsPagination) && propsPagination.currentPage ? propsPagination.currentPage : 1,
560
+ } : statePagination;
561
+ }
562
+
561
563
  if (Object.keys(states).length) {
562
564
  const {
563
565
  // eslint-disable-next-line @typescript-eslint/no-shadow
@@ -1372,6 +1374,7 @@ class Table<RecordType extends Record<string, any>> extends BaseComponent<Normal
1372
1374
  <div
1373
1375
  ref={this.rootWrapRef}
1374
1376
  className={classnames(className, `${prefixCls}-wrapper`)}
1377
+ data-column-fixed={anyColumnFixed}
1375
1378
  style={wrapStyle}
1376
1379
  id={id}
1377
1380
  >
@@ -76,6 +76,8 @@ export { default as ScrollBar } from './ScrollBar';
76
76
  export { default as TableSpan } from './TableSpan';
77
77
  export { default as FixRenderReturnProps } from './FixRenderReturnProps';
78
78
  export { default as WarnColumnWithoutDataIndex } from './WarnColumnWithoutDataIndex';
79
+ export { default as FixedColumnsChange } from './v2/FixedColumnsChange';
80
+ export { default as FixedZIndex } from './v2/FixedZIndex';
79
81
 
80
82
  // empty table
81
83
 
@@ -0,0 +1,104 @@
1
+ import React, { useState, useMemo } from 'react';
2
+ import { Table, Avatar } from '@douyinfe/semi-ui';
3
+ import * as dateFns from 'date-fns';
4
+
5
+ const DAY = 24 * 60 * 60 * 1000;
6
+ const figmaIconUrl = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png';
7
+
8
+ const getData = () => {
9
+ const data = [];
10
+ for (let i = 0; i < 46; i++) {
11
+ const isSemiDesign = i % 2 === 0;
12
+ const randomNumber = (i * 1000) % 199;
13
+ data.push({
14
+ key: '' + i,
15
+ name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi Pro 设计稿${i}.fig`,
16
+ owner: isSemiDesign ? '姜鹏志' : '郝宣',
17
+ size: randomNumber,
18
+ updateTime: new Date('2022-01-01').valueOf() + randomNumber * DAY,
19
+ avatarBg: isSemiDesign ? 'grey' : 'red'
20
+ });
21
+ }
22
+ return data;
23
+ };
24
+
25
+ const data = getData();
26
+
27
+ /**
28
+ * fix https://github.com/DouyinFE/semi-design/issues/381
29
+ */
30
+ App.storyName = 'fixed columns change';
31
+ function App() {
32
+ const [dataSource, setData] = useState(data);
33
+ const [rowKeys, setRowKeys] = useState([]);
34
+
35
+ const columns = [
36
+ {
37
+ title: '标题',
38
+ dataIndex: 'name',
39
+ width: 400,
40
+ render: (text, record, index) => {
41
+ return (
42
+ <div>
43
+ <Avatar size="small" shape="square" src={figmaIconUrl} style={{ marginRight: 12 }}></Avatar>
44
+ {text}
45
+ </div>
46
+ );
47
+ },
48
+ filters: [
49
+ {
50
+ text: 'Semi Design 设计稿',
51
+ value: 'Semi Design 设计稿',
52
+ },
53
+ {
54
+ text: 'Semi Pro 设计稿',
55
+ value: 'Semi Pro 设计稿',
56
+ },
57
+ ],
58
+ onFilter: (value, record) => record.name.includes(value),
59
+ },
60
+ {
61
+ title: '大小',
62
+ dataIndex: 'size',
63
+ sorter: (a, b) => a.size - b.size > 0 ? 1 : -1,
64
+ render: (text) => `${text} KB`
65
+ },
66
+ {
67
+ title: '所有者',
68
+ dataIndex: 'owner',
69
+ render: (text, record, index) => {
70
+ return (
71
+ <div>
72
+ <Avatar size="small" color={record.avatarBg} style={{ marginRight: 4 }}>{typeof text === 'string' && text.slice(0, 1)}</Avatar>
73
+ {text}
74
+ </div>
75
+ );
76
+ }
77
+ },
78
+ {
79
+ title: '更新日期',
80
+ dataIndex: 'updateTime',
81
+ sorter: (a, b) => a.updateTime - b.updateTime > 0 ? 1 : -1,
82
+ render: (value) => {
83
+ return dateFns.format(new Date(value), 'yyyy-MM-dd');
84
+ }
85
+ }
86
+ ];
87
+
88
+ return (
89
+ <Table
90
+ columns={columns}
91
+ dataSource={dataSource}
92
+ pagination={{
93
+ pageSize: 5,
94
+ }}
95
+ rowSelection={{
96
+ onChange: rowKeys => setRowKeys(rowKeys),
97
+ selectedRowKeys: rowKeys,
98
+ }}
99
+ scroll={{ y: 300 }}
100
+ />
101
+ );
102
+ }
103
+
104
+ export default App;