time input: use internationalized/Date.Time-based value, add onchange

This commit is contained in:
Elijah Duffy
2025-07-21 20:04:42 -07:00
parent 39debb8865
commit 1a111121a1

View File

@@ -6,29 +6,32 @@
import type { ClassValue } from 'svelte/elements';
import { generateIdentifier, targetMust } from './util';
import { FocusManager } from './focus';
import { Time } from '@internationalized/date';
interface Props {
name?: string;
label?: string;
value?: string;
value?: Time | null;
formattedValue?: string;
required?: boolean;
invalidMessage?: string;
showConfirm?: boolean;
compact?: boolean;
class?: ClassValue | null | undefined;
onchange?: (details: { time: Time | null; formattedTime: string }) => void;
}
let {
name,
label,
value = $bindable(''),
value = $bindable(null),
formattedValue = $bindable(''),
required,
invalidMessage = 'Please select a time',
showConfirm = false,
compact = false,
class: classValue
class: classValue,
onchange
}: Props = $props();
type ampmKey = 'AM' | 'PM';
@@ -121,17 +124,6 @@
return res;
};
/**
* prefixZero adds a leading zero to the string if it is less than 10
* @param str The string to prefix
*/
const prefixZero = (str: string) => {
if (str.length === 1) {
return '0' + str;
}
return str;
};
/**
* updateValue updates `value` with the current time in 24-hour format.
* If any component is invalid or blank, it sets `value` to an empty string.
@@ -142,7 +134,7 @@
let minuteValue = parseInt(values.minute);
if (isNaN(hourValue)) {
value = '';
value = null;
formattedValue = '';
updateHiddenInput();
return;
@@ -157,7 +149,7 @@
minuteValue = 0;
}
value = `${prefixZero((hourValue + (ampmLocal === 'PM' ? 12 : 0)).toString())}:${prefixZero(minuteValue.toString())}`;
value = new Time(hourValue + (ampmLocal === 'PM' ? 12 : 0), minuteValue, 0);
updateHiddenInput();
// update formatted value
@@ -170,8 +162,9 @@
* a keyup event to allow validation to detect the change.
*/
const updateHiddenInput = () => {
hiddenInput.value = value;
hiddenInput.value = value?.toString() ?? '';
hiddenInput.dispatchEvent(new KeyboardEvent('keyup'));
onchange?.({ time: value, formattedTime: formattedValue });
};
const components: Record<