Form Component Props & Events
Form Component Props & Events
Section titled “Form Component Props & Events”Complete reference for the <form-component> custom element API.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
id | string | — | ✅ | Unique identifier for the form instance. Used for hook subscriptions. |
theme | 'light' | 'dark' | 'light' | ❌ | Color theme for the form. |
spec | Field | string | — | ✅ | Form specification schema. Can be a JSON string or object. |
values | Record<string, any> | string | {} | ❌ | Initial form values. Can be a JSON string or object. |
hideMapeable | boolean | true | ❌ | Hide mapper context options in fields. |
submitButtonText | string | undefined | ❌ | If set, displays a submit button with this text. |
Props Details
Section titled “Props Details”A unique identifier that distinguishes this form from others on the page. This ID is used when subscribing to form events through the window.$useFormCore hooks.
<form-component id="checkout-form" /><form-component id="profile-form" />Controls the visual appearance of the form:
<!-- Light theme (default) --><form-component id="form1" theme="light" />
<!-- Dark theme --><form-component id="form2" theme="dark" />The form specification that defines the structure and fields. Can be passed as:
As a JavaScript object (Vue):
<template> <form-component :spec="formSpec" /></template>
<script setup>const formSpec = { type: 'collection', spec: [ { type: 'text', name: 'name', label: 'Name' } ]};</script>As a JSON string (HTML):
<form-component spec='{"type":"collection","spec":[{"type":"text","name":"name","label":"Name"}]}'/>values
Section titled “values”Initial values to populate the form. Keys should match field names in the spec:
<template> <form-component :spec="spec" :values="initialValues" /></template>
<script setup>const initialValues = { name: 'John Doe', preferences: { newsletter: true }};</script>hideMapeable
Section titled “hideMapeable”When set to true (default), hides the mapper context UI that allows mapping fields to dynamic data sources. Set to false when using forms within a flow/mapper context.
<!-- Show mapper options (for flow editor context) --><form-component :hide-mapeable="false" />submitButtonText
Section titled “submitButtonText”When provided, displays a submit button at the bottom of the form:
<form-component submit-button-text="Save Changes" />If not provided, no submit button is rendered (useful when embedding in parent forms).
Events
Section titled “Events”| Event | Payload | Description |
|---|---|---|
submit | (value: unknown, meta?: GenericObject) | Emitted when the form is submitted and validation passes. |
change | (value: unknown) | Emitted whenever any field value changes. |
action | (action: Item, value: unknown) | Emitted when a field action button is clicked. |
Event Details
Section titled “Event Details”submit
Section titled “submit”Triggered when the form is submitted (either via submit button or programmatically):
<template> <form-component @submit="handleSubmit" submit-button-text="Submit" /></template>
<script setup>function handleSubmit(data, meta) { // data: The complete form values console.log('Form data:', data);
// meta: Validation result from VeeValidate if (meta?.valid) { await saveData(data); }}</script>Payload structure:
// data - merged form values{ name: "John Doe", preferences: { newsletter: true }}
// meta - validation result (optional){ valid: true, errors: {}, results: {...}}change
Section titled “change”Emitted on every field change, debounced at the form level:
<template> <form-component @change="handleChange" /></template>
<script setup>function handleChange(data) { // data: Current complete form values console.log('Current values:', data);
// Use for auto-save, conditional logic, etc. if (data.country === 'US') { loadUSStates(); }}</script>action
Section titled “action”Triggered when a field’s action button is clicked:
const spec = { type: 'collection', spec: [ { type: 'select', name: 'connection', label: 'Connection', options: [], action: { label: 'Create New', value: 'create.connection', icon: 'plus', }, }, ],};<template> <form-component :spec="spec" @action="handleAction" /></template>
<script setup>function handleAction(action, currentValue) { // action.value: The action identifier // action.label: Display label // currentValue: Current field value
if (action.value === 'create.connection') { const newConnection = await openConnectionDialog(); // Update form spec with new options... }}</script>TypeScript Types
Section titled “TypeScript Types”import type { Field, Item } from '@ion-components/ui/types';import type { GenericObject } from 'env';
// Props interfaceinterface FormComponentProps { id: string; theme?: 'light' | 'dark'; spec: Field | string; values?: Record<string, any> | string; hideMapeable?: boolean; submitButtonText?: string;}
// Events interfaceinterface FormComponentEmits { (event: 'action', action: Item, value: unknown): void; (event: 'submit', value: unknown, meta?: GenericObject): void; (event: 'change', value: unknown): void;}Usage Examples
Section titled “Usage Examples”Complete Form with All Features
Section titled “Complete Form with All Features”<script setup lang="ts">import { ref } from 'vue';
const formId = 'complete-form';
const spec = { type: 'collection', name: 'user', spec: [ { type: 'text', name: 'name', label: 'Full Name', required: true }, { type: 'email', name: 'email', label: 'Email', required: true }, { type: 'select', name: 'role', label: 'Role', options: [ { label: 'Admin', value: 'admin' }, { label: 'User', value: 'user' }, { label: 'Guest', value: 'guest' }, ], }, { type: 'boolean', name: 'active', label: 'Active', default: true }, { type: 'number', name: 'maxSessions', label: 'Max Sessions', advanced: true }, ],};
const values = ref({ name: 'Jane Doe', role: 'user', active: true,});
function onSubmit(data: unknown, meta?: Record<string, any>) { if (meta?.valid) { console.log('Valid submission:', data); }}
function onChange(data: unknown) { console.log('Form updated:', data);}
function onAction(action: { label: string; value: string }, value: unknown) { console.log('Action triggered:', action.value, 'with value:', value);}</script>
<template> <form-component :id="formId" theme="dark" :spec="spec" :values="values" :hide-mapeable="true" submit-button-text="Save User" @submit="onSubmit" @change="onChange" @action="onAction" /></template>