svelte5-form
v0.0.3
Published
Svelte 5 form library
Readme
Svelte 5 Form Lib
A lightweight, type-safe form library for Svelte 5 using runes and snippets.
Features
- ✨ Built for Svelte 5 with runes
- 🎯 Type-safe form state management
- 🔄 Nested object and array support
- ✅ Built-in validation with visual feedback
- 🎨 Fully customizable styling
- 📦 Zero dependencies (except Svelte)
Installation
npm install svelte5-formQuick Start
<script lang="ts">
import { Form, Input, Select, Textarea } from 'svelte5-form';
let formData = $state({
name: '',
email: '',
role: '',
bio: ''
});
function handleSubmit(data) {
console.log('Form submitted:', data);
}
</script>
<Form
bind:defaultData={formData}
onSubmit={handleSubmit}
requiredProps={['name', 'email']}
submitText="Submit"
>
<Input
label="Name"
name="name"
placeholder="Enter your name"
/>
<Input
label="Email"
name="email"
type="email"
placeholder="[email protected]"
/>
<Select
label="Role"
name="role"
options={[
{ value: 'developer', label: 'Developer' },
{ value: 'designer', label: 'Designer' }
]}
/>
<Textarea
label="Bio"
name="bio"
placeholder="Tell us about yourself"
/>
</Form>Components
Form
Main form wrapper component.
Props:
defaultData(bindable) - Form data objectonSubmit- Submit handler functionrequiredProps- Array of required field names (optional)submitText- Submit button text (default: "Submit")submitClass- Custom submit button classesclass- Custom form classesloading- Show loading state (optional)schema- Validation schema (optional)
Input
Text input component with label support.
Props:
name- Field path (supports nested: "user.name" or "items[0].title")label- Input labeltype- Input type (default: "text")placeholder- Placeholder textclass- Custom input classeslabelClass- Custom label classesrequired- Show required indicator
Example:
<Input
label="First Name"
name="firstName"
placeholder="John"
required
/>
<!-- Nested object -->
<Input
label="Street Address"
name="address.street"
/>
<!-- Array item -->
<Input
label="First Item"
name="items[0].name"
/>Select
Dropdown select component.
Props:
name- Field pathlabel- Select labeloptions- Array of{ value, label }objectsplaceholder- Placeholder option textclass- Custom select classeslabelClass- Custom label classesrequired- Show required indicator
Example:
<Select
label="Country"
name="country"
placeholder="Select a country"
options={[
{ value: 'us', label: 'United States' },
{ value: 'uk', label: 'United Kingdom' },
{ value: 'ca', label: 'Canada' }
]}
required
/>Textarea
Multi-line text input component.
Props:
name- Field pathlabel- Textarea labelplaceholder- Placeholder textrows- Number of rows (default: 4)class- Custom textarea classeslabelClass- Custom label classesrequired- Show required indicator
Example:
<Textarea
label="Description"
name="description"
placeholder="Enter a description..."
rows={6}
/>Checkbox
Checkbox input component.
Props:
name- Field pathlabel- Checkbox labelclass- Custom checkbox classeslabelClass- Custom label classes
Example:
<Checkbox
label="Accept terms and conditions"
name="acceptTerms"
/>Advanced Usage
Nested Objects and Arrays
The library supports deep nested paths using dot notation and array indices:
<script>
let formData = $state({
user: {
profile: {
name: '',
email: ''
}
},
hobbies: ['', '']
});
</script>
<Form bind:defaultData={formData} onSubmit={handleSubmit}>
<Input name="user.profile.name" label="Name" />
<Input name="user.profile.email" label="Email" />
<Input name="hobbies[0]" label="First Hobby" />
<Input name="hobbies[1]" label="Second Hobby" />
</Form>Custom Validation
<script>
function handleSubmit(data) {
// Custom validation
if (data.password !== data.confirmPassword) {
alert('Passwords do not match');
return;
}
// Submit to API
fetch('/api/register', {
method: 'POST',
body: JSON.stringify(data)
});
}
</script>
<Form
bind:defaultData={formData}
onSubmit={handleSubmit}
requiredProps={['email', 'password', 'confirmPassword']}
>
<!-- form fields -->
</Form>Loading State
<script>
let isSubmitting = $state(false);
async function handleSubmit(data) {
isSubmitting = true;
try {
await api.post('/submit', data);
} finally {
isSubmitting = false;
}
}
</script>
<Form
bind:defaultData={formData}
onSubmit={handleSubmit}
loading={isSubmitting}
>
<!-- form fields -->
</Form>Custom Styling
<Form
bind:defaultData={formData}
onSubmit={handleSubmit}
class="max-w-2xl mx-auto p-6"
submitClass="bg-blue-500 hover:bg-blue-600 text-white px-6 py-3"
submitText="Create Account"
>
<Input
name="username"
label="Username"
class="border-2 border-gray-300 rounded-lg p-3"
labelClass="text-sm font-semibold text-gray-700"
/>
</Form>API Reference
Store Functions
import { getForm, setForm } from 'svelte5-form-manager';
// Get a value from the form
const value = getForm('user.email');
// Set a value in the form
setForm('user.email', '[email protected]');TypeScript Support
Full TypeScript support with type definitions included:
import type { FormData, FormProps } from 'svelte5-form';
interface MyFormData {
name: string;
email: string;
age: number;
}
let formData = $state({
name: '',
email: '',
age: 0
});License
MIT
