import React, { ReactElement, useMemo } from 'react'; import { getHours, getMinutes, getSeconds, setHours, setMinutes, setSeconds, } from 'date-fns'; import PanelColumn, { Unit } from './PanelColumn'; import { PanelContainer } from './StyledTimePicker'; import assert from '../../utils/assert'; import { leftPad } from './utils'; const supportedMinuteSteps = [1, 5, 10, 15, 20, 30, 60] as const; type MinuteStep = typeof supportedMinuteSteps[number]; export type PanelContentProps = { minuteStep: MinuteStep; onSelect: (val: Date) => void; resolvedValue: Date | undefined; with12Hours: boolean; withSeconds: boolean; }; const PanelContent = (props: PanelContentProps): ReactElement => { const { resolvedValue, with12Hours, withSeconds, onSelect, minuteStep, } = props; assert( supportedMinuteSteps.includes(minuteStep), `minuteStep ${minuteStep} is not supported` ); const setTime = ( isNewPM: boolean, newHour: number, newMinute: number, newSecond: number ): Date => { let newDate = new Date(); newDate = setHours( setMinutes(setSeconds(newDate, newSecond), newMinute), !with12Hours || !isNewPM ? newHour : newHour + 12 ); return newDate; }; const currentTime = resolvedValue !== undefined ? resolvedValue : new Date(); const rawHour = getHours(currentTime); const minute = getMinutes(currentTime); const second = getSeconds(currentTime); const isPM: boolean = with12Hours ? rawHour >= 12 : false; const hour = with12Hours ? rawHour % 12 : rawHour; const rawHours: Unit[] = useMemo( () => Array.from(new Array(24), (_, i) => { return { label: leftPad(i, 2), value: i }; }), [] ); const hours = useMemo(() => { if (!with12Hours) return rawHours; // Re-generate hours for AM/PM return rawHours .filter( isPM ? (h): boolean => h.value >= 12 : (h): boolean => h.value < 12 ) .map(h => { const hourValue = h.value % 12; const hourLabel = hourValue === 0 ? '12' : leftPad(hourValue, 2); return { ...h, label: hourLabel, value: hourValue, }; }); }, [with12Hours, isPM, rawHours]); const minutes: Unit[] = useMemo( () => Array.from(new Array(60 / minuteStep), (_, i) => { return { label: leftPad(i * minuteStep, 2), value: i * minuteStep }; }), [minuteStep] ); const seconds: Unit[] = useMemo( () => Array.from(new Array(60), (_, i) => { return { label: leftPad(i, 2), value: i }; }), [] ); return ( onSelect(setTime(isPM, newValue, minute, second)) } /> onSelect(setTime(isPM, hour, newValue, second)) } /> {withSeconds === true && ( onSelect(setTime(isPM, hour, minute, newValue)) } /> )} {with12Hours === true && ( onSelect(setTime(newValue !== 0, hour, minute, second)) } /> )} ); }; export default PanelContent;