Skip to content
On this page

Steps

Headless Wizard

Usage

Simple Usage

Step 1
preview
vue
<template>
  <p-steps>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 1</div>
            <div class="space-gap-2">
              <p-button disabled color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 2</div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev, toStep }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 3</div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Finish</p-button>
              <p-button @click="toStep(1)" color="info">To Step 1</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
  </p-steps>
</template>

Vertical Mode

Set direction to vertical to enable Vertical mode.

Step 1
preview
vue
<template>
  <p-steps direction="vertical">
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 1</div>
            <div class="space-gap-2">
              <p-button disabled color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 2</div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev, toStep }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 3</div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Finish</p-button>
              <p-button @click="toStep(1)" color="info">To Step 1</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
  </p-steps>
</template>

Loop Over

Add prop loop to enable Loop mode, it will loop over the steps and never finished.

Step 1
preview
vue
<template>
  <p-steps loop>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 1</div>
            <div class="space-gap-2">
              <p-button disabled color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 2</div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev, toStep }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">Step 3</div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Finish</p-button>
              <p-button @click="toStep(1)" color="info">To Step 1</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
  </p-steps>
</template>

Hooks

on-before-next hook

This hook ran when next function was called, suit for form validation.

preview
vue
<template>
  <p-steps :on-before-next="validate">
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">
              <label>Name</label>
              <p-input v-model="form.name" placeholder="Fill to next" />
            </div>
            <div class="space-x-2">
              <p-button disabled color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">
              <label>Email</label>
              <p-input v-model="form.email" placeholder="Fill to next" />
            </div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
  </p-steps>
</template>

<script setup>
  import { reactive } from 'vue-demi'
  import { dialog } from '@privyid/persona/core/'

  const form = reactive({
    name : '',
    email: '',
  })

  function validate (to, from) {
    if (from === 1) {
      if (!name.value) {
        dialog.alert({ text: 'Name is required' })

        return false // return false to prevent navigate to next step
      }
    }

    if (from === 2) {
      if (!form.email || !form.email.includes('@')) {
        dialog.alert({ text: 'Email must be valid email' })

        return false
      }
    }

    return true
  }
</script>

on-before-prev hook

Similar to on-before-next, but run when prev function called.

on-finished hook

This hook run when next function called in last step, and after on-before-next resolved. It's suit for handle save form, or sending POST to API.

preview
vue
<template>
  <p-steps
    :on-before-next="validate"
    :on-finished="save">
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">
              <label>Name</label>
              <p-input v-model="form.name" placeholder="Fill to next" />
            </div>
            <div class="space-gap-2">
              <p-button disabled color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
    <p-step>
      <template #default="{ next, prev }">
        <p-card>
          <div class="flex flex-col h-52">
            <div class="flex-grow">
              <label>Email</label>
              <p-input v-model="form.email" placeholder="Fill to next" />
            </div>
            <div class="space-gap-2">
              <p-button @click="prev" color="info">Prev</p-button>
              <p-button @click="next" color="info">Next</p-button>
            </div>
          </div>
        </p-card>
      </template>
    </p-step>
  </p-steps>
</template>

<script setup>
  import { reactive } from 'vue-demi'
  import { dialog } from '@privyid/persona/core/'

  const form = reactive({
    name : '',
    email: '',
  })

  function validate (to, from) { /* Example above */ }

  function save() {
    dialog.alert({ text: 'Success' })
  }
</script>

Binding v-model

You can binding current step with v-model

Step 1
preview

Step :

1

API

Props <p-steps>

PropsTypeDefaultDescription
directionStringhorizontalSlide direction, valid values is horizontal, vertical
loopBooleanfalseEnable loop mode
on-before-nextFunction-Hook which run before navigate to next page
on-before-prevFunction-Hook which run before navigate to previous page
on-finishedFunction-Hook which run on last step, after on-before-next hook resolved
keep-aliveBooleanfalseEnable KeepAlive
modelValueNumber1Binding v-model

Slot <p-steps>

NameDescription
defaultContent to place <p-step>

Events <p-steps>

NameArgumentsDescription
There no event here

Props <p-step>

PropsTypeDefaultDescription
on-before-nextFunction-Hook which run before navigate to next page
on-before-prevFunction-Hook which run before navigate to previous page

Slots <p-step>

NameDescription
defaultStep content

default slot contains scoped slots

ScopedTypeDefaultDescription
canNextBooleanfalseHook which indicate whether there is next step
canPrevBooleanfalseHook which indicate whether there is previous step
toStepFunction-Hook to jump to another step toStep(stepIndex), the argument use number type
nextFunction-Hook to jump to the next step
prevFunction-Hook to jump to the previous step
totalNumber1Show total steps
stepNumber1Show current step

Events <p-step>

NameArgumentsDescription
There no event here

See Also

Released under the MIT License.