Skip to main content

Control

Associates a label with and provides necessary attributes for a form control.

In the context of a form, a control refers to any interactive element such as an input field, a select dropdown, or a button. This includes custom components like select dropdowns or checkboxes that function as buttons but still serve as form inputs, typically activated by clicking on a label or pressing a key.

Each control and its label should be wrapped in its own Control component. This is important for accessibility, as it ensures that the label is associated with the control, and that the label is announced to screen readers when the control receives focus.

The Control component doesn't render an element itself, it strictly provides context and attributes for the control via a snippet prop and state for the Label.

Usage

+page.svelte
		<Control>
	{#snippet children({ props })}
		<input type="text" {...props} bind:value={$formData.name} />
	{/snippet}
</Control>
	

API Reference

Props

id
type: string

Optionally provide a unique id for the form item/control. If not provided, a unique ID will be generated for you.

This is useful when another library automatically generates IDs for form items. You can pass that ID to the id prop and the label will be associated with that control.

children
type: Snippet

The children snippet is used to provide attributes for the control element/component.

required

Composition

Since the Control component doesn't render an HTML element, it's a common practice to create a wrapper component around it to have consistent styling and behavior across your forms.

For example, you may want to automatically include the Label for each item, and you want the label and children content to be wrapped in a <div>.

Here's how you might do just that:

CustomControl.svelte
		<script lang="ts">
	import { Control, Label } from "formsnap";
	import type { ComponentProps } from "svelte";
 
	let {
		label,
		// Rename the children prop to childrenProp to avoid
		// conflicts with the Control component
		children: childrenProp,
		...restProps
	}: ComponentProps<typeof Control> & {
		label: string;
	} = $props();
</script>
 
<Control {...restProps}>
	{#snippet children({ props })}
		<div class="flex flex-col gap-2">
			<Label>{label}</Label>
			<!-- Forward the props to the children snippet -->
			{@render childrenProp({ props })}
		</div>
	{/snippet}
</Control>