ComponentsP3 본문

TimePicker

Input형 트리거 + 시간 목록/list, 웹 권장 input, 터치 보조 dial, 모바일 wheel — interval·minuteStep·hourCycle·minTime·maxTime으로 'HH:mm' 선택 범위를 만드는 비제어 컴포넌트입니다.

마지막 업데이트 2026-07-02

한눈에#

Input형 트리거 + 시간 목록/입력형/시계판 다이얼/컬럼 wheel로 시각만 고릅니다 — listinterval, input·dial·wheelminuteStep을 쓰고 모든 모드는 minTime/maxTime 범위를 지킵니다.

  • Input형 트리거 + 시간 선택 표면
  • interval·minuteStep·hourCycle·minTime·maxTime
  • list·input·dial·wheel 모드
  • 비제어 + BottomSheet 모바일

트리거 높이는 input.height로 폼 줄맞춤 — 웹 권장은 input/list, wheel은 모바일 컬럼 피커, dial은 터치·시각 보조

사용 시점#

회의 시작·마감처럼 시각만 고르면 TimePicker — 날짜나 날짜+시각은 다른 컴포넌트입니다.

권장 — 이렇게 쓰세요

지양 — 이러지 마세요

쓴다회의 시작·마감 시각처럼 시각만(interval·minTime/maxTime으로 업무 시간대 제한)

대신 DatePicker날짜를 고르거나 날짜+시각을 함께 잡을 때(나란히 배치)

플레이그라운드#

컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.

TimePicker를 직접 조작해 보세요

속성·테마·토큰을 바꾸고 React·Flutter 코드를 확인하는 풀스크린 빌더로 엽니다.

빌더 열기

플레이그라운드는 넓은 작업 영역이 필요해 웹·태블릿에서 편집할 수 있어요.

변형#

interval · minTime/maxTime — 업무 시간 15분 간격 · defaultValue

옵션은 minTime(기본 ‘00:00’)부터 interval분 간격으로 maxTime(기본 ‘23:59’, 포함)까지 생성됩니다. 형식이 어긋난 defaultValue(‘25:99’ 등)는 무시되고 placeholder가 표시됩니다. 팝업은 트리거 아래에 뜨고, 뷰포트 하단 공간이 부족하면 위로 플립됩니다.

표시 모드 (ADR-012 Track C)#

mode가 오버레이 내용을 가릅니다 — 기본 'list'는 인터벌 목록(기존 동작), 'input'데스크톱 웹 권장 컴팩트 입력형, 'dial'터치·시각 보조용 시계판 2단계 선택(Material time picker 계열), 'wheel'모바일 컬럼 wheel입니다. 기존 wheel 데스크톱 사용은 하위호환을 위해 input 표면으로 fallback합니다. 네 모드는 같은 트리거와 HH:mm 커밋 계약을 공유합니다.

input — 웹 권장 컴팩트 입력형

input은 웹 폼에서 가장 빠른 경로입니다. 시 · 분은 네이티브 <select>가 아니라 WDS Select라 목록 클릭은 물론 타입어헤드(숫자 타이핑 점프)·화살표 탐색을 그대로 쓸 수 있고, 오전/오후는 WDS SegmentedButton으로 고릅니다. 선택 버튼은 minuteStepminTime/maxTime 검증을 통과한 조합에서만 활성화됩니다. input과 wheel은 플랫폼 적응 쌍입니다 — 어느 이름을 쓰든 웹에서는 Select 필드, 모바일 시트에서는 엄지 스크롤 컬럼 wheel로 각 플랫폼 최적 관용구를 렌더합니다.

dial — 터치·시각 보조 시계판

dial은 시(0–23, 바깥/안쪽 두 링)를 먼저 고른 뒤 분을 고르면 HH:mm으로 확정합니다. 상단 readout이 조합 중인 시각(09:--)을 라이브로 보여주고, 선택된 시/분은 중심에서 숫자로 이어지는 hand로 표시되며, 시계판 표면을 드래그하면 각도에 가장 가까운 시/분으로 이동합니다. 즉시확정 관용구라 확정 버튼은 없지만 데스크톱 팝업에는 취소 버튼이 있습니다. 분 눈금은 minuteStep(기본 5, 5/10/15/20/30처럼 60을 나누는 값)으로 조절합니다. 시계판 위의 HH:mm 직접 입력 필드가 키보드 경로를 제공합니다 — 입력값도 minuteStepminTime/maxTime 범위를 모두 통과해야 Enter로 확정됩니다. 폼이 밀집된 웹 화면에서는 input 또는 list를 우선 사용하고, dial은 터치 디바이스나 시각적 탐색이 더 중요한 화면에서 보조 선택지로 사용합니다. compact 뷰포트(mobile)에서는 BottomSheet 안에 같은 시계판이 렌더됩니다.

wheel — 모바일 컬럼 wheel

wheel은 모바일 전용에 가까운 표면입니다. BottomSheet 안에서 오전/오후 → 시 → 분 순서의 컬럼 wheel을 노출합니다. hourCycle={12}면 오전/오후가 추가되고, hourCycle={24}(기본)이면 시간·분만 보입니다. 데스크톱에서 mode="wheel"을 쓰는 기존 코드는 하위호환으로 input 표면을 보여주지만, 새 웹 화면에서는 mode="input"을 권장합니다.

크기#

단일 크기입니다 — 트리거 높이는 input.height(44px)로 Input과 같은 폼 컨트롤 줄맞춤이고, 최소 폭은 ‘HH:mm’ + 시계 아이콘 기준 9rem(시간 전용이라 Select 14rem보다 좁음)입니다. 리스트는 최대 16rem 높이에서 스크롤됩니다.

상태#

Disabled
  • Focus — 트리거 :focus-visiblecolor.primary 아웃라인 링
  • 열림input.border-focus 보더 + aria-expanded="true"
  • 활성 옵션color.surface-hover 배경(마우스 호버도 활성을 따라감)
  • 선택 옵션aria-selected + color.primary-text 잉크
  • Disabledinput.bg-disabled 배경 + 커서 차단

비제어 컴포넌트입니다 — defaultValue로 시작하고 선택 시 onChange('HH:mm')로 알립니다. 같은 값 재선택은 발화하지 않습니다.

모바일#

DK 모바일 재활용 표준입니다 — mobile을 켜면 트리거 클릭 시 데스크톱 팝업 대신 BottomSheet(height half)가 열리고, 시간 리스트·다이얼·wheel이 시트 안에 렌더됩니다. 단일 선택이므로 list 항목과 dial 분은 즉시 확정되고, wheel은 선택으로 확정합니다. 시트 제목은 mobileTitle, 없으면 placeholder가 채워집니다. 모바일 표면에서는 데스크톱 팝업 테두리와 그림자를 제거하고 본문 폭을 채우며, 리스트는 모바일 터치 행 높이를 사용하고 다이얼은 좁은 화면에 맞춰 유동 폭으로 줄어듭니다. wheel도 내부 카드 테두리 없이 full-width 컬럼을 사용하며, 12시간제에서는 오전/오후 → 시 → 분 순서로 배치합니다. 라이브 데모는 데스크톱 뷰포트라 코드로 안내합니다.

<TimePicker
  mobile
  mobileTitle="시작 시간 선택"
  aria-label="시작 시간"
  interval={15}
  minTime="09:00"
  maxTime="18:00"
  onChange={(time) => applyStartTime(time)}
/>

<TimePicker
  responsive="mobile"
  mode="wheel"
  hourCycle={12}
  minuteStep={15}
  minTime="09:00"
  maxTime="18:00"
  aria-label="업무 시간"
/>

닫힘 경로(배경 클릭·Escape·닫기 버튼·핸들 드래그 다운)와 포커스 복원은 BottomSheet 계약을 그대로 따릅니다 — 값 변경 없이 닫힙니다.

Props#

Prop타입기본값설명
defaultValuestring초기 선택 시간 'HH:mm' — 형식이 어긋나면 무시
onChange(value: string) => void선택 변경 콜백 — 같은 값 재선택은 발화하지 않음
intervalnumber30옵션 간격(분) — 기본 30
minTimestring선택 가능한 최소 시간 'HH:mm' — list 옵션과 input/dial/wheel 선택·입력에 적용
maxTimestring선택 가능한 최대 시간 'HH:mm' (포함) — list 옵션과 input/dial/wheel 선택·입력에 적용
placeholderstring시간 선택선택 전 트리거에 표시되는 문구
mode'list' | 'input' | 'dial' | 'wheel'list표시 모드 — 'list'(기본): 인터벌 목록. 'input': 웹 권장 입력형. 'dial': 시계판 2단계. 'wheel': 모바일 컬럼 휠. input/wheel은 플랫폼 적응 쌍(웹=Select 필드·모바일=휠 크로스 폴백). 트리거는 공유
minuteStepnumberinput/dial/wheel 모드 분 눈금 — 5/10/15/20/30처럼 60을 나누는 5~30분 단위. 기본 5
hourCycle12 | 2424input/wheel 모드 표시 주기 — 12면 오전/오후를 노출하고 값은 계속 'HH:mm'으로 커밋. 기본 24
responsive'auto' | 'mobile' | 'desktop'적응형 표시 (ADR-012) — auto(기본): compact 뷰포트에서 borderless/full-width BottomSheet 목록 전환(탭 즉시 확정). mobile/desktop은 강제 override
mobilebooleanfalse@deprecated responsive='mobile' 사용. true면 BottomSheet 목록 강제 — 하위호환 alias
mobileTitlestring시트 제목 — 기본 placeholder
refRef<HTMLButtonElement>트리거 <button>으로 (병합) 전달되는 ref (React 19 ref-as-prop)

접근성#

list 모드 트리거는 role="combobox" + aria-haspopup="listbox", 팝업은 role="listbox"입니다. 포커스는 트리거에 머물고 aria-activedescendant가 활성 옵션 id를 가리킵니다(데스크톱 팝업 전용 — mobile 시트는 BottomSheet 포커스 트랩 계약을 따름). dial 모드 트리거는 aria-haspopup="dialog"를 노출하고, 데스크톱 팝업은 role="dialog"로 이름 붙은 뒤 열림 직후 직접 입력 필드에 포커스를 보냅니다. wheel 모드도 aria-haspopup="dialog"를 노출합니다. 데스크톱에서는 오전/오후 세그먼트가 button[aria-pressed]로, input 표면의 시·분 입력 컨트롤이 combobox로 동작하고, 모바일 wheel 컬럼은 spinbutton 의미론으로 현재 시간·분·오전/오후 값을 보고합니다. Escape는 값 변경 없이 닫고 트리거 포커스를 복원합니다.

키보드 열기는 데스크톱·모바일 두 표면 모두에서 동작합니다(WCAG 2.1.1) — mobile/compact에서도 트리거에 포커스를 두고 ··Enter·Space를 누르면 BottomSheet가 열립니다. 시트가 열린 뒤의 포커스 트랩·Escape 닫기는 BottomSheet 계약이 담당합니다.

동작
/ / Enter / Space (닫힘)열기 — 선택(없으면 첫) 옵션 활성
09 (list, 데스크톱)타입어헤드 — 닫혀 있으면 열며 해당 시각으로 점프(“9”→09:00, 이어 “3”→09:30)
/ (열림)활성 옵션 이동 — 양 끝에서 클램프
Enter / Space활성 옵션 선택 + 닫기 + 트리거 포커스 유지
Escape값 변경 없이 닫기
Tab닫고 기본 포커스 이동

외부 클릭으로도 닫히며, 선택 옵션은 aria-selected로 보고됩니다.

토큰#

component 토큰 없이 Input의 component 토큰(input.*)과 semantic을 직접 소비합니다(신설 기준 §4 미충족 — Select과 같은 dropdown 어휘).

속성토큰
트리거input.bg/fg/border/height/radius · placeholder input.placeholder
포커스color.focus-ring 아웃라인 · 열림 보더 input.border-focus
시계 아이콘icon.size-md · color.text-subtle
팝업color.surface-raised · radius.md · shadow.lg · z.dropdown
옵션 활성/선택color.surface-hover/selected · 선택 잉크 color.primary-text
눌림(옵션·시계판 숫자·wheel 항목)color.surface-pressed (선택 배경은 안 덮음)
다이얼 handcolor.primary · 선택 숫자와 중심을 잇는 구조적 geometry
옵션 높이control.height-sm
비활성input.bg-disabled · color.text-placeholder · 다이얼 범위 밖 눈금 muted
모션duration.fast + 팝업 등장 ease.emphasized-decelerate / ease.standard

관련#