fill-stateLast updated on
Last updated on
Track form completion progress with FillState
Query the fill state of a DraftForm to determine what's been filled, what's still needed, and what to ask next. FillState evaluates conditional visibility, required expressions, and dependency chains to give an accurate picture of form progress.
Examples
Basic usage
const draft = form.partialFill({
fields: { tenantName: 'John Doe' }
})
const state = draft.getFillState()
state.summary.completionPercent // e.g. 25
state.summary.requiredRemaining // e.g. 3
state.next // { kind: 'party', key: 'tenant', required: true, order: 0 }Progressive fill loop
let draft = form.partialFill()
while (true) {
const state = draft.getFillState()
if (state.summary.requiredRemaining === 0) break
const target = state.next
if (!target) break
const value = await collectValueFromUser(target)
draft = draft.update({
[target.kind === 'party' ? 'parties' : 'fields']: {
[target.key]: value
}
})
}
// All required data collected — fill the form
const filled = form.fill(draft.data)Including optional targets
By default, candidates only includes required targets. Pass includeOptional: true to include optional fields:
const state = draft.getFillState({ includeOptional: true })
// state.candidates now includes both required and optional targets
// Required targets are listed first (requiredFirst defaults to true)Checking blocked items
Items with conditional visibility that depends on unfilled fields appear in blocked:
const state = draft.getFillState()
for (const item of state.blocked) {
console.log(`${item.key} is hidden, waiting on: ${item.blockedBy.join(', ')}`)
}
// e.g. "spouseName is hidden, waiting on: maritalStatus"Checking rules
const state = draft.getFillState()
if (!state.rules.valid) {
for (const error of state.rules.errors) {
console.log(`Rule violation: ${error}`)
}
}API
FillState
Returned by draft.getFillState().
FillStateSummary
FillTarget
A candidate target that can be filled next.
FillItemState
Extended fill target with runtime state. Used in openRequired, openOptional, blocked, and done arrays.
FillTargetKind
type FillTargetKind = 'field' | 'party' | 'annex'FillTargetOptions
Options for getFillState, getNextFillTarget, and getAvailableFillTargets.
PartialFillOptions
Options for partialFill and safePartialFill on FormInstance.
UpdateOptions
Options for update and safeUpdate on DraftForm.
SafePartialFillResult
Returned by safePartialFill and safeUpdate.
type SafePartialFillResult<F extends Form> =
| { success: true; data: DraftForm<F> }
| { success: false; error: Error }FillValidationMode
type FillValidationMode = 'patch' | 'full' | 'none'| Mode | Behavior |
|---|---|
"patch" | Validate only the provided fields (default) |
"full" | Validate entire payload including required fields |
"none" | Skip validation entirely |
How visibility and blocking work
FillState evaluates conditional visible and required expressions on fields, parties, and annexes using the current data. Items are categorized as:
- openRequired — visible, required, not yet filled. These are what the user needs to answer.
- openOptional — visible, optional, not yet filled. Available but not blocking completion.
- blocked — not visible because a dependency hasn't been filled yet. The
blockedByarray shows which field or party needs a value first. Blocked items unblock automatically when their dependencies are filled. - done — already filled, regardless of visibility.
The candidates array contains all open (visible, unfilled) targets in declaration order. When requiredFirst is true (the default), required targets appear before optional ones.