or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

field.mdform-spy.mdform.mdhooks.mdindex.mdtypescript.md

field.mddocs/

0

# Field Component

1

2

Individual field components with subscription-based state management, validation, formatting, and parsing capabilities.

3

4

## Capabilities

5

6

### Field Component

7

8

React component for individual form fields that connects to form state and provides input props and field metadata.

9

10

```typescript { .api }

11

/**

12

* Form field component with subscription-based state management

13

* @param props - Field configuration and render props

14

* @returns React element for the field

15

*/

16

const Field: <

17

FieldValue = any,

18

T extends HTMLElement = HTMLElement,

19

FormValues = Record<string, any>

20

>(

21

props: FieldProps<FieldValue, T, FormValues>

22

) => React.ReactElement;

23

24

interface FieldProps<

25

FieldValue = any,

26

T extends HTMLElement = HTMLElement,

27

FormValues = Record<string, any>

28

> extends UseFieldConfig,

29

Omit<RenderableProps<FieldRenderProps<FieldValue, T>>, "children"> {

30

/** Field name (required) */

31

name: string;

32

/** Render function or React node */

33

children?: RenderableProps<FieldRenderProps<FieldValue, T>>["children"];

34

/** Additional HTML element props */

35

[key: string]: any;

36

}

37

38

interface FieldRenderProps<

39

FieldValue = any,

40

T extends HTMLElement = HTMLElement,

41

FormValues = any

42

> {

43

/** Input props to spread on form elements */

44

input: FieldInputProps<FieldValue, T>;

45

/** Field metadata and state information */

46

meta: FieldMeta;

47

}

48

49

interface FieldInputProps<

50

FieldValue = any,

51

T extends HTMLElement = HTMLElement

52

> {

53

/** Field name */

54

name: string;

55

/** Blur event handler */

56

onBlur: (event?: React.FocusEvent<T>) => void;

57

/** Change event handler */

58

onChange: (event: React.ChangeEvent<T> | any) => void;

59

/** Focus event handler */

60

onFocus: (event?: React.FocusEvent<T>) => void;

61

/** Current field value */

62

value: FieldValue;

63

/** Checkbox/radio checked state */

64

checked?: boolean;

65

/** Multiple selection support */

66

multiple?: boolean;

67

/** Input type attribute */

68

type?: string;

69

}

70

71

interface FieldMeta {

72

/** Whether field is currently focused */

73

active?: boolean;

74

/** Custom field data */

75

data?: Record<string, any>;

76

/** Whether field value differs from initial */

77

dirty?: boolean;

78

/** Whether field is dirty since last submit */

79

dirtySinceLastSubmit?: boolean;

80

/** Current field validation error */

81

error?: any;

82

/** Initial field value */

83

initial?: any;

84

/** Whether field has validation errors */

85

invalid?: boolean;

86

/** Array length for array fields */

87

length?: number;

88

/** Whether field was ever modified */

89

modified?: boolean;

90

/** Whether field was modified since last submit */

91

modifiedSinceLastSubmit?: boolean;

92

/** Whether field value equals initial value */

93

pristine?: boolean;

94

/** Submission error for this field */

95

submitError?: any;

96

/** Whether last submission failed */

97

submitFailed?: boolean;

98

/** Whether last submission succeeded */

99

submitSucceeded?: boolean;

100

/** Whether form is currently submitting */

101

submitting?: boolean;

102

/** Whether field was ever focused */

103

touched?: boolean;

104

/** Whether field passes validation */

105

valid?: boolean;

106

/** Whether field is currently being validated */

107

validating?: boolean;

108

/** Whether field was ever visited (focused then blurred) */

109

visited?: boolean;

110

}

111

```

112

113

**Usage Examples:**

114

115

```typescript

116

import React from "react";

117

import { Form, Field } from "react-final-form";

118

119

// Basic text input field

120

function BasicField() {

121

return (

122

<Field name="firstName">

123

{({ input, meta }) => (

124

<div>

125

<label>First Name</label>

126

<input {...input} type="text" placeholder="First Name" />

127

{meta.error && meta.touched && <span>{meta.error}</span>}

128

</div>

129

)}

130

</Field>

131

);

132

}

133

134

// Field with validation

135

function ValidatedField() {

136

const required = (value: any) => (value ? undefined : "Required");

137

138

return (

139

<Field name="email" validate={required}>

140

{({ input, meta }) => (

141

<div>

142

<label>Email</label>

143

<input {...input} type="email" placeholder="Email" />

144

{meta.error && meta.touched && (

145

<span className="error">{meta.error}</span>

146

)}

147

{meta.validating && <span>Validating...</span>}

148

</div>

149

)}

150

</Field>

151

);

152

}

153

154

// Select field

155

function SelectField() {

156

return (

157

<Field name="country">

158

{({ input, meta }) => (

159

<div>

160

<label>Country</label>

161

<select {...input}>

162

<option value="">Select a country</option>

163

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

164

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

165

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

166

</select>

167

{meta.error && meta.touched && <span>{meta.error}</span>}

168

</div>

169

)}

170

</Field>

171

);

172

}

173

174

// Checkbox field

175

function CheckboxField() {

176

return (

177

<Field name="subscribe" type="checkbox">

178

{({ input, meta }) => (

179

<div>

180

<label>

181

<input {...input} type="checkbox" />

182

Subscribe to newsletter

183

</label>

184

</div>

185

)}

186

</Field>

187

);

188

}

189

```

190

191

### Field Configuration

192

193

Fields support extensive configuration options for validation, formatting, parsing, and behavior customization.

194

195

```typescript { .api }

196

interface UseFieldConfig extends UseFieldAutoConfig {

197

/** Field state subscription configuration */

198

subscription?: FieldSubscription;

199

}

200

201

interface UseFieldAutoConfig {

202

/** Callback after successful submission */

203

afterSubmit?: () => void;

204

/** Allow null values instead of undefined */

205

allowNull?: boolean;

206

/** Callback before submission, return false to prevent */

207

beforeSubmit?: () => void | false;

208

/** Component to render (alternative to render prop) */

209

component?: React.ComponentType<any> | SupportedInputs;

210

/** Custom data attached to field */

211

data?: Record<string, any>;

212

/** Default value when field is undefined */

213

defaultValue?: any;

214

/** Function to format value for display */

215

format?: (value: any, name: string) => any;

216

/** Whether to format on blur instead of every change */

217

formatOnBlur?: boolean;

218

/** Initial field value */

219

initialValue?: any;

220

/** Custom equality function for value comparison */

221

isEqual?: (a: any, b: any) => boolean;

222

/** Multiple selection support */

223

multiple?: boolean;

224

/** Function to parse display value to stored value */

225

parse?: (value: any, name: string) => any;

226

/** Input type attribute */

227

type?: string;

228

/** Field validation function */

229

validate?: FieldValidator<any>;

230

/** Other fields to validate when this field changes */

231

validateFields?: string[];

232

/** Controlled field value */

233

value?: any;

234

}

235

236

interface FieldSubscription {

237

active?: boolean;

238

data?: boolean;

239

dirty?: boolean;

240

dirtySinceLastSubmit?: boolean;

241

error?: boolean;

242

initial?: boolean;

243

invalid?: boolean;

244

length?: boolean;

245

modified?: boolean;

246

modifiedSinceLastSubmit?: boolean;

247

pristine?: boolean;

248

submitError?: boolean;

249

submitFailed?: boolean;

250

submitSucceeded?: boolean;

251

submitting?: boolean;

252

touched?: boolean;

253

valid?: boolean;

254

validating?: boolean;

255

value?: boolean;

256

visited?: boolean;

257

}

258

259

type FieldValidator<FieldValue> = (

260

value: FieldValue,

261

allValues: Record<string, any>,

262

meta?: FieldState<FieldValue>

263

) => any | Promise<any>;

264

265

type SupportedInputs = "input" | "select" | "textarea";

266

```

267

268

**Usage Examples:**

269

270

```typescript

271

// Field with formatting and parsing

272

function CurrencyField() {

273

const format = (value: number) => {

274

if (value === undefined) return "";

275

return new Intl.NumberFormat("en-US", {

276

style: "currency",

277

currency: "USD",

278

}).format(value);

279

};

280

281

const parse = (value: string) => {

282

const number = parseFloat(value.replace(/[^0-9.-]/g, ""));

283

return isNaN(number) ? undefined : number;

284

};

285

286

return (

287

<Field

288

name="price"

289

format={format}

290

parse={parse}

291

>

292

{({ input, meta }) => (

293

<div>

294

<label>Price</label>

295

<input {...input} type="text" placeholder="$0.00" />

296

{meta.error && meta.touched && <span>{meta.error}</span>}

297

</div>

298

)}

299

</Field>

300

);

301

}

302

303

// Field with custom validation

304

function EmailField() {

305

const validateEmail = (value: string) => {

306

if (!value) return "Required";

307

if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {

308

return "Invalid email address";

309

}

310

return undefined;

311

};

312

313

return (

314

<Field

315

name="email"

316

validate={validateEmail}

317

subscription={{ value: true, error: true, touched: true }}

318

>

319

{({ input, meta }) => (

320

<div>

321

<label>Email</label>

322

<input {...input} type="email" />

323

{meta.error && meta.touched && <span>{meta.error}</span>}

324

</div>

325

)}

326

</Field>

327

);

328

}

329

330

// Field with component prop

331

function ComponentField() {

332

const TextInput = ({ input, meta, ...props }: any) => (

333

<div>

334

<input {...input} {...props} />

335

{meta.error && meta.touched && <span>{meta.error}</span>}

336

</div>

337

);

338

339

return (

340

<Field

341

name="description"

342

component={TextInput}

343

type="text"

344

placeholder="Enter description"

345

/>

346

);

347

}

348

```

349

350

### Field State Management

351

352

Fields maintain comprehensive state information and support advanced state management features.

353

354

```typescript { .api }

355

interface FieldState<FieldValue = any> {

356

/** Whether field is currently active (focused) */

357

active?: boolean;

358

/** Custom data attached to field */

359

data?: Record<string, any>;

360

/** Whether field value differs from initial */

361

dirty?: boolean;

362

/** Whether field is dirty since last submit */

363

dirtySinceLastSubmit?: boolean;

364

/** Current validation error */

365

error?: any;

366

/** Initial field value */

367

initial?: FieldValue;

368

/** Whether field has validation errors */

369

invalid?: boolean;

370

/** Array length for array fields */

371

length?: number;

372

/** Whether field was ever modified */

373

modified?: boolean;

374

/** Whether field was modified since last submit */

375

modifiedSinceLastSubmit?: boolean;

376

/** Whether field value equals initial value */

377

pristine?: boolean;

378

/** Submission error for this field */

379

submitError?: any;

380

/** Whether last submission failed */

381

submitFailed?: boolean;

382

/** Whether last submission succeeded */

383

submitSucceeded?: boolean;

384

/** Whether form is currently submitting */

385

submitting?: boolean;

386

/** Whether field was ever focused */

387

touched?: boolean;

388

/** Whether field passes validation */

389

valid?: boolean;

390

/** Whether field is currently being validated */

391

validating?: boolean;

392

/** Current field value */

393

value?: FieldValue;

394

/** Whether field was ever visited (focused then blurred) */

395

visited?: boolean;

396

}

397

```

398

399

### Array Fields

400

401

Fields support array operations for dynamic field lists and complex data structures.

402

403

```typescript { .api }

404

/**

405

* Array field operations available through field meta when length > 0

406

*/

407

interface ArrayFieldMeta extends FieldMeta {

408

/** Number of items in the array */

409

length?: number;

410

}

411

```

412

413

**Usage Example:**

414

415

```typescript

416

function ArrayField() {

417

return (

418

<Field name="items">

419

{({ input, meta }) => (

420

<div>

421

<label>Items ({meta.length || 0})</label>

422

{/* Array field rendering logic */}

423

{meta.length && <div>Array has {meta.length} items</div>}

424

</div>

425

)}

426

</Field>

427

);

428

}

429

```