UNPKG

@mantine/dates

Version:

Calendars, date and time pickers based on Mantine components

1 lines 10.7 kB
{"version":3,"file":"use-time-picker.cjs","names":["getParsedTime","getTimeString","clampTime"],"sources":["../../../src/components/TimePicker/use-time-picker.ts"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { useDidUpdate } from '@mantine/hooks';\nimport type {\n TimePickerAmPmLabels,\n TimePickerFormat,\n TimePickerPasteSplit,\n TimePickerType,\n} from './TimePicker.types';\nimport { clampTime } from './utils/clamp-time/clamp-time';\nimport { getParsedTime } from './utils/get-parsed-time/get-parsed-time';\nimport { getTimeString } from './utils/get-time-string/get-time-string';\n\ninterface UseTimePickerInput {\n value: string | undefined;\n defaultValue: string | undefined;\n onChange: ((value: string) => void) | undefined;\n format: TimePickerFormat;\n amPmLabels: TimePickerAmPmLabels;\n withSeconds: boolean | undefined;\n min: string | undefined;\n max: string | undefined;\n readOnly: boolean | undefined;\n disabled: boolean | undefined;\n clearable: boolean | undefined;\n pasteSplit: TimePickerPasteSplit | undefined;\n type: TimePickerType;\n}\n\nexport function useTimePicker({\n value,\n defaultValue,\n onChange,\n format,\n amPmLabels,\n withSeconds = false,\n min,\n max,\n clearable,\n readOnly,\n disabled,\n pasteSplit,\n type,\n}: UseTimePickerInput) {\n const parsedTime = getParsedTime({\n time: value || defaultValue || '',\n amPmLabels,\n format,\n });\n\n const initialTimeString = getTimeString({\n hours: parsedTime.hours,\n minutes: parsedTime.minutes,\n seconds: parsedTime.seconds,\n format,\n withSeconds,\n amPm: parsedTime.amPm,\n amPmLabels,\n });\n\n const acceptChange = useRef(true);\n const wasInvalidBefore = useRef(!initialTimeString.valid);\n\n const [hours, setHours] = useState<number | null>(parsedTime.hours);\n const [minutes, setMinutes] = useState<number | null>(parsedTime.minutes);\n const [seconds, setSeconds] = useState<number | null>(parsedTime.seconds);\n const [amPm, setAmPm] = useState<string | null>(parsedTime.amPm);\n\n const isClearable =\n clearable &&\n !readOnly &&\n !disabled &&\n (hours !== null || minutes !== null || seconds !== null || amPm !== null);\n\n const hoursRef = useRef<HTMLInputElement>(null);\n const minutesRef = useRef<HTMLInputElement>(null);\n const secondsRef = useRef<HTMLInputElement>(null);\n const amPmRef = useRef<HTMLSelectElement>(null);\n\n const focus = (field: 'hours' | 'minutes' | 'seconds' | 'amPm') => {\n if (field === 'hours') {\n hoursRef.current?.focus();\n }\n\n if (field === 'minutes') {\n minutesRef.current?.focus();\n }\n\n if (field === 'seconds') {\n secondsRef.current?.focus();\n }\n\n if (field === 'amPm') {\n amPmRef.current?.focus();\n }\n };\n\n const handleTimeChange = (field: 'hours' | 'minutes' | 'seconds' | 'amPm', val: any) => {\n const timeString = getTimeString({\n hours: field === 'hours' ? val : hours,\n minutes: field === 'minutes' ? val : minutes,\n seconds: field === 'seconds' ? val : seconds,\n amPm: field === 'amPm' ? val : amPm,\n format,\n withSeconds,\n amPmLabels,\n });\n\n if (timeString.valid) {\n acceptChange.current = false;\n wasInvalidBefore.current = false;\n if (field === 'hours') {\n setHours(val);\n }\n if (field === 'minutes') {\n setMinutes(val);\n }\n if (field === 'seconds') {\n setSeconds(val);\n }\n if (field === 'amPm') {\n setAmPm(val);\n }\n\n onChange?.(timeString.value);\n } else {\n acceptChange.current = false;\n if (!wasInvalidBefore.current) {\n onChange?.('');\n wasInvalidBefore.current = true;\n }\n }\n };\n\n const setTimeString = (timeString: string) => {\n acceptChange.current = false;\n\n const parsedTime = getParsedTime({ time: timeString, amPmLabels, format });\n setHours(parsedTime.hours);\n setMinutes(parsedTime.minutes);\n setSeconds(parsedTime.seconds);\n setAmPm(parsedTime.amPm);\n\n const next = getTimeString({ ...parsedTime, format, withSeconds, amPmLabels });\n wasInvalidBefore.current = !next.valid;\n onChange?.(timeString);\n };\n\n const onHoursChange = (value: number | null) => {\n let adjustedValue = value;\n if (format === '12h' && typeof value === 'number' && value > 12) {\n adjustedValue = ((value - 1) % 12) + 1;\n }\n\n setHours(adjustedValue);\n handleTimeChange('hours', adjustedValue);\n focus('hours');\n };\n\n const onMinutesChange = (value: number | null) => {\n setMinutes(value);\n handleTimeChange('minutes', value);\n focus('minutes');\n };\n\n const onSecondsChange = (value: number | null) => {\n setSeconds(value);\n handleTimeChange('seconds', value);\n focus('seconds');\n };\n\n const onAmPmChange = (value: string | null) => {\n setAmPm(value);\n handleTimeChange('amPm', value);\n focus('amPm');\n };\n\n const clear = () => {\n acceptChange.current = false;\n setHours(null);\n setMinutes(null);\n setSeconds(null);\n setAmPm(null);\n onChange?.('');\n wasInvalidBefore.current = true;\n focus('hours');\n };\n\n const onPaste = (event: React.ClipboardEvent<any>) => {\n event.preventDefault();\n const pastedValue = event.clipboardData.getData('text');\n const parsedTime = (pasteSplit || getParsedTime)({ time: pastedValue, format, amPmLabels });\n const timeString = getTimeString({ ...parsedTime, format, withSeconds, amPmLabels });\n if (timeString.valid) {\n acceptChange.current = false;\n const defaultMax = type === 'duration' ? undefined : '23:59:59';\n const clamped = clampTime(timeString.value, min || '00:00:00', max || defaultMax);\n onChange?.(clamped.timeString);\n setHours(parsedTime.hours);\n setMinutes(parsedTime.minutes);\n setSeconds(parsedTime.seconds);\n setAmPm(parsedTime.amPm);\n }\n };\n\n const hiddenInputValue = getTimeString({\n hours,\n minutes,\n seconds,\n format,\n withSeconds,\n amPm,\n amPmLabels: amPmLabels!,\n });\n\n useDidUpdate(() => {\n if (value === '') {\n acceptChange.current = false;\n setHours(null);\n setMinutes(null);\n setSeconds(null);\n setAmPm(null);\n acceptChange.current = true;\n return;\n }\n\n if (acceptChange.current && typeof value === 'string') {\n const parsedTime = getParsedTime({ time: value || '', amPmLabels, format });\n setHours(parsedTime.hours);\n setMinutes(parsedTime.minutes);\n setSeconds(parsedTime.seconds);\n setAmPm(parsedTime.amPm);\n }\n acceptChange.current = true;\n }, [value]);\n\n return {\n refs: { hours: hoursRef, minutes: minutesRef, seconds: secondsRef, amPm: amPmRef },\n values: { hours, minutes, seconds, amPm },\n setHours: onHoursChange,\n setMinutes: onMinutesChange,\n setSeconds: onSecondsChange,\n setAmPm: onAmPmChange,\n focus,\n clear,\n onPaste,\n setTimeString,\n isClearable,\n hiddenInputValue: hiddenInputValue.value,\n };\n}\n"],"mappings":"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"}