TimePicker
시 + 분 (+ 선택적으로 초) 선택. 12시간제 또는 24시간제.

import { TimePicker } from '@kalyx/react';
기본 사용
import { useState } from 'react';
import { TimePicker, type ISODateString } from '@kalyx/react';
function Example() {
const [time, setTime] = useState<ISODateString | null>(null);
return (
<TimePicker value={time} onChange={setTime} format="24h" step={15}>
<TimePicker.Input />
<TimePicker.HourList />
<TimePicker.MinuteList />
</TimePicker>
);
}
값은 여전히 ISO 8601 UTC 문자열이고, 날짜 부분은 placeholder 역할. 시/분만 필요하면 @kalyx/core의 getTime(iso)를 쓰세요.
직접 사용해보기
라이브 에디터는
React와 모든 Kalyx 컴포넌트를 스코프에 두고 실행되므로import줄을 생략했습니다. 프로젝트로 옮길 때 채워 넣으세요. 전체 import 는 위의 일반 코드 블록에 있습니다.
function Basic24h() { const [time, setTime] = React.useState(null); return ( <TimePicker value={time} onChange={setTime} format="24h" step={15}> <TimePicker.Input className="kx-live-input" style={{ minWidth: '8rem' }} /> <div className="kx-live-row" style={{ marginTop: 8 }}> <TimePicker.HourList classNames={{ root: 'kx-live-list', option: 'kx-live-option', optionSelected: 'kx-live-option-selected', }} /> <TimePicker.MinuteList classNames={{ root: 'kx-live-list', option: 'kx-live-option', optionSelected: 'kx-live-option-selected', }} /> </div> <div className="kx-live-value" style={{ marginTop: 8 }}> 선택됨: <code>{time ?? 'null'}</code> </div> </TimePicker> ); }
<TimePicker> (Root)
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
value | ISODateString | null | - | 제어형 시간. |
defaultValue | ISODateString | - | 비제어 초기값. |
onChange | (value: ISODateString | null) => void | - | 시/분/AM·PM 변경 시 호출. |
format | '12h' | '24h' | '24h' | 시간 포맷. |
step | number | 1 | 분 간격 (예: 5, 15, 30). |
withSeconds | boolean | false | 초 표시 (입력 + 리스트). |
displayTimezone | string | - | IANA 타임존. 설정 시 시/분 컨트롤이 이 타임존 기준으로 시간을 읽고 쓴다 (DST 인식). Timezone 참고. |
disabled | boolean | false | 전체 비활성. |
readOnly | boolean | false | 변경 방지. |
filterTime | (hours: number, minutes: number) => boolean | - | 슬롯별 비활성 predicate. true를 반환하면 해당 슬롯을 선택 불가로 만든다 (MUI X의 shouldDisableTime과 같은 극성. react-datepicker의 filterTime(슬롯을 유지하려면 true)과는 반대). 시(hour)는 해당 시의 모든 step 분이 true일 때만 비활성. format과 무관하게 항상 24시간 값을 받는다. |
locale | string | 'en-US' | AM/PM 라벨을 지역화하는 BCP 47 locale (ko-KR 이면 오전 / 오후). ARIA 라벨은 바뀌지 않는다. 그쪽은 labels 로 지정한다. |
onOpenChange | (isOpen: boolean) => void | - | TimePicker.Popover 가 열리거나 닫힐 때 호출된다. |
labels | Partial<TimePickerLabels> | - | ARIA 라벨 재정의. 키: timeInput, hourList, minuteList, amPmToggle, hourOption(h), minuteOption(m). |
children | ReactNode | - | 서브 컴포넌트. |
<TimePicker.Input>
HH:MM (또는 withSeconds 시 HH:MM:SS)을 표시하는 텍스트 입력. Enter/blur에서 파싱.
value,onChange,type제외한<input>속성 확장.aria-label기본값은 영어"Time"이다.locale="ko-KR"을 줘도 ARIA 라벨은 바뀌지 않는다. 한국어로 바꾸려면 Root 에labels={{ timeInput: '시간 입력' }}을 넘긴다.
<TimePicker.Popover>
선택적으로 쓰는 부유 컨테이너, role="dialog". 생략하면 리스트가 인라인으로 렌더된다.
TimePicker.Input 이 클릭과 ArrowDown 으로 열고 Escape 로 닫는다.
열림/닫힘을 관찰하려면 Root 의 onOpenChange 를 쓴다.
| Prop | 타입 | 설명 |
|---|---|---|
classNames | TimePickerPopoverClassNames | 스타일 슬롯. |
<TimePicker.HourList>
사용 가능한 시 목록 (role="listbox").
| Prop | 타입 | 설명 |
|---|---|---|
classNames | TimePickerHourListClassNames | 스타일. |
type TimePickerHourListClassNames = {
root?: string; // <ul>
option?: string; // <li role="option">
optionSelected?: string;
};
시 집합:
format="24h"→0~23format="12h"→1~12(<AmPmToggle>로 오전/오후 관리)
각 옵션은 현재 시일 때 data-selected 를 갖습니다. MinuteList 와 AmPmToggle 의 옵션도 같은 data-selected 플래그를 내보냅니다. 스타일링 참고.
<TimePicker.MinuteList>
step으로 필터된 분 목록 (role="listbox").
| Prop | 타입 | 설명 |
|---|---|---|
classNames | TimePickerMinuteListClassNames | 스타일 (HourList와 동일). |
<TimePicker.AmPmToggle>
AM/PM 두 라디오 버튼 (role="radiogroup"). format="12h"에서만 렌더.
| Prop | 타입 | 설명 |
|---|---|---|
classNames | TimePickerAmPmToggleClassNames | 스타일. |
type TimePickerAmPmToggleClassNames = {
root?: string;
option?: string;
optionSelected?: string;
};
패턴
12시간제
<TimePicker value={time} onChange={setTime} format="12h" step={15}>
<TimePicker.Input />
<div className="flex gap-2">
<TimePicker.HourList />
<TimePicker.MinuteList />
<TimePicker.AmPmToggle />
</div>
</TimePicker>
function TwelveHour() { const [time, setTime] = React.useState(null); return ( <TimePicker value={time} onChange={setTime} format="12h" step={15}> <TimePicker.Input className="kx-live-input" style={{ minWidth: '8rem' }} /> <div className="kx-live-row" style={{ marginTop: 8 }}> <TimePicker.HourList classNames={{ root: 'kx-live-list', option: 'kx-live-option', optionSelected: 'kx-live-option-selected', }} /> <TimePicker.MinuteList classNames={{ root: 'kx-live-list', option: 'kx-live-option', optionSelected: 'kx-live-option-selected', }} /> <TimePicker.AmPmToggle classNames={{ root: 'kx-live-ampm', option: 'kx-live-ampm-btn', optionSelected: 'kx-live-ampm-selected', }} /> </div> </TimePicker> ); }
초 포함
<TimePicker value={time} onChange={setTime} withSeconds>
<TimePicker.Input />
</TimePicker>
function WithSeconds() { const [time, setTime] = React.useState(null); return ( <TimePicker value={time} onChange={setTime} withSeconds> <TimePicker.Input className="kx-live-input" style={{ minWidth: '8rem' }} /> <div className="kx-live-value" style={{ marginTop: 8 }}> 선택됨: <code>{time ?? 'null'}</code> </div> </TimePicker> ); }
TimeValue 추출해 로직에 쓰기
import { TimePicker } from '@kalyx/react';
import { getTime } from '@kalyx/core';
function Example() {
const [time, setTime] = useState<ISODateString | null>(null);
useEffect(() => {
if (!time) return;
const { hours, minutes } = getTime(time); // { hours: 9, minutes: 30, seconds: 0 }
console.log('time_set', { hours, minutes });
}, [time]);
return (
<TimePicker value={time} onChange={setTime}>
<TimePicker.Input />
</TimePicker>
);
}
네이티브 폼 제출
TimePicker.Input에 name을 지정하면 화면의 HH:mm 문자열이 아니라 전체
UTC-ISO 값이 hidden input으로 제출됩니다.