state machine: add demo & fix
This commit is contained in:
@@ -40,7 +40,7 @@
|
|||||||
import { tweened } from 'svelte/motion';
|
import { tweened } from 'svelte/motion';
|
||||||
import { fade, fly } from 'svelte/transition';
|
import { fade, fly } from 'svelte/transition';
|
||||||
import { validateForm } from '@svelte-toolkit/validate';
|
import { validateForm } from '@svelte-toolkit/validate';
|
||||||
import { ArrowLeft, Check } from 'phosphor-svelte';
|
import { ArrowLeft, Check, CheckFat } from 'phosphor-svelte';
|
||||||
import type { IconDef } from './util';
|
import type { IconDef } from './util';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -167,6 +167,7 @@
|
|||||||
|
|
||||||
// validate the form
|
// validate the form
|
||||||
const result = await validateForm(formElement);
|
const result = await validateForm(formElement);
|
||||||
|
console.log('validated form', result);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
buttonComponent.animateBounce();
|
buttonComponent.animateBounce();
|
||||||
setTimeout(() => focusFirstInput(true), 50);
|
setTimeout(() => focusFirstInput(true), 50);
|
||||||
@@ -359,7 +360,7 @@
|
|||||||
{#if i >= index}
|
{#if i >= index}
|
||||||
<span class="mb-[0.0625rem]">{i + 1}</span>
|
<span class="mb-[0.0625rem]">{i + 1}</span>
|
||||||
{:else}
|
{:else}
|
||||||
<Check class="mt-0.5" size="1.5rem" weight="bold" />
|
<CheckFat size="0.9rem" weight="fill" />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -378,7 +379,7 @@
|
|||||||
onclick={() => (index -= 1)}
|
onclick={() => (index -= 1)}
|
||||||
transition:fly={{ x: -200, duration: 200 }}
|
transition:fly={{ x: -200, duration: 200 }}
|
||||||
>
|
>
|
||||||
<ArrowLeft />
|
<ArrowLeft size="1.5em" />
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -460,6 +461,7 @@
|
|||||||
{#if index < pages.length - 1 && page.button && $height > 0}
|
{#if index < pages.length - 1 && page.button && $height > 0}
|
||||||
<div class="mt-4" out:fade bind:this={buttonContainer}>
|
<div class="mt-4" out:fade bind:this={buttonContainer}>
|
||||||
<Button
|
<Button
|
||||||
|
type="submit"
|
||||||
icon={page.button.icon}
|
icon={page.button.icon}
|
||||||
onclick={handleContinueClick}
|
onclick={handleContinueClick}
|
||||||
animate={false}
|
animate={false}
|
||||||
|
|||||||
97
src/routes/statemachine/+page.svelte
Normal file
97
src/routes/statemachine/+page.svelte
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import PhoneInput from '$lib/PhoneInput.svelte';
|
||||||
|
import StateMachine, { type StateMachinePage } from '$lib/StateMachine.svelte';
|
||||||
|
import TextInput from '$lib/TextInput.svelte';
|
||||||
|
import { ArrowRight, Check } from 'phosphor-svelte';
|
||||||
|
|
||||||
|
let stateMachineRef: StateMachine;
|
||||||
|
let index = $state(1);
|
||||||
|
|
||||||
|
const pages: StateMachinePage[] = [
|
||||||
|
{
|
||||||
|
hero: {
|
||||||
|
text: 'Hey there!',
|
||||||
|
fontSize: 'large',
|
||||||
|
colour: 'light',
|
||||||
|
size: 'large'
|
||||||
|
},
|
||||||
|
snippet: firstPage,
|
||||||
|
button: {
|
||||||
|
text: 'Next',
|
||||||
|
onclick: () => console.log('next'),
|
||||||
|
icon: {
|
||||||
|
component: ArrowRight,
|
||||||
|
props: { size: '1.2em', weight: 'bold' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hero: {
|
||||||
|
text: 'How can we reach you?',
|
||||||
|
fontSize: 'small',
|
||||||
|
colour: 'dark',
|
||||||
|
size: 'small'
|
||||||
|
},
|
||||||
|
snippet: secondPage,
|
||||||
|
button: {
|
||||||
|
text: 'Submit',
|
||||||
|
onclick: () => console.log('finish'),
|
||||||
|
icon: {
|
||||||
|
component: Check,
|
||||||
|
props: { size: '1.2em', weight: 'bold' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const successPage: StateMachinePage = {
|
||||||
|
disableBack: true,
|
||||||
|
hero: {
|
||||||
|
text: 'All done! 🎉',
|
||||||
|
fontSize: 'small',
|
||||||
|
size: 'large',
|
||||||
|
colour: 'light'
|
||||||
|
},
|
||||||
|
snippet: finishedSnippet,
|
||||||
|
button: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const failurePage: StateMachinePage = {
|
||||||
|
disableBack: true,
|
||||||
|
hero: {
|
||||||
|
text: 'Something went wrong 😔',
|
||||||
|
fontSize: 'small',
|
||||||
|
size: 'large',
|
||||||
|
colour: 'dark'
|
||||||
|
},
|
||||||
|
snippet: failureSnippet,
|
||||||
|
button: false
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<StateMachine
|
||||||
|
bind:this={stateMachineRef}
|
||||||
|
{pages}
|
||||||
|
success={successPage}
|
||||||
|
failure={failurePage}
|
||||||
|
{index}
|
||||||
|
></StateMachine>
|
||||||
|
|
||||||
|
{#snippet firstPage()}
|
||||||
|
<TextInput label="What's your name?" validate={{ required: true }} />
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
{#snippet secondPage()}
|
||||||
|
<PhoneInput label="What's your phone number?" required={true} />
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
{#snippet finishedSnippet()}
|
||||||
|
<p>All done! Thanks so much for submitting.</p>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
{#snippet failureSnippet()}
|
||||||
|
<p class="my-3">
|
||||||
|
We're sorry for the inconvenience. Something went wrong on our end and we couldn't process your
|
||||||
|
submission.
|
||||||
|
</p>
|
||||||
|
{/snippet}
|
||||||
Reference in New Issue
Block a user