@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.
@@ -5,11 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined"));
8
+ var _get2 = _interopRequireDefault(require("lodash/get"));
9
9
 
10
- var _isNull2 = _interopRequireDefault(require("lodash/isNull"));
11
-
12
- var _omit2 = _interopRequireDefault(require("lodash/omit"));
10
+ var _isFunction2 = _interopRequireDefault(require("lodash/isFunction"));
13
11
 
14
12
  var _isEqual2 = _interopRequireDefault(require("lodash/isEqual"));
15
13
 
@@ -57,26 +55,15 @@ class OverflowList extends _baseComponent.default {
57
55
 
58
56
  this.resize = function () {
59
57
  let entries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
60
- // if any parent is growing, assume we have more room than before
61
- const growing = entries.some(entry => {
62
- const previousWidth = _this.previousWidths.get(entry.target) || 0;
63
- return entry.contentRect.width > previousWidth;
64
- });
65
-
66
- _this.repartition(growing);
67
58
 
68
- entries.forEach(entry => _this.previousWidths.set(entry.target, entry.contentRect.width));
69
- };
70
-
71
- this.repartition = growing => {
72
- // if not mounted or scroll mode, we do not
73
- if ((0, _isNull2.default)(this.spacer) || (0, _isUndefined2.default)(this.spacer) || this.isScrollMode()) {
74
- return;
75
- } // spacer has flex-shrink and width 1px so if it's much smaller then we know to shrink
59
+ var _a;
76
60
 
61
+ const containerWidth = (_a = entries[0]) === null || _a === void 0 ? void 0 : _a.target.clientWidth;
77
62
 
78
- const state = growing ? OverflowDirection.GROW : this.spacer.getBoundingClientRect().width < 0.9 ? OverflowDirection.SHRINK : OverflowDirection.NONE;
79
- this.foundation.handlePartition(state);
63
+ _this.setState({
64
+ containerWidth,
65
+ overflowStatus: 'calculating'
66
+ });
80
67
  };
81
68
 
82
69
  this.reintersect = entries => {
@@ -98,6 +85,18 @@ class OverflowList extends _baseComponent.default {
98
85
  return this.props.overflowRenderer(overflow);
99
86
  };
100
87
 
88
+ this.getItemKey = (item, defalutKey) => {
89
+ const {
90
+ itemKey
91
+ } = this.props;
92
+
93
+ if ((0, _isFunction2.default)(itemKey)) {
94
+ return itemKey(item);
95
+ }
96
+
97
+ return (0, _get2.default)(item, itemKey || 'key', defalutKey);
98
+ };
99
+
101
100
  this.renderItemList = () => {
102
101
  const {
103
102
  className,
@@ -109,9 +108,33 @@ class OverflowList extends _baseComponent.default {
109
108
  collapseFrom
110
109
  } = this.props;
111
110
  const {
112
- visible
111
+ visible,
112
+ overflowStatus
113
113
  } = this.state;
114
- const overflow = this.renderOverflow();
114
+ let overflow = this.renderOverflow();
115
+
116
+ if (!this.isScrollMode()) {
117
+ if (Array.isArray(overflow)) {
118
+ overflow = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, overflow);
119
+ }
120
+
121
+ if ( /*#__PURE__*/_react.default.isValidElement(overflow)) {
122
+ const child = /*#__PURE__*/_react.default.cloneElement(overflow);
123
+
124
+ overflow = /*#__PURE__*/_react.default.createElement(_resizeObserver.default, {
125
+ onResize: _ref => {
126
+ let [entry] = _ref;
127
+ this.setState({
128
+ overflowWidth: entry.target.clientWidth,
129
+ overflowStatus: 'calculating'
130
+ });
131
+ }
132
+ }, /*#__PURE__*/_react.default.createElement("div", {
133
+ className: "".concat(prefixCls, "-overflow")
134
+ }, child));
135
+ }
136
+ }
137
+
115
138
  const inner = renderMode === RenderMode.SCROLL ? [overflow[0], /*#__PURE__*/_react.default.createElement("div", {
116
139
  className: (0, _classnames.default)(wrapperClassName, "".concat(prefixCls, "-scroll-wrapper")),
117
140
  ref: ref => {
@@ -119,7 +142,7 @@ class OverflowList extends _baseComponent.default {
119
142
  },
120
143
  style: Object.assign({}, wrapperStyle),
121
144
  key: "".concat(prefixCls, "-scroll-wrapper")
122
- }, visible.map(visibleItemRenderer).map((item, ind) => {
145
+ }, visible.map(visibleItemRenderer).map(item => {
123
146
  const {
124
147
  forwardRef,
125
148
  key
@@ -129,26 +152,75 @@ class OverflowList extends _baseComponent.default {
129
152
  'data-scrollkey': "".concat(key),
130
153
  key
131
154
  });
132
- })), overflow[1]] : [collapseFrom === Boundary.START ? overflow : null, visible.map(visibleItemRenderer), collapseFrom === Boundary.END ? overflow : null, /*#__PURE__*/_react.default.createElement("div", {
133
- className: "".concat(prefixCls, "-spacer"),
134
- ref: ref => this.spacer = ref,
135
- key: "".concat(prefixCls, "-spacer")
136
- })];
155
+ })), overflow[1]] : [collapseFrom === Boundary.START ? overflow : null, visible.map((item, idx) => {
156
+ const {
157
+ key
158
+ } = item;
159
+ const element = visibleItemRenderer(item, idx);
160
+
161
+ const child = /*#__PURE__*/_react.default.cloneElement(element);
162
+
163
+ return /*#__PURE__*/_react.default.createElement(_resizeObserver.default, {
164
+ key: key,
165
+ onResize: _ref2 => {
166
+ let [entry] = _ref2;
167
+ return this.onItemResize(entry, item, idx);
168
+ }
169
+ }, /*#__PURE__*/_react.default.createElement("div", {
170
+ key: key,
171
+ className: "".concat(prefixCls, "-item")
172
+ }, child));
173
+ }), collapseFrom === Boundary.END ? overflow : null];
137
174
 
138
175
  const list = /*#__PURE__*/_react.default.createElement('div', {
139
176
  className: (0, _classnames.default)("".concat(prefixCls), className),
140
- style
177
+ style: Object.assign(Object.assign({}, style), renderMode === RenderMode.COLLAPSE ? {
178
+ maxWidth: '100%',
179
+ visibility: overflowStatus === "calculating" ? "hidden" : "visible"
180
+ } : null)
141
181
  }, ...inner);
142
182
 
143
183
  return list;
144
184
  };
145
185
 
186
+ this.onItemResize = (entry, item, idx) => {
187
+ const key = this.getItemKey(item, idx);
188
+ const width = this.itemSizeMap.get(key);
189
+
190
+ if (!width) {
191
+ this.itemSizeMap.set(key, entry.target.clientWidth);
192
+ } else if (width !== entry.target.clientWidth) {
193
+ // 某个item发生resize后,重新计算
194
+ this.itemSizeMap.set(key, entry.target.clientWidth);
195
+ this.setState({
196
+ overflowStatus: 'calculating'
197
+ });
198
+ }
199
+
200
+ const {
201
+ maxCount
202
+ } = this.state; // 已经按照最大值maxCount渲染完毕,触发真正的渲染。(-1 是overflow部分会占1)
203
+ // Already rendered maxCount items, trigger the real rendering. (-1 for the overflow part)
204
+
205
+ if (this.itemSizeMap.size === maxCount - 1) {
206
+ this.setState({
207
+ overflowStatus: 'calculating'
208
+ });
209
+ }
210
+ };
211
+
146
212
  this.state = {
147
213
  direction: OverflowDirection.GROW,
148
214
  lastOverflowCount: 0,
149
215
  overflow: [],
150
- visible: props.items,
151
- visibleState: new Map()
216
+ visible: [],
217
+ containerWidth: 0,
218
+ visibleState: new Map(),
219
+ itemSizeMap: new Map(),
220
+ overflowStatus: "calculating",
221
+ pivot: 0,
222
+ overflowWidth: 0,
223
+ maxCount: 0
152
224
  };
153
225
  this.foundation = new _foundation.default(this.adapter);
154
226
  this.previousWidths = new Map();
@@ -171,8 +243,18 @@ class OverflowList extends _baseComponent.default {
171
243
  // reset visible state if the above props change.
172
244
  newState.direction = OverflowDirection.GROW;
173
245
  newState.lastOverflowCount = 0;
174
- newState.overflow = [];
175
- newState.visible = props.items;
246
+
247
+ if (props.renderMode === RenderMode.SCROLL) {
248
+ newState.visible = props.items;
249
+ newState.overflow = [];
250
+ } else {
251
+ newState.visible = [];
252
+ newState.overflow = [];
253
+ }
254
+
255
+ newState.pivot = 0;
256
+ newState.maxCount = 0;
257
+ newState.overflowStatus = "calculating";
176
258
  }
177
259
 
178
260
  return newState;
@@ -190,43 +272,45 @@ class OverflowList extends _baseComponent.default {
190
272
  },
191
273
  notifyIntersect: res => {
192
274
  this.props.onIntersect && this.props.onIntersect(res);
193
- }
275
+ },
276
+ getItemSizeMap: () => this.itemSizeMap
194
277
  });
195
278
  }
196
279
 
197
- componentDidMount() {
198
- this.repartition(false);
199
- }
200
-
201
- shouldComponentUpdate(_nextProps, nextState) {
202
- // We want this component to always re-render, even when props haven't changed, so that
203
- // changes in the renderers' behavior can be reflected.
204
- // The following statement prevents re-rendering only in the case where the state changes
205
- // identity (i.e. setState was called), but the state is still the same when
206
- // shallow-compared to the previous state.
207
- const currState = (0, _omit2.default)(this.state, 'prevProps');
208
- const comingState = (0, _omit2.default)(nextState, 'prevProps');
209
- return !(currState !== comingState && (0, _isEqual2.default)(currState, comingState));
210
- }
211
-
212
280
  componentDidUpdate(prevProps, prevState) {
213
281
  if (!(0, _isEqual2.default)(prevProps.items, this.props.items)) {
214
282
  this.itemRefs = {};
215
283
  }
216
284
 
217
- if (!(0, _isEqual2.default)((0, _omit2.default)(prevState, 'prevProps'), (0, _omit2.default)(this.state, 'prevProps'))) {
218
- this.repartition(false);
219
- }
220
-
221
285
  const {
222
- direction,
223
286
  overflow,
224
- lastOverflowCount
287
+ containerWidth,
288
+ visible,
289
+ overflowStatus
225
290
  } = this.state;
226
291
 
227
- if ( // if a resize operation has just completed (transition to NONE)
228
- direction === OverflowDirection.NONE && direction !== prevState.direction && overflow.length !== lastOverflowCount) {
229
- this.props.onOverflow && this.props.onOverflow(overflow);
292
+ if (this.isScrollMode() || overflowStatus !== "calculating") {
293
+ return;
294
+ }
295
+
296
+ if (visible.length === 0 && overflow.length === 0 && this.props.items.length !== 0) {
297
+ // 推测container最多能渲染的数量
298
+ // Figure out the maximum number of items in this container
299
+ const maxCount = Math.min(this.props.items.length, Math.floor(containerWidth / _constants.numbers.MINIMUM_HTML_ELEMENT_WIDTH)); // 如果collapseFrom是start, 第一次用来计算容量时,倒转列表顺序渲染
300
+ // If collapseFrom === start, render item from end to start. Figuring out how many items in the end could fit in container.
301
+
302
+ const isCollapseFromStart = this.props.collapseFrom === Boundary.START;
303
+ const visible = isCollapseFromStart ? this.foundation.getReversedItems().slice(0, maxCount) : this.props.items.slice(0, maxCount);
304
+ const overflow = isCollapseFromStart ? this.foundation.getReversedItems().slice(maxCount) : this.props.items.slice(maxCount);
305
+ this.setState({
306
+ overflowStatus: 'calculating',
307
+ visible,
308
+ overflow,
309
+ maxCount: maxCount
310
+ });
311
+ this.itemSizeMap.clear();
312
+ } else {
313
+ this.foundation.handleCollapseOverflow();
230
314
  }
231
315
  }
232
316
 
@@ -258,7 +342,8 @@ OverflowList.defaultProps = {
258
342
  overflowRenderer: () => null,
259
343
  renderMode: 'collapse',
260
344
  threshold: 0.75,
261
- visibleItemRenderer: () => null
345
+ visibleItemRenderer: () => null,
346
+ onOverflow: () => null
262
347
  };
263
348
  OverflowList.propTypes = {
264
349
  // if render in scroll mode, key is required in items
@@ -714,7 +714,8 @@ class Select extends _baseComponent.default {
714
714
  innerBottomSlot,
715
715
  loading,
716
716
  virtualize,
717
- multiple
717
+ multiple,
718
+ emptyContent
718
719
  } = this.props; // Do a filter first, instead of directly judging in forEach, so that the focusIndex can correspond to
719
720
 
720
721
  const visibleOptions = options.filter(item => item._show);
@@ -737,7 +738,11 @@ class Select extends _baseComponent.default {
737
738
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
738
739
  _react.default.createElement("div", {
739
740
  id: "".concat(prefixcls, "-").concat(this.selectOptionListID),
740
- className: (0, _classnames.default)("".concat(prefixcls, "-option-list-wrapper"), dropdownClassName),
741
+ className: (0, _classnames.default)({
742
+ // When emptyContent is null and the option is empty, there is no need for the drop-down option for the user,
743
+ // so there is no need to set padding through this className
744
+ ["".concat(prefixcls, "-option-list-wrapper")]: !(isEmpty && emptyContent === null)
745
+ }, dropdownClassName),
741
746
  style: style,
742
747
  ref: this.setOptionContainerEl,
743
748
  onKeyDown: e => this.foundation.handleContainerKeyDown(e)
@@ -208,9 +208,9 @@ class Tag extends _react.Component {
208
208
  })) : null;
209
209
  return /*#__PURE__*/_react.default.createElement("div", Object.assign({
210
210
  "aria-label": this.props['aria-label'] || (0, _isString2.default)(children) ? "".concat(closable ? 'Closable ' : '', "Tag: ").concat(children) : ''
211
- }, wrapProps), /*#__PURE__*/_react.default.createElement("div", {
211
+ }, wrapProps), avatarSrc ? this.renderAvatar() : null, /*#__PURE__*/_react.default.createElement("div", {
212
212
  className: "".concat(prefixCls, "-content")
213
- }, avatarSrc ? this.renderAvatar() : null, children), closeIcon);
213
+ }, children), closeIcon);
214
214
  }
215
215
 
216
216
  }
@@ -47,16 +47,14 @@ var _reactSortableHoc = require("react-sortable-hoc");
47
47
 
48
48
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
49
49
 
50
+ const prefixCls = _constants.cssClasses.PREFIX;
50
51
  const SortableItem = (0, _reactSortableHoc.SortableElement)(props => props.item);
51
52
  const SortableList = (0, _reactSortableHoc.SortableContainer)(_ref => {
52
53
  let {
53
54
  items
54
55
  } = _ref;
55
56
  return /*#__PURE__*/_react.default.createElement("div", {
56
- style: {
57
- display: 'flex',
58
- flexFlow: 'row wrap'
59
- }
57
+ className: "".concat(prefixCls, "-sortable-list")
60
58
  }, items.map((item, index) =>
61
59
  /*#__PURE__*/
62
60
  // @ts-ignore skip SortableItem type check
@@ -66,7 +64,6 @@ const SortableList = (0, _reactSortableHoc.SortableContainer)(_ref => {
66
64
  item: item.item
67
65
  })));
68
66
  });
69
- const prefixCls = _constants.cssClasses.PREFIX;
70
67
 
71
68
  class TagInput extends _baseComponent.default {
72
69
  constructor(props) {
@@ -172,13 +169,15 @@ class TagInput extends _baseComponent.default {
172
169
  key: elementKey,
173
170
  visible: true,
174
171
  "aria-label": "".concat(!disabled ? 'Closable ' : '', "Tag: ").concat(value)
172
+ }, /*#__PURE__*/_react.default.createElement("div", {
173
+ className: "".concat(prefixCls, "-tag-content-wrapper")
175
174
  }, showIconHandler && /*#__PURE__*/_react.default.createElement(DragHandle, null), /*#__PURE__*/_react.default.createElement(_paragraph.default, {
176
175
  className: typoCls,
177
176
  ellipsis: {
178
177
  showTooltip: showContentTooltip,
179
178
  rows: 1
180
179
  }
181
- }, value));
180
+ }, value)));
182
181
  }
183
182
  });
184
183
  };