TapForm renders the same schema your manifest already declares — for a settings panel, an
action’s input, or a credential set — as a form in the host’s styling, validates on submit,
and hands you a typed value.
Props
What each schema construct renders
Submit drops the fields left blank, then checks what remains against the whole schema, so a
minimum, a pattern or a maxLength you declared is enforced too and its message lands
under the control it belongs to.
formFields(schema) returns the same list TapForm renders, as
{ name, label, kind, required, hint, options }, when you want the fields without the form.
An action behind a form
An action goes through an approval card, so the form collects the input and the host does the rest:tap.actions.run posts the values, and Tappify draws the approval card — the scope, the blast
radius, whether it can be undone and the cost — before anything runs. See
Add actions.
A form with no value has nothing to infer T from, so annotate the handler’s parameter —
ActionInput<"send-push"> here, TapSettingsValues in a settings panel. onSubmit returns
nothing, so hand the promise to void rather than returning it.
Point TapForm at the same file your manifest references. When the schema changes,
tappify extension types changes the type in the same
step, and a form that no longer matches its handler stops compiling.