useFormFieldEmit
A helper hook for custom input components that want to participate in <Form> validation timing. Returns four emitters
(onBlur, onFocus, onInput, onChange) that push their corresponding events up to the parent Form so it can run validation, track dirty/touched/blurred state, and trigger error UI.
Basic Usage
Call the hook at component setup, then wire each emitter onto the matching native event.
Try focusing in/out — validation events flow to the Form
<script lang="ts">
import { useFormFieldEmit } from 'sv5ui';
// Each method is a safe no-op outside a Form — wire them unconditionally.
const emit = useFormFieldEmit();
</script>
<!-- Hook the four emitters into the input's native events. -->
<input
type="text"
onblur={emit.onBlur}
onfocus={emit.onFocus}
oninput={emit.onInput}
onchange={emit.onChange}
/>Pair with useFormField
The two hooks compose: useFormField() reads context (name, ariaId, error, size); useFormFieldEmit() writes events back.
<!-- useFormField → read context (name, ariaId, error, size)
useFormFieldEmit → write events back to the parent Form -->
<script lang="ts">
import { useFormField, useFormFieldEmit } from 'sv5ui';
const formField = useFormField(); // READ
const emit = useFormFieldEmit(); // WRITE
</script>
<input
id={formField?.ariaId}
aria-invalid={!!formField?.error || undefined}
onblur={emit.onBlur}
oninput={emit.onInput}
onchange={emit.onChange}
onfocus={emit.onFocus}
/>Building a Custom Input
A complete custom input — pulls the FormField's ariaId and name from context, emits all four events to the parent Form.
No live demo — this snippet is a template for building your own input.
When dropped inside <Form> + <FormField>, it participates in validation just like the built-in <Input>.
<script lang="ts">
// Build your own input that integrates with Form validation.
import { useFormField, useFormFieldEmit } from 'sv5ui';
let { value = $bindable() }: { value?: string } = $props();
const formField = useFormField();
const emit = useFormFieldEmit();
</script>
<input
bind:value
id={formField?.ariaId}
name={formField?.name}
aria-invalid={!!formField?.error || undefined}
onblur={emit.onBlur}
onfocus={emit.onFocus}
oninput={emit.onInput}
onchange={emit.onChange}
class="rounded border px-3 py-1.5"
/>Safe Outside a Form
When there's no parent Form, every emitter is a no-op. You can reuse the same component everywhere without checking the context.
Useful when shipping reusable inputs that may be dropped into Form-driven flows OR ad-hoc layouts.
<script lang="ts">
// Same component used INSIDE a Form/FormField AND outside it.
// useFormFieldEmit() returns no-op functions when there's no Form
// context — no errors, no special handling needed.
import { useFormFieldEmit } from 'sv5ui';
const emit = useFormFieldEmit();
</script>
<input onblur={emit.onBlur} oninput={emit.onInput} />Return Value
An object with four void-returning methods. Each fires its event on the parent Form, or no-ops if there is none.
| Method | Type |
|---|---|
onBlur | () => void |
onFocus | () => void |
onInput | () => void |
onChange | () => void |