69 lines
1.5 KiB
TypeScript
69 lines
1.5 KiB
TypeScript
import type { DateInputProps } from "$/types/InputTypes";
|
|
import clsx from "clsx";
|
|
import type { ChangeEvent } from "react";
|
|
|
|
|
|
export default function DateTimeInput({
|
|
id,
|
|
className,
|
|
step = 60,
|
|
value,
|
|
onChange,
|
|
...inputProps
|
|
}: Readonly<DateInputProps>){
|
|
const changeDateTime = (e: ChangeEvent<HTMLInputElement>) => {
|
|
const match = new RegExp(/^(\d+)-(\d+)-(\d+)T(\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?$/).exec(e.target.value);
|
|
|
|
if(!match){
|
|
onChange(undefined);
|
|
return;
|
|
}
|
|
|
|
const [ ,
|
|
y, mo, d,
|
|
h, mi, s = "0", ms = "0"
|
|
] = match;
|
|
|
|
const date = new Date(
|
|
Number(y), Number(mo) - 1, Number(d),
|
|
Number(h), Number(mi), Number(s), Number(ms)
|
|
);
|
|
|
|
onChange(Number.isNaN(date.getTime()) ? undefined : date);
|
|
}
|
|
|
|
|
|
return (
|
|
<input
|
|
type="datetime-local"
|
|
id={id}
|
|
className={clsx(
|
|
"border rounded-lg px-2 py-1 outline-none",
|
|
className
|
|
)}
|
|
value={formatDateTime(value)}
|
|
onChange={changeDateTime}
|
|
step={step}
|
|
{...inputProps}
|
|
/>
|
|
);
|
|
}
|
|
|
|
|
|
function formatDateTime(date: Date | undefined){
|
|
if(!date || Number.isNaN(date.getTime())){
|
|
return "";
|
|
}
|
|
|
|
const y = date.getFullYear();
|
|
const mo = String(date.getMonth() + 1).padStart(2, "0");
|
|
const d = String(date.getDate()).padStart(2, "0");
|
|
|
|
const h = String(date.getHours()).padStart(2, "0");
|
|
const mi = String(date.getMinutes()).padStart(2, "0");
|
|
const s = String(date.getSeconds()).padStart(2, "0");
|
|
const ms = String(date.getMilliseconds()).padStart(2, "0");
|
|
|
|
return `${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}`;
|
|
}
|