@douyinfe/semi-ui 2.5.0 → 2.6.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 (97) hide show
  1. package/button/index.tsx +1 -1
  2. package/calendar/monthCalendar.tsx +14 -13
  3. package/cascader/index.tsx +21 -3
  4. package/cascader/item.tsx +25 -5
  5. package/datePicker/dateInput.tsx +8 -5
  6. package/datePicker/datePicker.tsx +6 -1
  7. package/datePicker/month.tsx +14 -7
  8. package/datePicker/monthsGrid.tsx +17 -5
  9. package/datePicker/navigation.tsx +8 -4
  10. package/datePicker/quickControl.tsx +1 -0
  11. package/datePicker/yearAndMonth.tsx +1 -1
  12. package/dist/css/semi.css +22 -8
  13. package/dist/css/semi.min.css +1 -1
  14. package/dist/umd/semi-ui.js +259 -104
  15. package/dist/umd/semi-ui.js.map +1 -1
  16. package/dist/umd/semi-ui.min.js +1 -1
  17. package/dist/umd/semi-ui.min.js.map +1 -1
  18. package/form/__test__/formApi.test.js +182 -0
  19. package/form/_story/FormApi/arrayDemo.jsx +4 -7
  20. package/form/_story/Layout/slotDemo.jsx +2 -2
  21. package/form/_story/demo.jsx +18 -1
  22. package/form/_story/form.stories.js +6 -6
  23. package/form/baseForm.tsx +2 -2
  24. package/form/hoc/withField.tsx +1 -1
  25. package/lib/cjs/_base/base.css +5 -5
  26. package/lib/cjs/button/Button.d.ts +4 -4
  27. package/lib/cjs/button/buttonGroup.d.ts +2 -2
  28. package/lib/cjs/button/index.d.ts +5 -6
  29. package/lib/cjs/calendar/monthCalendar.js +21 -5
  30. package/lib/cjs/cascader/index.d.ts +9 -2
  31. package/lib/cjs/cascader/index.js +14 -1
  32. package/lib/cjs/cascader/item.d.ts +6 -2
  33. package/lib/cjs/cascader/item.js +33 -4
  34. package/lib/cjs/datePicker/dateInput.d.ts +0 -2
  35. package/lib/cjs/datePicker/dateInput.js +17 -6
  36. package/lib/cjs/datePicker/datePicker.js +15 -12
  37. package/lib/cjs/datePicker/month.d.ts +1 -0
  38. package/lib/cjs/datePicker/month.js +18 -2
  39. package/lib/cjs/datePicker/monthsGrid.js +16 -4
  40. package/lib/cjs/datePicker/navigation.js +8 -0
  41. package/lib/cjs/datePicker/quickControl.js +1 -0
  42. package/lib/cjs/datePicker/yearAndMonth.js +1 -0
  43. package/lib/cjs/form/baseForm.js +2 -2
  44. package/lib/cjs/form/hoc/withField.js +1 -1
  45. package/lib/cjs/iconButton/index.d.ts +2 -2
  46. package/lib/cjs/navigation/Item.d.ts +2 -2
  47. package/lib/cjs/navigation/Item.js +8 -6
  48. package/lib/cjs/navigation/SubNav.js +2 -2
  49. package/lib/cjs/scrollList/scrollItem.d.ts +2 -1
  50. package/lib/cjs/scrollList/scrollItem.js +13 -3
  51. package/lib/cjs/table/Body/index.d.ts +2 -0
  52. package/lib/cjs/table/Body/index.js +13 -4
  53. package/lib/cjs/tooltip/index.js +6 -2
  54. package/lib/es/_base/base.css +5 -5
  55. package/lib/es/button/Button.d.ts +4 -4
  56. package/lib/es/button/buttonGroup.d.ts +2 -2
  57. package/lib/es/button/index.d.ts +5 -6
  58. package/lib/es/calendar/monthCalendar.js +22 -5
  59. package/lib/es/cascader/index.d.ts +9 -2
  60. package/lib/es/cascader/index.js +14 -1
  61. package/lib/es/cascader/item.d.ts +6 -2
  62. package/lib/es/cascader/item.js +31 -4
  63. package/lib/es/datePicker/dateInput.d.ts +0 -2
  64. package/lib/es/datePicker/dateInput.js +17 -6
  65. package/lib/es/datePicker/datePicker.js +15 -12
  66. package/lib/es/datePicker/month.d.ts +1 -0
  67. package/lib/es/datePicker/month.js +18 -2
  68. package/lib/es/datePicker/monthsGrid.js +16 -4
  69. package/lib/es/datePicker/navigation.js +8 -0
  70. package/lib/es/datePicker/quickControl.js +2 -0
  71. package/lib/es/datePicker/yearAndMonth.js +1 -0
  72. package/lib/es/form/baseForm.js +2 -2
  73. package/lib/es/form/hoc/withField.js +1 -1
  74. package/lib/es/iconButton/index.d.ts +2 -2
  75. package/lib/es/navigation/Item.d.ts +2 -2
  76. package/lib/es/navigation/Item.js +8 -6
  77. package/lib/es/navigation/SubNav.js +2 -2
  78. package/lib/es/scrollList/scrollItem.d.ts +2 -1
  79. package/lib/es/scrollList/scrollItem.js +13 -3
  80. package/lib/es/table/Body/index.d.ts +2 -0
  81. package/lib/es/table/Body/index.js +13 -4
  82. package/lib/es/tooltip/index.js +6 -2
  83. package/navigation/Item.tsx +15 -12
  84. package/navigation/SubNav.tsx +4 -4
  85. package/package.json +9 -9
  86. package/scrollList/_story/ScrollList/index.js +3 -0
  87. package/scrollList/_story/WheelList/index.js +3 -0
  88. package/scrollList/scrollItem.tsx +30 -9
  89. package/table/Body/index.tsx +15 -4
  90. package/table/__test__/table.test.js +18 -0
  91. package/table/_story/Perf/Virtualized/index.jsx +6 -0
  92. package/table/_story/v2/FixedExpandedRow/index.jsx +95 -0
  93. package/table/_story/v2/FixedHeaderMerge/index.jsx +1 -1
  94. package/table/_story/v2/defaultFilteredValue.tsx +0 -9
  95. package/table/_story/v2/index.js +2 -1
  96. package/tooltip/_story/tooltip.stories.js +702 -625
  97. package/tooltip/index.tsx +2 -2
@@ -92,6 +92,7 @@ class ScrollListDemo extends React.Component {
92
92
  type={1}
93
93
  selectedIndex={this.state.selectIndex1}
94
94
  onSelect={this.onSelectAP}
95
+ aria-label="时段"
95
96
  />
96
97
  <ScrollItem
97
98
  {...commonProps}
@@ -99,6 +100,7 @@ class ScrollListDemo extends React.Component {
99
100
  type={2}
100
101
  selectedIndex={this.state.selectIndex2}
101
102
  onSelect={this.onSelectHour}
103
+ aria-label="小时"
102
104
  />
103
105
  <ScrollItem
104
106
  {...commonProps}
@@ -106,6 +108,7 @@ class ScrollListDemo extends React.Component {
106
108
  type={3}
107
109
  selectedIndex={this.state.selectIndex3}
108
110
  onSelect={this.onSelectMinute}
111
+ aria-label="分钟"
109
112
  />
110
113
  </ScrollList>
111
114
  </div>
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { AriaAttributes } from 'react';
2
2
  import BaseComponent from '../_base/baseComponent';
3
3
  import PropTypes from 'prop-types';
4
4
  import classnames from 'classnames';
@@ -28,6 +28,7 @@ export interface ScrollItemProps<T extends Item> {
28
28
  motion?: Motion;
29
29
  style?: React.CSSProperties;
30
30
  type?: string | number; // used to identify the scrollItem, used internally by the semi component, and does not need to be exposed to the user
31
+ 'aria-label'?: AriaAttributes['aria-label'];
31
32
  }
32
33
 
33
34
  export interface ScrollItemState {
@@ -413,15 +414,15 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
413
414
  const { transform: itemTrans } = item;
414
415
 
415
416
  const transform = typeof itemTrans === 'function' ? itemTrans : commonTrans;
416
-
417
+ const selected = selectedIndex === index;
417
418
  const cls = classnames({
418
- [`${cssClasses.PREFIX}-item-sel`]: selectedIndex === index && mode !== wheelMode,
419
+ [`${cssClasses.PREFIX}-item-sel`]: selected && mode !== wheelMode,
419
420
  [`${cssClasses.PREFIX}-item-disabled`]: Boolean(item.disabled),
420
421
  });
421
422
 
422
423
  let text = '';
423
424
 
424
- if (selectedIndex === index) {
425
+ if (selected) {
425
426
  if (typeof transform === 'function') {
426
427
  text = transform(item.value, item.text);
427
428
  } else {
@@ -441,7 +442,14 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
441
442
 
442
443
  return (
443
444
  // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
444
- <li key={prefixKey + index} {...events} className={cls}>
445
+ <li
446
+ key={prefixKey + index}
447
+ {...events}
448
+ className={cls}
449
+ role="option"
450
+ aria-selected={selected}
451
+ aria-disabled={item.disabled}
452
+ >
445
453
  {text}
446
454
  </li>
447
455
  );
@@ -457,7 +465,14 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
457
465
 
458
466
  return (
459
467
  <div style={style} className={wrapperCls} ref={this._cacheWrapperNode}>
460
- <ul ref={this._cacheListNode}>{inner}</ul>
468
+ <ul
469
+ role="listbox"
470
+ aria-multiselectable={false}
471
+ aria-label={this.props['aria-label']}
472
+ ref={this._cacheListNode}
473
+ >
474
+ {inner}
475
+ </ul>
461
476
  </div>
462
477
  );
463
478
  };
@@ -470,13 +485,13 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
470
485
  const { prependCount, appendCount } = this.state;
471
486
 
472
487
  const prependList = times(prependCount).reduce((arr, num) => {
473
- const items = this.renderItemList(`pre_${ num }_`);
488
+ const items = this.renderItemList(`pre_${num}_`);
474
489
  arr.unshift(...items);
475
490
 
476
491
  return arr;
477
492
  }, []);
478
493
  const appendList = times(appendCount).reduce((arr, num) => {
479
- const items = this.renderItemList(`app_${ num }_`);
494
+ const items = this.renderItemList(`app_${num}_`);
480
495
  arr.push(...items);
481
496
  return arr;
482
497
  }, []);
@@ -500,7 +515,13 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
500
515
  <div className={selectorCls} ref={this._cacheSelectorNode} />
501
516
  <div className={postShadeCls} />
502
517
  <div className={listWrapperCls} ref={this._cacheWrapperNode} onScroll={this.scrollToSelectItem}>
503
- <ul ref={this._cacheListNode} onClick={this.clickToSelectItem}>
518
+ <ul
519
+ role="listbox"
520
+ aria-label={this.props['aria-label']}
521
+ aria-multiselectable={false}
522
+ ref={this._cacheListNode}
523
+ onClick={this.clickToSelectItem}
524
+ >
504
525
  {prependList}
505
526
  {inner}
506
527
  {appendList}
@@ -89,6 +89,8 @@ export interface BodyState {
89
89
 
90
90
  export interface BodyContext {
91
91
  getVirtualizedListRef: GetVirtualizedListRef;
92
+ flattenedColumns: ColumnProps[];
93
+ getCellWidths: (flattenedColumns: ColumnProps[]) => number[];
92
94
  }
93
95
 
94
96
  class Body extends BaseComponent<BodyProps, BodyState> {
@@ -128,6 +130,8 @@ class Body extends BaseComponent<BodyProps, BodyState> {
128
130
  listRef: React.MutableRefObject<any>;
129
131
  observer: ResizeObserver;
130
132
  foundation: BodyFoundation;
133
+ cellWidths: number[];
134
+ flattenedColumns: ColumnProps[];
131
135
  constructor(props: BodyProps, context: BodyContext) {
132
136
  super(props);
133
137
  this.ref = React.createRef();
@@ -142,7 +146,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
142
146
  };
143
147
 
144
148
  this.listRef = React.createRef();
145
- const { getVirtualizedListRef } = context;
149
+ const { getVirtualizedListRef, flattenedColumns, getCellWidths } = context;
146
150
  if (getVirtualizedListRef) {
147
151
  if (props.virtualized) {
148
152
  getVirtualizedListRef(this.listRef);
@@ -152,6 +156,8 @@ class Body extends BaseComponent<BodyProps, BodyState> {
152
156
  }
153
157
  }
154
158
  this.foundation = new BodyFoundation(this.adapter);
159
+ this.flattenedColumns = flattenedColumns;
160
+ this.cellWidths = getCellWidths(flattenedColumns);
155
161
  this.observer = null;
156
162
  }
157
163
 
@@ -199,7 +205,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
199
205
  this.observer.unobserve(bodyWrapDOM);
200
206
  this.observer = null;
201
207
  }
202
- }
208
+ },
203
209
  };
204
210
  }
205
211
 
@@ -494,7 +500,12 @@ class Body extends BaseComponent<BodyProps, BodyState> {
494
500
  }
495
501
 
496
502
  const { flattenedColumns, getCellWidths } = this.context;
497
- const cellWidths = getCellWidths(flattenedColumns);
503
+
504
+ // we use memoized cellWidths to avoid re-render expanded row (fix #686)
505
+ if (flattenedColumns !== this.flattenedColumns) {
506
+ this.flattenedColumns = flattenedColumns;
507
+ this.cellWidths = getCellWidths(flattenedColumns);
508
+ }
498
509
 
499
510
  return (
500
511
  <ExpandedRow
@@ -508,7 +519,7 @@ class Body extends BaseComponent<BodyProps, BodyState> {
508
519
  index={index}
509
520
  virtualized={virtualized}
510
521
  key={genExpandedRowKey(key)}
511
- cellWidths={cellWidths}
522
+ cellWidths={this.cellWidths}
512
523
  />
513
524
  );
514
525
  };
@@ -1930,4 +1930,22 @@ describe(`Table`, () => {
1930
1930
  expect(newExpandedRows.length).toEqual(1);
1931
1931
  expect(table.state(`expandedRowKeys`)).toEqual(['1']);
1932
1932
  });
1933
+
1934
+ it(`test expanded row re-render`, () => {
1935
+ const expandedRowRender = sinon.spy(() => <div>Semi Design</div>);
1936
+ const demo = mount(
1937
+ <Table
1938
+ columns={columns}
1939
+ dataSource={data}
1940
+ expandedRowRender={expandedRowRender}
1941
+ />
1942
+ );
1943
+
1944
+ const table = demo.find(BaseTable);
1945
+
1946
+ const expandIcons = demo.find(`.semi-table-tbody .semi-table-row .semi-table-expand-icon`);
1947
+ expandIcons.at(0).simulate('click');
1948
+ expandIcons.at(1).simulate('click');
1949
+ expect(expandedRowRender.calledTwice).toBeTruthy();
1950
+ });
1933
1951
  });
@@ -9,29 +9,35 @@ class PerfVirtualized extends React.Component {
9
9
  {
10
10
  title: 'A',
11
11
  dataIndex: 'key',
12
+ key: 'a',
12
13
  width: 150,
13
14
  },
14
15
  {
15
16
  title: 'B',
16
17
  dataIndex: 'key',
18
+ key: 'b',
17
19
  },
18
20
  {
19
21
  title: 'C',
20
22
  dataIndex: 'key',
23
+ key: 'c',
21
24
  },
22
25
  {
23
26
  title: 'D',
24
27
  dataIndex: 'key',
28
+ key: 'd',
25
29
  },
26
30
  {
27
31
  title: 'E',
28
32
  dataIndex: 'key',
29
33
  width: 200,
34
+ key: 'e',
30
35
  },
31
36
  {
32
37
  title: 'F',
33
38
  dataIndex: 'key',
34
39
  width: 100,
40
+ key: 'f'
35
41
  },
36
42
  ];
37
43
 
@@ -0,0 +1,95 @@
1
+ import React from 'react';
2
+ import { Table, Avatar } from '@douyinfe/semi-ui';
3
+ import { IconMore } from '@douyinfe/semi-icons';
4
+
5
+ const columns = [
6
+ {
7
+ title: '标题',
8
+ width: 500,
9
+ dataIndex: 'name',
10
+ render: (text, record, index) => {
11
+ return (
12
+ <span>
13
+ <Avatar size="small" shape="square" src={record.nameIconSrc} style={{ marginRight: 12 }}></Avatar>
14
+ {text}
15
+ </span>
16
+ );
17
+ },
18
+ },
19
+ {
20
+ title: '大小',
21
+ dataIndex: 'size',
22
+ },
23
+ {
24
+ title: '所有者',
25
+ dataIndex: 'owner',
26
+ render: (text, record, index) => {
27
+ return (
28
+ <div>
29
+ <Avatar size="small" color={record.avatarBg} style={{ marginRight: 4 }}>
30
+ {typeof text === 'string' && text.slice(0, 1)}
31
+ </Avatar>
32
+ {text}
33
+ </div>
34
+ );
35
+ },
36
+ },
37
+ {
38
+ title: '更新日期',
39
+ dataIndex: 'updateTime',
40
+ },
41
+ {
42
+ title: '',
43
+ dataIndex: 'operate',
44
+ render: () => {
45
+ return <IconMore />;
46
+ },
47
+ },
48
+ ];
49
+
50
+ const data = [
51
+ {
52
+ key: '1',
53
+ name: 'Semi Design 设计稿.fig',
54
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png',
55
+ size: '2M',
56
+ owner: '姜鹏志',
57
+ updateTime: '2020-02-02 05:13',
58
+ avatarBg: 'grey',
59
+ },
60
+ {
61
+ key: '2',
62
+ name: 'Semi Design 分享演示文稿',
63
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
64
+ size: '2M',
65
+ owner: '郝宣',
66
+ updateTime: '2020-01-17 05:31',
67
+ avatarBg: 'red',
68
+ },
69
+ {
70
+ key: '3',
71
+ name: '设计文档',
72
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
73
+ size: '34KB',
74
+ owner: 'Zoey Edwards',
75
+ updateTime: '2020-01-26 11:01',
76
+ avatarBg: 'light-blue',
77
+ },
78
+ ];
79
+
80
+ export default function App() {
81
+ const expandRowRender = (record, index) => {
82
+ console.log('render', index);
83
+ return <div>semi design</div>;
84
+ };
85
+
86
+ return (
87
+ <Table
88
+ rowKey="name"
89
+ columns={columns}
90
+ dataSource={data}
91
+ expandedRowRender={expandRowRender}
92
+ pagination={false}
93
+ />
94
+ );
95
+ }
@@ -45,7 +45,7 @@ export default function Demo() {
45
45
  const data = useMemo(() => {
46
46
  const data = [];
47
47
  for (let i = 0; i < 100; i++) {
48
- let age = 40 + (Math.random() > 0.5 ? 1 : -1) * (i % 9);
48
+ let age = (i * 1000) % 149;
49
49
  let name = `Edward King ${i}`;
50
50
  data.push({
51
51
  key: '' + i,
@@ -59,14 +59,6 @@ function App() {
59
59
  );
60
60
  }
61
61
 
62
- },
63
- {
64
- title: '更新日期',
65
- dataIndex: 'updateTime',
66
- sorter: (a, b) => a.updateTime - b.updateTime > 0 ? 1 : -1,
67
- render: (value) => {
68
- return dateFns.format(new Date(value), 'yyyy-MM-dd');
69
- }
70
62
  }
71
63
  ];
72
64
 
@@ -80,7 +72,6 @@ function App() {
80
72
  name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi Pro 设计稿${i}.fig`,
81
73
  owner: isSemiDesign ? '姜鹏志' : '郝宣',
82
74
  size: randomNumber,
83
- updateTime: new Date().valueOf() + randomNumber * DAY,
84
75
  avatarBg: isSemiDesign ? 'grey' : 'red'
85
76
  });
86
77
  }
@@ -2,4 +2,5 @@ export { default as DefaultFilteredValue } from './defaultFilteredValue';
2
2
  export { default as FixedColumnsChange } from './FixedColumnsChange';
3
3
  export { default as FixedZIndex } from './FixedZIndex';
4
4
  export { default as FixedHeaderMerge } from './FixedHeaderMerge';
5
- export { default as FixedResizable } from './FixedResizable';
5
+ export { default as FixedResizable } from './FixedResizable';
6
+ export { default as FixedExpandedRow } from './FixedExpandedRow';