feat: refactor form components

This commit is contained in:
EETagent 2022-11-29 11:24:40 +01:00
parent f3fd0c04e4
commit 30c504b82e
5 changed files with 145 additions and 89 deletions

View file

@ -0,0 +1,29 @@
<script lang="ts">
import Telephone from '../icons/Telephone.svelte';
import TextField from './TextField.svelte';
export let placeholder: string = '';
export let value: string = '';
export let error: string = '';
// Personal Id formatting
$: {
let x = value.replace(/\D/g, '').match(/(\d{0,6})(\d{0,4})/)!;
value = x[1] + (x[2] ? '/' + x[2] : '');
}
</script>
<TextField
bind:error
bind:value
on:keydown
on:keyup
on:change
type="text"
{placeholder}
icon
>
<div slot="icon" class="flex items-center justify-center">
<Telephone />
</div>
</TextField>

View file

@ -0,0 +1,14 @@
<script lang="ts">
import TextField from './TextField.svelte';
export let placeholder: string = '';
export let value: string = '';
export let error: string = '';
// Number formatting
$: {
value = value.replace(/[^0-9]/g, '');
}
</script>
<TextField bind:error bind:value on:keydown on:keyup on:change type="number" {placeholder} icon />

View file

@ -0,0 +1,30 @@
<script lang="ts">
import Telephone from '../icons/Telephone.svelte';
import TextField from './TextField.svelte';
export let placeholder: string = '';
export let value: string = '';
export let error: string = '';
// Phone Number formatting
$: {
let x = value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,3})(\d{0,3})/)!;
value =
'+' + x[1] + (x[2] ? ' ' + x[2] : '') + (x[3] ? ' ' + x[3] : '') + (x[4] ? ' ' + x[4] : '');
}
</script>
<TextField
bind:error
bind:value
on:keydown
on:keyup
on:change
type="tel"
{placeholder}
icon
>
<div slot="icon" class="flex items-center justify-center">
<Telephone />
</div>
</TextField>

View file

@ -1,34 +1,18 @@
<script lang="ts">
export let type: 'text' | 'number' | 'tel' | 'e-mail' | "password" = 'text';
export let format: 'default' | 'email' | 'tel' | 'name' | 'number' | 'birthdate' | 'personalIdNumber' = 'default';
export let type: 'text' | 'number' | 'tel' | 'e-mail' | 'password' = 'text';
const typeAction = (node: HTMLInputElement) => {
node.type = type;
};
export let placeholder: string = '';
export let value: string = '';
$: {
if (format === 'tel') {
let x = value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,3})(\d{0,3})/)!;
value = '+' + x[1] + (x[2] ? ' ' + x[2] : '') + (x[3] ? ' ' + x[3] : '') + (x[4] ? ' ' + x[4] : '');
} else if (format === 'number') {
value = value.replace(/[^0-9]/g, '');
} else if (format === 'birthdate') { // TODO: more intuitive date input
let x = value.replace(/\D/g, '').match(/(\d{0,2})(\d{0,2})(\d{0,4})/)!;
value = x[1] + (x[2] ? '.' + x[2] : '') + (x[3] ? '.' + x[3] : '');
} else if (format === 'personalIdNumber') {
let x = value.replace(/\D/g, '').match(/(\d{0,6})(\d{0,4})/)!;
value = x[1] + (x[2] ? '/' + x[2] : '');
}
}
export let icon: boolean = false;
export let error: string = "";
export let error: string = '';
</script>
<div class="relative flex justify-center items-center">
<input
class:error={error}
class:error
bind:value
on:click
on:keydown
@ -47,7 +31,8 @@
</div>
<style>
div, input {
div,
input {
@apply w-full;
}
.withIcon {

View file

@ -6,6 +6,8 @@
import Home from '$lib/components/icons/Home.svelte';
import Telephone from '$lib/components/icons/Telephone.svelte';
import SplitLayout from '$lib/components/layout/SplitLayout.svelte';
import IdField from '$lib/components/textfield/IdField.svelte';
import TelephoneField from '$lib/components/textfield/TelephoneField.svelte';
import TextField from '$lib/components/textfield/TextField.svelte';
import { createForm } from 'svelte-forms-lib';
@ -14,7 +16,7 @@
let applicationValue = '';
const pageCount = 3;
let pageIndex = 0;
let pageIndex = 2;
let pagesFilled = 0;
const formInitialValues = {
@ -39,7 +41,10 @@
validationSchema: yup.object().shape({
name: yup.string().required(),
email: yup.string().email().required(),
telephone: yup.string().required().matches(/^\+\d{1,3} \d{3} \d{3} \d{3}$/),
telephone: yup
.string()
.required()
.matches(/^\+\d{1,3} \d{3} \d{3} \d{3}$/),
birthSurname: yup.string().required(),
birthPlace: yup.string().required(),
birthDate: yup.string().required(),
@ -76,12 +81,7 @@
}
break;
case 3:
if (
$errors.citizenship ||
$errors.personalId ||
$errors.study ||
$errors.applicationId
) {
if ($errors.citizenship || $errors.personalId || $errors.study || $errors.applicationId) {
return true;
}
break;
@ -89,7 +89,7 @@
return false;
}
return false;
}
};
</script>
<SplitLayout>
@ -106,7 +106,7 @@
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /> Fusce suscipit libero eget
elit.
</p>
<div class="flex md:flex-col items-center justify-center w-full md:w-3/5">
<div class="flex md:flex-col items-center justify-center w-full">
<span class="w-full mt-8">
<TextField
error={$errors.name}
@ -116,7 +116,7 @@
placeholder="Jméno a příjmení"
/>
</span>
<span class="w-full mt-8">
<span class="w-full mt-8 ml-2 md:ml-0">
<TextField
error={$errors.email}
on:change={handleChange}
@ -131,20 +131,13 @@
</TextField>
</span>
</div>
<div class="mt-8 w-full md:w-3/5">
<TextField
<div class="mt-8 w-full">
<TelephoneField
error={$errors.telephone}
on:change={handleChange}
bind:value={$form.telephone}
type="tel"
format="tel"
placeholder="Telefon"
icon
>
<div slot="icon" class="flex items-center justify-center">
<Telephone />
</div>
</TextField>
/>
</div>
</form>
{/if}
@ -153,7 +146,7 @@
<p class="block mt-8 font-light text-sspsGray text-center">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /> Fusce suscipit libero eget elit.
</p>
<div class="flex flex-col w-full md:w-3/5">
<div class="flex flex-col w-full">
<span class="w-full mt-8">
<TextField
type="text"
@ -179,22 +172,23 @@
</span>
</div>
<div class="mt-8 flex items-center justify-center w-full md:w-3/5">
<div class="mt-8 flex items-center w-full">
<TextField
error={$errors.birthDate}
on:change={handleChange}
bind:value={$form.birthDate}
type="text"
format="birthdate"
placeholder="Datum narození"
/>
<TextField
error={$errors.sex}
on:change={handleChange}
bind:value={$form.sex}
type="text"
placeholder="Pohlaví"
/>
<div class="ml-2">
<TextField
error={$errors.sex}
on:change={handleChange}
bind:value={$form.sex}
type="text"
placeholder="Pohlaví"
/>
</div>
</div>
{/if}
{#if pageIndex === 2}
@ -202,7 +196,7 @@
<p class="block mt-8 font-light text-sspsGray text-center">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /> Fusce suscipit libero eget elit.
</p>
<div class="flex flex-col w-full md:w-3/5">
<div class="flex flex-col w-full">
<span class="w-full mt-8">
<TextField
error={$errors.address}
@ -212,24 +206,25 @@
placeholder="Adresa trvalého bydliště"
/>
</span>
<span class="w-full mt-8">
<TextField
error={$errors.parentEmail}
on:change={handleChange}
bind:value={$form.parentEmail}
type="e-mail"
placeholder="E-mail zákonného zástupce"
/>
</span>
<span class="w-full mt-8">
<TextField
error={$errors.parentTelephone}
on:change={handleChange}
bind:value={$form.parentTelephone}
type="tel"
placeholder="Telefon zákonného zástupce"
/>
</span>
<div class="mt-8 flex flex-row items-center md:flex-col">
<span class="w-full">
<TextField
error={$errors.parentEmail}
on:change={handleChange}
bind:value={$form.parentEmail}
type="e-mail"
placeholder="E-mail zákonného zástupce"
/>
</span>
<span class="w-full ml-2 md:ml-0 md:mt-8">
<TelephoneField
error={$errors.parentTelephone}
on:change={handleChange}
bind:value={$form.parentTelephone}
placeholder="Telefon zákonného zástupce"
/>
</span>
</div>
</div>
{/if}
{#if pageIndex === 3}
@ -237,7 +232,7 @@
<p class="block mt-8 font-light text-sspsGray text-center">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /> Fusce suscipit libero eget elit.
</p>
<div class="flex flex-col w-full md:w-3/5">
<div class="flex flex-col w-full">
<span class="w-full mt-8">
<TextField
error={$errors.citizenship}
@ -248,13 +243,11 @@
/>
</span>
</div>
<div class="mt-8 flex items-center justify-center w-full md:w-3/5">
<TextField
<div class="mt-8 flex items-center justify-center w-full">
<IdField
error={$errors.personalId}
on:change={handleChange}
bind:value={$form.personalId}
type="text"
format="personalIdNumber"
placeholder="Rodné číslo"
/>
<TextField
@ -265,7 +258,7 @@
placeholder="Obor"
/>
</div>
<div class="mt-8 flex flex-col w-full md:w-3/5">
<div class="mt-8 flex flex-col w-full">
<TextField
error={$errors.applicationId}
on:change={handleChange}
@ -287,25 +280,30 @@
}
errors.set(formInitialValues);
}}
class="w-full mt-8 md:w-3/5 p-3 rounded-lg font-semibold text-xl transition-colors duration-300 bg-sspsBlue hover:bg-sspsBlueDark text-white hover:cursor-pointer"
class="w-full mt-8 p-3 rounded-lg font-semibold text-xl transition-colors duration-300 bg-sspsBlue hover:bg-sspsBlueDark text-white hover:cursor-pointer"
type="submit"
value={pageIndex === pageCount ? 'Odeslat' : 'Pokračovat'}
/>
<div class="mt-8 flex flex-row justify-center">
{#each Array(pageCount + 1) as _, i}
<button class:dotActive={i === pageIndex} on:click={async (e) => {
if (i <= pagesFilled) { // never skip unfilled or invalid pages
pageIndex = i;
} else if (i == pagesFilled + 1) { // if next page is clicked, validate current page
await handleSubmit(e);
if (isPageInvalid()) return;
pagesFilled++;
pageIndex++;
errors.set(formInitialValues);
}
}
} class="dot" />
<button
class:dotActive={i === pageIndex}
on:click={async (e) => {
if (i <= pagesFilled) {
// never skip unfilled or invalid pages
pageIndex = i;
} else if (i == pagesFilled + 1) {
// if next page is clicked, validate current page
await handleSubmit(e);
if (isPageInvalid()) return;
pagesFilled++;
pageIndex++;
errors.set(formInitialValues);
}
}}
class="dot"
/>
{/each}
</div>
</div>