or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

colors.mddata-display.mdfeedback.mdforms.mdindex.mdinputs.mdlayout.mdnavigation.mdstyling.mdsurfaces.mdutilities.md

forms.mddocs/

0

# Form Components

1

2

Complete form controls including text fields, selects, checkboxes, and form validation with Material Design styling.

3

4

## Capabilities

5

6

### TextField

7

8

Complete text field component with label, input, helper text, and error states.

9

10

```typescript { .api }

11

/**

12

* Complete text field with label, input and helper text

13

* @param props - TextField configuration

14

* @returns TextField component

15

*/

16

function TextField(props: TextFieldProps): JSX.Element;

17

18

interface TextFieldProps extends CommonProps {

19

/** The variant to use */

20

variant?: 'filled' | 'outlined' | 'standard';

21

/** The size of the component */

22

size?: 'small' | 'medium';

23

/** The color of the component */

24

color?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';

25

/** If true, the component takes up the full width of its container */

26

fullWidth?: boolean;

27

/** The label content */

28

label?: React.ReactNode;

29

/** The helper text content */

30

helperText?: React.ReactNode;

31

/** If true, the label is displayed in an error state */

32

error?: boolean;

33

/** If true, the component is disabled */

34

disabled?: boolean;

35

/** If true, the Input will be required */

36

required?: boolean;

37

/** The default value */

38

defaultValue?: unknown;

39

/** The value of the component */

40

value?: unknown;

41

/** Callback fired when the value is changed */

42

onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;

43

/** Name attribute of the input element */

44

name?: string;

45

/** The short hint displayed in the input before the user enters a value */

46

placeholder?: string;

47

/** Type of the input element */

48

type?: string;

49

/** If true, the component will be displayed in focused state */

50

autoFocus?: boolean;

51

/** If true, the component displays a multiline input */

52

multiline?: boolean;

53

/** Maximum number of rows to display when multiline option is set to true */

54

maxRows?: number;

55

/** Minimum number of rows to display when multiline option is set to true */

56

minRows?: number;

57

/** Number of rows to display when multiline option is set to true */

58

rows?: number;

59

/** Render a Select element while passing the Input element to Select as input parameter */

60

select?: boolean;

61

/** The option elements to populate the select with */

62

children?: React.ReactNode;

63

/** Props applied to the Input element */

64

InputProps?: Partial<OutlinedInputProps>;

65

/** Props applied to the InputLabel element */

66

InputLabelProps?: Partial<InputLabelProps>;

67

/** Props applied to the FormHelperText element */

68

FormHelperTextProps?: Partial<FormHelperTextProps>;

69

}

70

```

71

72

**Usage Examples:**

73

74

```typescript

75

import { TextField, MenuItem } from "@mui/material";

76

77

// Basic text field

78

<TextField

79

label="Email"

80

variant="outlined"

81

type="email"

82

fullWidth

83

required

84

/>

85

86

// Text field with helper text and error

87

<TextField

88

label="Password"

89

type="password"

90

error

91

helperText="Password must be at least 8 characters"

92

fullWidth

93

/>

94

95

// Multiline text field

96

<TextField

97

label="Description"

98

multiline

99

rows={4}

100

fullWidth

101

placeholder="Enter your description here..."

102

/>

103

104

// Select field

105

<TextField

106

select

107

label="Country"

108

value={country}

109

onChange={handleChange}

110

fullWidth

111

>

112

<MenuItem value="us">United States</MenuItem>

113

<MenuItem value="ca">Canada</MenuItem>

114

<MenuItem value="uk">United Kingdom</MenuItem>

115

</TextField>

116

```

117

118

### FormControl

119

120

Provides context such as filled/focused/error/required for form inputs.

121

122

```typescript { .api }

123

/**

124

* Form control wrapper providing context

125

* @param props - FormControl configuration

126

* @returns FormControl component

127

*/

128

function FormControl(props: FormControlProps): JSX.Element;

129

130

interface FormControlProps extends CommonProps {

131

/** The color of the component */

132

color?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';

133

/** If true, the component is disabled */

134

disabled?: boolean;

135

/** If true, the label should be displayed in an error state */

136

error?: boolean;

137

/** If true, the component will take up the full width of its container */

138

fullWidth?: boolean;

139

/** If true, the component is focused */

140

focused?: boolean;

141

/** If true, the label is hidden */

142

hiddenLabel?: boolean;

143

/** The margin to apply to the component */

144

margin?: 'dense' | 'normal' | 'none';

145

/** If true, the label will indicate that the input is required */

146

required?: boolean;

147

/** The size of the component */

148

size?: 'small' | 'medium';

149

/** The variant to use */

150

variant?: 'standard' | 'outlined' | 'filled';

151

/** The component used for the root node */

152

component?: React.ElementType;

153

children?: React.ReactNode;

154

}

155

```

156

157

### FormControlLabel

158

159

Drop-in replacement for labels with built-in FormControl context.

160

161

```typescript { .api }

162

/**

163

* Label with FormControl context

164

* @param props - FormControlLabel configuration

165

* @returns FormControlLabel component

166

*/

167

function FormControlLabel(props: FormControlLabelProps): JSX.Element;

168

169

interface FormControlLabelProps extends CommonProps {

170

/** A control element. For instance, it can be a Radio, a Switch or a Checkbox */

171

control: React.ReactElement;

172

/** The text to be used in an enclosing label element */

173

label: React.ReactNode;

174

/** The position of the label */

175

labelPlacement?: 'end' | 'start' | 'top' | 'bottom';

176

/** If true, the component appears selected */

177

checked?: boolean;

178

/** If true, the control is disabled */

179

disabled?: boolean;

180

/** Name attribute of the input element */

181

name?: string;

182

/** Callback fired when the state is changed */

183

onChange?: (event: React.SyntheticEvent, checked: boolean) => void;

184

/** The value of the component */

185

value?: unknown;

186

/** If true, the input element is required */

187

required?: boolean;

188

}

189

```

190

191

### Checkbox

192

193

Checkbox input component with customizable states and styling.

194

195

```typescript { .api }

196

/**

197

* Checkbox input component

198

* @param props - Checkbox configuration

199

* @returns Checkbox component

200

*/

201

function Checkbox(props: CheckboxProps): JSX.Element;

202

203

interface CheckboxProps extends CommonProps {

204

/** If true, the component is checked */

205

checked?: boolean;

206

/** The icon to display when the component is checked */

207

checkedIcon?: React.ReactNode;

208

/** The color of the component */

209

color?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' | 'default';

210

/** The default checked state */

211

defaultChecked?: boolean;

212

/** If true, the component is disabled */

213

disabled?: boolean;

214

/** If true, the ripple effect is disabled */

215

disableRipple?: boolean;

216

/** The icon to display when the component is unchecked */

217

icon?: React.ReactNode;

218

/** If true, the component appears indeterminate */

219

indeterminate?: boolean;

220

/** The icon to display when the component is indeterminate */

221

indeterminateIcon?: React.ReactNode;

222

/** Attributes applied to the input element */

223

inputProps?: React.InputHTMLAttributes<HTMLInputElement>;

224

/** Pass a ref to the input element */

225

inputRef?: React.Ref<HTMLInputElement>;

226

/** Callback fired when the state is changed */

227

onChange?: (event: React.ChangeEvent<HTMLInputElement>, checked: boolean) => void;

228

/** If true, the input element is required */

229

required?: boolean;

230

/** The size of the component */

231

size?: 'small' | 'medium';

232

/** The value of the component */

233

value?: unknown;

234

}

235

```

236

237

**Usage Examples:**

238

239

```typescript

240

import { Checkbox, FormControlLabel, FormGroup } from "@mui/material";

241

242

// Basic checkbox

243

<FormControlLabel

244

control={<Checkbox />}

245

label="Accept terms and conditions"

246

/>

247

248

// Controlled checkbox

249

<FormControlLabel

250

control={

251

<Checkbox

252

checked={checked}

253

onChange={handleChange}

254

color="primary"

255

/>

256

}

257

label="Enable notifications"

258

/>

259

260

// Checkbox group

261

<FormGroup>

262

<FormControlLabel control={<Checkbox />} label="Option 1" />

263

<FormControlLabel control={<Checkbox />} label="Option 2" />

264

<FormControlLabel control={<Checkbox />} label="Option 3" />

265

</FormGroup>

266

```

267

268

### Radio and RadioGroup

269

270

Radio button components for single selection from multiple options.

271

272

```typescript { .api }

273

/**

274

* Radio button input component

275

* @param props - Radio configuration

276

* @returns Radio component

277

*/

278

function Radio(props: RadioProps): JSX.Element;

279

280

/**

281

* Groups radio buttons and manages selection

282

* @param props - RadioGroup configuration

283

* @returns RadioGroup component

284

*/

285

function RadioGroup(props: RadioGroupProps): JSX.Element;

286

287

interface RadioProps extends CommonProps {

288

/** If true, the component is checked */

289

checked?: boolean;

290

/** The icon to display when the component is checked */

291

checkedIcon?: React.ReactNode;

292

/** The color of the component */

293

color?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' | 'default';

294

/** If true, the component is disabled */

295

disabled?: boolean;

296

/** If true, the ripple effect is disabled */

297

disableRipple?: boolean;

298

/** The icon to display when the component is unchecked */

299

icon?: React.ReactNode;

300

/** Attributes applied to the input element */

301

inputProps?: React.InputHTMLAttributes<HTMLInputElement>;

302

/** Name attribute of the input element */

303

name?: string;

304

/** Callback fired when the state is changed */

305

onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;

306

/** If true, the input element is required */

307

required?: boolean;

308

/** The size of the component */

309

size?: 'small' | 'medium';

310

/** The value of the component */

311

value?: unknown;

312

}

313

314

interface RadioGroupProps extends CommonProps {

315

/** The default selected value */

316

defaultValue?: unknown;

317

/** The name used to reference the value of the control */

318

name?: string;

319

/** Callback fired when a radio button is selected */

320

onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string) => void;

321

/** Display group of radio buttons in a row */

322

row?: boolean;

323

/** Value of the selected radio button */

324

value?: unknown;

325

children?: React.ReactNode;

326

}

327

```

328

329

**Usage Examples:**

330

331

```typescript

332

import { Radio, RadioGroup, FormControlLabel, FormControl, FormLabel } from "@mui/material";

333

334

// Radio group

335

<FormControl component="fieldset">

336

<FormLabel component="legend">Gender</FormLabel>

337

<RadioGroup

338

aria-label="gender"

339

name="gender"

340

value={value}

341

onChange={handleChange}

342

>

343

<FormControlLabel value="female" control={<Radio />} label="Female" />

344

<FormControlLabel value="male" control={<Radio />} label="Male" />

345

<FormControlLabel value="other" control={<Radio />} label="Other" />

346

</RadioGroup>

347

</FormControl>

348

```

349

350

### Select

351

352

Select dropdown component for choosing from multiple options.

353

354

```typescript { .api }

355

/**

356

* Select dropdown component

357

* @param props - Select configuration

358

* @returns Select component

359

*/

360

function Select<T>(props: SelectProps<T>): JSX.Element;

361

362

interface SelectProps<T> extends CommonProps {

363

/** If true, the width of the popover will automatically be set according to the items inside the menu */

364

autoWidth?: boolean;

365

/** The default selected value */

366

defaultValue?: T;

367

/** If true, a value is displayed even if no items are selected */

368

displayEmpty?: boolean;

369

/** The icon that displays the arrow */

370

IconComponent?: React.ComponentType;

371

/** The input component */

372

input?: React.ReactElement;

373

/** Attributes applied to the input element */

374

inputProps?: React.InputHTMLAttributes<HTMLInputElement>;

375

/** The label element */

376

label?: React.ReactNode;

377

/** The ID of an element that acts as an additional label */

378

labelId?: string;

379

/** Props applied to the Menu element */

380

MenuProps?: Partial<MenuProps>;

381

/** If true, value must be an array and the menu will support multiple selections */

382

multiple?: boolean;

383

/** If true, the component uses a native select element */

384

native?: boolean;

385

/** Callback fired when a menu item is selected */

386

onChange?: (event: SelectChangeEvent<T>, child: React.ReactNode) => void;

387

/** Callback fired when the component requests to be closed */

388

onClose?: (event: React.SyntheticEvent) => void;

389

/** Callback fired when the component requests to be opened */

390

onOpen?: (event: React.SyntheticEvent) => void;

391

/** If true, the component is shown */

392

open?: boolean;

393

/** Render the selected value */

394

renderValue?: (value: T) => React.ReactNode;

395

/** Props applied to the clickable div element */

396

SelectDisplayProps?: React.HTMLAttributes<HTMLDivElement>;

397

/** The input value */

398

value?: T;

399

/** The variant to use */

400

variant?: 'standard' | 'outlined' | 'filled';

401

children?: React.ReactNode;

402

}

403

```

404

405

**Usage Examples:**

406

407

```typescript

408

import { Select, MenuItem, FormControl, InputLabel } from "@mui/material";

409

410

// Basic select

411

<FormControl fullWidth>

412

<InputLabel>Age</InputLabel>

413

<Select

414

value={age}

415

label="Age"

416

onChange={handleChange}

417

>

418

<MenuItem value={10}>Ten</MenuItem>

419

<MenuItem value={20}>Twenty</MenuItem>

420

<MenuItem value={30}>Thirty</MenuItem>

421

</Select>

422

</FormControl>

423

424

// Multiple select

425

<Select

426

multiple

427

value={selectedItems}

428

onChange={handleChange}

429

renderValue={(selected) => selected.join(', ')}

430

>

431

<MenuItem value="option1">Option 1</MenuItem>

432

<MenuItem value="option2">Option 2</MenuItem>

433

<MenuItem value="option3">Option 3</MenuItem>

434

</Select>

435

```

436

437

## Form Validation Pattern

438

439

```typescript

440

import React, { useState } from "react";

441

import {

442

TextField,

443

Button,

444

FormControl,

445

FormHelperText,

446

Box

447

} from "@mui/material";

448

449

interface FormData {

450

email: string;

451

password: string;

452

confirmPassword: string;

453

}

454

455

interface FormErrors {

456

email?: string;

457

password?: string;

458

confirmPassword?: string;

459

}

460

461

function SignupForm() {

462

const [formData, setFormData] = useState<FormData>({

463

email: "",

464

password: "",

465

confirmPassword: ""

466

});

467

const [errors, setErrors] = useState<FormErrors>({});

468

469

const validateForm = (): boolean => {

470

const newErrors: FormErrors = {};

471

472

if (!formData.email.includes("@")) {

473

newErrors.email = "Please enter a valid email address";

474

}

475

476

if (formData.password.length < 8) {

477

newErrors.password = "Password must be at least 8 characters";

478

}

479

480

if (formData.password !== formData.confirmPassword) {

481

newErrors.confirmPassword = "Passwords do not match";

482

}

483

484

setErrors(newErrors);

485

return Object.keys(newErrors).length === 0;

486

};

487

488

const handleSubmit = (event: React.FormEvent) => {

489

event.preventDefault();

490

if (validateForm()) {

491

// Submit form

492

console.log("Form submitted:", formData);

493

}

494

};

495

496

const handleChange = (field: keyof FormData) =>

497

(event: React.ChangeEvent<HTMLInputElement>) => {

498

setFormData(prev => ({

499

...prev,

500

[field]: event.target.value

501

}));

502

// Clear error when user starts typing

503

if (errors[field]) {

504

setErrors(prev => ({

505

...prev,

506

[field]: undefined

507

}));

508

}

509

};

510

511

return (

512

<Box component="form" onSubmit={handleSubmit} sx={{ mt: 1 }}>

513

<TextField

514

margin="normal"

515

required

516

fullWidth

517

label="Email Address"

518

type="email"

519

value={formData.email}

520

onChange={handleChange('email')}

521

error={!!errors.email}

522

helperText={errors.email}

523

/>

524

525

<TextField

526

margin="normal"

527

required

528

fullWidth

529

label="Password"

530

type="password"

531

value={formData.password}

532

onChange={handleChange('password')}

533

error={!!errors.password}

534

helperText={errors.password}

535

/>

536

537

<TextField

538

margin="normal"

539

required

540

fullWidth

541

label="Confirm Password"

542

type="password"

543

value={formData.confirmPassword}

544

onChange={handleChange('confirmPassword')}

545

error={!!errors.confirmPassword}

546

helperText={errors.confirmPassword}

547

/>

548

549

<Button

550

type="submit"

551

fullWidth

552

variant="contained"

553

sx={{ mt: 3, mb: 2 }}

554

>

555

Sign Up

556

</Button>

557

</Box>

558

);

559

}

560

```