(react) add multi select

Adding this new variant makes necessary to reorganize the files to keep
a clear separations of concerns. As of now Select/index.tsx is just an
entrypoint to render either the mono or multi variant of the select.
This commit is contained in:
Nathan Vasse
2023-06-12 14:27:40 +02:00
committed by NathanVss
parent 5a9d77042f
commit c8afa105dd
22 changed files with 2734 additions and 405 deletions

View File

@@ -0,0 +1,79 @@
import React, { useEffect, useRef, useState } from "react";
import { useCombobox } from "downshift";
import { useCunningham } from ":/components/Provider";
import {
getOptionsFilter,
optionToString,
SelectMonoAux,
SubProps,
} from ":/components/Forms/Select/mono-common";
export const SelectMonoSearchable = (props: SubProps) => {
const { t } = useCunningham();
const [optionsToDisplay, setOptionsToDisplay] = useState(props.options);
const [hasInputFocused, setHasInputFocused] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const downshiftReturn = useCombobox({
...props.downshiftProps,
items: optionsToDisplay,
itemToString: optionToString,
onInputValueChange: (e) => {
setOptionsToDisplay(props.options.filter(getOptionsFilter(e.inputValue)));
if (!e.inputValue) {
downshiftReturn.selectItem(null);
}
},
});
const [labelAsPlaceholder, setLabelAsPlaceholder] = useState(
!downshiftReturn.selectedItem
);
useEffect(() => {
if (hasInputFocused || downshiftReturn.inputValue) {
setLabelAsPlaceholder(false);
return;
}
setLabelAsPlaceholder(!downshiftReturn.selectedItem);
}, [
downshiftReturn.selectedItem,
hasInputFocused,
downshiftReturn.inputValue,
]);
const inputProps = downshiftReturn.getInputProps({
ref: inputRef,
disabled: props.disabled,
});
return (
<SelectMonoAux
{...props}
downshiftReturn={{
...downshiftReturn,
wrapperProps: {
onClick: () => {
inputRef.current?.focus();
},
},
toggleButtonProps: downshiftReturn.getToggleButtonProps({
disabled: props.disabled,
"aria-label": t("components.forms.select.toggle_button_aria_label"),
}),
}}
labelAsPlaceholder={labelAsPlaceholder}
options={optionsToDisplay}
>
<input
{...inputProps}
onFocus={(e) => {
inputProps.onFocus(e);
setHasInputFocused(true);
}}
onBlur={(e) => {
inputProps.onBlur(e);
setHasInputFocused(false);
}}
/>
</SelectMonoAux>
);
};