one-design-next 0.0.63 → 0.0.65

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.
@@ -1,18 +1,25 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
3
+ import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
4
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
2
5
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
6
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
4
7
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
- var _excluded = ["className", "light", "mode", "suffixIcon", "popupClassName", "popupMatchSelectWidth", "visible", "onVisibleChange", "showInnerSearch", "popupRender", "searchValue", "onSearch", "maxCount", "defaultValue", "value", "onChange", "placeholder", "showSearch", "size", "autoClearSearchValue", "optionRender"];
8
+ var _excluded = ["className", "rootClassName", "style", "light", "mode", "suffixIcon", "popupClassName", "popupMatchSelectWidth", "visible", "onVisibleChange", "showInnerSearch", "popupRender", "searchValue", "onSearch", "maxCount", "defaultValue", "value", "onChange", "placeholder", "showSearch", "size", "autoClearSearchValue", "optionRender", "tagRender", "options", "allowClear", "onClear", "tokenSeparators", "tokenMismatch", "tokenFeedback", "validateTokens", "onTokenPaste", "clearUndo", "feedbackDuration", "disabled"];
6
9
  import clsx from 'clsx';
7
10
  import RcSelect, { OptGroup, Option } from 'rc-select';
8
11
  import React, { useEffect, useRef, useState } from 'react';
9
12
  import Checkbox from "../checkbox";
10
13
  import Icon from "../icon";
11
14
  import Popover from "../popover";
15
+ import SelectFeedback from "./SelectFeedback";
12
16
  import "./style";
17
+ import { formatTokenPasteFeedback, readClipboardText, resolveTokenPaste, splitByTokenSeparators, toRawValueList } from "./tokenUtils";
13
18
  import useIcons from "./useIcons";
14
19
  var InternalSelect = function InternalSelect(props, ref) {
15
20
  var className = props.className,
21
+ rootClassName = props.rootClassName,
22
+ style = props.style,
16
23
  light = props.light,
17
24
  mode = props.mode,
18
25
  _props$suffixIcon = props.suffixIcon,
@@ -43,8 +50,26 @@ var InternalSelect = function InternalSelect(props, ref) {
43
50
  _props$autoClearSearc = props.autoClearSearchValue,
44
51
  autoClearSearchValue = _props$autoClearSearc === void 0 ? true : _props$autoClearSearc,
45
52
  _optionRender = props.optionRender,
53
+ tagRender = props.tagRender,
54
+ options = props.options,
55
+ allowClear = props.allowClear,
56
+ onClear = props.onClear,
57
+ tokenSeparators = props.tokenSeparators,
58
+ _props$tokenMismatch = props.tokenMismatch,
59
+ tokenMismatch = _props$tokenMismatch === void 0 ? 'keep' : _props$tokenMismatch,
60
+ tokenFeedback = props.tokenFeedback,
61
+ validateTokens = props.validateTokens,
62
+ onTokenPaste = props.onTokenPaste,
63
+ clearUndo = props.clearUndo,
64
+ _props$feedbackDurati = props.feedbackDuration,
65
+ feedbackDuration = _props$feedbackDurati === void 0 ? 4000 : _props$feedbackDurati,
66
+ disabled = props.disabled,
46
67
  rest = _objectWithoutProperties(props, _excluded);
47
68
  var isMultiple = mode === 'multiple' || mode === 'tags';
69
+ var enableTokenPaste = Boolean(tokenSeparators === null || tokenSeparators === void 0 ? void 0 : tokenSeparators.length) && isMultiple;
70
+ var enableTokenFeedback = tokenFeedback !== null && tokenFeedback !== void 0 ? tokenFeedback : enableTokenPaste;
71
+ var enableClearUndo = clearUndo !== null && clearUndo !== void 0 ? clearUndo : enableTokenPaste;
72
+ var useShell = enableTokenPaste || enableClearUndo || enableTokenFeedback;
48
73
  var _useIcons = useIcons(_objectSpread(_objectSpread({}, rest), {}, {
49
74
  multiple: isMultiple,
50
75
  hasFeedback: false,
@@ -69,13 +94,32 @@ var InternalSelect = function InternalSelect(props, ref) {
69
94
  _useState6 = _slicedToArray(_useState5, 2),
70
95
  searchValue = _useState6[0],
71
96
  setSearchValue = _useState6[1];
97
+ var _useState7 = useState([]),
98
+ _useState8 = _slicedToArray(_useState7, 2),
99
+ invalidValues = _useState8[0],
100
+ setInvalidValues = _useState8[1];
101
+ var _useState9 = useState(null),
102
+ _useState10 = _slicedToArray(_useState9, 2),
103
+ feedback = _useState10[0],
104
+ setFeedback = _useState10[1];
105
+ var undoSnapshotRef = useRef(null);
106
+ var feedbackTimerRef = useRef();
72
107
  var dropdownSearchInputRef = useRef(null);
108
+ var pastingRef = useRef(false);
73
109
  var handleVisibleChange = function handleVisibleChange(bool) {
74
110
  if (visibleProp === undefined) {
75
111
  setVisible(bool);
76
112
  }
77
113
  onVisibleChange === null || onVisibleChange === void 0 || onVisibleChange(bool);
78
114
  };
115
+
116
+ /** 外层 showSearch / 内层 showInnerSearch 共用:受控 searchValue 必须在此回写,否则输入框打不出字 */
117
+ var handleSearch = function handleSearch(text) {
118
+ if (searchValueProp === undefined) {
119
+ setSearchValue(text);
120
+ }
121
+ onSearch === null || onSearch === void 0 || onSearch(text);
122
+ };
79
123
  useEffect(function () {
80
124
  if (valueProp !== undefined) {
81
125
  setValue(valueProp);
@@ -99,25 +143,203 @@ var InternalSelect = function InternalSelect(props, ref) {
99
143
  }, 150);
100
144
  }
101
145
  }, [visible]);
102
- return /*#__PURE__*/React.createElement(RcSelect, _extends({
146
+ useEffect(function () {
147
+ return function () {
148
+ if (feedbackTimerRef.current) {
149
+ clearTimeout(feedbackTimerRef.current);
150
+ }
151
+ };
152
+ }, []);
153
+ var showFeedback = function showFeedback(next) {
154
+ if (!enableTokenFeedback && !(next !== null && next !== void 0 && next.undoable)) {
155
+ setFeedback(null);
156
+ return;
157
+ }
158
+ if (!enableTokenFeedback && !enableClearUndo) {
159
+ setFeedback(null);
160
+ return;
161
+ }
162
+ setFeedback(next);
163
+ if (feedbackTimerRef.current) {
164
+ clearTimeout(feedbackTimerRef.current);
165
+ }
166
+ if (next) {
167
+ feedbackTimerRef.current = setTimeout(function () {
168
+ setFeedback(null);
169
+ undoSnapshotRef.current = null;
170
+ }, feedbackDuration);
171
+ }
172
+ };
173
+ var commitValue = function commitValue(next, option) {
174
+ if (valueProp === undefined) {
175
+ setValue(next);
176
+ }
177
+ _onChange === null || _onChange === void 0 || _onChange(next, option);
178
+ };
179
+ var pruneInvalid = function pruneInvalid(nextValue) {
180
+ var rawList = toRawValueList(nextValue);
181
+ setInvalidValues(function (prev) {
182
+ return prev.filter(function (item) {
183
+ return rawList.some(function (raw) {
184
+ return String(raw) === String(item);
185
+ });
186
+ });
187
+ });
188
+ };
189
+ var handlePasteCapture = /*#__PURE__*/function () {
190
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(event) {
191
+ var text, tokens, currentRaw, result;
192
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
193
+ while (1) switch (_context.prev = _context.next) {
194
+ case 0:
195
+ if (!(!enableTokenPaste || disabled || !(tokenSeparators !== null && tokenSeparators !== void 0 && tokenSeparators.length))) {
196
+ _context.next = 2;
197
+ break;
198
+ }
199
+ return _context.abrupt("return");
200
+ case 2:
201
+ text = readClipboardText(event.clipboardData);
202
+ if (text) {
203
+ _context.next = 5;
204
+ break;
205
+ }
206
+ return _context.abrupt("return");
207
+ case 5:
208
+ tokens = splitByTokenSeparators(text, tokenSeparators);
209
+ if (tokens !== null && tokens !== void 0 && tokens.length) {
210
+ _context.next = 8;
211
+ break;
212
+ }
213
+ return _context.abrupt("return");
214
+ case 8:
215
+ event.preventDefault();
216
+ event.stopPropagation();
217
+ pastingRef.current = true;
218
+ currentRaw = toRawValueList(value);
219
+ _context.next = 14;
220
+ return resolveTokenPaste({
221
+ tokens: tokens,
222
+ currentValue: currentRaw,
223
+ currentInvalid: invalidValues,
224
+ options: options || [],
225
+ tokenMismatch: tokenMismatch,
226
+ maxCount: maxCount,
227
+ validateTokens: validateTokens
228
+ });
229
+ case 14:
230
+ result = _context.sent;
231
+ setInvalidValues(result.nextInvalid);
232
+ commitValue(result.nextValue);
233
+ onTokenPaste === null || onTokenPaste === void 0 || onTokenPaste(result);
234
+ if (enableTokenFeedback) {
235
+ showFeedback({
236
+ message: formatTokenPasteFeedback(result)
237
+ });
238
+ }
239
+ if (autoClearSearchValue) {
240
+ if (searchValueProp === undefined) {
241
+ setSearchValue('');
242
+ }
243
+ onSearch === null || onSearch === void 0 || onSearch('');
244
+ }
245
+
246
+ // 让受控/非受控 onChange 完成后再放开,避免同一次粘贴被 rc-select 再处理
247
+ window.setTimeout(function () {
248
+ pastingRef.current = false;
249
+ }, 0);
250
+ case 21:
251
+ case "end":
252
+ return _context.stop();
253
+ }
254
+ }, _callee);
255
+ }));
256
+ return function handlePasteCapture(_x) {
257
+ return _ref.apply(this, arguments);
258
+ };
259
+ }();
260
+ var handleClear = function handleClear() {
261
+ var current = valueProp === undefined ? value : valueProp;
262
+ var rawList = toRawValueList(current);
263
+ if (enableClearUndo && rawList.length) {
264
+ undoSnapshotRef.current = {
265
+ value: current,
266
+ invalid: _toConsumableArray(invalidValues)
267
+ };
268
+ showFeedback({
269
+ message: "\u5DF2\u6E05\u9664 ".concat(rawList.length, " \u9879"),
270
+ undoable: true
271
+ });
272
+ }
273
+ setInvalidValues([]);
274
+ onClear === null || onClear === void 0 || onClear();
275
+ };
276
+ var handleUndo = function handleUndo() {
277
+ var snapshot = undoSnapshotRef.current;
278
+ if (!snapshot) {
279
+ return;
280
+ }
281
+ undoSnapshotRef.current = null;
282
+ setInvalidValues(snapshot.invalid);
283
+ commitValue(snapshot.value);
284
+ showFeedback(null);
285
+ };
286
+ var mergedTagRender = tagRender || invalidValues.length > 0 ? function (tagProps) {
287
+ var isInvalid = invalidValues.some(function (item) {
288
+ return String(item) === String(tagProps.value);
289
+ });
290
+ if (tagRender) {
291
+ var node = tagRender(tagProps);
292
+ if (!isInvalid || ! /*#__PURE__*/React.isValidElement(node)) {
293
+ return node;
294
+ }
295
+ var element = node;
296
+ return /*#__PURE__*/React.cloneElement(element, {
297
+ className: clsx(element.props.className, 'odn-select-selection-item-invalid'),
298
+ // @ts-expect-error data attr for styling hooks
299
+ 'data-odn-select-tag-invalid': ''
300
+ });
301
+ }
302
+ return /*#__PURE__*/React.createElement("span", {
303
+ className: clsx('odn-select-selection-item', isInvalid && 'odn-select-selection-item-invalid'),
304
+ "data-odn-select-tag-invalid": isInvalid ? '' : undefined
305
+ }, /*#__PURE__*/React.createElement("span", {
306
+ className: "odn-select-selection-item-content"
307
+ }, tagProps.label), tagProps.closable ? /*#__PURE__*/React.createElement("span", {
308
+ className: "odn-select-selection-item-remove",
309
+ onMouseDown: function onMouseDown(e) {
310
+ e.preventDefault();
311
+ e.stopPropagation();
312
+ },
313
+ onClick: tagProps.onClose
314
+ }, typeof removeIcon === 'function' ? removeIcon(tagProps) : removeIcon) : null);
315
+ } : undefined;
316
+ var selectNode = /*#__PURE__*/React.createElement(RcSelect, _extends({
103
317
  ref: ref,
104
318
  prefixCls: "odn-select",
105
319
  className: clsx(className, "odn-select-".concat(size), showInnerSearch && 'odn-select-show-inner-search', light && 'odn-select-light', !light && 'odn-select-outlined'),
320
+ style: useShell ? {
321
+ width: '100%'
322
+ } : style,
106
323
  transitionName: "odn-slide-up",
107
324
  mode: mode,
325
+ options: options,
326
+ allowClear: allowClear,
327
+ onClear: handleClear,
328
+ tokenSeparators: tokenSeparators,
329
+ tagRender: mergedTagRender,
330
+ disabled: disabled,
108
331
  suffixIcon: function suffixIcon(suffixIconProps) {
109
332
  var suffixIconFinal = typeof _suffixIcon === 'function' ? _suffixIcon(suffixIconProps) : _suffixIcon;
110
333
  return /*#__PURE__*/React.createElement(React.Fragment, null, !!maxCount && mode === 'multiple' && Array.isArray(value) && /*#__PURE__*/React.createElement("span", {
111
334
  className: "odn-select-max-count"
112
335
  }, value.length, " / ", maxCount), suffixIconFinal);
113
336
  },
114
- menuItemSelectedIcon: mode === 'multiple' ? function (props) {
115
- var value = props.value,
116
- disabled = props.disabled,
117
- isSelected = props.isSelected;
337
+ menuItemSelectedIcon: mode === 'multiple' ? function (iconProps) {
338
+ var optionDisabled = iconProps.disabled,
339
+ isSelected = iconProps.isSelected;
118
340
  return /*#__PURE__*/React.createElement(Checkbox, {
119
341
  checked: isSelected,
120
- disabled: disabled
342
+ disabled: optionDisabled
121
343
  });
122
344
  } : itemIcon,
123
345
  dropdownClassName: clsx(mode && "odn-select-dropdown-".concat(mode), popupClassName),
@@ -127,18 +349,22 @@ var InternalSelect = function InternalSelect(props, ref) {
127
349
  open: visible,
128
350
  onDropdownVisibleChange: handleVisibleChange,
129
351
  searchValue: searchValue,
352
+ onSearch: handleSearch,
130
353
  value: value,
131
354
  onChange: function onChange(param, option) {
355
+ if (pastingRef.current) {
356
+ // 粘贴路径已在 capture 阶段 commit,忽略 rc-select 二次 onChange
357
+ return;
358
+ }
132
359
  if (valueProp === undefined) {
133
360
  setValue(param);
134
361
  }
362
+ pruneInvalid(param);
135
363
  if (autoClearSearchValue) {
136
364
  if (searchValueProp === undefined) {
137
365
  setSearchValue('');
138
366
  }
139
- if (onSearch) {
140
- onSearch('');
141
- }
367
+ handleSearch('');
142
368
  }
143
369
  _onChange === null || _onChange === void 0 || _onChange(param !== null && param !== void 0 ? param : null, option);
144
370
  },
@@ -156,13 +382,7 @@ var InternalSelect = function InternalSelect(props, ref) {
156
382
  placeholder: "\u8BF7\u8F93\u5165",
157
383
  value: searchValue,
158
384
  onChange: function onChange(e) {
159
- var value = e.target.value;
160
- if (searchValueProp === undefined) {
161
- setSearchValue(value);
162
- }
163
- if (onSearch) {
164
- onSearch(value);
165
- }
385
+ handleSearch(e.target.value);
166
386
  },
167
387
  onKeyDown: function onKeyDown(e) {
168
388
  e.stopPropagation();
@@ -190,30 +410,42 @@ var InternalSelect = function InternalSelect(props, ref) {
190
410
  return finalLabel;
191
411
  }
192
412
  }, rest));
413
+ if (!useShell) {
414
+ return selectNode;
415
+ }
416
+ return /*#__PURE__*/React.createElement("div", {
417
+ className: clsx('odn-select-shell', rootClassName),
418
+ style: style,
419
+ onPasteCapture: enableTokenPaste ? handlePasteCapture : undefined,
420
+ "data-odn-select-shell": true
421
+ }, selectNode, /*#__PURE__*/React.createElement(SelectFeedback, {
422
+ feedback: enableTokenFeedback || feedback !== null && feedback !== void 0 && feedback.undoable && enableClearUndo ? feedback : null,
423
+ onUndo: handleUndo
424
+ }));
193
425
  };
194
426
 
195
427
  // Select.Button 组件接口
196
428
 
197
429
  // Select.Button 组件
198
- var SelectButton = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
199
- var _ref$showArrow = _ref.showArrow,
200
- showArrow = _ref$showArrow === void 0 ? true : _ref$showArrow,
201
- _ref$size = _ref.size,
202
- size = _ref$size === void 0 ? 'middle' : _ref$size,
203
- _ref$disabled = _ref.disabled,
204
- disabled = _ref$disabled === void 0 ? false : _ref$disabled,
205
- prefix = _ref.prefix,
206
- _ref$placeholder = _ref.placeholder,
207
- placeholder = _ref$placeholder === void 0 ? '请选择' : _ref$placeholder,
208
- value = _ref.value,
209
- _ref$active = _ref.active,
210
- active = _ref$active === void 0 ? false : _ref$active,
211
- _ref$allowClear = _ref.allowClear,
212
- allowClear = _ref$allowClear === void 0 ? false : _ref$allowClear,
213
- onClick = _ref.onClick,
214
- onClear = _ref.onClear,
215
- className = _ref.className,
216
- style = _ref.style;
430
+ var SelectButton = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
431
+ var _ref2$showArrow = _ref2.showArrow,
432
+ showArrow = _ref2$showArrow === void 0 ? true : _ref2$showArrow,
433
+ _ref2$size = _ref2.size,
434
+ size = _ref2$size === void 0 ? 'middle' : _ref2$size,
435
+ _ref2$disabled = _ref2.disabled,
436
+ disabled = _ref2$disabled === void 0 ? false : _ref2$disabled,
437
+ prefix = _ref2.prefix,
438
+ _ref2$placeholder = _ref2.placeholder,
439
+ placeholder = _ref2$placeholder === void 0 ? '请选择' : _ref2$placeholder,
440
+ value = _ref2.value,
441
+ _ref2$active = _ref2.active,
442
+ active = _ref2$active === void 0 ? false : _ref2$active,
443
+ _ref2$allowClear = _ref2.allowClear,
444
+ allowClear = _ref2$allowClear === void 0 ? false : _ref2$allowClear,
445
+ onClick = _ref2.onClick,
446
+ onClear = _ref2.onClear,
447
+ className = _ref2.className,
448
+ style = _ref2.style;
217
449
  var buttonClasses = clsx('odn-select-button odn-select odn-select-outlined odn-select-single odn-select-allow-clear odn-select-show-arrow', "odn-select-button-".concat(size), {
218
450
  'odn-select-button-disabled': disabled,
219
451
  'odn-select-open': active
@@ -28,6 +28,15 @@ html {
28
28
  --odn-select-option-selected-color: var(--odn-color-black-12);
29
29
  --odn-select-option-selected-bg: var(--odn-color-blue-1);
30
30
  --odn-selection-item-font-weight: 400;
31
+ --odn-select-multiple-item-invalid-bg: var(--odn-color-red-1);
32
+ --odn-select-multiple-item-invalid-border-color: color-mix(
33
+ in srgb,
34
+ var(--odn-color-error) 40%,
35
+ transparent
36
+ );
37
+ --odn-select-multiple-item-invalid-color: var(--odn-color-error);
38
+ --odn-select-feedback-bg: var(--odn-color-brand-1);
39
+ --odn-select-feedback-color: var(--odn-color-primary);
31
40
  }
32
41
 
33
42
  .odn-select.odn-select-in-form-item {
@@ -663,11 +672,20 @@ html {
663
672
  }
664
673
 
665
674
  .odn-select-multiple .odn-select-selection-overflow-item-suffix {
675
+ /* 默认隐藏:多选主推 showInnerSearch;外层 showSearch 时后缀才是输入框载体 */
666
676
  display: none;
667
677
  min-height: var(--odn-select-multiple-item-height);
668
678
  margin-block: var(--odn-select-internal_fixed_item_margin);
669
679
  }
670
680
 
681
+ .odn-select-multiple.odn-select-show-search .odn-select-selection-overflow-item-suffix {
682
+ display: inline-flex;
683
+ align-items: center;
684
+ max-width: 100%;
685
+ flex: 1 1 auto;
686
+ min-width: 60px;
687
+ }
688
+
671
689
  .odn-select-multiple .odn-select-selection-search {
672
690
  display: inline-flex;
673
691
  position: relative;
@@ -1778,4 +1796,59 @@ html {
1778
1796
 
1779
1797
  .odn-select-selection-overflow-item-rest > span {
1780
1798
  min-width: 0;
1799
+ }
1800
+
1801
+ /* ===== 批量粘贴 / 反馈壳 ===== */
1802
+ .odn-select-shell {
1803
+ display: inline-flex;
1804
+ flex-direction: column;
1805
+ align-items: stretch;
1806
+ max-width: 100%;
1807
+ vertical-align: top;
1808
+ }
1809
+
1810
+ .odn-select-shell .odn-select {
1811
+ width: 100%;
1812
+ }
1813
+
1814
+ .odn-select-multiple .odn-select-selection-overflow .odn-select-selection-item.odn-select-selection-item-invalid,
1815
+ .odn-select-selection-item.odn-select-selection-item-invalid {
1816
+ color: var(--odn-select-multiple-item-invalid-color);
1817
+ background: var(--odn-select-multiple-item-invalid-bg);
1818
+ border: 1px solid var(--odn-select-multiple-item-invalid-border-color);
1819
+ }
1820
+
1821
+ .odn-select-feedback {
1822
+ display: flex;
1823
+ align-items: center;
1824
+ gap: 8px;
1825
+ margin-top: 8px;
1826
+ padding: 8px 12px;
1827
+ border-radius: var(--odn-select-border-radius-sm);
1828
+ background: var(--odn-select-feedback-bg);
1829
+ color: var(--odn-select-feedback-color);
1830
+ font-size: 13px;
1831
+ line-height: 20px;
1832
+ }
1833
+
1834
+ .odn-select-feedback-message {
1835
+ flex: 1;
1836
+ min-width: 0;
1837
+ }
1838
+
1839
+ .odn-select-feedback-undo {
1840
+ flex: none;
1841
+ margin: 0;
1842
+ padding: 0;
1843
+ border: none;
1844
+ background: transparent;
1845
+ color: var(--odn-select-feedback-color);
1846
+ font-size: 13px;
1847
+ line-height: 20px;
1848
+ text-decoration: underline;
1849
+ cursor: pointer;
1850
+ }
1851
+
1852
+ .odn-select-feedback-undo:hover {
1853
+ opacity: 0.85;
1781
1854
  }
@@ -0,0 +1,36 @@
1
+ import type { DefaultOptionType } from 'rc-select/lib/Select';
2
+ import type { ReactNode } from 'react';
3
+ export type RawValue = string | number;
4
+ export type TokenValidationItem = {
5
+ /** 原始粘贴片段 */
6
+ token: string;
7
+ /** 匹配到的 value;未匹配时可省略 */
8
+ value?: RawValue;
9
+ /** 展示文案 */
10
+ label?: ReactNode;
11
+ /** 是否有效(在候选内或业务认可) */
12
+ valid: boolean;
13
+ };
14
+ export type TokenPasteResult = {
15
+ added: RawValue[];
16
+ duplicated: string[];
17
+ invalid: string[];
18
+ nextValue: RawValue[];
19
+ nextInvalid: RawValue[];
20
+ };
21
+ /** 与 rc-select getSeparatedContent 对齐:任一分隔符命中才拆分 */
22
+ export declare function readClipboardText(clipboardData: DataTransfer | null): string;
23
+ export declare function splitByTokenSeparators(text: string, separators: string[]): string[] | null;
24
+ export declare function flattenSelectOptions(options?: DefaultOptionType[]): DefaultOptionType[];
25
+ export declare function matchOptionByToken(token: string, options: DefaultOptionType[]): DefaultOptionType | null;
26
+ export declare function toRawValueList(value: unknown): RawValue[];
27
+ export declare function resolveTokenPaste(params: {
28
+ tokens: string[];
29
+ currentValue: RawValue[];
30
+ currentInvalid: RawValue[];
31
+ options: DefaultOptionType[];
32
+ tokenMismatch: 'drop' | 'keep';
33
+ maxCount?: number;
34
+ validateTokens?: (tokens: string[]) => TokenValidationItem[] | Promise<TokenValidationItem[]>;
35
+ }): Promise<TokenPasteResult>;
36
+ export declare function formatTokenPasteFeedback(result: TokenPasteResult): string;