import React, { forwardRef } from 'react'; import { Menu, Box, Text, Chip } from 'folds'; import dayjs from 'dayjs'; import * as css from './styles.css'; import { PickerColumn } from './PickerColumn'; import { hour12to24, hour24to12, hoursToMs, inSameDay, minutesToMs } from '../../utils/time'; type TimePickerProps = { min: number; max: number; value: number; onChange: (value: number) => void; }; export const TimePicker = forwardRef( ({ min, max, value, onChange }, ref) => { const hour24 = dayjs(value).hour(); const selectedHour = hour24to12(hour24); const selectedMinute = dayjs(value).minute(); const selectedPM = hour24 >= 12; const handleSubmit = (newValue: number) => { onChange(Math.min(Math.max(min, newValue), max)); }; const handleHour = (hour: number) => { const seconds = hoursToMs(hour12to24(hour, selectedPM)); const lastSeconds = hoursToMs(hour24); const newValue = value + (seconds - lastSeconds); handleSubmit(newValue); }; const handleMinute = (minute: number) => { const seconds = minutesToMs(minute); const lastSeconds = minutesToMs(selectedMinute); const newValue = value + (seconds - lastSeconds); handleSubmit(newValue); }; const handlePeriod = (pm: boolean) => { const seconds = hoursToMs(hour12to24(selectedHour, pm)); const lastSeconds = hoursToMs(hour24); const newValue = value + (seconds - lastSeconds); handleSubmit(newValue); }; const minHour24 = dayjs(min).hour(); const maxHour24 = dayjs(max).hour(); const minMinute = dayjs(min).minute(); const maxMinute = dayjs(max).minute(); const minPM = minHour24 >= 12; const maxPM = maxHour24 >= 12; const minDay = inSameDay(min, value); const maxDay = inSameDay(max, value); return ( {Array.from(Array(12).keys()) .map((i) => { if (i === 0) return 12; return i; }) .map((hour) => ( handleHour(hour)} disabled={ (minDay && hour12to24(hour, selectedPM) < minHour24) || (maxDay && hour12to24(hour, selectedPM) > maxHour24) } > {hour < 10 ? `0${hour}` : hour} ))} {Array.from(Array(60).keys()).map((minute) => ( handleMinute(minute)} disabled={ (minDay && hour24 === minHour24 && minute < minMinute) || (maxDay && hour24 === maxHour24 && minute > maxMinute) } > {minute < 10 ? `0${minute}` : minute} ))} handlePeriod(false)} disabled={minDay && minPM} > AM handlePeriod(true)} disabled={maxDay && !maxPM} > PM ); } );