mirror of
https://github.com/apache/superset.git
synced 2024-09-06 22:07:34 -04:00
chore: Merges latest Select changes (#16587)
This commit is contained in:
parent
9de2196b7f
commit
37c2020035
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user