@rc-component/select 1.1.4 → 1.2.0-alpha.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 (99) hide show
  1. package/assets/index.css +63 -0
  2. package/assets/index.less +1 -0
  3. package/assets/patch.less +83 -0
  4. package/es/BaseSelect/index.d.ts +14 -3
  5. package/es/BaseSelect/index.js +137 -200
  6. package/es/OptionList.js +3 -3
  7. package/es/Select.d.ts +1 -1
  8. package/es/Select.js +5 -9
  9. package/es/SelectInput/Affix.d.ts +5 -0
  10. package/es/SelectInput/Affix.js +12 -0
  11. package/es/SelectInput/Content/MultipleContent.d.ts +4 -0
  12. package/es/SelectInput/Content/MultipleContent.js +152 -0
  13. package/es/SelectInput/Content/Placeholder.d.ts +5 -0
  14. package/es/SelectInput/Content/Placeholder.js +21 -0
  15. package/es/SelectInput/Content/SingleContent.d.ts +4 -0
  16. package/es/SelectInput/Content/SingleContent.js +98 -0
  17. package/es/SelectInput/Content/index.d.ts +6 -0
  18. package/es/SelectInput/Content/index.js +37 -0
  19. package/es/SelectInput/Input.d.ts +20 -0
  20. package/es/SelectInput/Input.js +214 -0
  21. package/es/SelectInput/context.d.ts +6 -0
  22. package/es/SelectInput/context.js +6 -0
  23. package/es/SelectInput/index.d.ts +39 -0
  24. package/es/SelectInput/index.js +189 -0
  25. package/es/SelectTrigger.d.ts +1 -0
  26. package/es/SelectTrigger.js +5 -3
  27. package/es/TransBtn.d.ts +10 -0
  28. package/es/TransBtn.js +12 -2
  29. package/es/hooks/useAllowClear.d.ts +8 -7
  30. package/es/hooks/useAllowClear.js +21 -23
  31. package/es/hooks/useBaseProps.d.ts +1 -0
  32. package/es/hooks/useComponents.d.ts +12 -0
  33. package/es/hooks/useComponents.js +23 -0
  34. package/es/hooks/useOpen.d.ts +15 -0
  35. package/es/hooks/useOpen.js +76 -0
  36. package/es/hooks/useSearchConfig.d.ts +2 -2
  37. package/es/hooks/useSearchConfig.js +3 -3
  38. package/es/hooks/useSelectTriggerControl.d.ts +1 -1
  39. package/es/hooks/useSelectTriggerControl.js +16 -21
  40. package/es/utils/keyUtil.js +4 -0
  41. package/lib/BaseSelect/index.d.ts +14 -3
  42. package/lib/BaseSelect/index.js +137 -201
  43. package/lib/OptionList.js +3 -3
  44. package/lib/Select.d.ts +1 -1
  45. package/lib/Select.js +5 -9
  46. package/lib/SelectInput/Affix.d.ts +5 -0
  47. package/lib/{hooks/useLayoutEffect.js → SelectInput/Affix.js} +11 -16
  48. package/lib/SelectInput/Content/MultipleContent.d.ts +4 -0
  49. package/lib/{Selector/MultipleSelector.js → SelectInput/Content/MultipleContent.js} +71 -104
  50. package/lib/SelectInput/Content/Placeholder.d.ts +5 -0
  51. package/lib/SelectInput/Content/Placeholder.js +29 -0
  52. package/lib/SelectInput/Content/SingleContent.d.ts +4 -0
  53. package/lib/SelectInput/Content/SingleContent.js +107 -0
  54. package/lib/SelectInput/Content/index.d.ts +6 -0
  55. package/lib/SelectInput/Content/index.js +46 -0
  56. package/lib/SelectInput/Input.d.ts +20 -0
  57. package/lib/SelectInput/Input.js +223 -0
  58. package/lib/SelectInput/context.d.ts +6 -0
  59. package/lib/SelectInput/context.js +15 -0
  60. package/lib/SelectInput/index.d.ts +39 -0
  61. package/lib/SelectInput/index.js +198 -0
  62. package/lib/SelectTrigger.d.ts +1 -0
  63. package/lib/SelectTrigger.js +5 -3
  64. package/lib/TransBtn.d.ts +10 -0
  65. package/lib/TransBtn.js +12 -3
  66. package/lib/hooks/useAllowClear.d.ts +8 -7
  67. package/lib/hooks/useAllowClear.js +21 -24
  68. package/lib/hooks/useBaseProps.d.ts +1 -0
  69. package/lib/hooks/useComponents.d.ts +12 -0
  70. package/lib/hooks/{useDelayReset.js → useComponents.js} +21 -30
  71. package/lib/hooks/useOpen.d.ts +15 -0
  72. package/lib/hooks/useOpen.js +82 -0
  73. package/lib/hooks/useSearchConfig.d.ts +2 -2
  74. package/lib/hooks/useSearchConfig.js +3 -3
  75. package/lib/hooks/useSelectTriggerControl.d.ts +1 -1
  76. package/lib/hooks/useSelectTriggerControl.js +16 -21
  77. package/lib/utils/keyUtil.js +4 -0
  78. package/package.json +5 -4
  79. package/es/Selector/Input.d.ts +0 -27
  80. package/es/Selector/Input.js +0 -61
  81. package/es/Selector/MultipleSelector.d.ts +0 -16
  82. package/es/Selector/MultipleSelector.js +0 -185
  83. package/es/Selector/SingleSelector.d.ts +0 -8
  84. package/es/Selector/SingleSelector.js +0 -104
  85. package/es/Selector/index.d.ts +0 -83
  86. package/es/Selector/index.js +0 -189
  87. package/es/hooks/useDelayReset.d.ts +0 -5
  88. package/es/hooks/useDelayReset.js +0 -33
  89. package/es/hooks/useLayoutEffect.d.ts +0 -5
  90. package/es/hooks/useLayoutEffect.js +0 -17
  91. package/lib/Selector/Input.d.ts +0 -27
  92. package/lib/Selector/Input.js +0 -70
  93. package/lib/Selector/MultipleSelector.d.ts +0 -16
  94. package/lib/Selector/SingleSelector.d.ts +0 -8
  95. package/lib/Selector/SingleSelector.js +0 -113
  96. package/lib/Selector/index.d.ts +0 -83
  97. package/lib/Selector/index.js +0 -196
  98. package/lib/hooks/useDelayReset.d.ts +0 -5
  99. package/lib/hooks/useLayoutEffect.d.ts +0 -5
@@ -4,28 +4,32 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.isMultiple = exports.default = void 0;
7
- var _classnames = _interopRequireDefault(require("classnames"));
8
- var _useLayoutEffect = _interopRequireDefault(require("@rc-component/util/lib/hooks/useLayoutEffect"));
9
- var _useMergedState = _interopRequireDefault(require("@rc-component/util/lib/hooks/useMergedState"));
10
- var _isMobile = _interopRequireDefault(require("@rc-component/util/lib/isMobile"));
11
- var _ref = require("@rc-component/util/lib/ref");
7
+ var _clsx = require("clsx");
12
8
  var _findDOMNode = require("@rc-component/util/lib/Dom/findDOMNode");
13
9
  var React = _interopRequireWildcard(require("react"));
14
10
  var _useAllowClear = require("../hooks/useAllowClear");
15
11
  var _useBaseProps = require("../hooks/useBaseProps");
16
- var _useDelayReset = _interopRequireDefault(require("../hooks/useDelayReset"));
17
12
  var _useLock = _interopRequireDefault(require("../hooks/useLock"));
18
13
  var _useSelectTriggerControl = _interopRequireDefault(require("../hooks/useSelectTriggerControl"));
19
- var _Selector = _interopRequireDefault(require("../Selector"));
20
14
  var _SelectTrigger = _interopRequireDefault(require("../SelectTrigger"));
21
- var _TransBtn = _interopRequireDefault(require("../TransBtn"));
22
15
  var _valueUtil = require("../utils/valueUtil");
23
16
  var _Polite = _interopRequireDefault(require("./Polite"));
17
+ var _useOpen = _interopRequireDefault(require("../hooks/useOpen"));
18
+ var _util = require("@rc-component/util");
19
+ var _SelectInput = _interopRequireDefault(require("../SelectInput"));
20
+ var _useComponents = _interopRequireDefault(require("../hooks/useComponents"));
21
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
22
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
25
23
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
26
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
24
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
28
- const DEFAULT_OMIT_PROPS = ['value', 'onChange', 'removeIcon', 'placeholder', 'autoFocus', 'maxTagCount', 'maxTagTextLength', 'maxTagPlaceholder', 'choiceTransitionName', 'onInputKeyDown', 'onPopupScroll', 'tabIndex'];
25
+ /**
26
+ * ZombieJ:
27
+ * We are currently refactoring the semantic structure of the component. Changelog:
28
+ * - Remove `suffixIcon` and change to `suffix`.
29
+ * - Add `components.root` for replacing response element.
30
+ * - Remove `getInputElement` and `getRawInputElement` since we can use `components.input` instead.
31
+ */
32
+
29
33
  const isMultiple = mode => mode === 'tags' || mode === 'multiple';
30
34
  exports.isMultiple = isMultiple;
31
35
  const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
@@ -47,6 +51,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
47
51
  notFoundContent = 'Not Found',
48
52
  onClear,
49
53
  maxCount,
54
+ placeholder,
50
55
  // Mode
51
56
  mode,
52
57
  // Status
@@ -72,6 +77,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
72
77
  // Icons
73
78
  allowClear,
74
79
  prefix,
80
+ suffix,
75
81
  suffixIcon,
76
82
  clearIcon,
77
83
  // Dropdown
@@ -94,49 +100,34 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
94
100
  onKeyUp,
95
101
  onKeyDown,
96
102
  onMouseDown,
103
+ // Components
104
+ components,
97
105
  // Rest Props
98
106
  ...restProps
99
107
  } = props;
100
108
 
101
109
  // ============================== MISC ==============================
102
110
  const multiple = isMultiple(mode);
103
- const mergedShowSearch = (showSearch !== undefined ? showSearch : multiple) || mode === 'combobox';
104
- const domProps = {
105
- ...restProps
106
- };
107
- DEFAULT_OMIT_PROPS.forEach(propName => {
108
- delete domProps[propName];
109
- });
110
- omitDomProps?.forEach(propName => {
111
- delete domProps[propName];
112
- });
113
-
114
- // ============================= Mobile =============================
115
- const [mobile, setMobile] = React.useState(false);
116
- React.useEffect(() => {
117
- // Only update on the client side
118
- setMobile((0, _isMobile.default)());
119
- }, []);
120
111
 
121
112
  // ============================== Refs ==============================
122
113
  const containerRef = React.useRef(null);
123
114
  const triggerRef = React.useRef(null);
124
- const selectorRef = React.useRef(null);
125
115
  const listRef = React.useRef(null);
126
- const blurRef = React.useRef(false);
127
- const customDomRef = React.useRef(null);
128
116
 
129
117
  /** Used for component focused management */
130
- const [mockFocused, setMockFocused, cancelSetMockFocused] = (0, _useDelayReset.default)();
118
+ const [focused, setFocused] = React.useState(false);
131
119
 
132
120
  // =========================== Imperative ===========================
133
121
  React.useImperativeHandle(ref, () => ({
134
- focus: selectorRef.current?.focus,
135
- blur: selectorRef.current?.blur,
122
+ focus: containerRef.current?.focus,
123
+ blur: containerRef.current?.blur,
136
124
  scrollTo: arg => listRef.current?.scrollTo(arg),
137
- nativeElement: containerRef.current || selectorRef.current?.nativeElement || (0, _findDOMNode.getDOM)(customDomRef.current)
125
+ nativeElement: (0, _findDOMNode.getDOM)(containerRef.current)
138
126
  }));
139
127
 
128
+ // =========================== Components ===========================
129
+ const mergedComponents = (0, _useComponents.default)(components, getInputElement, getRawInputElement);
130
+
140
131
  // ========================== Search Value ==========================
141
132
  const mergedSearchValue = React.useMemo(() => {
142
133
  if (mode !== 'combobox') {
@@ -150,37 +141,10 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
150
141
  // Only works in `combobox`
151
142
  const customizeInputElement = mode === 'combobox' && typeof getInputElement === 'function' && getInputElement() || null;
152
143
 
153
- // Used for customize replacement for `rc-cascader`
154
- const customizeRawInputElement = typeof getRawInputElement === 'function' && getRawInputElement();
155
- const customizeRawInputRef = (0, _ref.useComposeRef)(customDomRef, customizeRawInputElement?.props?.ref);
156
-
157
144
  // ============================== Open ==============================
158
- // SSR not support Portal which means we need delay `open` for the first time render
159
- const [rendered, setRendered] = React.useState(false);
160
- (0, _useLayoutEffect.default)(() => {
161
- setRendered(true);
162
- }, []);
163
- const [innerOpen, setInnerOpen] = (0, _useMergedState.default)(false, {
164
- defaultValue: defaultOpen,
165
- value: open
166
- });
167
- let mergedOpen = rendered ? innerOpen : false;
168
-
169
- // Not trigger `open` in `combobox` when `notFoundContent` is empty
145
+ // Not trigger `open` when `notFoundContent` is empty
170
146
  const emptyListContent = !notFoundContent && emptyOptions;
171
- if (disabled || emptyListContent && mergedOpen && mode === 'combobox') {
172
- mergedOpen = false;
173
- }
174
- const triggerOpen = emptyListContent ? false : mergedOpen;
175
- const onToggleOpen = React.useCallback(newOpen => {
176
- const nextOpen = newOpen !== undefined ? newOpen : !mergedOpen;
177
- if (!disabled) {
178
- setInnerOpen(nextOpen);
179
- if (mergedOpen !== nextOpen) {
180
- onPopupVisibleChange?.(nextOpen);
181
- }
182
- }
183
- }, [disabled, mergedOpen, setInnerOpen, onPopupVisibleChange]);
147
+ const [mergedOpen, triggerOpen] = (0, _useOpen.default)(open, onPopupVisibleChange, nextOpen => disabled || emptyListContent ? false : nextOpen);
184
148
 
185
149
  // ============================= Search =============================
186
150
  const tokenWithEnter = React.useMemo(() => (tokenSeparators || []).some(tokenSeparator => ['\n', '\r\n'].includes(tokenSeparator)), [tokenSeparators]);
@@ -202,7 +166,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
202
166
  onSearchSplit?.(patchLabels);
203
167
 
204
168
  // Should close when paste finish
205
- onToggleOpen(false);
169
+ triggerOpen(false);
206
170
 
207
171
  // Tell Selector that break next actions
208
172
  ret = false;
@@ -212,6 +176,11 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
212
176
  source: fromTyping ? 'typing' : 'effect'
213
177
  });
214
178
  }
179
+
180
+ // Open if from typing
181
+ if (searchText && fromTyping && ret) {
182
+ triggerOpen(true);
183
+ }
215
184
  return ret;
216
185
  };
217
186
 
@@ -238,15 +207,12 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
238
207
  // ============================ Disabled ============================
239
208
  // Close dropdown & remove focus state when disabled change
240
209
  React.useEffect(() => {
241
- if (innerOpen && disabled) {
242
- setInnerOpen(false);
243
- }
244
-
245
210
  // After onBlur is triggered, the focused does not need to be reset
246
- if (disabled && !blurRef.current) {
247
- setMockFocused(false);
211
+ if (disabled) {
212
+ triggerOpen(false);
213
+ setFocused(false);
248
214
  }
249
- }, [disabled]);
215
+ }, [disabled, mergedOpen]);
250
216
 
251
217
  // ============================ Keyboard ============================
252
218
  /**
@@ -259,7 +225,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
259
225
  const keyLockRef = React.useRef(false);
260
226
 
261
227
  // KeyDown
262
- const onInternalKeyDown = (event, ...rest) => {
228
+ const onInternalKeyDown = event => {
263
229
  const clearLock = getClearLock();
264
230
  const {
265
231
  key
@@ -273,7 +239,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
273
239
 
274
240
  // We only manage open state here, close logic should handle by list component
275
241
  if (!mergedOpen) {
276
- onToggleOpen(true);
242
+ triggerOpen(true);
277
243
  }
278
244
  }
279
245
  setClearLock(!!mergedSearchValue);
@@ -302,9 +268,9 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
302
268
  if (isEnterKey) {
303
269
  keyLockRef.current = true;
304
270
  }
305
- listRef.current?.onKeyDown(event, ...rest);
271
+ listRef.current?.onKeyDown(event);
306
272
  }
307
- onKeyDown?.(event, ...rest);
273
+ onKeyDown?.(event);
308
274
  };
309
275
 
310
276
  // KeyUp
@@ -319,13 +285,13 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
319
285
  };
320
286
 
321
287
  // ============================ Selector ============================
322
- const onSelectorRemove = val => {
288
+ const onSelectorRemove = (0, _util.useEvent)(val => {
323
289
  const newValues = displayValues.filter(i => i !== val);
324
290
  onDisplayValuesChange(newValues, {
325
291
  type: 'remove',
326
292
  values: [val]
327
293
  });
328
- };
294
+ });
329
295
  const onInputBlur = () => {
330
296
  // Unlock the Enter key after the input blur; otherwise, the Enter key needs to be pressed twice to trigger the correct effect.
331
297
  keyLockRef.current = false;
@@ -333,31 +299,20 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
333
299
 
334
300
  // ========================== Focus / Blur ==========================
335
301
  /** Record real focus status */
336
- const focusRef = React.useRef(false);
337
- const onContainerFocus = (...args) => {
338
- setMockFocused(true);
339
- if (!disabled) {
340
- if (onFocus && !focusRef.current) {
341
- onFocus(...args);
342
- }
302
+ // const focusRef = React.useRef<boolean>(false);
343
303
 
304
+ const onInternalFocus = event => {
305
+ setFocused(true);
306
+ if (!disabled) {
344
307
  // `showAction` should handle `focus` if set
345
308
  if (showAction.includes('focus')) {
346
- onToggleOpen(true);
309
+ triggerOpen(true);
347
310
  }
311
+ onFocus?.(event);
348
312
  }
349
- focusRef.current = true;
350
313
  };
351
- const onContainerBlur = (...args) => {
352
- blurRef.current = true;
353
- setMockFocused(false, () => {
354
- focusRef.current = false;
355
- blurRef.current = false;
356
- onToggleOpen(false);
357
- });
358
- if (disabled) {
359
- return;
360
- }
314
+ const onInternalBlur = event => {
315
+ setFocused(false);
361
316
  if (mergedSearchValue) {
362
317
  // `tags` mode should move `searchValue` into values
363
318
  if (mode === 'tags') {
@@ -371,17 +326,11 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
371
326
  });
372
327
  }
373
328
  }
374
- if (onBlur) {
375
- onBlur(...args);
329
+ if (!disabled) {
330
+ triggerOpen(false);
331
+ onBlur?.(event);
376
332
  }
377
333
  };
378
-
379
- // Give focus back of Select
380
- const activeTimeoutIds = [];
381
- React.useEffect(() => () => {
382
- activeTimeoutIds.forEach(timeoutId => clearTimeout(timeoutId));
383
- activeTimeoutIds.splice(0, activeTimeoutIds.length);
384
- }, []);
385
334
  const onInternalMouseDown = (event, ...restArgs) => {
386
335
  const {
387
336
  target
@@ -389,18 +338,9 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
389
338
  const popupElement = triggerRef.current?.getPopupElement();
390
339
 
391
340
  // We should give focus back to selector if clicked item is not focusable
392
- if (popupElement && popupElement.contains(target)) {
393
- const timeoutId = setTimeout(() => {
394
- const index = activeTimeoutIds.indexOf(timeoutId);
395
- if (index !== -1) {
396
- activeTimeoutIds.splice(index, 1);
397
- }
398
- cancelSetMockFocused();
399
- if (!mobile && !popupElement.contains(document.activeElement)) {
400
- selectorRef.current?.focus();
401
- }
402
- });
403
- activeTimeoutIds.push(timeoutId);
341
+ if (popupElement?.contains(target) && triggerOpen) {
342
+ // Tell `open` not to close since it's safe in the popup
343
+ triggerOpen(true, true);
404
344
  }
405
345
  onMouseDown?.(event, ...restArgs);
406
346
  };
@@ -414,58 +354,53 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
414
354
 
415
355
  // Used for raw custom input trigger
416
356
  let onTriggerVisibleChange;
417
- if (customizeRawInputElement) {
357
+ if (!!mergedComponents.root) {
418
358
  onTriggerVisibleChange = newOpen => {
419
- onToggleOpen(newOpen);
359
+ triggerOpen(newOpen);
420
360
  };
421
361
  }
422
362
 
423
363
  // Close when click on non-select element
424
- (0, _useSelectTriggerControl.default)(() => [containerRef.current, triggerRef.current?.getPopupElement()], triggerOpen, onToggleOpen, !!customizeRawInputElement);
364
+ (0, _useSelectTriggerControl.default)(() => [(0, _findDOMNode.getDOM)(containerRef.current), triggerRef.current?.getPopupElement()], mergedOpen, triggerOpen, !!mergedComponents.root);
425
365
 
426
366
  // ============================ Context =============================
427
367
  const baseSelectContext = React.useMemo(() => ({
428
368
  ...props,
429
369
  notFoundContent,
430
370
  open: mergedOpen,
431
- triggerOpen,
371
+ triggerOpen: mergedOpen,
432
372
  id,
433
- showSearch: mergedShowSearch,
373
+ showSearch,
434
374
  multiple,
435
- toggleOpen: onToggleOpen,
375
+ toggleOpen: triggerOpen,
436
376
  showScrollBar,
437
377
  styles,
438
378
  classNames
439
- }), [props, notFoundContent, triggerOpen, mergedOpen, id, mergedShowSearch, multiple, onToggleOpen, showScrollBar, styles, classNames]);
379
+ }), [props, notFoundContent, triggerOpen, id, showSearch, multiple, mergedOpen, showScrollBar, styles, classNames]);
440
380
 
441
381
  // ==================================================================
442
382
  // == Render ==
443
383
  // ==================================================================
444
384
 
445
- // ============================= Arrow ==============================
446
- const showSuffixIcon = !!suffixIcon || loading;
447
- let arrowNode;
448
- if (showSuffixIcon) {
449
- arrowNode = /*#__PURE__*/React.createElement(_TransBtn.default, {
450
- className: (0, _classnames.default)(`${prefixCls}-arrow`, classNames?.suffix, {
451
- [`${prefixCls}-arrow-loading`]: loading
452
- }),
453
- style: styles?.suffix,
454
- customizeIcon: suffixIcon,
455
- customizeIconProps: {
456
- loading,
385
+ // ============================= Suffix =============================
386
+ const mergedSuffixIcon = React.useMemo(() => {
387
+ const nextSuffix = suffix ?? suffixIcon;
388
+ if (typeof nextSuffix === 'function') {
389
+ return nextSuffix({
457
390
  searchValue: mergedSearchValue,
458
391
  open: mergedOpen,
459
- focused: mockFocused,
460
- showSearch: mergedShowSearch
461
- }
462
- });
463
- }
392
+ focused,
393
+ showSearch,
394
+ loading
395
+ });
396
+ }
397
+ return nextSuffix;
398
+ }, [suffix, suffixIcon, mergedSearchValue, mergedOpen, focused, showSearch, loading]);
464
399
 
465
400
  // ============================= Clear ==============================
466
401
  const onClearMouseDown = () => {
467
402
  onClear?.();
468
- selectorRef.current?.focus();
403
+ containerRef.current?.focus();
469
404
  onDisplayValuesChange([], {
470
405
  type: 'clear',
471
406
  values: displayValues
@@ -475,7 +410,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
475
410
  const {
476
411
  allowClear: mergedAllowClear,
477
412
  clearIcon: clearNode
478
- } = (0, _useAllowClear.useAllowClear)(prefixCls, onClearMouseDown, displayValues, allowClear, clearIcon, disabled, mergedSearchValue, mode);
413
+ } = (0, _useAllowClear.useAllowClear)(prefixCls, displayValues, allowClear, clearIcon, disabled, mergedSearchValue, mode);
479
414
 
480
415
  // =========================== OptionList ===========================
481
416
  const optionList = /*#__PURE__*/React.createElement(OptionList, {
@@ -483,25 +418,69 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
483
418
  });
484
419
 
485
420
  // ============================= Select =============================
486
- const mergedClassName = (0, _classnames.default)(prefixCls, className, {
487
- [`${prefixCls}-focused`]: mockFocused,
421
+ const mergedClassName = (0, _clsx.clsx)(prefixCls, className, {
422
+ [`${prefixCls}-focused`]: focused,
488
423
  [`${prefixCls}-multiple`]: multiple,
489
424
  [`${prefixCls}-single`]: !multiple,
490
- [`${prefixCls}-allow-clear`]: allowClear,
491
- [`${prefixCls}-show-arrow`]: showSuffixIcon,
425
+ [`${prefixCls}-allow-clear`]: mergedAllowClear,
426
+ [`${prefixCls}-show-arrow`]: mergedSuffixIcon !== undefined && mergedSuffixIcon !== null,
492
427
  [`${prefixCls}-disabled`]: disabled,
493
428
  [`${prefixCls}-loading`]: loading,
494
429
  [`${prefixCls}-open`]: mergedOpen,
495
430
  [`${prefixCls}-customize-input`]: customizeInputElement,
496
- [`${prefixCls}-show-search`]: mergedShowSearch
431
+ [`${prefixCls}-show-search`]: showSearch
497
432
  });
498
433
 
499
- // >>> Selector
500
- const selectorNode = /*#__PURE__*/React.createElement(_SelectTrigger.default, {
434
+ // >>> Render
435
+ let renderNode = /*#__PURE__*/React.createElement(_SelectInput.default, _extends({}, restProps, {
436
+ // Ref
437
+ ref: containerRef
438
+ // Style
439
+ ,
440
+ prefixCls: prefixCls,
441
+ className: mergedClassName
442
+ // Focus state
443
+ ,
444
+ focused: focused
445
+ // UI
446
+ ,
447
+ prefix: prefix,
448
+ suffix: mergedSuffixIcon,
449
+ clearIcon: clearNode
450
+ // Type or mode
451
+ ,
452
+ multiple: multiple,
453
+ mode: mode
454
+ // Values
455
+ ,
456
+ displayValues: displayValues,
457
+ placeholder: placeholder,
458
+ searchValue: mergedSearchValue,
459
+ activeValue: activeValue,
460
+ onSearch: onInternalSearch,
461
+ onSearchSubmit: onInternalSearchSubmit,
462
+ onInputBlur: onInputBlur,
463
+ onFocus: onInternalFocus,
464
+ onBlur: onInternalBlur,
465
+ onClearMouseDown: onClearMouseDown,
466
+ onKeyDown: onInternalKeyDown,
467
+ onKeyUp: onInternalKeyUp,
468
+ onSelectorRemove: onSelectorRemove
469
+ // Token handling
470
+ ,
471
+ tokenWithEnter: tokenWithEnter
472
+ // Open
473
+ ,
474
+ onMouseDown: onInternalMouseDown
475
+ // Components
476
+ ,
477
+ components: mergedComponents
478
+ }));
479
+ renderNode = /*#__PURE__*/React.createElement(_SelectTrigger.default, {
501
480
  ref: triggerRef,
502
481
  disabled: disabled,
503
482
  prefixCls: prefixCls,
504
- visible: triggerOpen,
483
+ visible: mergedOpen,
505
484
  popupElement: optionList,
506
485
  animation: animation,
507
486
  transitionName: transitionName,
@@ -516,58 +495,15 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
516
495
  getPopupContainer: getPopupContainer,
517
496
  empty: emptyOptions,
518
497
  onPopupVisibleChange: onTriggerVisibleChange,
519
- onPopupMouseEnter: onPopupMouseEnter
520
- }, customizeRawInputElement ? ( /*#__PURE__*/React.cloneElement(customizeRawInputElement, {
521
- ref: customizeRawInputRef
522
- })) : /*#__PURE__*/React.createElement(_Selector.default, _extends({}, props, {
523
- prefixClassName: classNames?.prefix,
524
- prefixStyle: styles?.prefix,
525
- prefixCls: prefixCls,
526
- inputElement: customizeInputElement,
527
- ref: selectorRef,
528
- id: id,
529
- prefix: prefix,
530
- showSearch: mergedShowSearch,
531
- autoClearSearchValue: autoClearSearchValue,
532
- mode: mode,
533
- activeDescendantId: activeDescendantId,
534
- tagRender: tagRender,
535
- values: displayValues,
536
- open: mergedOpen,
537
- onToggleOpen: onToggleOpen,
538
- activeValue: activeValue,
539
- searchValue: mergedSearchValue,
540
- onSearch: onInternalSearch,
541
- onSearchSubmit: onInternalSearchSubmit,
542
- onRemove: onSelectorRemove,
543
- tokenWithEnter: tokenWithEnter,
544
- onInputBlur: onInputBlur
545
- })));
546
-
547
- // >>> Render
548
- let renderNode;
549
-
550
- // Render raw
551
- if (customizeRawInputElement) {
552
- renderNode = selectorNode;
553
- } else {
554
- renderNode = /*#__PURE__*/React.createElement("div", _extends({
555
- className: mergedClassName
556
- }, domProps, {
557
- ref: containerRef,
558
- onMouseDown: onInternalMouseDown,
559
- onKeyDown: onInternalKeyDown,
560
- onKeyUp: onInternalKeyUp,
561
- onFocus: onContainerFocus,
562
- onBlur: onContainerBlur
563
- }), /*#__PURE__*/React.createElement(_Polite.default, {
564
- visible: mockFocused && !mergedOpen,
565
- values: displayValues
566
- }), selectorNode, arrowNode, mergedAllowClear && clearNode);
567
- }
498
+ onPopupMouseEnter: onPopupMouseEnter,
499
+ onPopupMouseDown: onInternalMouseDown
500
+ }, renderNode);
568
501
  return /*#__PURE__*/React.createElement(_useBaseProps.BaseSelectContext.Provider, {
569
502
  value: baseSelectContext
570
- }, renderNode);
503
+ }, /*#__PURE__*/React.createElement(_Polite.default, {
504
+ visible: focused && !mergedOpen,
505
+ values: displayValues
506
+ }), renderNode);
571
507
  });
572
508
 
573
509
  // Set display name for dev
package/lib/OptionList.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _classnames = _interopRequireDefault(require("classnames"));
7
+ var _clsx = require("clsx");
8
8
  var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
9
9
  var _useMemo = _interopRequireDefault(require("@rc-component/util/lib/hooks/useMemo"));
10
10
  var _omit = _interopRequireDefault(require("@rc-component/util/lib/omit"));
@@ -324,7 +324,7 @@ const OptionList = (_, ref) => {
324
324
  if (group) {
325
325
  const groupTitle = data.title ?? (isTitleType(label) ? label.toString() : undefined);
326
326
  return /*#__PURE__*/React.createElement("div", {
327
- className: (0, _classnames.default)(itemPrefixCls, `${itemPrefixCls}-group`, data.className),
327
+ className: (0, _clsx.clsx)(itemPrefixCls, `${itemPrefixCls}-group`, data.className),
328
328
  title: groupTitle
329
329
  }, label !== undefined ? label : key);
330
330
  }
@@ -342,7 +342,7 @@ const OptionList = (_, ref) => {
342
342
  const selected = isSelected(value);
343
343
  const mergedDisabled = disabled || !selected && overMaxCount;
344
344
  const optionPrefixCls = `${itemPrefixCls}-option`;
345
- const optionClassName = (0, _classnames.default)(itemPrefixCls, optionPrefixCls, className, contextClassNames?.popup?.listItem, {
345
+ const optionClassName = (0, _clsx.clsx)(itemPrefixCls, optionPrefixCls, className, contextClassNames?.popup?.listItem, {
346
346
  [`${optionPrefixCls}-grouped`]: groupOption,
347
347
  [`${optionPrefixCls}-active`]: activeIndex === itemIndex && !mergedDisabled,
348
348
  [`${optionPrefixCls}-disabled`]: mergedDisabled,
package/lib/Select.d.ts CHANGED
@@ -125,7 +125,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
125
125
  classNames?: Partial<Record<SemanticName, string>>;
126
126
  styles?: Partial<Record<SemanticName, React.CSSProperties>>;
127
127
  }
128
- declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
128
+ declare const TypedSelect: (<ValueType = any, OptionType extends DefaultOptionType | BaseOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
129
129
  Option: typeof Option;
130
130
  OptGroup: typeof OptGroup;
131
131
  };
package/lib/Select.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _useMergedState = _interopRequireDefault(require("@rc-component/util/lib/hooks/useMergedState"));
7
+ var _useControlledState = _interopRequireDefault(require("@rc-component/util/lib/hooks/useControlledState"));
8
8
  var _warning = _interopRequireDefault(require("@rc-component/util/lib/warning"));
9
9
  var React = _interopRequireWildcard(require("react"));
10
10
  var _BaseSelect = _interopRequireWildcard(require("./BaseSelect"));
@@ -107,7 +107,7 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
107
107
  optionFilterProp: legacyOptionFilterProp,
108
108
  filterSort: legacyFilterSort
109
109
  };
110
- const [mergedShowSearch, searchConfig] = (0, _useSearchConfig.default)(showSearch, searchProps);
110
+ const [mergedShowSearch, searchConfig] = (0, _useSearchConfig.default)(showSearch, searchProps, mode);
111
111
  const {
112
112
  filterOption,
113
113
  searchValue,
@@ -134,10 +134,8 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
134
134
  /* eslint-enable react-hooks/exhaustive-deps */);
135
135
 
136
136
  // =========================== Search ===========================
137
- const [mergedSearchValue, setSearchValue] = (0, _useMergedState.default)('', {
138
- value: searchValue,
139
- postState: search => search || ''
140
- });
137
+ const [internalSearchValue, setSearchValue] = (0, _useControlledState.default)('', searchValue);
138
+ const mergedSearchValue = internalSearchValue || '';
141
139
 
142
140
  // =========================== Option ===========================
143
141
  const parsedOptions = (0, _useOptions.default)(options, children, mergedFieldNames, optionFilterProp, optionLabelProp);
@@ -192,9 +190,7 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
192
190
  }, [mergedFieldNames, optionLabelProp, valueOptions]);
193
191
 
194
192
  // =========================== Values ===========================
195
- const [internalValue, setInternalValue] = (0, _useMergedState.default)(defaultValue, {
196
- value
197
- });
193
+ const [internalValue, setInternalValue] = (0, _useControlledState.default)(defaultValue, value);
198
194
 
199
195
  // Merged value with LabelValueType
200
196
  const rawLabeledValues = React.useMemo(() => {
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ export interface AffixProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ children?: React.ReactNode;
4
+ }
5
+ export default function Affix(props: AffixProps): React.JSX.Element;