sorted options only when selecting again
This commit is contained in:
@@ -11,6 +11,63 @@ import DoneIcon from "@mui/icons-material/Done";
|
|||||||
import FilterListIcon from "@mui/icons-material/FilterList";
|
import FilterListIcon from "@mui/icons-material/FilterList";
|
||||||
import { ResourceField, ResourceMode } from "../types/config";
|
import { ResourceField, ResourceMode } from "../types/config";
|
||||||
|
|
||||||
|
function FilterAutocomplete({
|
||||||
|
options,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
options: string[];
|
||||||
|
value: string[];
|
||||||
|
label: string;
|
||||||
|
onChange: (val: string[]) => void;
|
||||||
|
}) {
|
||||||
|
const listboxRef = React.useRef<HTMLUListElement>(null);
|
||||||
|
const scrollPosRef = React.useRef(0);
|
||||||
|
const [frozenValue, setFrozenValue] = React.useState<string[]>(value);
|
||||||
|
|
||||||
|
const sortedOptions = React.useMemo(() => {
|
||||||
|
const sel = new Set(frozenValue);
|
||||||
|
const picked: string[] = [];
|
||||||
|
const rest: string[] = [];
|
||||||
|
for (const o of options) {
|
||||||
|
if (sel.has(o)) picked.push(o);
|
||||||
|
else rest.push(o);
|
||||||
|
}
|
||||||
|
return [...picked, ...rest];
|
||||||
|
}, [options, frozenValue]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Autocomplete
|
||||||
|
multiple
|
||||||
|
freeSolo
|
||||||
|
disableCloseOnSelect
|
||||||
|
limitTags={1}
|
||||||
|
options={sortedOptions}
|
||||||
|
value={value}
|
||||||
|
getOptionKey={(option) => option}
|
||||||
|
onChange={(_, val) => onChange(val.length > 0 ? val : [])}
|
||||||
|
onOpen={() => setFrozenValue(value)}
|
||||||
|
onClose={() => setFrozenValue(value)}
|
||||||
|
ListboxProps={{
|
||||||
|
ref: listboxRef,
|
||||||
|
onScroll: (e) => { scrollPosRef.current = (e.target as HTMLUListElement).scrollTop; },
|
||||||
|
}}
|
||||||
|
renderOption={(props, option, { selected }) => {
|
||||||
|
const { key, ...rest } = props;
|
||||||
|
return (
|
||||||
|
<li key={key} {...rest}>
|
||||||
|
{selected ? <DoneIcon sx={{ fontSize: 14, mr: 1, color: 'primary.main' }} /> : <Box sx={{ width: 22, mr: 1 }} />}
|
||||||
|
{option}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
renderInput={(params) => <TextField {...params} placeholder={`Add ${label}...`} />}
|
||||||
|
sx={{ '& .MuiOutlinedInput-root': { minHeight: '3rem', py: 0.5 } }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function extractOptions(
|
function extractOptions(
|
||||||
fieldName: string,
|
fieldName: string,
|
||||||
field: ResourceField,
|
field: ResourceField,
|
||||||
@@ -94,35 +151,13 @@ function renderFilterInput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selected = Array.isArray(value) ? value : [];
|
const selected = Array.isArray(value) ? value : [];
|
||||||
// const sortedOptions = React.useMemo(() => {
|
|
||||||
// const sel = new Set(selected);
|
|
||||||
// const picked: string[] = [];
|
|
||||||
// const rest: string[] = [];
|
|
||||||
// for (const o of options) {
|
|
||||||
// if (sel.has(o)) picked.push(o);
|
|
||||||
// else rest.push(o);
|
|
||||||
// }
|
|
||||||
// return [...picked, ...rest];
|
|
||||||
// }, [options, selected]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Autocomplete
|
<FilterAutocomplete
|
||||||
multiple
|
|
||||||
freeSolo
|
|
||||||
disableCloseOnSelect
|
|
||||||
limitTags={1}
|
|
||||||
value={selected}
|
|
||||||
// options={sortedOptions}
|
|
||||||
options={options}
|
options={options}
|
||||||
onChange={(_, val) => onChange("value", val.length > 0 ? val : undefined)}
|
value={selected}
|
||||||
renderOption={(props, option, { selected }) => (
|
label={field.label}
|
||||||
<li {...props}>
|
onChange={(val) => onChange("value", val.length > 0 ? val : undefined)}
|
||||||
{selected ? <DoneIcon sx={{ fontSize: 14, mr: 1, color: 'primary.main' }} /> : <Box sx={{ width: 22, mr: 1 }} />}
|
|
||||||
{option}
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
renderInput={(params) => <TextField {...params} placeholder={`Add ${field.label}...`} />}
|
|
||||||
sx={{ '& .MuiOutlinedInput-root': { minHeight: '3rem', py: 0.5 } }}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user