docs(specs): add header/nav redesign spec
Design spec for replacing the white bg-surface header with a brand-navy header, incl. 4px brand-purple accent strip, mint active underline, mobile logo fix, and integrated login page header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
71
frontend/src/lib/components/DateInput.svelte
Normal file
71
frontend/src/lib/components/DateInput.svelte
Normal file
@@ -0,0 +1,71 @@
|
||||
<script lang="ts">
|
||||
import { isoToGerman, handleGermanDateInput } from '$lib/utils/date.js';
|
||||
import * as m from '$lib/paraglide/messages.js';
|
||||
|
||||
interface Props {
|
||||
value?: string;
|
||||
errorMessage?: string | null;
|
||||
class?: string;
|
||||
id?: string;
|
||||
name?: string;
|
||||
placeholder?: string;
|
||||
oninput?: () => void;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
let {
|
||||
value = $bindable(''),
|
||||
errorMessage = $bindable<string | null>(null),
|
||||
class: extraClass,
|
||||
id,
|
||||
name,
|
||||
placeholder = m.form_placeholder_date(),
|
||||
oninput: onInputCallback,
|
||||
...rest
|
||||
}: Props = $props();
|
||||
|
||||
// ─── Display state ────────────────────────────────────────────────────────
|
||||
let display = $state(isoToGerman(value));
|
||||
|
||||
// ─── Validation helper ────────────────────────────────────────────────────
|
||||
function isCalendarValid(iso: string): boolean {
|
||||
if (!iso) return false;
|
||||
const [, mm, dd] = iso.match(/^\d{4}-(\d{2})-(\d{2})$/) ?? [];
|
||||
const month = parseInt(mm, 10);
|
||||
const day = parseInt(dd, 10);
|
||||
return month >= 1 && month <= 12 && day >= 1 && day <= 31;
|
||||
}
|
||||
|
||||
// ─── Input handler ────────────────────────────────────────────────────────
|
||||
function handleInput(e: Event) {
|
||||
const { display: formatted, iso } = handleGermanDateInput(e);
|
||||
display = formatted;
|
||||
|
||||
if (formatted === '') {
|
||||
value = '';
|
||||
errorMessage = null;
|
||||
} else if (iso && isCalendarValid(iso)) {
|
||||
value = iso;
|
||||
errorMessage = null;
|
||||
} else {
|
||||
value = '';
|
||||
errorMessage = m.form_date_error();
|
||||
}
|
||||
onInputCallback?.();
|
||||
}
|
||||
</script>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
maxlength="10"
|
||||
id={id}
|
||||
placeholder={placeholder}
|
||||
class={extraClass}
|
||||
value={display}
|
||||
oninput={handleInput}
|
||||
{...rest}
|
||||
/>
|
||||
{#if name}
|
||||
<input type="hidden" name={name} value={value} />
|
||||
{/if}
|
||||
Reference in New Issue
Block a user