Interactive demo of text input fields
/**
* 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 inputemail- Email input with built-in validationtel- 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
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'text' | 'email' | 'tel' | - | Input type (required) |
label | string | - | Label shown above the input |
placeholder | string | - | Placeholder text |
hideLabel | boolean | false | Hide the label visually |
helperText | string | - | Help text shown below input |
tooltip | string | - | Tooltip text for additional info |
icon | ReactNode | - | Icon element to display |
size | 'sm' | 'md' | 'lg' | 'md' | Input size variant |
disabled | boolean | function | ConditionGroup | false | Disable the input |
hidden | boolean | function | ConditionGroup | Responsive | false | Hide the field |
readOnly | boolean | function | ConditionGroup | false | Make input read-only |
columns | Partial<Record<Breakpoint, number>> | - | Grid columns by breakpoint |
autocomplete | string | - | 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-invalidfor validation states aria-describedbylinks to helper text and error messages