Skip to main content

Text Field

Please refer to MUI's official docs for more details on component's usage guide and API documentation.

Variants

Use variant={'filled' | 'standard'} prop for different text fields.


// MUI Imports
import TextField from '@mui/material/TextField'
import Grid from '@mui/material/Grid'

const TextFieldVariant = () => {
return (
<Grid container spacing={6}>
<Grid item xs={12} md={4}>
<TextField fullWidth id='outlined-basic' label='Outlined' />
</Grid>
<Grid item xs={12} md={4}>
<TextField fullWidth id='filled-basic' label='Filled' variant='filled' />
</Grid>
<Grid item xs={12} md={4}>
<TextField fullWidth id='standard-basic' label='Standard' variant='standard' />
</Grid>
</Grid>
)
}

export default TextFieldVariant
Form Props

Standard form attributes are supported e.g. required, disabled, type, etc. as well as helperText which is used to give context about a field's input, such as how the input will be used.

Some important text


// MUI Imports
import Grid from '@mui/material/Grid'
import TextField from '@mui/material/TextField'

const TextFieldFormProps = () => {
return (
<Grid container spacing={6}>
<Grid item xs={12} md={4}>
<TextField fullWidth required id='form-props-required' label='Required' defaultValue='Hello World' />
</Grid>
<Grid item xs={12} md={4}>
<TextField fullWidth disabled id='form-props-disabled' label='Disabled' defaultValue='Hello World' />
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
type='password'
label='Password'
id='form-props-password-input'
autoComplete='current-password'
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
label='Read Only'
defaultValue='Hello World'
id='form-props-read-only-input'
InputProps={{ readOnly: true }}
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField fullWidth type='number' label='Number' id='form-props-number' InputLabelProps={{ shrink: true }} />
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
label='Label'
placeholder='Placeholder'
id='form-props-full-width'
InputLabelProps={{ shrink: true }}
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField fullWidth id='form-props-search' label='Search field' type='search' />
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
label='Helper text'
id='form-props-helperText'
defaultValue='Default Value'
helperText='Some important text'
/>
</Grid>
</Grid>
)
}

export default TextFieldFormProps
Controlled and Uncontrolled

Manage value prop with the help of a state for controlled TextField and use defaultChecked prop for uncontrolled TextField.


// React Imports
import { useState } from 'react'
import type { ChangeEvent } from 'react'

// MUI Imports
import Box from '@mui/material/Box'
import TextField from '@mui/material/TextField'

const TextFieldControlledUncontrolled = () => {
// States
const [name, setName] = useState<string>('Cat in the Hat')

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setName(event.target.value)
}

return (
<Box component='form' noValidate autoComplete='off' className='flex gap-4 flex-wrap flex-col'>
<TextField value={name} label='Controlled' onChange={handleChange} id='controlled-text-field' />
<TextField id='uncontrolled-text-field' label='Uncontrolled' defaultValue='foo' />
</Box>
)
}

export default TextFieldControlledUncontrolled
Sizes

Use size prop for different sizes of text fields.


// MUI Imports
import Box from '@mui/material/Box'
import TextField from '@mui/material/TextField'

const TextFieldSizes = () => {
return (
<Box component='form' noValidate autoComplete='off' className='flex gap-4 flex-wrap flex-col'>
<TextField label='Size' id='size-small' defaultValue='Small' size='small' />
<TextField label='Size' id='size-medium' defaultValue='Medium' />
</Box>
)
}

export default TextFieldSizes
Color

color={'secondary' | 'success' | 'error' | 'warning' | 'info'} prop changes the highlight color of the text field when focused.


// MUI Imports
import Box from '@mui/material/Box'
import TextField from '@mui/material/TextField'

const TextFieldColor = () => {
return (
<Box component='form' noValidate autoComplete='off' className='flex gap-4 flex-wrap flex-col'>
<TextField id='color-outlined' label='Outlined success' color='success' />
<TextField id='color-filled' label='Filled success' variant='filled' color='success' />
<TextField id='color-standard' label='Standard success' color='success' variant='standard' />
</Box>
)
}

export default TextFieldColor
Input Adornment

The main way is with an InputAdornment. This can be used to add a prefix, a suffix or an action to an input. For instance, you can use an icon button to hide or reveal the password.

Kg

Kg

Weight


// React Imports
import { useState } from 'react'
import type { ChangeEvent } from 'react'

// MUI Imports
import Box from '@mui/material/Box'
import TextField from '@mui/material/TextField'
import InputLabel from '@mui/material/InputLabel'
import IconButton from '@mui/material/IconButton'
import FormControl from '@mui/material/FormControl'
import OutlinedInput from '@mui/material/OutlinedInput'
import FormHelperText from '@mui/material/FormHelperText'
import InputAdornment from '@mui/material/InputAdornment'

// Third-party Imports
import classnames from 'classnames'

type State = {
weight: string
password: string
showPassword: boolean
}

const TextFieldInputAdornment = () => {
// States
const [values, setValues] = useState<State>({
weight: '',
password: '',
showPassword: false
})

const handleChange = (prop: keyof State) => (event: ChangeEvent<HTMLInputElement>) => {
setValues({ ...values, [prop]: event.target.value })
}

const handleClickShowPassword = () => {
setValues({ ...values, showPassword: !values.showPassword })
}

return (
<Box component='form' noValidate autoComplete='off' className='flex gap-4 flex-wrap flex-col'>
<TextField
id='icons-start-adornment'
label='With normal TextField'
InputProps={{
startAdornment: <InputAdornment position='start'>Kg</InputAdornment>
}}
/>
<FormControl>
<OutlinedInput
value={values.weight}
id='icons-adornment-weight'
onChange={handleChange('weight')}
aria-describedby='icons-weight-helper-text'
endAdornment={<InputAdornment position='end'>Kg</InputAdornment>}
inputProps={{
'aria-label': 'weight'
}}
/>
<FormHelperText id='icons-weight-helper-text'>Weight</FormHelperText>
</FormControl>
<FormControl>
<InputLabel htmlFor='icons-adornment-password'>Password</InputLabel>
<OutlinedInput
label='Password'
value={values.password}
id='icons-adornment-password'
onChange={handleChange('password')}
type={values.showPassword ? 'text' : 'password'}
endAdornment={
<InputAdornment position='end'>
<IconButton
edge='end'
onClick={handleClickShowPassword}
onMouseDown={e => e.preventDefault()}
aria-label='toggle password visibility'
>
<i className={values.showPassword ? 'ri-eye-line' : 'ri-eye-off-line'} />
</IconButton>
</InputAdornment>
}
/>
</FormControl>
</Box>
)
}

export default TextFieldInputAdornment
Icons

There are multiple ways to display an icon with a text field.


// MUI Imports
import Grid from '@mui/material/Grid'
import Input from '@mui/material/Input'
import TextField from '@mui/material/TextField'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import InputAdornment from '@mui/material/InputAdornment'

const TextFieldIcons = () => {
return (
<Grid container spacing={6}>
<Grid item xs={12}>
<FormControl fullWidth variant='standard'>
<InputLabel htmlFor='input-with-icon-adornment'>With a start adornment</InputLabel>
<Input
id='input-with-icon-adornment'
startAdornment={
<InputAdornment position='start'>
<i className='ri-account-circle-line' />
</InputAdornment>
}
/>
</FormControl>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
label='TextField'
variant='standard'
id='input-with-icon-textfield'
InputProps={{
startAdornment: (
<InputAdornment position='start'>
<i className='ri-account-circle-line' />
</InputAdornment>
)
}}
/>
</Grid>
<Grid item xs={12}>
<Grid container spacing={2} className='items-end'>
<Grid item xs={1} className='flex justify-center'>
<i className='ri-account-circle-line text-actionActive' />
</Grid>
<Grid item xs={11}>
<TextField fullWidth variant='standard' id='input-with-icon-grid' label='With a grid' />
</Grid>
</Grid>
</Grid>
</Grid>
)
}

export default TextFieldIcons
Validation

The error prop toggles the error state, the helperText prop can then be used to provide feedback to the user about the error.

Incorrect entry.


// MUI Imports
import Box from '@mui/material/Box'
import TextField from '@mui/material/TextField'

const TextFieldValidation = () => {
return (
<Box component='form' noValidate autoComplete='off' className='flex gap-4 flex-col'>
<TextField error id='validation-error' label='Error' defaultValue='Hello World' />
<TextField
error
label='Error'
defaultValue='Hello World'
helperText='Incorrect entry.'
id='validation-error-helper-text'
/>
</Box>
)
}

export default TextFieldValidation
Layout

fullWidth can be used to make the input take up the full width of its container.

margin prop can be used to alter the vertical spacing of inputs. Using none (default) doesn't apply margins to the FormControl whereas dense and normal do.

Some important text

Some important text

Some important text


// MUI Imports
import Grid from '@mui/material/Grid'
import TextField from '@mui/material/TextField'

const TextFieldLayout = () => {
return (
<Grid container spacing={6}>
<Grid item xs={12}>
<TextField fullWidth label='Full width' id='outlined-full-width' className='mbe-4' />
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
label='None'
className='mie-4'
id='outlined-margin-none'
defaultValue='Margin None'
helperText='Some important text'
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
label='Dense'
margin='dense'
className='mie'
id='outlined-margin-dense'
defaultValue='Margin Dense'
helperText='Some important text'
/>
</Grid>
<Grid item xs={12} md={4}>
<TextField
fullWidth
label='Normal'
margin='normal'
id='outlined-margin-normal'
defaultValue='Margin Normal'
helperText='Some important text'
/>
</Grid>
</Grid>
)
}

export default TextFieldLayout
Components

TextField is composed of smaller components (FormControl, Input, FilledInput, InputLabel, OutlinedInput, and FormHelperText) that you can leverage directly to significantly customize your form inputs.

Some important helper text

Disabled

Error


// React Imports
import { useState } from 'react'
import type { ChangeEvent } from 'react'

// MUI Imports
import Grid from '@mui/material/Grid'
import Input from '@mui/material/Input'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import FilledInput from '@mui/material/FilledInput'
import OutlinedInput from '@mui/material/OutlinedInput'
import FormHelperText from '@mui/material/FormHelperText'

const TextFieldComponents = () => {
// States
const [name, setName] = useState<string>('Composed TextField')

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setName(event.target.value)
}

return (
<Grid container spacing={6}>
<Grid item xs={12} md={4}>
<FormControl fullWidth variant='standard'>
<InputLabel htmlFor='component-basic'>Name</InputLabel>
<Input id='component-basic' value={name} onChange={handleChange} />
</FormControl>
</Grid>
<Grid item xs={12} md={4}>
<FormControl fullWidth variant='standard'>
<InputLabel htmlFor='component-helper'>Name</InputLabel>
<Input id='component-helper' value={name} onChange={handleChange} aria-describedby='component-helper-text' />
<FormHelperText id='component-helper-text'>Some important helper text</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={4}>
<FormControl fullWidth disabled variant='standard'>
<InputLabel htmlFor='component-disabled'>Name</InputLabel>
<Input id='component-disabled' value={name} onChange={handleChange} />
<FormHelperText>Disabled</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={4}>
<FormControl fullWidth error variant='standard'>
<InputLabel htmlFor='component-error'>Name</InputLabel>
<Input id='component-error' value={name} onChange={handleChange} aria-describedby='component-error-text' />
<FormHelperText id='component-error-text'>Error</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={4}>
<FormControl fullWidth>
<InputLabel htmlFor='component-outlined'>Name</InputLabel>
<OutlinedInput id='component-outlined' value={name} onChange={handleChange} label='Name' />
</FormControl>
</Grid>
<Grid item xs={12} md={4}>
<FormControl fullWidth variant='filled'>
<InputLabel htmlFor='component-filled'>Name</InputLabel>
<FilledInput id='component-filled' value={name} onChange={handleChange} />
</FormControl>
</Grid>
</Grid>
)
}

export default TextFieldComponents
Inputs

// MUI Imports
import Grid from '@mui/material/Grid'
import Input from '@mui/material/Input'

const TextFieldInputs = () => {
return (
<Grid container spacing={6}>
<Grid item xs={12} md={6}>
<Input fullWidth defaultValue='Hello world' inputProps={{ 'aria-label': 'description' }} />
</Grid>
<Grid item xs={12} md={6}>
<Input fullWidth placeholder='Placeholder' inputProps={{ 'aria-label': 'description' }} />
</Grid>
<Grid item xs={12} md={6}>
<Input fullWidth defaultValue='Disabled' disabled inputProps={{ 'aria-label': 'description' }} />
</Grid>
<Grid item xs={12} md={6}>
<Input fullWidth defaultValue='Error' error inputProps={{ 'aria-label': 'description' }} />
</Grid>
</Grid>
)
}

export default TextFieldInputs
Customized

Use styled hook to customize your text field.


// MUI Imports
import Box from '@mui/material/Box'
import InputLabel from '@mui/material/InputLabel'
import MuiInputBase from '@mui/material/InputBase'
import FormControl from '@mui/material/FormControl'
import { styled } from '@mui/material/styles'
import type { InputBaseProps } from '@mui/material/InputBase'

// Styled InputBase component
const InputBase = styled(MuiInputBase)<InputBaseProps>(({ theme }) => ({
marginTop: theme.spacing(4),
'& .MuiInputBase-input': {
fontSize: 16,
borderRadius: 4,
padding: '10px 12px',
position: 'relative',
backgroundColor: 'var(--mui-palette-background-paper)',
transition: theme.transitions.create(['border-color', 'box-shadow']),
border: theme.palette.mode === 'light' ? '1px solid #ced4da' : '1px solid var(--mui-palette-divider)',
fontFamily: [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"'
].join(','),
'&:focus': {
borderColor: 'var(--mui-palette-primary-main)',
boxShadow: '0 0 0 0.2rem rgb(var(--mui-palette-primary-mainChannel) / 0.25)'
}
}
}))

const TextFieldCustomized = () => {
return (
<Box component='form' noValidate autoComplete='off' className='flex gap-4' onSubmit={e => e.preventDefault()}>
<FormControl fullWidth variant='standard'>
<InputLabel shrink htmlFor='bootstrap-input' className='-translate-y-[0.25rem] scale-[0.75]'>
Bootstrap
</InputLabel>
<InputBase defaultValue='react-bootstrap' id='bootstrap-input' />
</FormControl>
</Box>
)
}

export default TextFieldCustomized