본문으로 건너뛰기
Amineslab UI

Component

TimeInput

PC에서는 시계 아이콘이 있는 직접 입력, 모바일에서는 휠로 시간을 선택합니다.

Playground

옵션을 조절하며 화면과 사용 코드를 함께 확인하세요.

PC 1280px
Controls

비어 있을 때 안내 문구

시간 표시 형식 · 값은 항상 24시간 HH:mm

inline을 켜면 시간 입력 옆의 레이블에 적용됩니다.

inline을 켜면 시간 입력 옆의 레이블에 적용됩니다.

트리거 없이 시간 선택을 직접 표시

오류 상태

Code
import { useState } from 'react'

import { TimeInput, type ControlSize } from '@amineslab/ui'

function TimeExample({ size = 'md', placeholder = 'HH:mm', opaque = false, inline = false, inlineLabelPosition = 'top', inlineLabel = '시간', hourCycle = '24', variant = 'filled', step = 1, minTime = '', maxTime = '', disabled = false, invalid = false, }) {
    const [value, setValue] = useState('09:30');
    return (<div className="grid w-full max-w-xs gap-3">
      <TimeInput size={size as ControlSize} placeholder={placeholder} inline={inline} hourCycle={hourCycle === '12' ? 12 : 24} inlineLabel={inlineLabel} aria-label={inlineLabel || '시간'} inlineLabelPosition={inlineLabelPosition === 'start' ? 'start' : 'top'} opaque={opaque} variant={variant === 'outline' ? 'outline' : 'filled'} value={value} onValueChange={setValue} step={step} minTime={minTime || undefined} maxTime={maxTime || undefined} disabled={disabled} invalid={invalid}/>
    </div>);
}

export default function ExamplePreview() {
  return (<TimeExample {...({"size":"md","placeholder":"HH:mm","opaque":false,"inline":false,"inlineLabelPosition":"top","inlineLabel":"시간","hourCycle":"24","variant":"filled","step":1,"minTime":"","maxTime":"","disabled":false,"invalid":false} as const)}/>)
}

Props

@amineslab/ui에서 TimeInput를 가져옵니다.

import { TimeInput } from '@amineslab/ui'

TimeInput

NameTypeDefaultDescription
inlinebooleanfalsePC는 직접 입력, 모바일은 추가 시트 없이 휠을 표시합니다.
inlineLabelPosition'top' | 'start''top'시간 레이블을 위 또는 시작 쪽에 배치합니다.
inlineLabelstring'시간'인라인 시간 선택의 레이블입니다. 빈 문자열이면 레이블과 여백을 숨깁니다. aria-label로 접근 가능한 이름을 지정할 수 있습니다.
value / onValueChangestring / (value: string) => void-HH:mm 형식입니다. PC는 완성된 입력을 전달하고 blur에서 부분 입력을 보완합니다. 모두 지우면 빈 문자열을 전달합니다. 모바일 휠 선택은 즉시 반영합니다.
minTime / maxTimestring-입력·휠 선택 결과를 HH:mm 범위 안으로 보정합니다.
stepnumber1최소 시간(없으면 00:00)을 기준으로 가까운 분 간격에 맞춥니다. 1~60 범위입니다.
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'트리거 크기입니다.
hourCycle12 | 2424시간 표시 형식. 12시간제는 오전/오후와 01~12, 24시간제는 00~23을 표시합니다. value/onChange의 시간은 항상 24시간 HH:mm입니다.
placeholderstring-미선택 트리거 문구이자 모바일 시트의 제목입니다.
disabledbooleanfalse트리거를 비활성화합니다.
invalidbooleanfalse오류 테두리와 aria-invalid를 적용합니다.
variant'filled' | 'outline''filled'입력 표면을 선택합니다.
id / classNamestring-트리거 식별자와 스타일을 전달합니다. 인라인 기간 선택에서는 그룹에 적용합니다.
aria-describedby / aria-invalidstring / AriaAttributes["aria-invalid"]-폼 설명·오류 메시지와 실제 트리거를 연결합니다.
aria-requiredAriaAttributes["aria-required"]-필수 입력 상태를 실제 트리거에 전달합니다.
onBlurFocusEventHandler<TimeInputElement>-PC 입력, 모바일 트리거 또는 인라인 휠 그룹에서 포커스를 잃을 때 호출합니다.
refRef<TimeInputElement>-PC는 input, 모바일은 button, 모바일 inline은 fieldset입니다.
opaquebooleanfalseelevation 레이어 아래 불투명한 테마 바탕을 추가합니다. hover·focus·invalid 표현은 유지합니다.

Examples

자주 쓰는 조합을 살펴보고, 필요한 예시의 코드를 펼쳐 확인하세요.

공통 필드 표면

variant는 filled·outline 표현을, opaque는 elevation 아래의 불투명 바탕을 정합니다. focus와 hover는 중립 elevation을 사용하고 invalid 테두리는 포커스 중에도 유지합니다. NumberInput·PhoneInput·PasswordInput은 Input의 아이콘·문자열·ReactNode 슬롯을 상속합니다. SelectField에서는 같은 표면 props를 직접 지정하거나 triggerProps로 세부 설정할 수 있습니다.

투명 바탕
불투명 바탕
Outline + 불투명 바탕
<TimeInput />

<TimeInput opaque />

<TimeInput variant="outline" opaque />

시간 범위와 분 간격

PC 직접 입력과 모바일 휠에 같은 시간 범위와 분 간격을 적용합니다.

import { useState } from 'react'

import { TimeInput, type ControlSize } from '@amineslab/ui'

function TimeExample({ size = 'md', placeholder = 'HH:mm', opaque = false, inline = false, inlineLabelPosition = 'top', inlineLabel = '시간', hourCycle = '24', variant = 'filled', step = 1, minTime = '', maxTime = '', disabled = false, invalid = false, }) {
    const [value, setValue] = useState('09:30');
    return (<div className="grid w-full max-w-xs gap-3">
      <TimeInput size={size as ControlSize} placeholder={placeholder} inline={inline} hourCycle={hourCycle === '12' ? 12 : 24} inlineLabel={inlineLabel} aria-label={inlineLabel || '시간'} inlineLabelPosition={inlineLabelPosition === 'start' ? 'start' : 'top'} opaque={opaque} variant={variant === 'outline' ? 'outline' : 'filled'} value={value} onValueChange={setValue} step={step} minTime={minTime || undefined} maxTime={maxTime || undefined} disabled={disabled} invalid={invalid}/>
    </div>);
}

export default function ExamplePreview() {
  return (<TimeExample minTime="09:30" maxTime="18:00" step={15}/>)
}

12시간제 · 오전/오후 전환

부분 입력은 내부에만 보관하고 완성된 HH:mm을 전달합니다. 포커스를 벗어나면 빈 자리를 0으로 채웁니다.

import { useState } from 'react'

import { TimeInput, type ControlSize } from '@amineslab/ui'

function TimeExample({ size = 'md', placeholder = 'HH:mm', opaque = false, inline = false, inlineLabelPosition = 'top', inlineLabel = '시간', hourCycle = '24', variant = 'filled', step = 1, minTime = '', maxTime = '', disabled = false, invalid = false, }) {
    const [value, setValue] = useState('09:30');
    return (<div className="grid w-full max-w-xs gap-3">
      <TimeInput size={size as ControlSize} placeholder={placeholder} inline={inline} hourCycle={hourCycle === '12' ? 12 : 24} inlineLabel={inlineLabel} aria-label={inlineLabel || '시간'} inlineLabelPosition={inlineLabelPosition === 'start' ? 'start' : 'top'} opaque={opaque} variant={variant === 'outline' ? 'outline' : 'filled'} value={value} onValueChange={setValue} step={step} minTime={minTime || undefined} maxTime={maxTime || undefined} disabled={disabled} invalid={invalid}/>
    </div>);
}

export default function ExamplePreview() {
  return (<TimeExample hourCycle="12"/>)
}

날짜 선택기 안의 인라인 시간 입력

추가 시트 없이 PC는 직접 입력, 모바일은 휠을 표시합니다. 단일 시간은 레이블을 왼쪽에 둘 수 있습니다.

시간
import { useState } from 'react'

import { TimeInput, type ControlSize } from '@amineslab/ui'

function TimeExample({ size = 'md', placeholder = 'HH:mm', opaque = false, inline = false, inlineLabelPosition = 'top', inlineLabel = '시간', hourCycle = '24', variant = 'filled', step = 1, minTime = '', maxTime = '', disabled = false, invalid = false, }) {
    const [value, setValue] = useState('09:30');
    return (<div className="grid w-full max-w-xs gap-3">
      <TimeInput size={size as ControlSize} placeholder={placeholder} inline={inline} hourCycle={hourCycle === '12' ? 12 : 24} inlineLabel={inlineLabel} aria-label={inlineLabel || '시간'} inlineLabelPosition={inlineLabelPosition === 'start' ? 'start' : 'top'} opaque={opaque} variant={variant === 'outline' ? 'outline' : 'filled'} value={value} onValueChange={setValue} step={step} minTime={minTime || undefined} maxTime={maxTime || undefined} disabled={disabled} invalid={invalid}/>
    </div>);
}

export default function ExamplePreview() {
  return (<TimeExample inline inlineLabelPosition="start"/>)
}

TimeField로 사용하기

TimeField는 기본 입력에 label·required·description·error를 함께 제공합니다. FormStack 안에 직접 넣으며 FormField로 다시 감싸지 않습니다.

라벨·설명·필수 표시를 Field가 함께 처리합니다.

import { useState } from 'react'

import { TimeField } from '@amineslab/ui'

const fieldDescription = '라벨·설명·필수 표시를 Field가 함께 처리합니다.';

function TimeFieldExample() {
    const [value, setValue] = useState('');
    return (<TimeField label="시작 시간" description={fieldDescription} required value={value} onValueChange={setValue}/>);
}

export default function ExamplePreview() {
  return (<TimeFieldExample />)
}

사용 기준

권장하는 사용
  • 시간 입력은 TimeInput을 사용합니다.
  • 모바일에서는 필드를 누르면 휠 시트가 열리고, inline이면 휠을 바로 표시합니다.
  • DatePicker와 DateRangePicker도 같은 입력을 사용합니다.
피해야 할 사용
  • 겉모양만으로 사용을 결정하지 마세요.
  • 의미와 키보드 동작, 모바일에서의 흐름을 함께 확인하세요.

접근성

화면에 맞는 이름을 제공하고, 키보드만으로 작업을 마칠 수 있는지 확인하세요.

이 컴포넌트에는 별도의 키보드 조작이 필요하지 않습니다.