Skip to content

$field()

$field is a composable for managing individual form field state and behavior. It provides type-safe validation, reactive state management, and automatic integration with forms.

Creates and manages a single input field that can be bound to a form. Handles validation, error messages, and value storage with full TypeScript support.

✅ Signature

ts
$field<FormName, InputName>(formName: FormName, inputName: InputName): {
  state: Ref<ArkInputState<FormSchema, InputName>>
  errors: Ref<string[]>
  messages: Ref<string[]>
  readonly: ComputedRef<boolean>
  input: ComputedRef<InputType | null>
  validate(): Result<InputType>
  set(data: InputType): Result<InputType>
  clear(fields?: ("input" | "errors" | "messages")[]): void
}

📥 Parameters

NameTypeDescription
formNamestringThe form this field belongs to. Must match a form defined in defineArkform
inputNamestringField identifier that must exist in the form's schema

🧠 Internal State

Each field uses useState to persist data with the key:

ts
arkform:input:${formName}:${inputName}

The state contains:

  • id: Unique field ID
  • name: Field name (same as inputName)
  • formName: Parent form name
  • input: Current field value (typed based on schema)
  • mode: Field state - "idle" | "error" | "success"
  • readonly: Whether the field is read-only

🧩 Returned API

state: Ref<ArkInputState>

Full reactive state object for the field.

errors: Ref<string[]>

Validation error messages from Arktype validation.

messages: Ref<string[]>

Success or informational messages.

readonly: ComputedRef<boolean>

Whether the field is in read-only mode.

input: ComputedRef<InputType | null>

The field's current value, strongly typed based on the schema.

validate(): Result<InputType>

Validates the current field value against its schema. Returns:

  • ok(value) if validation passes
  • err(errorMessage) if validation fails

Uses the field's schema defined in defineArkform for validation.

set(data: InputType): Result<InputType>

Sets the field value with type checking:

  • Accepts string | number | boolean | null
  • Rejects NaN, arrays, objects, functions, etc.
  • Returns Result indicating success/failure

clear(fields?: ("input" | "errors" | "messages")[])

Clears specified field state:

  • "input" → Resets value to null
  • "errors" → Clears error array
  • "messages" → Clears message array

Default: clears all three.

🔁 Usage Example

ts
// Define your forms first
const { $form, $field } = defineArkform({
  login: {
    schema: arktype({
      email: "string.email",
      password: "string"
    })
  }
})

// Use the field
const emailField = $field("login", "email")

// Set value
emailField.set("user@example.com")

// Validate
const result = emailField.validate()
if (result.ok) {
  console.log("Valid email:", result.data)
} else {
  console.log("Validation error:", result.message)
}

// Clear field
emailField.clear()

Component Integration

Fields automatically integrate with the <field> component:

vue
<template>
  <arkform name="login">
    <!-- This automatically binds to $field("login", "email") -->
    <field name="email" placeholder="Enter email" />
    <field name="password" is="textarea" rows="4" />
  </arkform>
</template>

🧠 Notes

  • Fields are automatically registered with their parent form when accessed
  • The <field> component provides the UI layer and automatically calls $field internally
  • Type safety is enforced - you can only reference fields that exist in your schema
  • Field state persists across component remounts and HMR