refactor(select): rewrite with hook (#27318)

* refactor(select): rewrite with hook

* Update index.tsx

* Update index.tsx

* Update index.tsx

* fix test

* Update index.tsx

* Update index.tsx
This commit is contained in:
Tom Xu 2020-10-24 20:33:18 +08:00 committed by GitHub
parent 5c072cdec9
commit b0245e742b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1062 additions and 143 deletions

View File

@ -7,9 +7,9 @@
import * as React from 'react';
import toArray from 'rc-util/lib/Children/toArray';
import { SelectProps as RcSelectProps } from 'rc-select';
import classNames from 'classnames';
import omit from 'omit.js';
import RcSelect from 'rc-select';
import Select, { InternalSelectProps, OptionType } from '../select';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import devWarning from '../_util/devWarning';
@ -17,8 +17,6 @@ import { isValidElement } from '../_util/reactNode';
const { Option } = Select;
const InternalSelect = Select as React.ComponentClass<RcSelectProps>;
export interface DataSourceItemObject {
value: string;
text: string;
@ -37,14 +35,13 @@ function isSelectOptionOrSelectOptGroup(child: any): Boolean {
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
}
const AutoComplete: React.ForwardRefRenderFunction<Select, AutoCompleteProps> = (props, ref) => {
const AutoComplete: React.ForwardRefRenderFunction<RcSelect<any>, AutoCompleteProps> = (
props,
ref,
) => {
const { prefixCls: customizePrefixCls, className, children, dataSource } = props;
const childNodes: React.ReactElement[] = toArray(children);
const selectRef = React.useRef<Select>();
React.useImperativeHandle<Select, Select>(ref, () => selectRef.current!);
// ============================= Input =============================
let customizeInput: React.ReactElement | undefined;
@ -113,8 +110,8 @@ const AutoComplete: React.ForwardRefRenderFunction<Select, AutoCompleteProps> =
const prefixCls = getPrefixCls('select', customizePrefixCls);
return (
<InternalSelect
ref={selectRef as any}
<Select
ref={ref}
{...omit(props, ['dataSource'])}
prefixCls={prefixCls}
className={classNames(`${prefixCls}-auto-complete`, className)}
@ -122,14 +119,14 @@ const AutoComplete: React.ForwardRefRenderFunction<Select, AutoCompleteProps> =
getInputElement={getInputElement}
>
{optionChildren}
</InternalSelect>
</Select>
);
}}
</ConfigConsumer>
);
};
const RefAutoComplete = React.forwardRef<Select, AutoCompleteProps>(AutoComplete);
const RefAutoComplete = React.forwardRef<unknown, AutoCompleteProps>(AutoComplete);
type RefAutoCompleteWithOption = typeof RefAutoComplete & {
Option: OptionType;

View File

@ -1,5 +1,951 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Calendar Calendar MonthSelect should display correct label 1`] = `
<div
class="ant-picker-calendar ant-picker-calendar-full"
>
<div
class="ant-picker-calendar-header"
>
<div
class="ant-select ant-picker-calendar-year-select ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
>
<span
class="ant-select-selection-search"
>
<input
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
aria-autocomplete="list"
aria-controls="rc_select_TEST_OR_SSR_list"
aria-haspopup="listbox"
aria-owns="rc_select_TEST_OR_SSR_list"
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
<span
class="ant-select-selection-item"
title="2019"
>
2019
</span>
</div>
<span
aria-hidden="true"
class="ant-select-arrow"
style="user-select: none;"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-select-suffix"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-select ant-picker-calendar-month-select ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
>
<span
class="ant-select-selection-search"
>
<input
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
aria-autocomplete="list"
aria-controls="rc_select_TEST_OR_SSR_list"
aria-haspopup="listbox"
aria-owns="rc_select_TEST_OR_SSR_list"
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
<span
class="ant-select-selection-item"
title="Jan"
>
Jan
</span>
</div>
<span
aria-hidden="true"
class="ant-select-arrow"
style="user-select: none;"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-select-suffix"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-radio-group ant-radio-group-outline ant-picker-calendar-mode-switch"
>
<label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
>
<span
class="ant-radio-button ant-radio-button-checked"
>
<input
checked=""
class="ant-radio-button-input"
type="radio"
value="month"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Month
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="year"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Year
</span>
</label>
</div>
</div>
<div
class="ant-picker-panel"
tabindex="0"
>
<div
class="ant-picker-date-panel"
>
<div
class="ant-picker-body"
>
<table
class="ant-picker-content"
>
<thead>
<tr>
<th>
Su
</th>
<th>
Mo
</th>
<th>
Tu
</th>
<th>
We
</th>
<th>
Th
</th>
<th>
Fr
</th>
<th>
Sa
</th>
</tr>
</thead>
<tbody>
<tr>
<td
class="ant-picker-cell"
title="2018-12-30"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
30
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2018-12-31"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
31
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view ant-picker-cell-selected"
title="2019-01-01"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
01
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-02"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
02
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-03"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
03
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-04"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
04
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-05"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
05
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-06"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
06
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-07"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
07
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-08"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
08
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-09"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
09
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-10"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
10
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-11"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
11
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-12"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
12
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-13"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
13
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-14"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
14
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-15"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
15
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-16"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
16
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-17"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
17
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-18"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
18
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-19"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
19
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-20"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
20
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-21"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
21
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-22"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
22
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-23"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
23
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-24"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
24
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-25"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
25
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-26"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
26
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-27"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
27
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-28"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
28
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-29"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
29
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-30"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
30
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell ant-picker-cell-in-view"
title="2019-01-31"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
31
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-01"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
01
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-02"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
02
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
<tr>
<td
class="ant-picker-cell"
title="2019-02-03"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
03
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-04"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
04
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-05"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
05
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-06"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
06
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-07"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
07
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-08"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
08
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
<td
class="ant-picker-cell"
title="2019-02-09"
>
<div
class="ant-picker-cell-inner ant-picker-calendar-date"
>
<div
class="ant-picker-calendar-date-value"
>
09
</div>
<div
class="ant-picker-calendar-date-content"
/>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
`;
exports[`Calendar Calendar should support locale 1`] = `
<div
class="ant-picker-calendar ant-picker-calendar-full"

View File

@ -117,9 +117,7 @@ describe('Calendar', () => {
it('Calendar MonthSelect should display correct label', () => {
const validRange = [Moment('2018-02-02'), Moment('2019-06-1')];
const wrapper = mount(<Calendar validRange={validRange} defaultValue={Moment('2019-01-01')} />);
const { options } = wrapper.find('MonthSelect > Select').props();
expect(options.length).toBe(6);
expect(options[5]).toEqual({ label: 'Jun', value: 5 });
expect(wrapper.render()).toMatchSnapshot();
});
it('Calendar should change mode by prop', () => {

View File

@ -10,7 +10,7 @@ import rtlTest from '../../../tests/shared/rtlTest';
const { Option } = Select;
describe('Select', () => {
focusTest(Select);
focusTest(Select, { refFocus: true });
mountTest(Select);
rtlTest(Select);

View File

@ -5,7 +5,7 @@ import omit from 'omit.js';
import classNames from 'classnames';
import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps } from 'rc-select';
import { OptionProps } from 'rc-select/lib/Option';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import getIcons from './utils/iconUtil';
import SizeContext, { SizeType } from '../config-provider/SizeContext';
@ -35,148 +35,126 @@ export interface SelectProps<VT>
mode?: 'multiple' | 'tags';
}
// We still use class here since `forwardRef` not support generic in typescript
class Select<ValueType extends SelectValue = SelectValue> extends React.Component<
SelectProps<ValueType>
> {
static Option = Option;
const SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
static OptGroup = OptGroup;
static SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
static defaultProps = {
transitionName: 'slide-up',
choiceTransitionName: '',
bordered: true,
};
selectRef = React.createRef<RcSelect<ValueType>>();
public focus = () => {
if (this.selectRef.current) {
this.selectRef.current.focus();
}
};
public blur = () => {
if (this.selectRef.current) {
this.selectRef.current.blur();
}
};
getMode = () => {
const { mode } = this.props as InternalSelectProps<ValueType>;
if ((mode as any) === 'combobox') {
return undefined;
}
if (mode === Select.SECRET_COMBOBOX_MODE_DO_NOT_USE) {
return 'combobox';
}
return mode;
};
renderSelect = ({
const InternalSelect = <VT extends SelectValue = SelectValue>(
{
prefixCls: customizePrefixCls,
bordered = true,
className,
getPopupContainer,
dropdownClassName,
listHeight = 256,
listItemHeight = 24,
size: customizeSize,
notFoundContent,
transitionName = 'slide-up',
...props
}: SelectProps<VT>,
ref: React.Ref<RcSelect<VT>>,
) => {
const {
getPopupContainer: getContextPopupContainer,
getPrefixCls,
renderEmpty,
direction,
virtual,
dropdownMatchSelectWidth,
}: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
notFoundContent,
className,
size: customizeSize,
listHeight = 256,
listItemHeight = 24,
getPopupContainer,
dropdownClassName,
bordered,
} = this.props as InternalSelectProps<ValueType>;
} = React.useContext(ConfigContext);
const size = React.useContext(SizeContext);
const prefixCls = getPrefixCls('select', customizePrefixCls);
const mode = this.getMode();
const prefixCls = getPrefixCls('select', customizePrefixCls);
const isMultiple = mode === 'multiple' || mode === 'tags';
const mode = React.useMemo(() => {
const { mode: m } = props as InternalSelectProps<VT>;
// ===================== Empty =====================
let mergedNotFound: React.ReactNode;
if (notFoundContent !== undefined) {
mergedNotFound = notFoundContent;
} else if (mode === 'combobox') {
mergedNotFound = null;
} else {
mergedNotFound = renderEmpty('Select');
if ((m as any) === 'combobox') {
return undefined;
}
// ===================== Icons =====================
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons({
...this.props,
multiple: isMultiple,
prefixCls,
});
if (m === SECRET_COMBOBOX_MODE_DO_NOT_USE) {
return 'combobox';
}
const selectProps = omit(this.props, [
'prefixCls',
'suffixIcon',
'itemIcon',
'removeIcon',
'clearIcon',
'size',
'bordered',
]);
return m;
}, [props.mode]);
const rcSelectRtlDropDownClassName = classNames(dropdownClassName, {
[`${prefixCls}-dropdown-${direction}`]: direction === 'rtl',
});
return (
<SizeContext.Consumer>
{size => {
const mergedSize = customizeSize || size;
const mergedClassName = classNames(
{
[`${prefixCls}-lg`]: mergedSize === 'large',
[`${prefixCls}-sm`]: mergedSize === 'small',
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-borderless`]: !bordered,
},
className,
);
const isMultiple = mode === 'multiple' || mode === 'tags';
return (
<RcSelect<ValueType>
ref={this.selectRef}
virtual={virtual}
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
{...selectProps}
listHeight={listHeight}
listItemHeight={listItemHeight}
mode={mode}
prefixCls={prefixCls}
direction={direction}
inputIcon={suffixIcon}
menuItemSelectedIcon={itemIcon}
removeIcon={removeIcon}
clearIcon={clearIcon}
notFoundContent={mergedNotFound}
className={mergedClassName}
getPopupContainer={getPopupContainer || getContextPopupContainer}
dropdownClassName={rcSelectRtlDropDownClassName}
/>
);
}}
</SizeContext.Consumer>
);
};
render() {
return <ConfigConsumer>{this.renderSelect}</ConfigConsumer>;
// ===================== Empty =====================
let mergedNotFound: React.ReactNode;
if (notFoundContent !== undefined) {
mergedNotFound = notFoundContent;
} else if (mode === 'combobox') {
mergedNotFound = null;
} else {
mergedNotFound = renderEmpty('Select');
}
// ===================== Icons =====================
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons({
...props,
multiple: isMultiple,
prefixCls,
});
const selectProps = omit(props, ['suffixIcon', 'itemIcon']);
const rcSelectRtlDropDownClassName = classNames(dropdownClassName, {
[`${prefixCls}-dropdown-${direction}`]: direction === 'rtl',
});
const mergedSize = customizeSize || size;
const mergedClassName = classNames(
{
[`${prefixCls}-lg`]: mergedSize === 'large',
[`${prefixCls}-sm`]: mergedSize === 'small',
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-borderless`]: !bordered,
},
className,
);
return (
<RcSelect<VT>
ref={ref}
virtual={virtual}
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
{...selectProps}
transitionName={transitionName}
listHeight={listHeight}
listItemHeight={listItemHeight}
mode={mode}
prefixCls={prefixCls}
direction={direction}
inputIcon={suffixIcon}
menuItemSelectedIcon={itemIcon}
removeIcon={removeIcon}
clearIcon={clearIcon}
notFoundContent={mergedNotFound}
className={mergedClassName}
getPopupContainer={getPopupContainer || getContextPopupContainer}
dropdownClassName={rcSelectRtlDropDownClassName}
/>
);
};
const SelectRef = React.forwardRef(InternalSelect) as <VT extends SelectValue = SelectValue>(
props: SelectProps<VT> & { ref?: React.Ref<RcSelect<VT>> },
) => React.ReactElement;
type InternalSelectType = typeof SelectRef;
interface SelectInterface extends InternalSelectType {
SECRET_COMBOBOX_MODE_DO_NOT_USE: string;
Option: typeof Option;
OptGroup: typeof OptGroup;
}
const Select = SelectRef as SelectInterface;
Select.SECRET_COMBOBOX_MODE_DO_NOT_USE = SECRET_COMBOBOX_MODE_DO_NOT_USE;
Select.Option = Option;
Select.OptGroup = OptGroup;
export default Select;