Merge pull request #5923 from tchak/improuve-multi-select
Improuve multi select
This commit is contained in:
commit
1745f58496
1 changed files with 55 additions and 47 deletions
|
@ -31,23 +31,46 @@ function ComboMultipleDropdownList({
|
||||||
if (label == undefined) {
|
if (label == undefined) {
|
||||||
label = 'Choisir une option';
|
label = 'Choisir une option';
|
||||||
}
|
}
|
||||||
if (Array.isArray(options[0]) == false) {
|
if (!Array.isArray(options[0])) {
|
||||||
options = options.map((o) => [o, o]);
|
options = options.filter((o) => o).map((o) => [o, o]);
|
||||||
}
|
}
|
||||||
const inputRef = useRef();
|
const inputRef = useRef();
|
||||||
const [term, setTerm] = useState('');
|
const [term, setTerm] = useState('');
|
||||||
const [selections, setSelections] = useState(selected);
|
const [selections, setSelections] = useState(selected);
|
||||||
const [newValues, setNewValues] = useState([]);
|
const [newValues, setNewValues] = useState([]);
|
||||||
|
|
||||||
|
const optionValueByLabel = (label) => {
|
||||||
|
const maybeOption = newValues.includes(label)
|
||||||
|
? [label, label]
|
||||||
|
: options.find(([optionLabel]) => optionLabel == label);
|
||||||
|
return maybeOption ? maybeOption[1] : undefined;
|
||||||
|
};
|
||||||
|
const optionLabelByValue = (value) => {
|
||||||
|
const maybeOption = newValues.includes(value)
|
||||||
|
? [value, value]
|
||||||
|
: options.find(([, optionValue]) => optionValue == value);
|
||||||
|
return maybeOption ? maybeOption[0] : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const extraOptions = useMemo(
|
||||||
|
() =>
|
||||||
|
acceptNewValues && term && term.length > 2 && !optionLabelByValue(term)
|
||||||
|
? [[term, term]]
|
||||||
|
: [],
|
||||||
|
[acceptNewValues, term, newValues.join(',')]
|
||||||
|
);
|
||||||
const results = useMemo(
|
const results = useMemo(
|
||||||
() =>
|
() =>
|
||||||
(term
|
[
|
||||||
? matchSorter(
|
...extraOptions,
|
||||||
options.filter((o) => !o[0].startsWith('--')),
|
...(term
|
||||||
term
|
? matchSorter(
|
||||||
)
|
options.filter(([label]) => !label.startsWith('--')),
|
||||||
: options
|
term
|
||||||
).filter((o) => o[0] && !selections.includes(o[1])),
|
)
|
||||||
[term, selections.join(',')]
|
: options)
|
||||||
|
].filter(([, value]) => !selections.includes(value)),
|
||||||
|
[term, selections.join(','), newValues.join(',')]
|
||||||
);
|
);
|
||||||
const hiddenField = useMemo(
|
const hiddenField = useMemo(
|
||||||
() => document.querySelector(`input[data-uuid="${hiddenFieldId}"]`),
|
() => document.querySelector(`input[data-uuid="${hiddenFieldId}"]`),
|
||||||
|
@ -60,22 +83,12 @@ function ComboMultipleDropdownList({
|
||||||
|
|
||||||
const onKeyDown = (event) => {
|
const onKeyDown = (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
if (term && options.map((o) => o[0]).includes(term)) {
|
|
||||||
event.preventDefault();
|
|
||||||
return onSelect(term);
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
acceptNewValues &&
|
|
||||||
term &&
|
term &&
|
||||||
matchSorter(
|
[...extraOptions, ...options].map(([label]) => label).includes(term)
|
||||||
options.map((o) => o[0]),
|
|
||||||
term
|
|
||||||
).length == 0 // ignore when was pressed for selecting popover option
|
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setNewValues([...newValues, term]);
|
return onSelect(term);
|
||||||
saveSelection([...selections, term]);
|
|
||||||
setTerm('');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -89,19 +102,23 @@ function ComboMultipleDropdownList({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelect = (value) => {
|
const onSelect = (value) => {
|
||||||
let sel = options.find((o) => o[0] == value)[1];
|
const maybeValue = [...extraOptions, ...options].find(
|
||||||
saveSelection([...selections, sel]);
|
([val]) => val == value
|
||||||
|
);
|
||||||
|
const selectedValue = maybeValue && maybeValue[1];
|
||||||
|
if (value) {
|
||||||
|
setNewValues([...newValues, selectedValue]);
|
||||||
|
saveSelection([...selections, selectedValue]);
|
||||||
|
}
|
||||||
setTerm('');
|
setTerm('');
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRemove = (value) => {
|
const onRemove = (label) => {
|
||||||
saveSelection(
|
const optionValue = optionValueByLabel(label);
|
||||||
selections.filter((s) =>
|
if (optionValue) {
|
||||||
newValues.includes(value)
|
saveSelection(selections.filter((value) => value != optionValue));
|
||||||
? s != value
|
setNewValues(newValues.filter((value) => value != optionValue));
|
||||||
: s !== options.find((o) => o[0] == value)[1]
|
}
|
||||||
)
|
|
||||||
);
|
|
||||||
inputRef.current.focus();
|
inputRef.current.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,10 +133,7 @@ function ComboMultipleDropdownList({
|
||||||
{selections.map((selection) => (
|
{selections.map((selection) => (
|
||||||
<ComboboxToken
|
<ComboboxToken
|
||||||
key={selection}
|
key={selection}
|
||||||
value={
|
value={optionLabelByValue(selection)}
|
||||||
newValues.find((newValue) => newValue == selection) ||
|
|
||||||
options.find((o) => o[1] == selection)[0]
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -136,21 +150,15 @@ function ComboMultipleDropdownList({
|
||||||
{results.length === 0 && (
|
{results.length === 0 && (
|
||||||
<p>
|
<p>
|
||||||
Aucun résultat{' '}
|
Aucun résultat{' '}
|
||||||
<button
|
<button onClick={() => setTerm('')}>Effacer</button>
|
||||||
onClick={() => {
|
|
||||||
setTerm('');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Effacer
|
|
||||||
</button>
|
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<ComboboxList>
|
<ComboboxList>
|
||||||
{results.map((value, index) => {
|
{results.map(([label], index) => {
|
||||||
if (value[0].startsWith('--')) {
|
if (label.startsWith('--')) {
|
||||||
return <ComboboxSeparator key={index} value={value[0]} />;
|
return <ComboboxSeparator key={index} value={label} />;
|
||||||
}
|
}
|
||||||
return <ComboboxOption key={index} value={value[0]} />;
|
return <ComboboxOption key={index} value={label} />;
|
||||||
})}
|
})}
|
||||||
</ComboboxList>
|
</ComboboxList>
|
||||||
</ComboboxPopover>
|
</ComboboxPopover>
|
||||||
|
|
Loading…
Reference in a new issue