@douyinfe/semi-ui 2.25.0 → 2.25.2
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.
- package/dist/css/semi.css +18 -11
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +216 -108
- package/dist/umd/semi-ui.js.map +1 -1
- package/dist/umd/semi-ui.min.js +1 -1
- package/dist/umd/semi-ui.min.js.map +1 -1
- package/lib/cjs/overflowList/index.d.ts +805 -6
- package/lib/cjs/overflowList/index.js +145 -60
- package/lib/cjs/select/index.js +7 -2
- package/lib/cjs/tag/index.js +2 -2
- package/lib/cjs/tagInput/index.js +5 -6
- package/lib/es/overflowList/index.d.ts +805 -6
- package/lib/es/overflowList/index.js +143 -62
- package/lib/es/select/index.js +7 -2
- package/lib/es/tag/index.js +2 -2
- package/lib/es/tagInput/index.js +5 -6
- package/package.json +8 -8
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import _omit from "lodash/omit";
|
|
1
|
+
import _get from "lodash/get";
|
|
2
|
+
import _isFunction from "lodash/isFunction";
|
|
4
3
|
import _isEqual from "lodash/isEqual";
|
|
5
4
|
|
|
6
5
|
/* eslint-disable arrow-body-style */
|
|
@@ -8,7 +7,7 @@ import React from 'react';
|
|
|
8
7
|
import cls from 'classnames';
|
|
9
8
|
import BaseComponent from '../_base/baseComponent';
|
|
10
9
|
import PropTypes from 'prop-types';
|
|
11
|
-
import { cssClasses, strings } from '@douyinfe/semi-foundation/lib/es/overflowList/constants';
|
|
10
|
+
import { cssClasses, strings, numbers } from '@douyinfe/semi-foundation/lib/es/overflowList/constants';
|
|
12
11
|
import ResizeObserver from '../resizeObserver';
|
|
13
12
|
import IntersectionObserver from './intersectionObserver';
|
|
14
13
|
import OverflowListFoundation from '@douyinfe/semi-foundation/lib/es/overflowList/foundation';
|
|
@@ -36,26 +35,15 @@ class OverflowList extends BaseComponent {
|
|
|
36
35
|
|
|
37
36
|
this.resize = function () {
|
|
38
37
|
let entries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
39
|
-
// if any parent is growing, assume we have more room than before
|
|
40
|
-
const growing = entries.some(entry => {
|
|
41
|
-
const previousWidth = _this.previousWidths.get(entry.target) || 0;
|
|
42
|
-
return entry.contentRect.width > previousWidth;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
_this.repartition(growing);
|
|
46
|
-
|
|
47
|
-
entries.forEach(entry => _this.previousWidths.set(entry.target, entry.contentRect.width));
|
|
48
|
-
};
|
|
49
38
|
|
|
50
|
-
|
|
51
|
-
// if not mounted or scroll mode, we do not
|
|
52
|
-
if (_isNull(this.spacer) || _isUndefined(this.spacer) || this.isScrollMode()) {
|
|
53
|
-
return;
|
|
54
|
-
} // spacer has flex-shrink and width 1px so if it's much smaller then we know to shrink
|
|
39
|
+
var _a;
|
|
55
40
|
|
|
41
|
+
const containerWidth = (_a = entries[0]) === null || _a === void 0 ? void 0 : _a.target.clientWidth;
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
_this.setState({
|
|
44
|
+
containerWidth,
|
|
45
|
+
overflowStatus: 'calculating'
|
|
46
|
+
});
|
|
59
47
|
};
|
|
60
48
|
|
|
61
49
|
this.reintersect = entries => {
|
|
@@ -77,6 +65,18 @@ class OverflowList extends BaseComponent {
|
|
|
77
65
|
return this.props.overflowRenderer(overflow);
|
|
78
66
|
};
|
|
79
67
|
|
|
68
|
+
this.getItemKey = (item, defalutKey) => {
|
|
69
|
+
const {
|
|
70
|
+
itemKey
|
|
71
|
+
} = this.props;
|
|
72
|
+
|
|
73
|
+
if (_isFunction(itemKey)) {
|
|
74
|
+
return itemKey(item);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return _get(item, itemKey || 'key', defalutKey);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
80
|
this.renderItemList = () => {
|
|
81
81
|
const {
|
|
82
82
|
className,
|
|
@@ -88,9 +88,32 @@ class OverflowList extends BaseComponent {
|
|
|
88
88
|
collapseFrom
|
|
89
89
|
} = this.props;
|
|
90
90
|
const {
|
|
91
|
-
visible
|
|
91
|
+
visible,
|
|
92
|
+
overflowStatus
|
|
92
93
|
} = this.state;
|
|
93
|
-
|
|
94
|
+
let overflow = this.renderOverflow();
|
|
95
|
+
|
|
96
|
+
if (!this.isScrollMode()) {
|
|
97
|
+
if (Array.isArray(overflow)) {
|
|
98
|
+
overflow = /*#__PURE__*/React.createElement(React.Fragment, null, overflow);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if ( /*#__PURE__*/React.isValidElement(overflow)) {
|
|
102
|
+
const child = /*#__PURE__*/React.cloneElement(overflow);
|
|
103
|
+
overflow = /*#__PURE__*/React.createElement(ResizeObserver, {
|
|
104
|
+
onResize: _ref => {
|
|
105
|
+
let [entry] = _ref;
|
|
106
|
+
this.setState({
|
|
107
|
+
overflowWidth: entry.target.clientWidth,
|
|
108
|
+
overflowStatus: 'calculating'
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
112
|
+
className: "".concat(prefixCls, "-overflow")
|
|
113
|
+
}, child));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
94
117
|
const inner = renderMode === RenderMode.SCROLL ? [overflow[0], /*#__PURE__*/React.createElement("div", {
|
|
95
118
|
className: cls(wrapperClassName, "".concat(prefixCls, "-scroll-wrapper")),
|
|
96
119
|
ref: ref => {
|
|
@@ -98,7 +121,7 @@ class OverflowList extends BaseComponent {
|
|
|
98
121
|
},
|
|
99
122
|
style: Object.assign({}, wrapperStyle),
|
|
100
123
|
key: "".concat(prefixCls, "-scroll-wrapper")
|
|
101
|
-
}, visible.map(visibleItemRenderer).map(
|
|
124
|
+
}, visible.map(visibleItemRenderer).map(item => {
|
|
102
125
|
const {
|
|
103
126
|
forwardRef,
|
|
104
127
|
key
|
|
@@ -108,24 +131,71 @@ class OverflowList extends BaseComponent {
|
|
|
108
131
|
'data-scrollkey': "".concat(key),
|
|
109
132
|
key
|
|
110
133
|
});
|
|
111
|
-
})), overflow[1]] : [collapseFrom === Boundary.START ? overflow : null, visible.map(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
134
|
+
})), overflow[1]] : [collapseFrom === Boundary.START ? overflow : null, visible.map((item, idx) => {
|
|
135
|
+
const {
|
|
136
|
+
key
|
|
137
|
+
} = item;
|
|
138
|
+
const element = visibleItemRenderer(item, idx);
|
|
139
|
+
const child = /*#__PURE__*/React.cloneElement(element);
|
|
140
|
+
return /*#__PURE__*/React.createElement(ResizeObserver, {
|
|
141
|
+
key: key,
|
|
142
|
+
onResize: _ref2 => {
|
|
143
|
+
let [entry] = _ref2;
|
|
144
|
+
return this.onItemResize(entry, item, idx);
|
|
145
|
+
}
|
|
146
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
147
|
+
key: key,
|
|
148
|
+
className: "".concat(prefixCls, "-item")
|
|
149
|
+
}, child));
|
|
150
|
+
}), collapseFrom === Boundary.END ? overflow : null];
|
|
116
151
|
const list = /*#__PURE__*/React.createElement('div', {
|
|
117
152
|
className: cls("".concat(prefixCls), className),
|
|
118
|
-
style
|
|
153
|
+
style: Object.assign(Object.assign({}, style), renderMode === RenderMode.COLLAPSE ? {
|
|
154
|
+
maxWidth: '100%',
|
|
155
|
+
visibility: overflowStatus === "calculating" ? "hidden" : "visible"
|
|
156
|
+
} : null)
|
|
119
157
|
}, ...inner);
|
|
120
158
|
return list;
|
|
121
159
|
};
|
|
122
160
|
|
|
161
|
+
this.onItemResize = (entry, item, idx) => {
|
|
162
|
+
const key = this.getItemKey(item, idx);
|
|
163
|
+
const width = this.itemSizeMap.get(key);
|
|
164
|
+
|
|
165
|
+
if (!width) {
|
|
166
|
+
this.itemSizeMap.set(key, entry.target.clientWidth);
|
|
167
|
+
} else if (width !== entry.target.clientWidth) {
|
|
168
|
+
// 某个item发生resize后,重新计算
|
|
169
|
+
this.itemSizeMap.set(key, entry.target.clientWidth);
|
|
170
|
+
this.setState({
|
|
171
|
+
overflowStatus: 'calculating'
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const {
|
|
176
|
+
maxCount
|
|
177
|
+
} = this.state; // 已经按照最大值maxCount渲染完毕,触发真正的渲染。(-1 是overflow部分会占1)
|
|
178
|
+
// Already rendered maxCount items, trigger the real rendering. (-1 for the overflow part)
|
|
179
|
+
|
|
180
|
+
if (this.itemSizeMap.size === maxCount - 1) {
|
|
181
|
+
this.setState({
|
|
182
|
+
overflowStatus: 'calculating'
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
123
187
|
this.state = {
|
|
124
188
|
direction: OverflowDirection.GROW,
|
|
125
189
|
lastOverflowCount: 0,
|
|
126
190
|
overflow: [],
|
|
127
|
-
visible:
|
|
128
|
-
|
|
191
|
+
visible: [],
|
|
192
|
+
containerWidth: 0,
|
|
193
|
+
visibleState: new Map(),
|
|
194
|
+
itemSizeMap: new Map(),
|
|
195
|
+
overflowStatus: "calculating",
|
|
196
|
+
pivot: 0,
|
|
197
|
+
overflowWidth: 0,
|
|
198
|
+
maxCount: 0
|
|
129
199
|
};
|
|
130
200
|
this.foundation = new OverflowListFoundation(this.adapter);
|
|
131
201
|
this.previousWidths = new Map();
|
|
@@ -148,8 +218,18 @@ class OverflowList extends BaseComponent {
|
|
|
148
218
|
// reset visible state if the above props change.
|
|
149
219
|
newState.direction = OverflowDirection.GROW;
|
|
150
220
|
newState.lastOverflowCount = 0;
|
|
151
|
-
|
|
152
|
-
|
|
221
|
+
|
|
222
|
+
if (props.renderMode === RenderMode.SCROLL) {
|
|
223
|
+
newState.visible = props.items;
|
|
224
|
+
newState.overflow = [];
|
|
225
|
+
} else {
|
|
226
|
+
newState.visible = [];
|
|
227
|
+
newState.overflow = [];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
newState.pivot = 0;
|
|
231
|
+
newState.maxCount = 0;
|
|
232
|
+
newState.overflowStatus = "calculating";
|
|
153
233
|
}
|
|
154
234
|
|
|
155
235
|
return newState;
|
|
@@ -167,45 +247,45 @@ class OverflowList extends BaseComponent {
|
|
|
167
247
|
},
|
|
168
248
|
notifyIntersect: res => {
|
|
169
249
|
this.props.onIntersect && this.props.onIntersect(res);
|
|
170
|
-
}
|
|
250
|
+
},
|
|
251
|
+
getItemSizeMap: () => this.itemSizeMap
|
|
171
252
|
});
|
|
172
253
|
}
|
|
173
254
|
|
|
174
|
-
componentDidMount() {
|
|
175
|
-
this.repartition(false);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
shouldComponentUpdate(_nextProps, nextState) {
|
|
179
|
-
// We want this component to always re-render, even when props haven't changed, so that
|
|
180
|
-
// changes in the renderers' behavior can be reflected.
|
|
181
|
-
// The following statement prevents re-rendering only in the case where the state changes
|
|
182
|
-
// identity (i.e. setState was called), but the state is still the same when
|
|
183
|
-
// shallow-compared to the previous state.
|
|
184
|
-
const currState = _omit(this.state, 'prevProps');
|
|
185
|
-
|
|
186
|
-
const comingState = _omit(nextState, 'prevProps');
|
|
187
|
-
|
|
188
|
-
return !(currState !== comingState && _isEqual(currState, comingState));
|
|
189
|
-
}
|
|
190
|
-
|
|
191
255
|
componentDidUpdate(prevProps, prevState) {
|
|
192
256
|
if (!_isEqual(prevProps.items, this.props.items)) {
|
|
193
257
|
this.itemRefs = {};
|
|
194
258
|
}
|
|
195
259
|
|
|
196
|
-
if (!_isEqual(_omit(prevState, 'prevProps'), _omit(this.state, 'prevProps'))) {
|
|
197
|
-
this.repartition(false);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
260
|
const {
|
|
201
|
-
direction,
|
|
202
261
|
overflow,
|
|
203
|
-
|
|
262
|
+
containerWidth,
|
|
263
|
+
visible,
|
|
264
|
+
overflowStatus
|
|
204
265
|
} = this.state;
|
|
205
266
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
267
|
+
if (this.isScrollMode() || overflowStatus !== "calculating") {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (visible.length === 0 && overflow.length === 0 && this.props.items.length !== 0) {
|
|
272
|
+
// 推测container最多能渲染的数量
|
|
273
|
+
// Figure out the maximum number of items in this container
|
|
274
|
+
const maxCount = Math.min(this.props.items.length, Math.floor(containerWidth / numbers.MINIMUM_HTML_ELEMENT_WIDTH)); // 如果collapseFrom是start, 第一次用来计算容量时,倒转列表顺序渲染
|
|
275
|
+
// If collapseFrom === start, render item from end to start. Figuring out how many items in the end could fit in container.
|
|
276
|
+
|
|
277
|
+
const isCollapseFromStart = this.props.collapseFrom === Boundary.START;
|
|
278
|
+
const visible = isCollapseFromStart ? this.foundation.getReversedItems().slice(0, maxCount) : this.props.items.slice(0, maxCount);
|
|
279
|
+
const overflow = isCollapseFromStart ? this.foundation.getReversedItems().slice(maxCount) : this.props.items.slice(maxCount);
|
|
280
|
+
this.setState({
|
|
281
|
+
overflowStatus: 'calculating',
|
|
282
|
+
visible,
|
|
283
|
+
overflow,
|
|
284
|
+
maxCount: maxCount
|
|
285
|
+
});
|
|
286
|
+
this.itemSizeMap.clear();
|
|
287
|
+
} else {
|
|
288
|
+
this.foundation.handleCollapseOverflow();
|
|
209
289
|
}
|
|
210
290
|
}
|
|
211
291
|
|
|
@@ -237,7 +317,8 @@ OverflowList.defaultProps = {
|
|
|
237
317
|
overflowRenderer: () => null,
|
|
238
318
|
renderMode: 'collapse',
|
|
239
319
|
threshold: 0.75,
|
|
240
|
-
visibleItemRenderer: () => null
|
|
320
|
+
visibleItemRenderer: () => null,
|
|
321
|
+
onOverflow: () => null
|
|
241
322
|
};
|
|
242
323
|
OverflowList.propTypes = {
|
|
243
324
|
// if render in scroll mode, key is required in items
|
package/lib/es/select/index.js
CHANGED
|
@@ -667,7 +667,8 @@ class Select extends BaseComponent {
|
|
|
667
667
|
innerBottomSlot,
|
|
668
668
|
loading,
|
|
669
669
|
virtualize,
|
|
670
|
-
multiple
|
|
670
|
+
multiple,
|
|
671
|
+
emptyContent
|
|
671
672
|
} = this.props; // Do a filter first, instead of directly judging in forEach, so that the focusIndex can correspond to
|
|
672
673
|
|
|
673
674
|
const visibleOptions = options.filter(item => item._show);
|
|
@@ -690,7 +691,11 @@ class Select extends BaseComponent {
|
|
|
690
691
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
691
692
|
React.createElement("div", {
|
|
692
693
|
id: "".concat(prefixcls, "-").concat(this.selectOptionListID),
|
|
693
|
-
className: cls(
|
|
694
|
+
className: cls({
|
|
695
|
+
// When emptyContent is null and the option is empty, there is no need for the drop-down option for the user,
|
|
696
|
+
// so there is no need to set padding through this className
|
|
697
|
+
["".concat(prefixcls, "-option-list-wrapper")]: !(isEmpty && emptyContent === null)
|
|
698
|
+
}, dropdownClassName),
|
|
694
699
|
style: style,
|
|
695
700
|
ref: this.setOptionContainerEl,
|
|
696
701
|
onKeyDown: e => this.foundation.handleContainerKeyDown(e)
|
package/lib/es/tag/index.js
CHANGED
|
@@ -170,9 +170,9 @@ export default class Tag extends Component {
|
|
|
170
170
|
})) : null;
|
|
171
171
|
return /*#__PURE__*/React.createElement("div", Object.assign({
|
|
172
172
|
"aria-label": this.props['aria-label'] || _isString(children) ? "".concat(closable ? 'Closable ' : '', "Tag: ").concat(children) : ''
|
|
173
|
-
}, wrapProps), /*#__PURE__*/React.createElement("div", {
|
|
173
|
+
}, wrapProps), avatarSrc ? this.renderAvatar() : null, /*#__PURE__*/React.createElement("div", {
|
|
174
174
|
className: "".concat(prefixCls, "-content")
|
|
175
|
-
},
|
|
175
|
+
}, children), closeIcon);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
}
|
package/lib/es/tagInput/index.js
CHANGED
|
@@ -18,16 +18,14 @@ import Popover from '../popover';
|
|
|
18
18
|
import Paragraph from '../typography/paragraph';
|
|
19
19
|
import { IconClear, IconHandle } from '@douyinfe/semi-icons';
|
|
20
20
|
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
|
|
21
|
+
const prefixCls = cssClasses.PREFIX;
|
|
21
22
|
const SortableItem = SortableElement(props => props.item);
|
|
22
23
|
const SortableList = SortableContainer(_ref => {
|
|
23
24
|
let {
|
|
24
25
|
items
|
|
25
26
|
} = _ref;
|
|
26
27
|
return /*#__PURE__*/React.createElement("div", {
|
|
27
|
-
|
|
28
|
-
display: 'flex',
|
|
29
|
-
flexFlow: 'row wrap'
|
|
30
|
-
}
|
|
28
|
+
className: "".concat(prefixCls, "-sortable-list")
|
|
31
29
|
}, items.map((item, index) =>
|
|
32
30
|
/*#__PURE__*/
|
|
33
31
|
// @ts-ignore skip SortableItem type check
|
|
@@ -37,7 +35,6 @@ const SortableList = SortableContainer(_ref => {
|
|
|
37
35
|
item: item.item
|
|
38
36
|
})));
|
|
39
37
|
});
|
|
40
|
-
const prefixCls = cssClasses.PREFIX;
|
|
41
38
|
|
|
42
39
|
class TagInput extends BaseComponent {
|
|
43
40
|
constructor(props) {
|
|
@@ -143,13 +140,15 @@ class TagInput extends BaseComponent {
|
|
|
143
140
|
key: elementKey,
|
|
144
141
|
visible: true,
|
|
145
142
|
"aria-label": "".concat(!disabled ? 'Closable ' : '', "Tag: ").concat(value)
|
|
143
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
144
|
+
className: "".concat(prefixCls, "-tag-content-wrapper")
|
|
146
145
|
}, showIconHandler && /*#__PURE__*/React.createElement(DragHandle, null), /*#__PURE__*/React.createElement(Paragraph, {
|
|
147
146
|
className: typoCls,
|
|
148
147
|
ellipsis: {
|
|
149
148
|
showTooltip: showContentTooltip,
|
|
150
149
|
rows: 1
|
|
151
150
|
}
|
|
152
|
-
}, value));
|
|
151
|
+
}, value)));
|
|
153
152
|
}
|
|
154
153
|
});
|
|
155
154
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-ui",
|
|
3
|
-
"version": "2.25.
|
|
3
|
+
"version": "2.25.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/es/index.js",
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"lib/*"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@douyinfe/semi-animation": "2.25.
|
|
21
|
-
"@douyinfe/semi-animation-react": "2.25.
|
|
22
|
-
"@douyinfe/semi-foundation": "2.25.
|
|
23
|
-
"@douyinfe/semi-icons": "2.25.
|
|
24
|
-
"@douyinfe/semi-illustrations": "2.25.
|
|
25
|
-
"@douyinfe/semi-theme-default": "2.25.
|
|
20
|
+
"@douyinfe/semi-animation": "2.25.2",
|
|
21
|
+
"@douyinfe/semi-animation-react": "2.25.2",
|
|
22
|
+
"@douyinfe/semi-foundation": "2.25.2",
|
|
23
|
+
"@douyinfe/semi-icons": "2.25.2",
|
|
24
|
+
"@douyinfe/semi-illustrations": "2.25.2",
|
|
25
|
+
"@douyinfe/semi-theme-default": "2.25.2",
|
|
26
26
|
"async-validator": "^3.5.0",
|
|
27
27
|
"classnames": "^2.2.6",
|
|
28
28
|
"copy-text-to-clipboard": "^2.1.1",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
],
|
|
70
70
|
"author": "",
|
|
71
71
|
"license": "MIT",
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "d1cdea565d328c70a4de8636aed30c88f60732dd",
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@babel/plugin-proposal-decorators": "^7.15.8",
|
|
75
75
|
"@babel/plugin-transform-runtime": "^7.15.8",
|