S
Text Field

Text Input

A basic text input field for single-line text entry. Supports text, email, and tel input types.

stable
input text email tel form

Interactive demo of text input fields

Your name as it appears on official documents

We'll never share your email

Optional - for urgent matters only

/**
 * Text Field Demo - Interactive example of text input fields
 */

import { Form, FormBuilder } from '@saastro/forms';

import { FormProvider } from '@/components/FormProvider';
import { TooltipProvider } from '@/components/ui/tooltip';

const config = FormBuilder.create('text-demo')
  .layout('manual')
  .columns(12)
  .addField('name', (f) =>
    f
      .type('text')
      .label('Your Name')
      .placeholder('Enter your full name')
      .helperText('Your name as it appears on official documents')
      .required('Name is required')
      .minLength(2, 'Name must be at least 2 characters')
      .columns({ default: 12, md: 6 }),
  )
  .addField('email', (f) =>
    f
      .type('email')
      .label('Email Address')
      .placeholder('you@example.com')
      .helperText("We'll never share your email")
      .required('Email is required')
      .email('Please enter a valid email address')
      .columns({ default: 12, md: 6 }),
  )
  .addField('phone', (f) =>
    f
      .type('tel')
      .label('Phone Number')
      .placeholder('+1 (555) 123-4567')
      .helperText('Optional - for urgent matters only')
      .optional()
      .columns({ default: 12 }),
  )
  .addStep('main', ['name', 'email', 'phone'])
  .build();

export default function TextDemo() {
  const handleSubmit = (data: Record<string, unknown>) => {
    console.log('Form submitted:', data);
    alert('Form submitted! Check console for data.');
  };

  return (
    <TooltipProvider>
      <FormProvider>
        <Form config={config} onSubmit={handleSubmit} className="space-y-4" />
      </FormProvider>
    </TooltipProvider>
  );
}

Overview

The text field type is the most basic input field in @saastro/forms. It supports three input types:

  • text - Standard text input
  • email - Email input with built-in validation
  • tel - Telephone number input

Usage

JSON Configuration

{
  "type": "text",
  "label": "Your Name",
  "placeholder": "Enter your name",
  "schema": {
    "required": true,
    "minLength": 2
  }
}

FormBuilder API

import { FormBuilder } from '@saastro/forms';

const config = FormBuilder.create('contact-form')
  .addField('name', (f) =>
    f
      .type('text')
      .label('Your Name')
      .placeholder('Enter your name')
      .required('Name is required')
      .minLength(2, 'Name must be at least 2 characters'),
  )
  .addStep('main', ['name'])
  .build();

Email Type

Use type: 'email' for email fields with automatic format validation:

.addField('email', (f) =>
  f.type('email')
    .label('Email Address')
    .placeholder('you@example.com')
    .required()
    .email('Please enter a valid email')
)

Tel Type

Use type: 'tel' for phone number inputs:

.addField('phone', (f) =>
  f.type('tel')
    .label('Phone Number')
    .placeholder('+1 (555) 123-4567')
    .required()
)

Props

PropTypeDefaultDescription
type'text' | 'email' | 'tel'-Input type (required)
labelstring-Label shown above the input
placeholderstring-Placeholder text
hideLabelbooleanfalseHide the label visually
helperTextstring-Help text shown below input
tooltipstring-Tooltip text for additional info
iconReactNode-Icon element to display
size'sm' | 'md' | 'lg''md'Input size variant
disabledboolean | function | ConditionGroupfalseDisable the input
hiddenboolean | function | ConditionGroup | ResponsivefalseHide the field
readOnlyboolean | function | ConditionGroupfalseMake input read-only
columnsPartial<Record<Breakpoint, number>>-Grid columns by breakpoint
autocompletestring-HTML autocomplete attribute

Validation

Declarative (JSON-serializable)

{
  "schema": {
    "required": true,
    "requiredMessage": "This field is required",
    "minLength": 2,
    "minLengthMessage": "Minimum 2 characters",
    "maxLength": 100,
    "pattern": "^[a-zA-Z]+$",
    "patternMessage": "Only letters allowed"
  }
}

Zod Schema

import { z } from 'zod';

.addField('name', (f) =>
  f.type('text')
    .label('Name')
    .schema(z.string().min(2).max(100))
)

Fluent Validation API

.addField('name', (f) =>
  f.type('text')
    .label('Name')
    .required('Name is required')
    .minLength(2, 'Too short')
    .maxLengthValidation(100, 'Too long')
)

Styling

Custom Classes

.addField('name', (f) =>
  f.type('text')
    .label('Name')
    .classNames({
      wrapper: 'col-span-6',
      input: 'border-blue-500',
      label: 'text-blue-700',
      error: 'text-red-600',
    })
)

Responsive Layout

.addField('name', (f) =>
  f.type('text')
    .label('Name')
    .columns({ default: 12, md: 6, lg: 4 })
)

Accessibility

  • Uses native <input> element for built-in accessibility
  • Automatically associates label with input via htmlFor
  • Error messages are announced to screen readers
  • Supports aria-invalid for validation states
  • aria-describedby links to helper text and error messages