Interactive demo of input group field
/**
* Input Group Field Demo - Interactive examples of input group fields
*/
import { Form, FormBuilder } from '@saastro/forms';
import { FormProvider } from '@/components/FormProvider';
import { TooltipProvider } from '@/components/ui/tooltip';
const config = FormBuilder.create('input-group-demo')
.layout('manual')
.columns(12)
.addField('price', (f) =>
f
.type('input-group')
.label('Price')
.placeholder('0.00')
.helperText('Enter the price in USD')
.required('Price is required')
.columns({ default: 12, md: 6 }),
)
.addField('weight', (f) =>
f
.type('input-group')
.label('Weight')
.placeholder('0')
.helperText('Enter weight in kilograms')
.required()
.columns({ default: 12, md: 6 }),
)
.addField('website', (f) =>
f
.type('input-group')
.label('Website')
.placeholder('yoursite')
.helperText('Enter your website domain')
.optional()
.columns({ default: 12 }),
)
.addStep('main', ['price', 'weight', 'website'])
.build();
export default function InputGroupDemo() {
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 input group field extends the standard text input with prefix and suffix elements. Use it for formatted inputs like currency, URLs, or measurements.
Usage
With Prefix
import { FormBuilder } from '@saastro/forms';
const config = FormBuilder.create('form')
.addField('price', (f) =>
f
.type('input-group')
.label('Price')
.placeholder('0.00')
// Configure prefix via component props
.required('Price is required'),
)
.addStep('main', ['price'])
.build();
With Suffix
.addField('weight', (f) =>
f.type('input-group')
.label('Weight')
.placeholder('0')
// Configure suffix via component props
.required()
)
With Both
.addField('website', (f) =>
f.type('input-group')
.label('Website')
.placeholder('example')
// Configure both prefix and suffix
.optional()
)
JSON Configuration
{
"type": "input-group",
"label": "Price",
"placeholder": "0.00",
"prefix": "$",
"schema": { "required": true }
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'input-group' | - | Field type (required) |
label | string | - | Label text |
placeholder | string | - | Placeholder text |
helperText | string | - | Help text below field |
prefix | string | ReactNode | - | Prefix element (configured via registry) |
suffix | string | ReactNode | - | Suffix element (configured via registry) |
size | 'sm' | 'md' | 'lg' | 'md' | Input size variant |
columns | Partial<Record<Breakpoint, number>> | - | Grid columns by breakpoint |
disabled | boolean | function | ConditionGroup | false | Disable the field |
hidden | boolean | function | ConditionGroup | Responsive | false | Hide the field |
Common Patterns
Currency Input
.addField('amount', (f) =>
f.type('input-group')
.label('Amount')
.placeholder('0.00')
// Prefix: $ configured in registry
)
URL Input
.addField('domain', (f) =>
f.type('input-group')
.label('Domain')
.placeholder('yoursite')
// Prefix: https:// Suffix: .com
)
Percentage Input
.addField('discount', (f) =>
f.type('input-group')
.label('Discount')
.placeholder('0')
// Suffix: %
)
Validation
Required with Number Validation
.addField('price', (f) =>
f.type('input-group')
.label('Price')
.required('Price is required')
.numberRange(0, 10000)
)
Styling
Custom Classes
.addField('price', (f) =>
f.type('input-group')
.label('Price')
.placeholder('0.00')
.required()
.classNames({
wrapper: 'bg-muted/30 p-4 rounded-lg',
input: 'border-2 border-primary/20 font-mono',
label: 'text-lg font-semibold',
error: 'text-destructive text-sm',
})
)
Size Variants
.addField('amount', (f) =>
f.type('input-group')
.label('Amount')
.size('lg')
)
Responsive Layout
.addField('price', (f) =>
f.type('input-group')
.label('Price')
.columns({ default: 12, md: 4 })
)
JSON Styling
{
"type": "input-group",
"label": "Price",
"prefix": "$",
"wrapper_className": "bg-muted/30 p-4 rounded-lg",
"input_className": "border-2 border-primary/20 font-mono",
"label_className": "text-lg font-semibold",
"size": "lg",
"columns": { "default": 12, "md": 4 }
}
Related Fields
Accessibility
- Prefix/suffix are decorative, not read separately
- Main input retains full accessibility
- Proper labeling maintained