67 lines
1.6 KiB
TypeScript
67 lines
1.6 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import flatpickr from 'flatpickr';
|
|
import type { Instance } from 'flatpickr/dist/types/instance';
|
|
import 'flatpickr/dist/flatpickr.min.css';
|
|
|
|
type Props = {
|
|
id: string;
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
required?: boolean;
|
|
placeholder?: string;
|
|
};
|
|
|
|
export function FormTimePicker({ id, value, onChange, required, placeholder = 'Select time' }: Props) {
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
const fpRef = useRef<Instance | null>(null);
|
|
const onChangeRef = useRef(onChange);
|
|
onChangeRef.current = onChange;
|
|
|
|
useEffect(() => {
|
|
const el = inputRef.current;
|
|
if (!el) return;
|
|
|
|
fpRef.current = flatpickr(el, {
|
|
enableTime: true,
|
|
noCalendar: true,
|
|
dateFormat: 'H:i',
|
|
altInput: true,
|
|
altFormat: 'h:i K',
|
|
altInputClass: 'form-input form-picker-input form-picker-input--time',
|
|
time_24hr: false,
|
|
defaultDate: value || undefined,
|
|
disableMobile: true,
|
|
onChange: (_dates, timeStr) => {
|
|
onChangeRef.current(timeStr);
|
|
},
|
|
});
|
|
|
|
return () => {
|
|
fpRef.current?.destroy();
|
|
fpRef.current = null;
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const fp = fpRef.current;
|
|
if (!fp) return;
|
|
const current = fp.selectedDates.length ? fp.formatDate(fp.selectedDates[0], 'H:i') : '';
|
|
if (current !== value) {
|
|
fp.setDate(value || '', false);
|
|
}
|
|
}, [value]);
|
|
|
|
return (
|
|
<input
|
|
ref={inputRef}
|
|
id={id}
|
|
type="text"
|
|
className="form-picker-source"
|
|
readOnly
|
|
required={required}
|
|
placeholder={placeholder}
|
|
aria-required={required || undefined}
|
|
/>
|
|
);
|
|
}
|