chore: Merges latest Select changes (#16587)

This commit is contained in:
Michael S. Molina 2021-09-07 10:41:55 -03:00 committed by GitHub
parent 9de2196b7f
commit 37c2020035
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -49,8 +49,12 @@ type PickedSelectProps = Pick<
| 'autoFocus' | 'autoFocus'
| 'disabled' | 'disabled'
| 'filterOption' | 'filterOption'
| 'labelInValue'
| 'loading'
| 'notFoundContent' | 'notFoundContent'
| 'onChange' | 'onChange'
| 'onClear'
| 'onFocus'
| 'placeholder' | 'placeholder'
| 'showSearch' | 'showSearch'
| 'value' | 'value'
@ -73,6 +77,7 @@ export interface SelectProps extends PickedSelectProps {
allowNewOptions?: boolean; allowNewOptions?: boolean;
ariaLabel: string; ariaLabel: string;
header?: ReactNode; header?: ReactNode;
lazyLoading?: boolean;
mode?: 'single' | 'multiple'; mode?: 'single' | 'multiple';
name?: string; // discourage usage name?: string; // discourage usage
options: OptionsType | OptionsPagePromise; options: OptionsType | OptionsPagePromise;
@ -84,15 +89,11 @@ export interface SelectProps extends PickedSelectProps {
const StyledContainer = styled.div` const StyledContainer = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%;
`; `;
const StyledSelect = styled(AntdSelect, { const StyledSelect = styled(AntdSelect)`
shouldForwardProp: prop => prop !== 'hasHeader', ${({ theme }) => `
})<{ hasHeader: boolean }>`
${({ theme, hasHeader }) => `
width: 100%;
margin-top: ${hasHeader ? theme.gridUnit : 0}px;
&& .ant-select-selector { && .ant-select-selector {
border-radius: ${theme.gridUnit}px; border-radius: ${theme.gridUnit}px;
} }
@ -163,8 +164,12 @@ const Select = ({
filterOption = true, filterOption = true,
header = null, header = null,
invertSelection = false, invertSelection = false,
labelInValue = false,
lazyLoading = true,
loading = false,
mode = 'single', mode = 'single',
name, name,
onChange,
options, options,
pageSize = DEFAULT_PAGE_SIZE, pageSize = DEFAULT_PAGE_SIZE,
placeholder = t('Select ...'), placeholder = t('Select ...'),
@ -182,13 +187,13 @@ const Select = ({
); );
const [selectValue, setSelectValue] = useState(value); const [selectValue, setSelectValue] = useState(value);
const [searchedValue, setSearchedValue] = useState(''); const [searchedValue, setSearchedValue] = useState('');
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(loading);
const [isTyping, setIsTyping] = useState(false); const [isTyping, setIsTyping] = useState(false);
const [error, setError] = useState(''); const [error, setError] = useState('');
const [isDropdownVisible, setIsDropdownVisible] = useState(false); const [isDropdownVisible, setIsDropdownVisible] = useState(false);
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
const [totalCount, setTotalCount] = useState(0); const [totalCount, setTotalCount] = useState(0);
const [loadingEnabled, setLoadingEnabled] = useState(false); const [loadingEnabled, setLoadingEnabled] = useState(!lazyLoading);
const fetchedQueries = useRef(new Map<string, number>()); const fetchedQueries = useRef(new Map<string, number>());
const mappedMode = isSingleMode const mappedMode = isSingleMode
? undefined ? undefined
@ -197,16 +202,21 @@ const Select = ({
: 'multiple'; : 'multiple';
useEffect(() => { useEffect(() => {
fetchedQueries.current.clear();
setSelectOptions( setSelectOptions(
options && Array.isArray(options) ? options : EMPTY_OPTIONS, options && Array.isArray(options) ? options : EMPTY_OPTIONS,
); );
}, [options]); }, [options]);
useEffect(() => { useEffect(() => {
if (isAsync && value) { setSelectValue(value);
const array: AntdLabeledValue[] = Array.isArray(value) }, [value]);
? (value as AntdLabeledValue[])
: [value as AntdLabeledValue]; useEffect(() => {
if (isAsync && selectValue) {
const array: AntdLabeledValue[] = Array.isArray(selectValue)
? (selectValue as AntdLabeledValue[])
: [selectValue as AntdLabeledValue];
const options: AntdLabeledValue[] = []; const options: AntdLabeledValue[] = [];
array.forEach(element => { array.forEach(element => {
const found = selectOptions.find( const found = selectOptions.find(
@ -220,23 +230,20 @@ const Select = ({
setSelectOptions([...selectOptions, ...options]); setSelectOptions([...selectOptions, ...options]);
} }
} }
}, [isAsync, selectOptions, value]); }, [isAsync, selectOptions, selectValue]);
useEffect(() => {
setSelectValue(value);
}, [value]);
const handleTopOptions = useCallback( const handleTopOptions = useCallback(
(selectedValue: AntdSelectValue | undefined) => { (selectedValue: AntdSelectValue | undefined) => {
// bringing selected options to the top of the list // bringing selected options to the top of the list
if (selectedValue !== undefined && selectedValue !== null) { if (selectedValue !== undefined && selectedValue !== null) {
const isLabeledValue = isAsync || labelInValue;
const topOptions: OptionsType = []; const topOptions: OptionsType = [];
const otherOptions: OptionsType = []; const otherOptions: OptionsType = [];
selectOptions.forEach(opt => { selectOptions.forEach(opt => {
let found = false; let found = false;
if (Array.isArray(selectedValue)) { if (Array.isArray(selectedValue)) {
if (isAsync) { if (isLabeledValue) {
found = found =
(selectedValue as AntdLabeledValue[]).find( (selectedValue as AntdLabeledValue[]).find(
element => element.value === opt.value, element => element.value === opt.value,
@ -245,7 +252,7 @@ const Select = ({
found = selectedValue.includes(opt.value); found = selectedValue.includes(opt.value);
} }
} else { } else {
found = isAsync found = isLabeledValue
? (selectedValue as AntdLabeledValue).value === opt.value ? (selectedValue as AntdLabeledValue).value === opt.value
: selectedValue === opt.value; : selectedValue === opt.value;
} }
@ -265,10 +272,10 @@ const Select = ({
!topOptions.find( !topOptions.find(
tOpt => tOpt =>
tOpt.value === tOpt.value ===
(isAsync ? (val as AntdLabeledValue)?.value : val), (isLabeledValue ? (val as AntdLabeledValue)?.value : val),
) )
) { ) {
if (isAsync) { if (isLabeledValue) {
const labelValue = val as AntdLabeledValue; const labelValue = val as AntdLabeledValue;
topOptions.push({ topOptions.push({
label: labelValue.label, label: labelValue.label,
@ -288,7 +295,7 @@ const Select = ({
} }
} }
}, },
[isAsync, isSingleMode, selectOptions], [isAsync, isSingleMode, labelInValue, selectOptions],
); );
const handleOnSelect = ( const handleOnSelect = (
@ -405,6 +412,10 @@ const Select = ({
const newOptions = [...selectOptions, newOption]; const newOptions = [...selectOptions, newOption];
setSelectOptions(newOptions); setSelectOptions(newOptions);
setSelectValue(searchValue); setSelectValue(searchValue);
if (onChange) {
onChange(searchValue, newOptions);
}
} }
} }
setSearchedValue(searchValue); setSearchedValue(searchValue);
@ -416,6 +427,7 @@ const Select = ({
allowNewOptions, allowNewOptions,
initialOptions, initialOptions,
isSingleMode, isSingleMode,
onChange,
searchedValue, searchedValue,
selectOptions, selectOptions,
], ],
@ -489,6 +501,12 @@ const Select = ({
} }
}, [handleTopOptions, isSingleMode, selectValue]); }, [handleTopOptions, isSingleMode, selectValue]);
useEffect(() => {
if (loading !== undefined && loading !== isLoading) {
setIsLoading(loading);
}
}, [isLoading, loading]);
const dropdownRender = ( const dropdownRender = (
originNode: ReactElement & { ref?: RefObject<HTMLElement> }, originNode: ReactElement & { ref?: RefObject<HTMLElement> },
) => { ) => {
@ -521,12 +539,11 @@ const Select = ({
<StyledContainer> <StyledContainer>
{header} {header}
<StyledSelect <StyledSelect
hasHeader={!!header}
aria-label={ariaLabel || name} aria-label={ariaLabel || name}
dropdownRender={dropdownRender} dropdownRender={dropdownRender}
filterOption={handleFilterOption} filterOption={handleFilterOption}
getPopupContainer={triggerNode => triggerNode.parentNode} getPopupContainer={triggerNode => triggerNode.parentNode}
labelInValue={isAsync} labelInValue={isAsync || labelInValue}
maxTagCount={MAX_TAG_COUNT} maxTagCount={MAX_TAG_COUNT}
mode={mappedMode} mode={mappedMode}
onDeselect={handleOnDeselect} onDeselect={handleOnDeselect}
@ -536,6 +553,7 @@ const Select = ({
onSearch={shouldShowSearch ? handleOnSearch : undefined} onSearch={shouldShowSearch ? handleOnSearch : undefined}
onSelect={handleOnSelect} onSelect={handleOnSelect}
onClear={() => setSelectValue(undefined)} onClear={() => setSelectValue(undefined)}
onChange={onChange}
options={selectOptions} options={selectOptions}
placeholder={placeholder} placeholder={placeholder}
showSearch={shouldShowSearch} showSearch={shouldShowSearch}