/**
* `useFormField` — Single source of truth for the ARIA wiring that every
* Form primitive duplicates: error/helper id derivation, `aria-describedby`,
* `aria-invalid`, and the mutually-exclusive error-over-helper convention.
*
* Layout (label position, error/helper placement, required marker) stays
* component-specific because real Form primitives differ in shape — Input
* stacks the label on top, Checkbox/Toggle put it inline, RadioGroup and
* SegmentGroup have a group caption + per-item labels. The hook does not
* touch markup; it just exposes the IDs and the `invalid` boolean.
*
* **`fieldId` must be supplied by the caller** because Svelte's
* `$props.id()` rune is only valid at component top-level — the caller
* computes it once with `$props.id()` and threads it through here. That
* keeps the hook itself usable from any context (test runs, non-Svelte
* code, future refactors) without inheriting the rune placement rules.
*
* The pure `computeFormFieldAria` helper carries the logic and is
* directly unit-tested. `useFormField` is a one-line reactive wrapper
* around it that re-evaluates on every prop change via `$derived`.
*
* @example
* ```svelte
*
*
*
*
* {#if ff.errorId}
{error}
{/if}
* ```
*/
export interface UseFormFieldInputs {
/** The DOM id to apply to the field element. Compute once in the caller via `$props.id()`. */
fieldId: string;
/** Helper text shown below the field when no error is set. */
helper?: string;
/** Error message — when truthy, replaces `helper` and flags the field invalid. */
error?: string;
/** Required flag — exposed verbatim for the caller's label markup. */
required?: boolean;
/** Disabled flag — exposed verbatim. */
disabled?: boolean;
}
export interface UseFormFieldReturn {
/** Stable id to apply to the field's interactive element + its `