useDateTimePicker
날짜와 시간을 함께 선택하기 위한 훅입니다. useDatePicker를 확장하여 시간 상태(시, 분, 초, 오전/오후)와 중첩된 시간 선택기를 제공합니다.
Import
import { useDateTimePicker } from "react-date-range-picker-headless";사용법
import { useState } from "react";import { useDateTimePicker } from "react-date-range-picker-headless";
function MyDateTimePicker() { const [dateTime, setDateTime] = useState<Date | null>(null);
const picker = useDateTimePicker({ value: dateTime, onChange: setDateTime, time: { precision: "minute", hourFormat: "24", minuteStep: 5 }, });
return ( <div ref={picker.containerRef}> <button onClick={picker.handleToggle}> {picker.displayValue || picker.locale.dateTimePlaceholder} </button> {picker.isOpen && ( <div ref={picker.popupRef} onKeyDown={picker.handleKeyDown}> {/* Calendar (same as useDatePicker) */} <div> <button onClick={picker.handlePrevMonth}>{picker.locale.prevMonth}</button> <span>{picker.locale.formatMonthYear(picker.calendar.month)}</span> <button onClick={picker.handleNextMonth}>{picker.locale.nextMonth}</button> </div> {/* ...calendar grid... */}
{/* Time display */} <div> <span>Time: {picker.timeDisplayValue}</span> </div>
{/* Time controls */} <div> <input type="number" value={picker.tempHour} onChange={(e) => picker.handleHourChange(Number(e.target.value))} /> <span>:</span> <input type="number" value={picker.tempMinute} onChange={(e) => picker.handleMinuteChange(Number(e.target.value))} /> </div>
<button onClick={picker.handleConfirm}>{picker.locale.confirm}</button> </div> )} </div> );}옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value | Date | null | — | 필수. 현재 날짜-시간 값입니다. |
onChange | (dateTime: Date | null) => void | — | 필수. 날짜-시간이 변경될 때 호출됩니다. |
time | TimeConfig | { precision: "minute", hourFormat: "24", minuteStep: 5, secondStep: 1 } | 시간 선택기 설정입니다. |
minDate | Date | — | 선택 가능한 가장 이른 날짜입니다. |
maxDate | Date | — | 선택 가능한 가장 늦은 날짜입니다. |
locale | Partial<Locale> | DEFAULT_LOCALE | 로케일 문자열을 재정의합니다. |
initialMonth | Date | — | 초기에 표시할 월입니다. |
size | DatePickerSize | — | UI 패스스루 속성입니다. |
weekStartsOn | WeekDay | "sunday" | 한 주의 시작 요일입니다. |
isDateUnavailable | (date: Date) => boolean | — | 특정 날짜를 비활성화하는 사용자 정의 함수입니다. |
displayFormat | string | — | 표시 값에 대한 사용자 정의 포맷 문자열입니다. |
open | boolean | — | 제어되는 열림 상태입니다. |
initialOpen | boolean | false | 초기 열림 상태입니다. |
onOpenChange | (open: boolean) => void | — | 열림 상태가 변경될 때의 콜백입니다. |
required | boolean | false | true일 경우, handleClear는 아무 작업도 하지 않습니다. |
today | Date | new Date() | 오늘 날짜를 재정의합니다. |
onMonthChange | (month: Date) => void | — | 월이 변경될 때의 콜백입니다. |
disablePast | boolean | false | 과거 날짜를 비활성화합니다. |
disableFuture | boolean | false | 미래 날짜를 비활성화합니다. |
showOutsideDays | boolean | false | 인접한 달의 날짜를 표시합니다. |
highlightDates | Date[] | — | 강조할 날짜들입니다. |
shouldCloseOnSelect | boolean | false | 날짜-시간 선택기의 경우, 날짜 클릭이 아닌 사전 설정(preset) 클릭에만 적용됩니다. |
numberOfMonths | number | 1 | 달력 월의 수입니다. |
captionLayout | CaptionLayout | "buttons" | 캡션 레이아웃 모드입니다. |
fromYear | number | current year - 100 | 드롭다운의 시작 연도입니다. |
toYear | number | current year + 10 | 드롭다운의 종료 연도입니다. |
반환 값
날짜 상태
| 이름 | 타입 | 설명 |
|---|---|---|
isOpen | boolean | 팝업이 열려 있는지 여부입니다. |
tempDate | Date | null | 임시로 선택된 날짜입니다. |
currentMonth | Date | 현재 표시된 월입니다. |
locale | Locale | 결정된 로케일 객체입니다. |
시간 상태
| 이름 | 타입 | 설명 |
|---|---|---|
isTimePickerOpen | boolean | 시간 선택기 하위 패널이 열려 있는지 여부입니다. |
tempHour | number | 현재 임시 시(hour) 값입니다. |
tempMinute | number | 현재 임시 분(minute) 값입니다. |
tempSecond | number | 현재 임시 초(second) 값입니다. |
tempPeriod | TimePeriod | 현재 오전/오후 기간 ("AM" 또는 "PM")입니다. |
날짜 액션
| 이름 | 타입 | 설명 |
|---|---|---|
handleDateClick | (date: Date) => void | 날짜 셀 클릭을 처리합니다. |
handlePrevMonth | () => void | 이전 월로 이동합니다. |
handleNextMonth | () => void | 다음 월로 이동합니다. |
handleOpen | () => void | 팝업을 엽니다. |
handleClose | () => void | 팝업을 닫습니다. |
handleToggle | () => void | 팝업을 토글합니다. |
handleConfirm | () => void | 날짜와 시간을 확정하고 닫습니다. |
handleCancel | () => void | 취소하고 원래대로 되돌립니다. |
handleClear | () => void | 값을 지웁니다. |
handleGoToToday | () => void | 오늘 날짜로 이동합니다. |
시간 액션
| 이름 | 타입 | 설명 |
|---|---|---|
handleHourChange | (hour: number) => void | 시(hour)를 업데이트합니다. |
handleMinuteChange | (minute: number) => void | 분(minute)을 업데이트합니다. |
handleSecondChange | (second: number) => void | 초(second)를 업데이트합니다. |
handlePeriodChange | (period: TimePeriod) => void | 오전/오후를 토글합니다. |
handleTimePickerOpen | () => void | 시간 선택기 하위 패널을 엽니다. |
handleTimePickerClose | () => void | 시간 선택기 하위 패널을 닫습니다. |
handleTimePickerConfirm | () => void | 시간 선택기 하위 패널을 확정합니다. |
handleTimePickerCancel | () => void | 시간 선택기 하위 패널을 취소합니다. |
계산된 값
| 이름 | 타입 | 설명 |
|---|---|---|
calendar | CalendarMonth | 현재 월의 달력 데이터입니다. |
calendars | CalendarMonth[] | 달력 월의 배열입니다. |
getDayProps | (date: Date, referenceMonth?: Date) => DayProps | 날짜 셀 속성(props)입니다. |
displayValue | string | 포맷된 날짜-시간 문자열입니다. |
timeDisplayValue | string | 포맷된 시간 문자열입니다. |
hasValue | boolean | 값이 확정되었는지 여부입니다. |
canConfirm | boolean | 확정이 유효한지 여부입니다. |
containerRef | RefObject<HTMLDivElement | null> | 컨테이너 ref입니다. |
popupRef | RefObject<HTMLDivElement | null> | 팝업 ref입니다. |
timePickerRef | RefObject<HTMLDivElement | null> | 시간 선택기 하위 패널 ref입니다. |
focusedDate | Date | null | 키보드로 포커스된 날짜입니다. |
handleKeyDown | (e: KeyboardEvent<HTMLElement>) => void | 키보드 핸들러입니다. |
resolvedTimeConfig | Required<TimeConfig> | 기본값이 채워진, 결정된 시간 설정입니다. |
years | number[] | 드롭다운 모드용 연도 배열입니다. |
months | number[] | 드롭다운 모드용 월 배열입니다. |
handleYearSelect | (year: number, calendarIndex?: number) => void | 연도를 설정합니다. |
handleMonthSelect | (month: number, calendarIndex?: number) => void | 월을 설정합니다. |
주요 동작
시간 설정
time 옵션은 TimeConfig 객체를 받습니다:
interface TimeConfig { precision?: "hour" | "minute" | "second"; // 기본값: "minute" hourFormat?: "12" | "24"; // 기본값: "24" minuteStep?: 1 | 2 | 3 | 5 | 10 | 15 | 20 | 30; // 기본값: 5 secondStep?: 1 | 2 | 3 | 5 | 10 | 15 | 20 | 30; // 기본값: 1 itemHeight?: number; // 기본값: 32}shouldCloseOnSelect
날짜-시간 선택기에서, shouldCloseOnSelect는 날짜 클릭이 아닌 사전 설정(preset) 클릭에만 동작합니다. 이는 사용자가 날짜를 선택한 후에도 시간을 설정해야 하기 때문입니다.
resolvedTimeConfig
resolvedTimeConfig 반환 값은 모든 기본값이 채워진, 완전히 결정된 시간 설정을 포함합니다. 시간 관련 UI 컴포넌트를 만들 때 이 값을 사용하면 기본값을 다시 계산하는 것을 피할 수 있습니다.