91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import React, { useCallback, useEffect } from "react";
|
|
|
|
import { getLabel } from "../../Dropdown";
|
|
import { IOption } from "../../Dropdown/DropdownMenu/DropdownOption";
|
|
import Chip from "../Chip";
|
|
import classes from "./classes.module.scss";
|
|
|
|
type IProps = {
|
|
selectedOptions: IOption[];
|
|
onSelectedOptionsChange: (options: IOption[]) => void;
|
|
onChange?: (input: string) => void;
|
|
value?: string;
|
|
placeholder?: string;
|
|
disabled?: boolean;
|
|
onClear?: () => void;
|
|
onFocus?: () => void;
|
|
onBlur?: () => void;
|
|
};
|
|
|
|
export default function ChipContainer(props: IProps) {
|
|
const {
|
|
selectedOptions,
|
|
onChange,
|
|
value: propValue,
|
|
placeholder = "Rechercher",
|
|
disabled = false,
|
|
onFocus,
|
|
onBlur,
|
|
onSelectedOptionsChange,
|
|
} = props;
|
|
|
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
const [value, setValue] = React.useState(propValue || "");
|
|
|
|
const changeValue = useCallback(
|
|
(value: string) => {
|
|
setValue(value);
|
|
onChange && onChange(value);
|
|
},
|
|
[onChange],
|
|
);
|
|
|
|
const handleOnChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => changeValue(event.target.value), [changeValue]);
|
|
|
|
const handleFocus = useCallback(() => {
|
|
setIsFocused(true);
|
|
onFocus?.();
|
|
}, [onFocus]);
|
|
|
|
const handleBlur = useCallback(
|
|
(e: React.FocusEvent<HTMLInputElement, Element>) => {
|
|
setIsFocused(false);
|
|
onBlur?.();
|
|
},
|
|
[onBlur],
|
|
);
|
|
|
|
const onChipDelete = useCallback(
|
|
(option: IOption) => {
|
|
const newSelectedOptions = selectedOptions.filter((selectedOption) => selectedOption.id !== option.id);
|
|
onSelectedOptionsChange && onSelectedOptionsChange(newSelectedOptions);
|
|
},
|
|
[selectedOptions, onSelectedOptionsChange],
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (propValue !== undefined) {
|
|
setValue(propValue);
|
|
}
|
|
}, [propValue]);
|
|
|
|
return (
|
|
<div className={classes["root"]} data-is-focused={isFocused} data-has-value={value !== ""} data-is-disabled={disabled}>
|
|
<div className={classes["content"]}>
|
|
{selectedOptions.map((option) => (
|
|
<Chip key={option.id} text={getLabel(option) ?? ""} onDelete={() => onChipDelete(option)} />
|
|
))}
|
|
<input
|
|
type="text"
|
|
value={value}
|
|
placeholder={placeholder}
|
|
className={classes["input"]}
|
|
onChange={handleOnChange}
|
|
onFocus={handleFocus}
|
|
onBlur={handleBlur}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|