Я пытаюсь установить максимальную высоту в текстовом поле MUI со свойством select. Я хочу установить максимальную высоту для меню:
<TextField
fullWidth
label = "Select State"
name = "state"
onChange = {handleChangeEvent}
required
select
SelectProps = {{ native: true }}
value = {values.state}
>
{states.map((option) => (
<option
key = {option.value}
value = {option.value}
>
{option.label}
</option>
))}
</TextField>
Я попытался использовать MenuProps
, который работает для компонента Select
, но не для TextField
:
<TextField
...
SelectProps = {{
MenuProps: {
sx: { maxHeight: 200 }
}
}}
...
</TextField>
Я также попытался установить свойства sx
и style
в TextField
.
Как я могу стилизовать это?
MUI создает компонент TextField
, используя интересное сочетание нативных HTML-элементов, псевдоэлементов, состояний и событий. Простой атрибут size
, который ведет себя как родное поле ввода HTML Select , не существует для TextField
. Из-за сочетания используемых элементов реквизит TextField
SelectProps = {{native:true}}
нельзя использовать, если вы хотите ограничить высоту пунктов меню. MUI MenuItem
необходимы для управления высотой меню. Возможно, лучшим решением будет использование Переопределения стилей темы, как показано ниже.
Переопределение стиля выглядит так:
const theme = createTheme( {
components: {
MuiPopover: {
styleOverrides: {
root: {
'&#menu-TEXTFIELD_IDENTIFIER .MuiPaper-root.MuiMenu-paper.MuiPaper-elevation.MuiPaper-rounded.MuiPopover-paper': {
maxHeight: '86px' // Example maximum of two options displayed. About 43px per select option.
}
}
}
}
}
} );
Компонент, используемый для отображения пунктов меню выбора, — это MuiPopover. Переопределение стиля используется, поскольку этот компонент нельзя легко выбрать с помощью правил выбора CSS со свойством sx. MuiPopover не является ни родственником, ни потомком корневого элемента, используемого для TextField
.
В приведенном выше переопределении стиля TEXTFIELD_IDENTIFIER — это идентификатор, который вы назначаете свойству id
компонента TextField
. TextField
присваивает префикс меню- id
при создании MuiPopover. Использование этого id
как части селектора переопределения стиля предотвращает влияние переопределения на каждый MuiPopover в вашем приложении.
Пример кода ниже. Доступна живая демонстрация кода.
В демо отображаются два поля выбора, но переопределение стиля влияет только на первое. Хотя здесь используется ThemeProvider
, обычно он применяется в точке входа приложения.
import * as React from 'react';
import {
Box,
TextField,
MenuItem
} from '@mui/material';
import { createTheme, ThemeProvider } from '@mui/material/styles';
interface selectOption {
value: string
}
const theme = createTheme( {
components: {
MuiPopover: {
styleOverrides: {
root: {
'&#menu-first-select-box .MuiPaper-root.MuiMenu-paper.MuiPaper-elevation.MuiPaper-rounded.MuiPopover-paper': {
maxHeight: '86px' // About 43px per select option.
}
}
}
}
}
} );
export default function ColorTextFields() {
const [ firstValue, setFirstValue ] = React.useState( 'One' );
const [ secondValue, setSecondValue ] = React.useState( 'Six' );
const firstOptions: selectOption[] = [
{ value: 'One' },
{ value: 'Two' },
{ value: 'Three' },
{ value: 'Four' },
{ value: 'Five' }
];
const secondOptions: selectOption[] = [
{ value: 'Six' },
{ value: 'Seven' },
{ value: 'Eight' },
{ value: 'Nine' },
{ value: 'Ten' }
];
function handleFirstChange( e: React.ChangeEvent<HTMLInputElement> ) {
setFirstValue( e.target.value );
}
function handleSecondChange( e: React.ChangeEvent<HTMLInputElement> ) {
setSecondValue( e.target.value );
}
function buildOptions( option: selectOption ): React.ReactElement<typeof MenuItem> {
return (
<MenuItem
key = { option.value }
id = { option.value }
value = { option.value }
>
{ option.value }
</MenuItem>
)
}
return (
<ThemeProvider theme = { theme }>
<Box
component = "form"
sx = {{
'& > :not(style)': { m: 1, width: '25ch' }
}}
noValidate
autoComplete = "off"
>
<TextField
id = { 'first-select-box' }
name = { 'first-select-box' }
label = "First Select"
select
SelectProps = { { native: false } }
variant = "standard"
value = { firstValue }
onChange = { handleFirstChange }
>
{ firstOptions.map( buildOptions ) }
</TextField>
<TextField
id = { 'second-select-box' }
name = { 'second-select-box' }
label = "Second select"
select
SelectProps = { { native: false } }
variant = "outlined"
value = { secondValue }
onChange = { handleSecondChange }
>
{ secondOptions.map( buildOptions ) }
</TextField>
</Box>
</ThemeProvider>
);
}