TextField | Dashforge-UI
DocsStarter Kits
v0.1.0-alpha

TextField

An intelligent input component built on MUI TextField. Supports standalone usage, seamless DashForm integration with automatic field binding, validation error gating, and reactive visibility. The foundation for composed field behaviors.

Quick Start

Copy & Paste

import { TextField } from '@dashforge/ui';

<TextField label="Email" name="email" />

Examples

Common TextField patterns and configurations

Basic

A simple text field with a label

<TextField label="Name" name="name" />
Disabled

A disabled text field

<TextField label="Name" name="name" disabled />
Error State

A text field displaying an error

Invalid email

<TextField
  label="Email"
  name="email"
  error
  helperText="Invalid email"
/>
Full Width

A text field that spans the full width

<TextField
  label="Address"
  name="address"
  fullWidth
/>
Inline Layout

A text field with label on the left

<TextField
  label="Email"
  name="email"
  layout="inline"
  fullWidth
/>
Inline with Helper Text

Inline layout with helper text below control

Must be unique

<TextField
  label="Username"
  name="username"
  layout="inline"
  helperText="Must be unique"
  fullWidth
/>
Multiline

A text field with multiple lines

<TextField
  label="Description"
  name="description"
  multiline
  rows={4}
/>

Layout Variants

Floating, stacked, and inline label layouts

TextField supports three layout modes: floating (default), stacked, and inline. The layout prop controls label positioning and composition independently of the MUI variant (outlined/filled/standard).

Floating (Default)
Live Preview

We will never share your email.

<TextField
  label="Email"
  name="email"
  placeholder="Enter your email"
  helperText="We will never share your email."
  fullWidth
/>

What to observe: Standard MUI floating label behavior. Label animates up when field is focused or has value. This is the migration-friendly default.

Stacked Layout
Live Preview

We will never share your email.

<TextField
  label="Email"
  name="email"
  placeholder="Enter your email"
  helperText="We will never share your email."
  layout="stacked"
  fullWidth
/>

What to observe: External label above input field. Label is always visible and stationary. Helper text appears below the input.

Inline Layout
Live Preview

We will never share your email.

<TextField
  label="Email"
  name="email"
  placeholder="Enter your email"
  helperText="We will never share your email."
  layout="inline"
  fullWidth
/>

What to observe: External label to the left of input field, aligned to the top. Helper text appears below the input. Useful for compact horizontal forms.

Layout Architecture

Floating layout (default): Uses standard MUI TextField composition with internal floating label. This preserves the familiar MUI behavior and ensures easy migration.

Custom layouts (stacked/inline): Use an internal FieldLayoutShell component to manage external label and helper text positioning. The shell renders labels and helper text outside MUI TextField while preserving all Dashforge capabilities (form integration, validation, conditional visibility, etc.).

Spacing values for custom layouts are defined in the theme's fieldLayout configuration, ensuring consistency across all form-connected components (TextField, Select, Autocomplete, etc.).

Layout with Error State
Live Preview

Invalid email format

<TextField
  label="Email"
  name="email"
  error
  helperText="Invalid email format"
  fullWidth
/>
Live Preview

Invalid email format

<TextField
  label="Email"
  name="email"
  layout="stacked"
  error
  helperText="Invalid email format"
  fullWidth
/>
Live Preview

Invalid email format

<TextField
  label="Email"
  name="email"
  layout="inline"
  error
  helperText="Invalid email format"
  fullWidth
/>

What to observe: Error states work identically across all layouts. Labels turn red and helper text displays error messages with appropriate styling.

Interactive Playground

Experiment with props and see live results

Interactive Playground

Live Playground

Configuration
Presets
Properties
Field Layout
MUI Variant
States
Live Preview

Helper text

Generated Code

tsx

<TextField
  label="Name"
  placeholder="Enter your name"
  helperText="Helper text"
  name="fieldName"
/>

Dashforge Capabilities

Progressive adoption from controlled components to predictive forms

Use TextField as a controlled component, integrate with React Hook Form, or leverage reactive capabilities. Choose the adoption level that fits your workflow.

Controlled

Available Now

Works as a standard React controlled component. No proprietary lock-in—use familiar patterns.

Standard value and onChange props

Low adoption friction for existing codebases

Suitable for incremental migration

<TextField
  value={name}
  onChange={(e) => setName(e.target.value)}
  label="Name"
/>

React Hook Form Ready

Integration-Friendly

Integrates with React Hook Form via DashForm. Automatic validation, error handling, and familiar RHF patterns.

Works with RHF through DashFormBridge

Automatic validation and error handling

Supports gradual adoption without rewrites

<DashForm>
  <TextField 
    name="email"
    label="Email"
  />
</DashForm>

Reactive Visibility

Available Now

Conditional rendering via visibleWhen. Fields respond to form state changes without manual orchestration.

Conditional rendering via visibleWhen

Engine evaluates the predicate

Useful for dependent text fields

<TextField
  name="other"
  label="Other"
  visibleWhen={(engine) => 
    engine.getNode('category')?.value === 'other'
  }
/>

Access Control (RBAC)

Control field visibility and interaction based on user permissions. Fields can be hidden, disabled, or readonly when users lack access.

Hide when unauthorized

<TextField
  name="salary"
  access={{
    resource: 'user.salary',
    action: 'read',
    onUnauthorized: 'hide',
  }}
/>

Disable when cannot edit

<TextField
  name="status"
  access={{
    resource: 'user.status',
    action: 'update',
    onUnauthorized: 'disable',
  }}
/>

Readonly for view-only

<TextField
  name="email"
  access={{
    resource: 'user.email',
    action: 'update',
    onUnauthorized: 'readonly',
  }}
/>

Combined with visibleWhen

<TextField
  name="other"
  visibleWhen={(engine) =>
    engine.getNode('category')?.value === 'other'
  }
  access={{
    resource: 'form.other',
    action: 'read',
    onUnauthorized: 'hide',
  }}
/>

Note: When combining visibleWhen with RBAC, both conditions must be satisfied. The field shows only if UI logic returns true AND the user has required permissions.


Form Integration

Real-world scenarios with React Hook Form and dynamic visibility

Live scenarios showing DashForm integration and reactive visibility in real form contexts.

React Hook Form Integration

Try it: Type in the fields and submit the form

TextField integrates seamlessly with React Hook Form through DashForm. Fields self-register, errors display after blur, and validation follows RHF patterns. Try submitting with empty fields or invalid email.

Live Preview
import { DashForm } from '@dashforge/forms';
import { TextField } from '@dashforge/ui';

function RegistrationForm() {
  const handleSubmit = (data: FormData) => {
    console.log('Submitted:', data);
  };

  return (
    <DashForm
      defaultValues={{ firstName: '', email: '' }}
      onSubmit={handleSubmit}
      mode="onBlur"
    >
      <TextField
        name="firstName"
        label="First Name"
        rules={{ required: 'Name is required' }}
      />
      <TextField
        name="email"
        label="Email"
        rules={{
          required: 'Email is required',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
            message: 'Invalid email address'
          }
        }}
      />
      <button type="submit">Submit</button>
    </DashForm>
  );
}

// TextField automatically:
// - Registers with React Hook Form
// - Syncs value from form state
// - Displays validation errors when touched
// - Tracks dirty/touched state

Why it matters

Drop TextField into existing form architectures without rewriting validation or state management.

Reactive Conditional Visibility

Try it: Select a contact method and watch fields appear

TextField supports conditional rendering through visibleWhen. Fields render based on engine state—query field values and make rendering decisions. Select "Email" or "Phone" to see conditional fields appear without manual state orchestration.

Live Preview
import { DashForm } from '@dashforge/forms';
import { TextField, Select } from '@dashforge/ui';

function ContactForm() {
  return (
    <DashForm defaultValues={{ contactMethod: '', phone: '', email: '' }}>
      <Select
        name="contactMethod"
        label="Preferred Contact Method"
        options={[
          { label: 'Email', value: 'email' },
          { label: 'Phone', value: 'phone' }
        ]}
      />

      {/* Email field: renders only when email is selected */}
      <TextField
        name="email"
        label="Email Address"
        rules={{ required: 'Email is required' }}
        visibleWhen={(engine) => {
          const node = engine.getNode('contactMethod');
          return node?.value === 'email';
        }}
      />

      {/* Phone field: renders only when phone is selected */}
      <TextField
        name="phone"
        label="Phone Number"
        rules={{ required: 'Phone is required' }}
        visibleWhen={(engine) => {
          const node = engine.getNode('contactMethod');
          return node?.value === 'phone';
        }}
      />
    </DashForm>
  );
}

// The Engine API provides:
// - getNode(name): Access any field's state
// - Component re-renders on dependency changes
// - Component makes rendering decision (engine provides state)

Why it matters

Build adaptive forms where field visibility responds to user input. Define the predicate—the component handles rendering.


API Reference

Complete props and type definitions

Explicit vs Auto-Bound Props: When inside DashForm, TextField receives value, error, helperText, onChange, and onBlur automatically through field binding. Explicit props always take precedence over form-provided values.

PropTypeDefaultDescription
namestring-Field name for form integration (required)
labelstring-Label text displayed above the input
valuestring-Controlled value of the input
onChange(event) => void-Callback fired when the value changes
errorbooleanfalseIf true, displays error state. Explicit error prop overrides form-provided error state. When inside DashForm without explicit prop, error is gated (shows only when touched OR submitted).
helperTextstring-Helper text displayed below input. Explicit helperText prop overrides form-provided validation error message. When inside DashForm, validation errors display as helperText (gated by touched/submitted state).
disabledbooleanfalseIf true, the input is disabled
fullWidthbooleanfalseIf true, the input takes up the full width of its container
multilinebooleanfalseIf true, the input becomes a textarea
rowsnumber-Number of rows to display when multiline is true
layout'floating' | 'stacked' | 'inline''floating'Field layout mode. floating: standard MUI floating label (internal). stacked: external label above control. inline: external label to left of control. Layout is architectural, not just styling.
rulesValidationRules-Validation rules for DashForm integration. Format follows React Hook Form rules contract. Only used when inside DashForm—ignored in standalone mode.
visibleWhen(engine: Engine) => boolean-Component-level conditional rendering predicate. Receives engine instance with access to all field state via getNode(name). When false, component renders null. Re-evaluates on dependency changes. Only works inside DashForm (requires engine).

Under the hood

How TextField behaves and why it works this way

Form integration

Automatically binds to form state inside DashForm. No Controller, no manual wiring. Works as a standard MUI TextField when used standalone.

Behavior model

Errors appear only after blur or submit. Fields can react to form state using visibleWhen. No manual orchestration required.

Architecture

Built on top of MUI TextField. Fully typed with TypeScript. Designed as a foundation for composed form behaviors.


On This Page