VfSteps
Basic
VfSteps renders the progress indicator in a stepped form. Override the steps slot on VfForm to render VfSteps with custom props or alongside additional content.
<VfForm stepped hide-errors>
<template #steps="{ pager }">
<VfSteps :pager="pager" />
</template>
<VfGroup name="personal" page="Personal">
<VfText name="name" label="Name" />
</VfGroup>
<VfGroup name="contact" page="Contact">
<VfText name="email" label="Email" />
</VfGroup>
<VfGroup name="address" page="Address">
<VfText name="city" label="City" />
</VfGroup>
</VfForm><template>
<VfForm stepped hide-errors>
<template #steps="{ pager }">
<VfSteps :pager="pager" />
</template>
<VfGroup name="personal" page="Personal">
<VfText name="name" label="Name" />
</VfGroup>
<VfGroup name="contact" page="Contact">
<VfText name="email" label="Email" />
</VfGroup>
<VfGroup name="address" page="Address">
<VfText name="city" label="City" />
</VfGroup>
</VfForm>
</template><script setup lang="ts">
import { defineSchema, defineSlot, useForm } from '@vueform/ui'
import { h, resolveComponent } from 'vue'
const schema = defineSchema({
personal: {
type: 'group',
page: 'Personal',
schema: {
name: { type: 'text', label: 'Name' },
},
},
contact: {
type: 'group',
page: 'Contact',
schema: {
email: { type: 'text', label: 'Email' },
},
},
address: {
type: 'group',
page: 'Address',
schema: {
city: { type: 'text', label: 'City' },
},
},
})
const [MyForm] = useForm({
schema,
stepped: true,
hideErrors: true,
slots: {
steps: defineSlot('VfForm.steps', {
props: ['pager'],
setup: (props) => () => {
const VfSteps = resolveComponent('VfSteps')
return h(VfSteps, { pager: props.pager })
},
}),
},
})
</script>
<template>
<MyForm />
</template>Props
Configure the component's behavior and appearance with these props.
Component
| Prop | Default | Description |
|---|---|---|
pager | — | Required. The pager instance managing multi-step form navigation. |
Customization
| Prop | Default | Description |
|---|---|---|
parts | — | Custom DOM attribute overrides for the component's structural parts. |
class | — | CSS classes to apply to the component's root element. |
classes | — | Custom CSS class overrides for the component's structural parts. |
reclass | — | CSS class overrides that replace (rather than merge with) default classes. |
slots | — | Custom Vue components to use for named slots. Every component resolves it through the standard outlets pipeline (see useOutlets). |
presets | — | Named configuration presets to apply to the component. |
template | — | A custom Vue component to use as the template instead of the default. |
component | — | A custom Vue component to render in the component's default slot. |
Context
Reactive properties and methods accessible on the component's Context object.
General
| Name | Description |
|---|---|
props | The resolved component props with defaults applied. |
Layout
| Name | Description |
|---|---|
classes | The resolved CSS class map for the component. |
parts | The resolved DOM attribute overrides for internal elements. |
Events
| Name | Description |
|---|---|
fire() | Fires an event synchronously, invoking before, main, and after listeners in order. |
fireAsync() | Fires an event asynchronously, awaiting each callback and short-circuiting when any returns false. |
on() | Subscribes a callback to a specific event. |
off() | Removes a previously registered event callback. |
onBefore() | Registers a callback that runs before the main event listeners. |
onAfter() | Registers a callback that runs after the main event listeners. |
Events
Events emitted by the component. See Events for details.
| Name | Params | Description |
|---|---|---|
beforeMount | context$ | Emitted before the component is mounted. |
mounted | context$ | Emitted after the component is mounted. |
beforeUnmount | context$ | Emitted before the component is unmounted. |
unmounted | context$ | Emitted after the component is unmounted. |
updated | context$ | Emitted after the component is updated. |
Slots
Named Slots for replacing parts of the component's rendering.
| Name | Scope | Description |
|---|---|---|
template | context | Slot that replaces the entire component rendering. Receives the full component context as a single context prop. |
wrapper | index label meta selected invalid loading enabled completed el$ page | Slot that replaces each step wrapper element. Receives step state and page info. |
default | index label meta selected invalid loading enabled completed el$ bindings | Slot that replaces each step's inner content. Receives step state. |
Parts
DOM attribute overrides targeting internal elements. See Parts for details.
root
The root steps container element.
| Element | <div> |
| Classes | .vf-steps |
list
The ordered list element containing all steps.
| Element | <ol> |
| Classes | .vf-steps-wrapper |
wrapper
Each step wrapper. Receives the step's resolved page.
| Element | <li> |
| Classes | .vf-step-wrapper |
| Bindings | data-selected data-enabled data-completed data-invalid data-loading |
step
The step content element.
| Element | <li> |
| Classes | .vf-step |
Tokens
All the CSS variables that control this component's appearance with default values in the default theme. See Themes & Tokens for details.
:root {
/**
* Component tokens
* -------------------------------------------------------------------------- */
--vf-steps-margin: 0 0 var(--vf-gutter) 0;
--vf-steps-bg-danger: var(--vf-red);
--vf-steps-bg-disabled: var(--vf-gray-200);
--vf-steps-bg-enabled: var(--vf-brand);
--vf-steps-color-danger: var(--vf-red);
--vf-steps-color-disabled: var(--vf-gray-400);
--vf-steps-color-enabled: inherit;
--vf-steps-color-selected: inherit;
--vf-steps-icon-color: var(--vf-white);
--vf-steps-icon-completed: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M2 8l4 5 8-10'/></svg>");
--vf-steps-icon-danger: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><rect x='6' y='0' width='4' height='9' rx='2' fill='white'/><circle cx='8' cy='13' r='2' fill='white'/></svg>");
--vf-steps-icon-selected: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><circle cx='4' cy='4' r='4' fill='white'/></svg>");
--vf-steps-font-size: 1rem;
}{
/**
* Component tokens
* -------------------------------------------------------------------------- */
stepsMargin: '0 0 $gutter 0',
stepsBgDanger: '$red',
stepsBgDisabled: '$gray200',
stepsBgEnabled: '$brand',
stepsColorDanger: '$red',
stepsColorDisabled: '$gray400',
stepsColorEnabled: 'inherit',
stepsColorSelected: 'inherit',
stepsIconColor: '$white',
stepsIconCompleted: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M2 8l4 5 8-10'/></svg>\")",
stepsIconDanger: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><rect x='6' y='0' width='4' height='9' rx='2' fill='white'/><circle cx='8' cy='13' r='2' fill='white'/></svg>\")",
stepsIconSelected: "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><circle cx='4' cy='4' r='4' fill='white'/></svg>\")",
stepsFontSize: '1rem',
}