@douyinfe/semi-ui 2.11.1 → 2.12.0-beta.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 (60) hide show
  1. package/README.md +1 -1
  2. package/button/Button.tsx +1 -1
  3. package/dist/css/semi.css +33 -0
  4. package/dist/css/semi.min.css +1 -1
  5. package/dist/umd/semi-ui.js +2334 -322
  6. package/dist/umd/semi-ui.js.map +1 -1
  7. package/dist/umd/semi-ui.min.js +1 -1
  8. package/dist/umd/semi-ui.min.js.map +1 -1
  9. package/form/_story/FormSubmit/index.tsx +45 -0
  10. package/form/_story/form.stories.js +2 -1
  11. package/lib/cjs/button/Button.d.ts +1 -1
  12. package/lib/cjs/modal/Modal.js +3 -2
  13. package/lib/cjs/modal/ModalContent.d.ts +2 -0
  14. package/lib/cjs/modal/ModalContent.js +17 -9
  15. package/lib/cjs/progress/index.js +1 -1
  16. package/lib/cjs/select/index.js +1 -1
  17. package/lib/cjs/slider/index.js +9 -5
  18. package/lib/cjs/tabs/TabBar.d.ts +1 -0
  19. package/lib/cjs/tabs/TabBar.js +8 -1
  20. package/lib/cjs/tabs/TabPane.js +2 -1
  21. package/lib/cjs/tabs/index.js +2 -1
  22. package/lib/cjs/tabs/interface.d.ts +1 -0
  23. package/lib/cjs/tag/index.d.ts +2 -0
  24. package/lib/cjs/tag/index.js +60 -11
  25. package/lib/cjs/tag/interface.d.ts +1 -0
  26. package/lib/cjs/tagInput/index.js +3 -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/treeSelect/index.js +2 -2
  45. package/modal/Modal.tsx +2 -1
  46. package/modal/ModalContent.tsx +14 -8
  47. package/package.json +9 -9
  48. package/progress/index.tsx +1 -1
  49. package/select/index.tsx +1 -2
  50. package/slider/index.tsx +5 -3
  51. package/table/_story/v2/index.js +2 -1
  52. package/table/_story/v2/radioRowSelection.tsx +107 -0
  53. package/tabs/TabBar.tsx +7 -0
  54. package/tabs/TabPane.tsx +1 -0
  55. package/tabs/index.tsx +2 -1
  56. package/tabs/interface.ts +1 -0
  57. package/tag/index.tsx +32 -2
  58. package/tag/interface.ts +1 -0
  59. package/tagInput/index.tsx +1 -0
  60. package/treeSelect/index.tsx +1 -1
@@ -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}
@@ -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> = [];