68 lines
1.3 KiB
TypeScript
68 lines
1.3 KiB
TypeScript
import type { DateInputProps } from "$/types/InputTypes";
|
|
import clsx from "clsx";
|
|
import type { ChangeEvent } from "react";
|
|
|
|
|
|
export default function TimeInput({
|
|
id,
|
|
className,
|
|
step = 60,
|
|
value,
|
|
onChange,
|
|
...inputProps
|
|
}: Readonly<DateInputProps>){
|
|
const changeTime = (e: ChangeEvent<HTMLInputElement>) => {
|
|
const match = new RegExp(/^(\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?$/).exec(e.target.value);
|
|
|
|
if(!match){
|
|
onChange(undefined);
|
|
return;
|
|
}
|
|
|
|
const [ , h, m, s = "0", ms = "0"] = match;
|
|
|
|
const newDate = new Date();
|
|
newDate.setHours(Number(h), Number(m), Number(s), Number(ms));
|
|
|
|
onChange(Number.isNaN(newDate) ? undefined : newDate);
|
|
}
|
|
|
|
|
|
return (
|
|
<input
|
|
type="time"
|
|
id={id}
|
|
className={clsx(
|
|
"border rounded-lg px-2 py-1 outline-none",
|
|
className
|
|
)}
|
|
value={formatTime(value, step)}
|
|
onChange={changeTime}
|
|
step={step}
|
|
{...inputProps}
|
|
/>
|
|
);
|
|
}
|
|
|
|
|
|
function formatTime(date: Date | undefined, step: number){
|
|
if(!date || Number.isNaN(date.getTime())){
|
|
return "";
|
|
}
|
|
|
|
const h = String(date.getHours()).padStart(2, "0");
|
|
const m = String(date.getMinutes()).padStart(2, "0");
|
|
const s = String(date.getSeconds()).padStart(2, "0");
|
|
const ms = String(date.getMilliseconds()).padStart(3, "0");
|
|
|
|
let time = `${h}:${m}`;
|
|
if(step < 60){
|
|
time += `:${s}`;
|
|
}
|
|
if(step < 1){
|
|
time += `.${ms}`;
|
|
}
|
|
|
|
return time;
|
|
}
|