diff --git a/ui-core/src/components/inputs/TimePicker.tsx b/ui-core/src/components/inputs/TimePicker.tsx index d737250c..e6511a34 100644 --- a/ui-core/src/components/inputs/TimePicker.tsx +++ b/ui-core/src/components/inputs/TimePicker.tsx @@ -1,11 +1,14 @@ -import React, { useState, useRef } from 'react'; +import React, { useState, useRef, useCallback } from 'react'; import cx from 'classnames'; import Input, { type InputProps } from './Input'; import InputModal from '../Modal'; -export type TimePickerProps = InputProps & { +export type TimePickerProps = Omit< + InputProps, + 'type' | 'name' | 'value' | 'onClick' | 'onChange' | 'ref' | 'step' +> & { hours?: number; minutes?: number; seconds?: number; @@ -42,6 +45,10 @@ const TimeRange = ({ range, selectedItem, className, onSelectItem }: TimeRangePr ); +function formatTimeValue(value: number, max: number) { + return Math.max(0, Math.min(max, value)).toString().padStart(2, '0'); +} + const TimePicker = ({ onTimeChange, hours = 0, @@ -53,78 +60,82 @@ const TimePicker = ({ const [isModalOpen, setIsModalOpen] = useState(false); const inputRef = useRef(null); - const incrementMinute = (increment: number) => { - let newMinutes = minutes + increment; - let newHours = hours; - - if (newMinutes >= 60) { - newMinutes = 0; - newHours = (newHours + 1) % 24; - } else if (newMinutes < 0) { - newMinutes = 59; - newHours = (newHours + 23) % 24; // minus 1 hour - } - onTimeChange({ hours: newHours, minutes: newMinutes, seconds }); - }; - - const incrementSeconds = (increment: number) => { - let newSeconds = seconds + increment; - let newMinutes = minutes; - let newHours = hours; - - if (newSeconds >= 60) { - newSeconds = 0; - newMinutes += 1; + const incrementMinute = useCallback( + (increment: number) => { + let newMinutes = minutes + increment; + let newHours = hours; if (newMinutes >= 60) { newMinutes = 0; newHours = (newHours + 1) % 24; - } - } else if (newSeconds < 0) { - newSeconds = 59; - newMinutes -= 1; - - if (newMinutes < 0) { + } else if (newMinutes < 0) { newMinutes = 59; newHours = (newHours + 23) % 24; // minus 1 hour } - } - onTimeChange({ hours: newHours, minutes: newMinutes, seconds: newSeconds }); - }; - - const handleChange = (event: React.ChangeEvent) => { - const value = event.target.value; - if (!displaySeconds) { - const [h, m] = value.split(':'); - if (h !== undefined && m !== undefined) { - onTimeChange({ hours: parseInt(h), minutes: parseInt(m) }); - } - } else { - const [h, m, s] = value.split(':'); - if (h !== undefined && m !== undefined && s !== undefined) { - onTimeChange({ hours: parseInt(h), minutes: parseInt(m), seconds: parseInt(s) }); + onTimeChange({ hours: newHours, minutes: newMinutes, seconds }); + }, + [hours, minutes, seconds, onTimeChange] + ); + + const incrementSeconds = useCallback( + (increment: number) => { + let newSeconds = seconds + increment; + let newMinutes = minutes; + let newHours = hours; + + if (newSeconds >= 60) { + newSeconds = 0; + newMinutes += 1; + + if (newMinutes >= 60) { + newMinutes = 0; + newHours = (newHours + 1) % 24; + } + } else if (newSeconds < 0) { + newSeconds = 59; + newMinutes -= 1; + + if (newMinutes < 0) { + newMinutes = 59; + newHours = (newHours + 23) % 24; // minus 1 hour + } } - } - }; + onTimeChange({ hours: newHours, minutes: newMinutes, seconds: newSeconds }); + }, + [hours, minutes, seconds, onTimeChange] + ); - const formatTimeValue = (value: number, max: number) => - Math.max(0, Math.min(max, value)).toString().padStart(2, '0'); + const handleChange = useCallback( + (event: React.ChangeEvent) => { + const value = event.target.value; + if (!displaySeconds) { + const [h, m] = value.split(':'); + if (h !== undefined && m !== undefined) { + onTimeChange({ hours: parseInt(h), minutes: parseInt(m) }); + } + } else { + const [h, m, s] = value.split(':'); + if (h !== undefined && m !== undefined && s !== undefined) { + onTimeChange({ hours: parseInt(h), minutes: parseInt(m), seconds: parseInt(s) }); + } + } + }, + [displaySeconds, onTimeChange] + ); const displayedSecondsPart = displaySeconds ? `:${formatTimeValue(seconds, 59)}` : ''; const selectedTime = `${formatTimeValue(hours, 23)}:${formatTimeValue(minutes, 59)}${displayedSecondsPart}`; const hoursRange = [...Array(24).keys()]; const minutesAndSecondsRange = [...Array(12).keys()].map((i) => i * 5); - const openModal = () => { - setIsModalOpen(true); - }; - - const closeModal = () => setIsModalOpen(false); + const openModal = useCallback(() => setIsModalOpen(true), []); + const closeModal = useCallback(() => setIsModalOpen(false), []); return (