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