Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(useStepper): new function (#1754)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
- Loading branch information
Showing
5 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
<script setup lang="ts"> | ||
import { useStepper } from '@vueuse/core' | ||
import { reactive } from 'vue' | ||
const form = reactive({ | ||
firstName: 'Jon', | ||
lastName: '', | ||
billingAddress: '', | ||
contractAccepted: false, | ||
carbonOffsetting: false, | ||
payment: 'credit-card' as 'paypal' | 'credit-card', | ||
}) | ||
const stepper = useStepper({ | ||
'user-information': { | ||
title: 'User information', | ||
isValid: () => form.firstName && form.lastName, | ||
}, | ||
'billing-address': { | ||
title: 'Billing address', | ||
isValid: () => form.billingAddress?.trim() !== '', | ||
}, | ||
'terms': { | ||
title: 'Terms', | ||
isValid: () => form.contractAccepted === true, | ||
}, | ||
'payment': { | ||
title: 'Payment', | ||
isValid: () => ['credit-card', 'paypal'].includes(form.payment), | ||
}, | ||
}) | ||
function submit() { | ||
if (stepper.current.value.isValid()) | ||
stepper.goToNext() | ||
} | ||
function allStepsBeforeAreValid(index: number): boolean { | ||
return !Array(index) | ||
.fill(null) | ||
.some((_, i) => !stepper.at(i)?.isValid()) | ||
} | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<div class="flex gap-2 justify-center"> | ||
<div v-for="(step, id, i) in stepper.steps.value" :key="id" class=""> | ||
<button | ||
:disabled="!allStepsBeforeAreValid(i) && stepper.isBefore(id)" | ||
@click="stepper.goTo(id)" | ||
v-text="step.title" | ||
/> | ||
</div> | ||
</div> | ||
|
||
<form class="mt-10" @submit.prevent="submit"> | ||
<span class="text-lg font-bold" v-text="stepper.current.value.title" /> | ||
<div class="flex flex-col justify-center gap-2 mt-2"> | ||
<div> | ||
<div v-if="stepper.isCurrent('user-information')"> | ||
<span>First name:</span> | ||
<input v-model="form.firstName" class="!mt-0.5" type="text"> | ||
<span>Last name:</span> | ||
<input v-model="form.lastName" class="!mt-0.5" type="text"> | ||
</div> | ||
|
||
<div v-if="stepper.isCurrent('billing-address')"> | ||
<input v-model="form.billingAddress" type="text"> | ||
</div> | ||
|
||
<div v-if="stepper.isCurrent('terms')"> | ||
<div> | ||
<input id="carbon-offsetting" v-model="form.carbonOffsetting" type="checkbox" class="mr-2"> | ||
<label for="carbon-offsetting">I accept to deposit a carbon offsetting fee</label> | ||
</div> | ||
<div> | ||
<input id="contract" v-model="form.contractAccepted" type="checkbox" class="mr-2"> | ||
<label for="contract">I accept the terms of the contract</label> | ||
</div> | ||
</div> | ||
|
||
<div v-if="stepper.isCurrent('payment')"> | ||
<div> | ||
<input id="credit-card" v-model="form.payment" type="radio" class="mr-2" value="credit-card"> | ||
<label for="credit-card">Credit card</label> | ||
</div> | ||
<div> | ||
<input id="paypal" v-model="form.payment" type="radio" class="mr-2" value="paypal"> | ||
<label for="paypal">PayPal</label> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div> | ||
<button v-if="!stepper.isLast" :disabled="!stepper.current.value.isValid()"> | ||
Next | ||
</button> | ||
<button v-if="stepper.isLast" :disabled="!stepper.current.value.isValid()"> | ||
Submit | ||
</button> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
<div class="flex flex-col gap-4 mt-12"> | ||
<div class="w-full px-4 py-2 rounded border border-main space-y-2 overflow-auto h-full"> | ||
<span class="font-bold">Form</span> | ||
<pre v-text="form" /> | ||
</div> | ||
|
||
<div class="w-full px-4 py-2 rounded border border-main space-y-2 overflow-auto h-full"> | ||
<span class="font-bold">Wizard</span> | ||
<pre v-text="stepper" /> | ||
</div> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
--- | ||
category: Utilities | ||
--- | ||
|
||
# useStepper | ||
|
||
Provides helpers for building a multi-step wizard interface. | ||
|
||
## Usage | ||
|
||
### Steps as array | ||
|
||
```js | ||
import { useStepper } from '@vueuse/core' | ||
|
||
const { | ||
steps, | ||
stepNames, | ||
index, | ||
current, | ||
next, | ||
previous, | ||
isFirst, | ||
isLast, | ||
goTo, | ||
goNext, | ||
goPrevious, | ||
goBackTo, | ||
isNext, | ||
isPrevious, | ||
isCurrent, | ||
isBefore, | ||
isAfter, | ||
} = useStepper([ | ||
'billing-address', | ||
'terms', | ||
'payment', | ||
]) | ||
|
||
// Access the step through `current` | ||
console.log(current.value) // 'billing-address' | ||
``` | ||
|
||
### Steps as object | ||
|
||
```js | ||
import { useStepper } from '@vueuse/core' | ||
|
||
const { | ||
steps, | ||
stepNames, | ||
index, | ||
current, | ||
next, | ||
previous, | ||
isFirst, | ||
isLast, | ||
goTo, | ||
goNext, | ||
goPrevious, | ||
goBackTo, | ||
isNext, | ||
isPrevious, | ||
isCurrent, | ||
isBefore, | ||
isAfter, | ||
} = useStepper({ | ||
'user-information': { | ||
title: 'User information', | ||
}, | ||
'billing-address': { | ||
title: 'Billing address', | ||
}, | ||
'terms': { | ||
title: 'Terms', | ||
}, | ||
'payment': { | ||
title: 'Payment', | ||
}, | ||
}) | ||
|
||
// Access the step object through `current` | ||
console.log(current.value.title) // 'User information' | ||
``` |
Oops, something went wrong.