feat: role system
This commit is contained in:
95
src/shared/ui/MultiSelect/index.tsx
Normal file
95
src/shared/ui/MultiSelect/index.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import {
|
||||
Autocomplete,
|
||||
Checkbox,
|
||||
CircularProgress,
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank";
|
||||
import CheckBoxIcon from "@mui/icons-material/CheckBox";
|
||||
|
||||
export interface MultiSelectOption<TValue = number | string> {
|
||||
readonly value: TValue;
|
||||
readonly label: string;
|
||||
}
|
||||
|
||||
interface MultiSelectProps<TValue = number | string> {
|
||||
readonly options: MultiSelectOption<TValue>[];
|
||||
readonly value: TValue[];
|
||||
readonly onChange: (values: TValue[]) => void;
|
||||
readonly label?: string;
|
||||
readonly placeholder?: string;
|
||||
readonly loading?: boolean;
|
||||
readonly disabled?: boolean;
|
||||
readonly error?: boolean;
|
||||
readonly helperText?: string;
|
||||
readonly size?: "small" | "medium";
|
||||
readonly fullWidth?: boolean;
|
||||
}
|
||||
|
||||
export function MultiSelect<TValue = number | string>({
|
||||
options,
|
||||
value,
|
||||
onChange,
|
||||
label,
|
||||
placeholder,
|
||||
loading = false,
|
||||
disabled = false,
|
||||
error = false,
|
||||
helperText,
|
||||
size = "small",
|
||||
fullWidth = true,
|
||||
}: MultiSelectProps<TValue>) {
|
||||
const selectedOptions = options.filter((opt) => value.includes(opt.value));
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
multiple
|
||||
disableCloseOnSelect
|
||||
fullWidth={fullWidth}
|
||||
size={size}
|
||||
disabled={disabled}
|
||||
loading={loading}
|
||||
options={options}
|
||||
value={selectedOptions}
|
||||
getOptionLabel={(option) => option.label}
|
||||
isOptionEqualToValue={(option, selected) => option.value === selected.value}
|
||||
onChange={(_, newSelected) => {
|
||||
onChange(newSelected.map((opt) => opt.value));
|
||||
}}
|
||||
renderOption={(props, option, { selected }) => {
|
||||
const { key, ...rest } = props as React.HTMLAttributes<HTMLLIElement> & { key: React.Key };
|
||||
return (
|
||||
<li key={key} {...rest}>
|
||||
<Checkbox
|
||||
icon={<CheckBoxOutlineBlankIcon fontSize="small" />}
|
||||
checkedIcon={<CheckBoxIcon fontSize="small" />}
|
||||
style={{ marginRight: 8 }}
|
||||
checked={selected}
|
||||
/>
|
||||
{option.label}
|
||||
</li>
|
||||
);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label={label}
|
||||
placeholder={selectedOptions.length === 0 ? placeholder : undefined}
|
||||
error={error}
|
||||
helperText={helperText}
|
||||
slotProps={{
|
||||
input: {
|
||||
...params.InputProps,
|
||||
endAdornment: (
|
||||
<>
|
||||
{loading && <CircularProgress color="inherit" size={16} />}
|
||||
{params.InputProps.endAdornment}
|
||||
</>
|
||||
),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user