100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
Box,
|
|
Typography,
|
|
FormControl,
|
|
Select,
|
|
MenuItem,
|
|
FormHelperText,
|
|
InputLabel,
|
|
} from '@mui/material';
|
|
import { Controller, useFormContext } from 'react-hook-form';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
export interface SelectOption {
|
|
value: string | number;
|
|
label: string;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export interface SelectFormFieldProps {
|
|
name: string;
|
|
label: string;
|
|
options: SelectOption[];
|
|
helperText?: string;
|
|
defaultValue?: string | number;
|
|
disabled?: boolean;
|
|
required?: boolean;
|
|
fullWidth?: boolean;
|
|
size?: 'small' | 'medium';
|
|
displayEmpty?: boolean;
|
|
emptyLabel?: string;
|
|
multiple?: boolean;
|
|
}
|
|
|
|
export const SelectFormField: React.FC<SelectFormFieldProps> = ({
|
|
name,
|
|
label,
|
|
options,
|
|
helperText,
|
|
defaultValue = '',
|
|
disabled = false,
|
|
required = false,
|
|
fullWidth = true,
|
|
size = 'medium',
|
|
displayEmpty = true,
|
|
emptyLabel,
|
|
multiple = false,
|
|
}) => {
|
|
const { control } = useFormContext();
|
|
const { t } = useTranslation();
|
|
|
|
const defaultEmptyLabel = emptyLabel || t('common.pleaseSelect');
|
|
|
|
return (
|
|
<Box>
|
|
<Typography variant="subtitle1" gutterBottom>
|
|
{required && <span style={{ color: 'red' }}>*</span>}
|
|
{label}
|
|
</Typography>
|
|
<Controller
|
|
name={name}
|
|
control={control}
|
|
defaultValue={multiple ? [] : defaultValue}
|
|
rules={{
|
|
required: required ? t('form.fieldRequired', { field: label }) : false,
|
|
}}
|
|
render={({ field, fieldState: { error } }) => (
|
|
<FormControl fullWidth={fullWidth} error={!!error} size={size}>
|
|
<Select
|
|
{...field}
|
|
disabled={disabled}
|
|
displayEmpty={displayEmpty}
|
|
multiple={multiple}
|
|
>
|
|
{displayEmpty && !multiple && (
|
|
<MenuItem value="">
|
|
{defaultEmptyLabel}
|
|
</MenuItem>
|
|
)}
|
|
{options.map((option) => (
|
|
<MenuItem
|
|
key={option.value}
|
|
value={option.value}
|
|
disabled={option.disabled}
|
|
>
|
|
{option.label}
|
|
</MenuItem>
|
|
))}
|
|
</Select>
|
|
{(error || helperText) && (
|
|
<FormHelperText>
|
|
{error?.message || helperText}
|
|
</FormHelperText>
|
|
)}
|
|
</FormControl>
|
|
)}
|
|
/>
|
|
</Box>
|
|
);
|
|
}; |