your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 // @ts-nocheck
3 import DatePickerField from './DatePicker.svelte';
4 import TimePicker from './TimePicker.svelte';
5 import { untrack } from 'svelte';
6 import { browser } from '$app/environment';
7
8 let {
9 value = $bindable(''),
10 required = false,
11 minValue = ''
12 }: {
13 value: string;
14 required?: boolean;
15 minValue?: string;
16 } = $props();
17
18 let datePart = $state('');
19 let timePart = $state('00:00');
20 let timeEl: HTMLDivElement | undefined = $state(undefined);
21
22 const locale = browser ? navigator.language || 'en' : 'en';
23 let minDatePart = $derived(minValue ? minValue.split('T')[0] || '' : '');
24
25 // Sync external value -> date/time parts
26 $effect(() => {
27 const v = value;
28 untrack(() => {
29 if (v) {
30 const [d, t] = v.split('T');
31 if (d && d !== datePart) datePart = d;
32 if (t && t !== timePart) timePart = t;
33 }
34 });
35 });
36
37 // Sync date/time parts -> external value
38 $effect(() => {
39 const d = datePart;
40 const t = timePart;
41 untrack(() => {
42 if (d) {
43 const newVal = `${d}T${t || '00:00'}`;
44 if (newVal !== value) value = newVal;
45 }
46 });
47 });
48
49 function focusTime() {
50 // Small delay to let the popover finish closing
51 setTimeout(() => {
52 if (timeEl) {
53 const segment = timeEl.querySelector('[data-segment]');
54 if (segment instanceof HTMLElement) {
55 segment.focus();
56 }
57 }
58 }, 50);
59 }
60</script>
61
62<div class="flex items-center gap-1.5">
63 <DatePickerField
64 bind:value={datePart}
65 {required}
66 minValue={minDatePart}
67 {locale}
68 onSelect={focusTime}
69 />
70 <div bind:this={timeEl}>
71 <TimePicker bind:value={timePart} {locale} />
72 </div>
73</div>