@douyinfe/semi-ui 2.11.2 → 2.12.0-beta.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 (63) hide show
  1. package/button/Button.tsx +1 -1
  2. package/dist/css/semi.css +33 -0
  3. package/dist/css/semi.min.css +1 -1
  4. package/dist/umd/semi-ui.js +2338 -323
  5. package/dist/umd/semi-ui.js.map +1 -1
  6. package/dist/umd/semi-ui.min.js +1 -1
  7. package/dist/umd/semi-ui.min.js.map +1 -1
  8. package/form/_story/FormSubmit/index.tsx +45 -0
  9. package/form/_story/form.stories.js +2 -1
  10. package/lib/cjs/button/Button.d.ts +1 -1
  11. package/lib/cjs/modal/Modal.js +3 -2
  12. package/lib/cjs/modal/ModalContent.d.ts +2 -0
  13. package/lib/cjs/modal/ModalContent.js +17 -9
  14. package/lib/cjs/progress/index.js +1 -1
  15. package/lib/cjs/select/index.js +1 -1
  16. package/lib/cjs/slider/index.js +9 -5
  17. package/lib/cjs/tabs/TabBar.d.ts +1 -0
  18. package/lib/cjs/tabs/TabBar.js +8 -1
  19. package/lib/cjs/tabs/TabPane.js +2 -1
  20. package/lib/cjs/tabs/index.js +2 -1
  21. package/lib/cjs/tabs/interface.d.ts +1 -0
  22. package/lib/cjs/tag/index.d.ts +2 -0
  23. package/lib/cjs/tag/index.js +60 -11
  24. package/lib/cjs/tag/interface.d.ts +1 -0
  25. package/lib/cjs/tagInput/index.js +3 -2
  26. package/lib/cjs/tooltip/TooltipStyledTransition.js +5 -2
  27. package/lib/cjs/treeSelect/index.js +3 -3
  28. package/lib/es/button/Button.d.ts +1 -1
  29. package/lib/es/modal/Modal.js +3 -2
  30. package/lib/es/modal/ModalContent.d.ts +2 -0
  31. package/lib/es/modal/ModalContent.js +16 -9
  32. package/lib/es/progress/index.js +1 -1
  33. package/lib/es/select/index.js +1 -1
  34. package/lib/es/slider/index.js +9 -5
  35. package/lib/es/tabs/TabBar.d.ts +1 -0
  36. package/lib/es/tabs/TabBar.js +8 -1
  37. package/lib/es/tabs/TabPane.js +2 -1
  38. package/lib/es/tabs/index.js +2 -1
  39. package/lib/es/tabs/interface.d.ts +1 -0
  40. package/lib/es/tag/index.d.ts +2 -0
  41. package/lib/es/tag/index.js +56 -9
  42. package/lib/es/tag/interface.d.ts +1 -0
  43. package/lib/es/tagInput/index.js +3 -2
  44. package/lib/es/tooltip/TooltipStyledTransition.js +5 -2
  45. package/lib/es/treeSelect/index.js +2 -2
  46. package/modal/Modal.tsx +2 -1
  47. package/modal/ModalContent.tsx +14 -8
  48. package/package.json +9 -9
  49. package/progress/index.tsx +1 -1
  50. package/select/index.tsx +1 -2
  51. package/slider/index.tsx +5 -3
  52. package/table/_story/v2/index.js +2 -1
  53. package/table/_story/v2/radioRowSelection.tsx +107 -0
  54. package/tabs/TabBar.tsx +7 -0
  55. package/tabs/TabPane.tsx +1 -0
  56. package/tabs/index.tsx +2 -1
  57. package/tabs/interface.ts +1 -0
  58. package/tag/index.tsx +32 -2
  59. package/tag/interface.ts +1 -0
  60. package/tagInput/index.tsx +1 -0
  61. package/tooltip/TooltipStyledTransition.tsx +2 -1
  62. package/tooltip/_story/tooltip.stories.js +90 -0
  63. package/treeSelect/index.tsx +1 -1
@@ -5,4 +5,5 @@ export { default as FixedHeaderMerge } from './FixedHeaderMerge';
5
5
  export { default as FixedResizable } from './FixedResizable';
6
6
  export { default as FixedExpandedRow } from './FixedExpandedRow';
7
7
  export { default as FixedMemoryLeak } from './FixedMemoryLeak';
8
- export { default as FixedOnHeaderRow } from './FixedOnHeaderRow';
8
+ export { default as FixedOnHeaderRow } from './FixedOnHeaderRow';
9
+ export { default as RadioRowSelection } from './radioRowSelection';
@@ -0,0 +1,107 @@
1
+ import React, { useMemo, useState } from 'react';
2
+ import { Table, Avatar, Radio } from '@douyinfe/semi-ui';
3
+ import { IconMore } from '@douyinfe/semi-icons';
4
+
5
+ App.storyName = '行选择 - 单选';
6
+ export default function App() {
7
+ const [selectedRowKey, setSelectedRowKey] = useState();
8
+ const columns = [
9
+ {
10
+ title: '',
11
+ dataIndex: 'selection',
12
+ width: 20,
13
+ render: (text, record, index) => {
14
+ return (
15
+ <Radio checked={selectedRowKey === record.key} onChange={() => setSelectedRowKey(record.key)} />
16
+ );
17
+ },
18
+ },
19
+ {
20
+ title: '标题',
21
+ dataIndex: 'name',
22
+ width: 400,
23
+ render: (text, record, index) => {
24
+ return (
25
+ <div>
26
+ <Avatar
27
+ size="small"
28
+ shape="square"
29
+ src={record.nameIconSrc}
30
+ style={{ marginRight: 12 }}
31
+ ></Avatar>
32
+ {text}
33
+ </div>
34
+ );
35
+ },
36
+ },
37
+ {
38
+ title: '大小',
39
+ dataIndex: 'size',
40
+ },
41
+ {
42
+ title: '所有者',
43
+ dataIndex: 'owner',
44
+ render: (text, record, index) => {
45
+ return (
46
+ <div>
47
+ <Avatar size="small" color={record.avatarBg} style={{ marginRight: 4 }}>
48
+ {typeof text === 'string' && text.slice(0, 1)}
49
+ </Avatar>
50
+ {text}
51
+ </div>
52
+ );
53
+ },
54
+ },
55
+ {
56
+ title: '更新日期',
57
+ dataIndex: 'updateTime',
58
+ },
59
+ {
60
+ title: '',
61
+ dataIndex: 'operate',
62
+ render: () => {
63
+ return <IconMore />;
64
+ },
65
+ },
66
+ ];
67
+ const data = useMemo(() => ([
68
+ {
69
+ key: '1',
70
+ name: 'Semi Design 设计稿.fig',
71
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png',
72
+ size: '2M',
73
+ owner: '姜鹏志',
74
+ updateTime: '2020-02-02 05:13',
75
+ avatarBg: 'grey',
76
+ },
77
+ {
78
+ key: '2',
79
+ name: 'Semi Design 分享演示文稿',
80
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
81
+ size: '2M',
82
+ owner: '郝宣',
83
+ updateTime: '2020-01-17 05:31',
84
+ avatarBg: 'red',
85
+ },
86
+ {
87
+ key: '3',
88
+ name: '设计文档',
89
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/docs-icon.png',
90
+ size: '34KB',
91
+ owner: 'Zoey Edwards',
92
+ updateTime: '2020-01-26 11:01',
93
+ avatarBg: 'light-blue',
94
+ },
95
+ {
96
+ key: '4',
97
+ name: 'Semi Pro 设计稿.fig',
98
+ nameIconSrc: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png',
99
+ size: '2M',
100
+ owner: '姜鹏志',
101
+ updateTime: '2020-02-02 05:13',
102
+ avatarBg: 'grey',
103
+ }
104
+ ]), []);
105
+
106
+ return <Table columns={columns} dataSource={data} pagination={{ pageSize: 3 }} />;
107
+ }
package/tabs/TabBar.tsx CHANGED
@@ -88,6 +88,10 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
88
88
  }
89
89
  };
90
90
 
91
+ handleKeyDown = (event: React.KeyboardEvent, itemKey: string, closable: boolean) => {
92
+ this.props.handleKeyDown(event, itemKey, closable);
93
+ }
94
+
91
95
  renderTabItem = (panel: PlainTab): ReactNode => {
92
96
  const { size, type, deleteTabItem } = this.props;
93
97
  const panelIcon = panel.icon ? this.renderIcon(panel.icon) : null;
@@ -110,9 +114,12 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
110
114
  <div
111
115
  role="tab"
112
116
  id={`semiTab${key}`}
117
+ data-tabkey={`semiTab${key}`}
113
118
  aria-controls={`semiTabPanel${key}`}
114
119
  aria-disabled={panel.disabled ? 'true' : 'false'}
115
120
  aria-selected={isSelected ? 'true' : 'false'}
121
+ tabIndex={isSelected ? 0 : -1}
122
+ onKeyDown={e => this.handleKeyDown(e, key, panel.closable)}
116
123
  {...events}
117
124
  className={className}
118
125
  key={this._getItemKey(key)}
package/tabs/TabPane.tsx CHANGED
@@ -96,6 +96,7 @@ class TabPane extends PureComponent<TabPaneProps> {
96
96
  className={classNames}
97
97
  style={style}
98
98
  aria-hidden={active ? 'false' : 'true'}
99
+ tabIndex={0}
99
100
  {...getDataAttr(restProps)}
100
101
  >
101
102
  {motion ? (
package/tabs/index.tsx CHANGED
@@ -266,7 +266,8 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
266
266
  tabBarExtraContent,
267
267
  tabPosition,
268
268
  type,
269
- deleteTabItem: this.deleteTabItem
269
+ deleteTabItem: this.deleteTabItem,
270
+ handleKeyDown: this.foundation.handleKeyDown
270
271
  } as TabBarProps;
271
272
 
272
273
  const tabBar = renderTabBar ? renderTabBar(tabBarProps, TabBar) : <TabBar {...tabBarProps} />;
package/tabs/interface.ts CHANGED
@@ -53,6 +53,7 @@ export interface TabBarProps {
53
53
  dropdownStyle?: CSSProperties;
54
54
  closable?: boolean;
55
55
  deleteTabItem?: (tabKey: string, event: MouseEvent<Element>) => void;
56
+ handleKeyDown?: (event: React.KeyboardEvent, itemKey: string, closable: boolean) => void;
56
57
  }
57
58
 
58
59
  export interface TabPaneProps {
package/tag/index.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
1
2
  /* eslint-disable no-unused-vars */
2
3
  /* eslint-disable max-len */
3
4
  import React, { Component } from 'react';
@@ -7,7 +8,9 @@ import { cssClasses, strings } from '@douyinfe/semi-foundation/tag/constants';
7
8
  import Avatar from '../avatar/index';
8
9
  import { IconClose } from '@douyinfe/semi-icons';
9
10
  import { TagProps, TagSize, TagColor, TagType } from './interface';
11
+ import { handlePrevent } from '@douyinfe/semi-foundation/utils/a11y';
10
12
  import '@douyinfe/semi-foundation/tag/tag.scss';
13
+ import { isString } from 'lodash';
11
14
 
12
15
  export * from './interface';
13
16
 
@@ -50,6 +53,7 @@ export default class Tag extends Component<TagProps, TagState> {
50
53
  className: PropTypes.string,
51
54
  avatarSrc: PropTypes.string,
52
55
  avatarShape: PropTypes.oneOf(avatarShapeSet),
56
+ 'aria-label': PropTypes.string,
53
57
  };
54
58
 
55
59
  constructor(props: TagProps) {
@@ -58,6 +62,7 @@ export default class Tag extends Component<TagProps, TagState> {
58
62
  visible: true,
59
63
  };
60
64
  this.close = this.close.bind(this);
65
+ this.handleKeyDown = this.handleKeyDown.bind(this);
61
66
  }
62
67
 
63
68
  // any other way to achieve this?
@@ -88,6 +93,26 @@ export default class Tag extends Component<TagProps, TagState> {
88
93
  this.setVisible(false);
89
94
  }
90
95
 
96
+ handleKeyDown(event: any) {
97
+ const { closable, onClick } = this.props;
98
+ switch (event.key) {
99
+ case "Backspace":
100
+ case "Delete":
101
+ closable && this.close(event, this.props.children);
102
+ handlePrevent(event);
103
+ break;
104
+ case "Enter":
105
+ onClick(event);
106
+ handlePrevent(event);
107
+ break;
108
+ case 'Escape':
109
+ event.target.blur();
110
+ break;
111
+ default:
112
+ break;
113
+ }
114
+ }
115
+
91
116
  renderAvatar() {
92
117
  const { avatarShape, avatarSrc } = this.props;
93
118
  const avatar = <Avatar src={avatarSrc} shape={avatarShape} />;
@@ -95,10 +120,13 @@ export default class Tag extends Component<TagProps, TagState> {
95
120
  }
96
121
 
97
122
  render() {
98
- const { children, size, color, closable, visible, onClose, className, type, avatarSrc, avatarShape, ...attr } = this.props;
123
+ const { children, size, color, closable, visible, onClose, onClick, className, type, avatarSrc, avatarShape, ...attr } = this.props;
99
124
  const { visible: isVisible } = this.state;
125
+ const clickable = onClick !== Tag.defaultProps.onClick || closable;
126
+ const a11yProps = { role: 'button', tabIndex: 0, onKeyDown: this.handleKeyDown };
100
127
  const baseProps = {
101
128
  ...attr,
129
+ onClick,
102
130
  className: classNames(
103
131
  prefixCls,
104
132
  {
@@ -114,13 +142,15 @@ export default class Tag extends Component<TagProps, TagState> {
114
142
  className
115
143
  ),
116
144
  };
145
+ const wrapProps = clickable ? ({ ...baseProps, ...a11yProps }) : baseProps;
117
146
  const closeIcon = closable ? (
147
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events
118
148
  <div className={`${prefixCls}-close`} onClick={e => this.close(e, children)}>
119
149
  <IconClose size="small" />
120
150
  </div>
121
151
  ) : null;
122
152
  return (
123
- <div {...baseProps}>
153
+ <div aria-label={this.props['aria-label'] || isString(children) ? `${closable ? 'Closable ' : ''}Tag: ${children}` : '' } {...wrapProps}>
124
154
  <div className={`${prefixCls}-content`}>
125
155
  {avatarSrc ? this.renderAvatar() : null}
126
156
  {children}
package/tag/interface.ts CHANGED
@@ -33,6 +33,7 @@ export interface TagProps {
33
33
  className?: string;
34
34
  avatarSrc?: string;
35
35
  avatarShape?: AvatarShape;
36
+ 'aria-label'?: React.AriaAttributes['aria-label'];
36
37
  }
37
38
 
38
39
  export interface TagGroupProps {
@@ -328,6 +328,7 @@ class TagInput extends BaseComponent<TagInputProps, TagInputState> {
328
328
  closable={!disabled}
329
329
  key={`${index}${value}`}
330
330
  visible
331
+ aria-label={`${!disabled ? 'Closable ' : ''}Tag: ${value}`}
331
332
  >
332
333
  <Paragraph
333
334
  className={typoCls}
@@ -18,8 +18,9 @@ const TooltipTransition: React.FC<TooltipTransitionProps> = (props = {}) => {
18
18
  const { children } = props;
19
19
  const motion = getMotionObjFromProps(props);
20
20
 
21
+ // add fillMode forward to fix issue 715, tooltip close will flashing under react 18
21
22
  return (
22
- <StyledTransition {...props} enter={enterCls} leave={leaveCls} duration={'100ms'} {...motion}>
23
+ <StyledTransition {...props} enter={enterCls} leave={leaveCls} duration={'100ms'} {...motion} fillMode='forward'>
23
24
  {typeof children === 'function' ?
24
25
  ({ animateCls, animateEvents, animateStyle }: any) => children({ animateCls, animateEvents, animateStyle }) :
25
26
  children}
@@ -24,6 +24,7 @@ import ArrowPointAtCenter from './ArrowPointAtCenter';
24
24
  import CustomContainer from './CustomContainer';
25
25
  import ContainerPosition from './ContainerPosition';
26
26
  import { IconList, IconSidebar, IconEdit } from '@douyinfe/semi-icons';
27
+ import TooltipTransition from '../TooltipStyledTransition';
27
28
 
28
29
  export default {
29
30
  title: 'Tooltip',
@@ -1007,3 +1008,92 @@ export const autoFocusContentDemo = () => {
1007
1008
  </div>
1008
1009
  );
1009
1010
  };
1011
+
1012
+
1013
+ export const FlashWithReact18 = () => {
1014
+ const [visible, setV] = useState(false);
1015
+
1016
+ const change = () => {
1017
+ setV(false);
1018
+ }
1019
+
1020
+ return (<>
1021
+ <Tooltip content='test work with react 18' position='bottom' trigger='custom' visible={visible}>
1022
+ <Button style={{ marginLeft: 10 }} onClick={() => setV(true)}>show, semi with react 18 motion=true, abnormal</Button>
1023
+ </Tooltip>
1024
+ <Button style={{ marginLeft: 10 }} onClick={() => change()}>hide</Button>
1025
+
1026
+ </>);
1027
+ }
1028
+
1029
+
1030
+
1031
+
1032
+ export const Transition = () => {
1033
+
1034
+ const [transitionState, setT] = useState('');
1035
+
1036
+ const [insert, setInsert] = useState(false);
1037
+
1038
+ const handleLeave = () => {
1039
+ console.log('set insert false')
1040
+ setInsert(false);
1041
+ }
1042
+
1043
+ const CommonDOM = () => {
1044
+ const enterCls = `semi-tooltip-bounceIn`;
1045
+ const leaveCls = `semi-tooltip-zoomOut`;
1046
+ const animateStyle = {
1047
+ animationDirection: 'normal',
1048
+ animationName: transitionState === 'enter' ? enterCls : leaveCls,
1049
+ animationDuration: '1000ms',
1050
+ }
1051
+
1052
+ const handleEnd = () => {
1053
+ if (transitionState === 'enter') {
1054
+ console.log('animation end of show');
1055
+ } else if (transitionState === 'leave') {
1056
+ console.log('animation end of hide');
1057
+ handleLeave();
1058
+ }
1059
+ }
1060
+
1061
+ return <div style={{ ...animateStyle }} onAnimationEnd={handleEnd}>test</div>
1062
+ };
1063
+
1064
+ const toggleShow = (insert) => {
1065
+ if (!transitionState) {
1066
+ setT('enter');
1067
+ setInsert(insert);
1068
+ } else if (transitionState === 'enter') {
1069
+ setT('leave');
1070
+ } else if (transitionState === 'leave') {
1071
+ setT('enter');
1072
+ setInsert(insert);
1073
+ }
1074
+ };
1075
+
1076
+ return (
1077
+ <>
1078
+ <div style={{ width: 200, height: 90, border: '1px solid var(--semi-color-text-1)' }}>
1079
+ {
1080
+ insert ? (
1081
+ <CommonDOM></CommonDOM>
1082
+ ): null
1083
+ }
1084
+ </div>
1085
+ <Button onClick={() => toggleShow(true)}>show</Button>
1086
+ <Button onClick={() => toggleShow(false)}>hide</Button>
1087
+ </>
1088
+ )
1089
+ }
1090
+
1091
+ export const TransitionDemo = () => {
1092
+ const [key, setKey] = useState(1);
1093
+ return (
1094
+ <>
1095
+ <Transition key={key} />
1096
+ <Button onClick={() => setKey(Math.random())}>reset Demo</Button>
1097
+ </>
1098
+ )
1099
+ }
@@ -731,7 +731,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
731
731
  let renderKeys = [];
732
732
  if (checkRelation === 'related') {
733
733
  renderKeys = normalizeKeyList([...checkedKeys], keyEntities, leafOnly);
734
- } else if (checkRelation === 'unRelated') {
734
+ } else if (checkRelation === 'unRelated' && Object.keys(keyEntities).length > 0) {
735
735
  renderKeys = [...realCheckedKeys];
736
736
  }
737
737
  const tagList: Array<React.ReactNode> = [];