Overview
Text input elements capture user-entered text and numbers. Choose the right type based on what you’re collecting—each type provides appropriate validation and UI.
| Element | Best For | Validation |
|---|
text | Short text (names, titles) | Length, pattern |
textarea | Long text (descriptions) | Length |
url | Web addresses | URL format |
password | Sensitive data (API keys) | Length, pattern |
number | Numeric values | Min/max |
Text Input
Single-line text input for short text like usernames, titles, or labels.
Properties
| Property | Type | Description |
|---|
id | string | Unique identifier (becomes prop name) |
inputType | 'text' | Must be 'text' |
title | string | Field title |
description | string | Help text |
label | string | Input label |
placeholder | string | Placeholder text |
defaultValue | string | Initial value |
validation | object | Validation rules |
Validation
| Rule | Type | Description |
|---|
required | boolean | Field must not be empty |
minLength | number | Minimum characters |
maxLength | number | Maximum characters |
pattern | string | Regex pattern to match |
Example
{
id: "username",
inputType: "text",
title: "Username",
description: "Your display name",
label: "Username",
placeholder: "johndoe",
defaultValue: "",
validation: {
required: true,
minLength: 3,
maxLength: 20,
pattern: "^[a-zA-Z0-9_]+$" // Alphanumeric and underscores
}
}
Usage in Layout
type Settings = {
username: string;
};
export default function ClassicLayout({ username }: AppProps<Settings>) {
return <div>Welcome, {username}!</div>;
}
Common Patterns
Display name:
{
id: "displayName",
inputType: "text",
title: "Display Name",
label: "Name",
placeholder: "John Doe",
validation: { required: true, maxLength: 50 }
}
Title or heading:
{
id: "title",
inputType: "text",
title: "LinkApp Title",
label: "Title",
placeholder: "Enter a title",
defaultValue: "My LinkApp",
validation: { maxLength: 100 }
}
Custom label:
{
id: "buttonText",
inputType: "text",
title: "Button Text",
label: "Text",
placeholder: "Click me",
defaultValue: "Learn More",
validation: { required: true, maxLength: 30 }
}
Textarea
Multi-line text input for longer content like descriptions or messages.
Properties
| Property | Type | Description |
|---|
id | string | Unique identifier |
inputType | 'textarea' | Must be 'textarea' |
title | string | Field title |
description | string | Help text |
label | string | Input label |
placeholder | string | Placeholder text |
defaultValue | string | Initial value |
validation | object | Validation rules |
Validation
| Rule | Type | Description |
|---|
required | boolean | Field must not be empty |
minLength | number | Minimum characters |
maxLength | number | Maximum characters |
Example
{
id: "bio",
inputType: "textarea",
title: "Bio",
description: "Tell users about yourself",
label: "Your bio",
placeholder: "I'm a creator who...",
defaultValue: "",
validation: {
maxLength: 500
}
}
Usage in Layout
type Settings = {
bio: string;
};
export default function ClassicLayout({ bio }: AppProps<Settings>) {
return (
<div>
<p className="bio">{bio}</p>
</div>
);
}
Common Patterns
Description field:
{
id: "description",
inputType: "textarea",
title: "Description",
label: "Describe your app",
placeholder: "This app helps you...",
validation: { required: true, maxLength: 300 }
}
Custom message:
{
id: "welcomeMessage",
inputType: "textarea",
title: "Welcome Message",
label: "Message",
placeholder: "Welcome! Here's what you need to know...",
validation: { maxLength: 1000 }
}
URL input with built-in validation to ensure valid HTTP/HTTPS addresses.
Properties
| Property | Type | Description |
|---|
id | string | Unique identifier |
inputType | 'url' | Must be 'url' |
title | string | Field title |
description | string | Help text |
label | string | Input label |
placeholder | string | Placeholder URL |
defaultValue | string | Initial URL |
validation | object | Validation rules |
Validation
| Rule | Type | Description |
|---|
required | boolean | Field must not be empty |
pattern | string | Additional regex pattern |
URL inputs automatically validate that the value starts with http:// or
https://. Use pattern for additional constraints like requiring HTTPS.
Example
{
id: "websiteUrl",
inputType: "url",
title: "Website URL",
description: "Your website address",
label: "Website",
placeholder: "https://example.com",
defaultValue: "",
validation: {
required: true,
pattern: "^https://.*" // Require HTTPS
}
}
Usage in Layout
type Settings = {
websiteUrl: string;
};
export default function ClassicLayout({ websiteUrl }: AppProps<Settings>) {
return (
<a href={websiteUrl} target="_blank" rel="noopener">
Visit Website
</a>
);
}
Common Patterns
External link:
{
id: "externalUrl",
inputType: "url",
title: "External Link",
label: "URL",
placeholder: "https://example.com",
validation: { required: true }
}
API endpoint:
{
id: "apiEndpoint",
inputType: "url",
title: "API Endpoint",
description: "Your API base URL",
label: "Endpoint",
placeholder: "https://api.example.com",
validation: { required: true, pattern: "^https://.*" }
}
Masked input for sensitive data like API keys or credentials.
Properties
| Property | Type | Description |
|---|
id | string | Unique identifier |
inputType | 'password' | Must be 'password' |
title | string | Field title |
description | string | Help text |
label | string | Input label |
placeholder | string | Placeholder text |
defaultValue | string | Initial value (masked) |
validation | object | Validation rules |
Validation
| Rule | Type | Description |
|---|
required | boolean | Field must not be empty |
minLength | number | Minimum characters |
maxLength | number | Maximum characters |
pattern | string | Regex pattern |
Values are masked in the UI but transmitted as plain text to your layout.
Always handle sensitive data securely.
Example
{
id: "apiKey",
inputType: "password",
title: "API Key",
description: "Get your API key from settings.example.com",
label: "API Key",
placeholder: "Enter your API key",
validation: {
required: true,
minLength: 20,
pattern: "^[a-zA-Z0-9]+$"
}
}
Usage in Layout
type Settings = {
apiKey: string;
};
export default function ClassicLayout({ apiKey }: AppProps<Settings>) {
// Use API key to fetch data
useEffect(() => {
fetch("https://api.example.com/data", {
headers: { Authorization: `Bearer ${apiKey}` },
});
}, [apiKey]);
return <div>Loading data...</div>;
}
Common Patterns
API key:
{
id: "apiKey",
inputType: "password",
title: "API Key",
description: "Your secret API key",
label: "Key",
validation: { required: true, minLength: 16 }
}
Secret token:
{
id: "secretToken",
inputType: "password",
title: "Secret Token",
label: "Token",
placeholder: "Enter your secret token",
validation: { required: true }
}
Numeric input with min/max validation.
Properties
| Property | Type | Description |
|---|
id | string | Unique identifier |
inputType | 'number' | Must be 'number' |
title | string | Field title |
description | string | Help text |
label | string | Input label |
placeholder | number | string | Placeholder value |
defaultValue | number | Initial value |
validation | object | Validation rules |
Validation
| Rule | Type | Description |
|---|
required | boolean | Field must not be empty |
min | number | Minimum value (inclusive) |
max | number | Maximum value (inclusive) |
Example
{
id: "itemCount",
inputType: "number",
title: "Number of Items",
description: "How many items to display",
label: "Count",
placeholder: 10,
defaultValue: 5,
validation: {
required: true,
min: 1,
max: 100
}
}
Usage in Layout
type Settings = {
itemCount: number;
};
export default function ClassicLayout({ itemCount }: AppProps<Settings>) {
return (
<div>
Showing {itemCount} items
{Array.from({ length: itemCount }).map((_, i) => (
<div key={i}>Item {i + 1}</div>
))}
</div>
);
}
Common Patterns
Item limit:
{
id: "maxItems",
inputType: "number",
title: "Maximum Items",
label: "Max",
defaultValue: 10,
validation: { min: 1, max: 50 }
}
Timeout/duration:
{
id: "timeoutSeconds",
inputType: "number",
title: "Timeout",
description: "Timeout in seconds",
label: "Seconds",
defaultValue: 30,
validation: { min: 5, max: 300 }
}
Percentage:
{
id: "opacity",
inputType: "number",
title: "Opacity",
description: "Opacity percentage (0-100)",
label: "Opacity %",
defaultValue: 100,
validation: { min: 0, max: 100 }
}
Complete Example
Here’s a contact form using multiple text input types:
export default {
settings: {
title: "Contact Form",
elements: [
{
id: "formTitle",
inputType: "text",
title: "Form Title",
label: "Title",
defaultValue: "Get in Touch",
validation: { required: true, maxLength: 50 },
},
{
id: "description",
inputType: "textarea",
title: "Form Description",
label: "Description",
placeholder: "We'd love to hear from you...",
validation: { maxLength: 200 },
},
{
id: "submitUrl",
inputType: "url",
title: "Submit URL",
description: "Where form submissions are sent",
label: "Endpoint",
validation: { required: true, pattern: "^https://.*" },
},
{
id: "apiKey",
inputType: "password",
title: "API Key",
description: "Your form service API key",
label: "Key",
validation: { required: true, minLength: 20 },
},
{
id: "maxSubmissions",
inputType: "number",
title: "Submission Limit",
description: "Maximum submissions per user",
label: "Max",
defaultValue: 1,
validation: { min: 1, max: 10 },
},
],
},
};
Validation Error Messages
When validation fails, users see helpful messages:
| Rule | Example Error |
|---|
required: true | ”This field is required” |
minLength: 3 | ”Must be at least 3 characters” |
maxLength: 100 | ”Must be at most 100 characters” |
min: 1 | ”Must be at least 1” |
max: 100 | ”Must be at most 100” |
pattern: '^[a-z]+$' | ”Invalid format” |
Add clear description text to help users understand what’s expected and
avoid validation errors.
Next Steps