Skip to content
IC Reactor

CandidFormVisitor

CandidFormVisitor generates form metadata from Candid IDL types.

Use it when you already have an IDL.ServiceClass and want low-level metadata for dynamic forms. If you want a higher-level API, use MetadataReactor which uses this visitor internally.

import { CandidFormVisitor } from "@ic-reactor/candid"
import { CandidFormVisitor } from "@ic-reactor/candid"
import { IDL } from "@icp-sdk/core/candid"
const visitor = new CandidFormVisitor()
const service = idlFactory({ IDL })
const serviceMeta = service.accept(visitor, null)
const methodMeta = serviceMeta["icrc1_transfer"]
console.log(methodMeta?.schema) // Zod tuple schema for all args
console.log(methodMeta?.defaults) // default form values
type FormArgumentsMeta = {
candidType: string
functionType: "query" | "update" | "value"
functionName: string
args: FormFieldNode[]
defaults: unknown[]
schema: z.ZodTypeAny
argCount: number
isEmpty: boolean
}

Every FormFieldNode includes:

Property Type Description
type FormFieldType Candid field category
label string Raw field label
displayLabel string Human-readable label
name string Form path
schema z.ZodTypeAny Field-level validation schema
component FormFieldComponentType Suggested renderer component
renderHint FormRenderHint Primitive/compound and input type hints
defaultValue unknown Default value for initialization
candidType string Original Candid type text

Typical component values:

  • record-container
  • tuple-container
  • variant-select
  • optional-toggle
  • vector-list
  • blob-upload
  • principal-input
  • text-input
  • number-input
  • boolean-checkbox
  • null-hidden
  • recursive-lazy
  • unknown-fallback

renderHint shape:

type FormRenderHint = {
isCompound: boolean
isPrimitive: boolean
inputType?: "text" | "number" | "checkbox" | "select" | "file" | "textarea"
}
const form = useForm({
defaultValues: methodMeta.defaults,
validators: { onBlur: methodMeta.schema },
onSubmit: async ({ value }) => {
await actor.icrc1_transfer(...value)
},
})

Use MetadataReactor if you want to work directly from canister ID + client manager and avoid manual visitor wiring.