96 lines
2.3 KiB
TypeScript
96 lines
2.3 KiB
TypeScript
|
|
import React from 'react';
|
||
|
|
import {
|
||
|
|
Box,
|
||
|
|
Typography,
|
||
|
|
FormControl,
|
||
|
|
Select,
|
||
|
|
MenuItem,
|
||
|
|
FormHelperText,
|
||
|
|
InputLabel,
|
||
|
|
} from '@mui/material';
|
||
|
|
import { Controller, useFormContext } from 'react-hook-form';
|
||
|
|
|
||
|
|
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();
|
||
|
|
|
||
|
|
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 ? `${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="">
|
||
|
|
{emptyLabel}
|
||
|
|
</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>
|
||
|
|
);
|
||
|
|
};
|