From 7a7fade491ba473b03f77ce3c87d00886bb4bd45 Mon Sep 17 00:00:00 2001 From: Elijah Duffy Date: Thu, 3 Jul 2025 11:08:02 -0700 Subject: [PATCH] date input: add labels, validation, fix NaN checking --- src/lib/Dateinput.svelte | 80 +++++++++++++++++++++++++--------------- src/lib/Label.svelte | 2 +- 2 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/lib/Dateinput.svelte b/src/lib/Dateinput.svelte index e5ef838..81a22c1 100644 --- a/src/lib/Dateinput.svelte +++ b/src/lib/Dateinput.svelte @@ -2,7 +2,9 @@ import { InputValidatorEvent, liveValidator, validate } from '@svelte-toolkit/validate'; import { CalendarBlank } from 'phosphor-svelte'; import { type Snippet } from 'svelte'; - import type { ClassValue, FormEventHandler, KeyboardEventHandler } from 'svelte/elements'; + import type { ClassValue, KeyboardEventHandler } from 'svelte/elements'; + import { generateIdentifier } from './util.js'; + import Label from './Label.svelte'; type FormatString = 'year' | 'month' | 'day'; const blankState = { @@ -16,7 +18,9 @@ value?: Date; min?: Date; max?: Date; + label?: string; required?: boolean; + invalidMessage?: string; class?: ClassValue | undefined | null; format?: FormatString[]; } @@ -24,13 +28,19 @@ let { name, value = $bindable(), + /** min specifies lower bounds for the date input (WARNING: NOT IMPLEMENTED) */ min = new Date(1900, 0, 1), + /** max specifies upper bounds for the date input (WARNING: NOT IMPLEMENTED) */ max = new Date(2100, 11, 31), + label, required = false, + invalidMessage = 'Valid date is required', class: classList, format = ['year', 'month', 'day'] }: Props = $props(); + const id = $derived(generateIdentifier('dateinput', name)); + const inputSnippets = $derived.by(() => { const found: Partial> = {}; const arr: Snippet[] = []; @@ -56,11 +66,8 @@ let valid = $state(true); let containerElement: HTMLDivElement; - let yearValid = $state(true); let yearElement = $state(null); - let monthValid = $state(true); let monthElement = $state(null); - let dayValid = $state(true); let dayElement = $state(null); let previousYearValue = $state(undefined); let yearValue = $derived.by(() => { @@ -108,8 +115,8 @@ setPrevious(); previousYearValue = undefined; value = undefined; - return; } + return; } } @@ -121,8 +128,8 @@ setPrevious(); previousMonthValue = undefined; value = undefined; - return; } + return; } } @@ -134,8 +141,8 @@ setPrevious(); previousDayValue = undefined; value = undefined; - return; } + return; } } @@ -193,28 +200,46 @@ }; -
- +
+ + {#if label} + + {/if} - {#each inputSnippets as snippet, i} - {@render snippet()} +
+ - {#if i < inputSnippets.length - 1} - - - {/if} - {/each} + {#each inputSnippets as snippet, i} + {@render snippet()} - + {#if i < inputSnippets.length - 1} + - + {/if} + {/each} + + +
+ + +
+ +
{#snippet year()} @@ -235,7 +260,6 @@ }} use:liveValidator={{ constrain: true }} onvalidate={(e) => { - yearValid = e.detail.valid; handleComponentValidate(e); }} >
@@ -259,7 +283,6 @@ }} use:liveValidator={{ constrain: true }} onvalidate={(e) => { - monthValid = e.detail.valid; handleComponentValidate(e); }} > @@ -283,7 +306,6 @@ }} use:liveValidator={{ constrain: true }} onvalidate={(e) => { - dayValid = e.detail.valid; handleComponentValidate(e); }} > diff --git a/src/lib/Label.svelte b/src/lib/Label.svelte index 228eea3..9ebca9c 100644 --- a/src/lib/Label.svelte +++ b/src/lib/Label.svelte @@ -15,7 +15,7 @@ 'transition-fontColor block', error && !bigError ? 'mt-1 text-sm font-normal text-red-500' - : 'text-text dark:text-background mb-3 text-base font-medium', + : 'text-text dark:text-background mb-2 text-base font-medium', bigError && 'text-red-500!' ]} >