Skip to content

DateTimePicker

날과 시각을 한 팝업에서 고릅니다. 달력과 시계는 정확히 같은 높이로 나란히 서고, 그래서 팝업은 크기가 다른 두 덩어리가 아니라 하나의 사각형입니다.

tsx
import { DateTimePicker } from 'neba';

<DateTimePicker label="게시 시각" placeholder="순간을 고르세요" minuteStep={15} clearable />;

Props

Prop타입기본값설명
variant공통'solid' | 'outline' | 'text''outline'표면의 무게. 채움 / 하이라인 / 없음
size공통'xs' | 'sm' | 'md' | 'lg' | 'xl''md'높이와 타입 스케일
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'의미론적 색 역할. 임의 색상값은 받지 않습니다
density공통'default' | 'compact''default'여백만 바꿉니다. 높이와 글자 크기는 그대로
elevation공통0 | 1 | 2 | 30그림자 깊이. 0은 그림자 없음
valueDate | null선택된 순간. onValueChange와 함께 제어 컴포넌트로 씁니다
defaultValueDate | null초기 값
onValueChange(value: Date | null) => void선택이 바뀔 때
defaultMonthDate값이 없을 때 달력이 열리는 달. 기본값은 이번 달
minDateDate | null고를 수 있는 가장 이른 순간. DatePicker와 달리 시각까지 읽습니다 — 그 날은 달력에 남고, 시계에서 그 앞 시간들이 빠집니다
maxDateDate | nullminDate의 반대쪽 끝
shouldDisableDate(date: Date) => boolean범위 안이지만 고를 수 없는 날 — 주말, 공휴일, 이미 예약된 방. 셀은 목록에 남은 채 비활성이 됩니다
weekStartsOn공통0 | 1 | 2 | 3 | 4 | 5 | 6주가 시작하는 요일. 일요일이 0입니다. 기본값은 로케일이 말하는 것
hour12boolean12시간 다이얼과 오전/오후 열. 기본값은 로케일이 하는 대로
showSecondsbooleanfalse초 열을 추가합니다
hourStepnumber1시 열의 간격
minuteStepnumber1분 열의 간격
secondStepnumber1초 열의 간격
shouldDisableTime(value: Date, unit: 'hour' | 'minute' | 'second' | 'meridiem') => boolean개별 행을 막습니다. 열마다 행마다 한 번씩, 그 행이 만들 순간과 어느 열인지를 받습니다
showNowButtonbooleantrue푸터에 지금으로 가는 단축 버튼
openboolean팝업이 열려 있는지. onOpenChange와 함께 제어 컴포넌트로 씁니다
defaultOpenbooleanfalse처음에 열린 채로 시작
onOpenChange(open: boolean) => void열리거나 닫힐 때
localestringBCP 47 태그. 월·요일 이름, 헤더의 연/월 버튼 순서, 트리거의 표기를 정합니다. 기본값은 브라우저의 로케일
formatIntl.DateTimeFormatOptions트리거가 값을 쓰는 방식. Intl에 그대로 넘어갑니다
placeholderReactNode아무것도 고르지 않았을 때 트리거에 보이는 내용
clearablebooleanfalse값을 비우는 ×를 트리거에 답니다
closeOnSelectbooleanfalse날을 고르는 즉시 닫습니다. 순간은 날 *그리고* 시각이므로, 둘 중 첫 번째에서 닫으면 두 번째를 묻지 못한 채 끝납니다
labelsPartial<PickerLabels>스크린 리더가 듣는 문자열들. 열여덟 개가 한 벌이라 프롭 하나로 받습니다 — 날짜 이름은 여기 없고 Intl이 만듭니다
namestring폼 제출 시의 필드 이름. 값은 YYYY-MM-DDTHH:MM, 로컬 기준입니다
fullWidthbooleanfalse컨테이너 너비만큼 확장
labelReactNode컨트롤과 연결되는 라벨. Base UI Field가 묶어 줍니다
descriptionReactNode보조 설명
errorReactNode오류 메시지. 값이 있으면 invalid 상태도 함께 켜지고 색 계열이 danger로 넘어갑니다
invalidboolean!!error메시지 없이 invalid만 켭니다. 외부 폼 라이브러리가 유효성을 가질 때
readOnlybooleanfalse값은 보이지만 바꿀 수 없음. 색과 가장자리는 유지한 채 채도만 빠집니다
disabledbooleanfalse사용 불가. 색 계열을 버리고 중립 회색이 됩니다

나머지는 전부 DatePickerTimePicker의 것 그대로입니다 — 같은 세 가지 달력 뷰, 같은 열 동작, 같은 Date 값. 여기서 읽을 만한 것은 정말로 다른 부분입니다.

범위를 시각까지 읽습니다

DateTimePicker가 필드 두 개를 나란히 놓는 대신 별도의 컴포넌트일 값을 하는 대목입니다.

DatePickerminDate는 날짜 단위입니다 — 27일은 있거나 없거나입니다. 여기서는 아닙니다. 스케줄 폼이 실제로 필요로 하는 규칙은 "지금 이전은 안 됨"이고, 지금은 날인 동시에 시각이기 때문입니다. 그래서 27일 09:30이 minDate이면 달력에서 27일은 그대로 고를 수 있고, 시계에서 오전이 흐려집니다.

시계 쪽 검사는 TimePicker가 하는 구간 비교를, 열이 어느 날에 쓰고 있는지 알 수 있도록 절대 시간축 위로 옮긴 것입니다. 경계가 되는 날에는 최솟값 이전 시간들이 막히고, 그 뒤의 날에는 하나도 막히지 않습니다.

값은 하나, 반쪽은 둘, 순서는 없음

날을 고르면 날이 바뀌고 시계는 그대로입니다. 시를 고르면 시계가 바뀌고 날은 그대로입니다. 날짜를 고칠 때마다 시각을 자정으로 되돌리는 피커는 순간을 고르는 일을 순서 있는 작업으로 만듭니다. 팝업을 쓰인 순서대로 읽는 사람은 없습니다.

closeOnSelect의 기본값이 false이고 푸터에 Done이 있는 것도 같은 이유입니다. 순간은 날 그리고 시각이므로, 둘 중 첫 번째에서 닫으면 두 번째를 묻지 못한 채 끝납니다.

글리프는 하나입니다

트리거는 달력을 달고 시계는 달지 않습니다. 컨트롤은 한 번에 두 가지를 말할 수 없고, 읽는 사람이 눈으로 찾는 쪽은 날짜입니다.

접근성

달력은 role="grid", 시계는 role="listbox" 열들입니다 — 이 컴포넌트를 이루는 두 컴포넌트에서와 정확히 같습니다. DatePickerTimePicker를 보세요. 트리거는 Intl로 양쪽을 한 문자열에 씁니다. 스크린 리더가 읽는 것은 이어 붙여야 할 두 필드가 아니라 하나의 문장입니다.

Released under the MIT License