TimePicker

TimePicker

사용자로부터 시간 값을 입력받는 컴포넌트예요. TimeInput보다 더 많은 기능을 제공하는 대안이에요. 24시간·12시간 형식, 시간·분·초 드롭다운 등을 지원해요.

출처: 문서

본문

사용법 (Usage)

TimePicker 컴포넌트는 TimeInput의 대안으로 더 많은 기능을 제공해요. 24시간·12시간 형식, 시간·분·초 드롭다운 등을 지원해요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker label="Enter time" placeholder="Enter time" />;
}

제어 컴포넌트 (Controlled)

TimePicker 컴포넌트의 값은 24시간 형식의 hh:mm:ss 또는 hh:mm 문자열이에요(예: 18:34:55). 값이 없으면 빈 문자열로 표현돼요. onChange 함수는 입력된 값이 유효할 때만 호출돼요. 입력 값이 유효한 경우는 다음과 같아요.

  • 모든 입력이 비어 있음. 이 경우 onChange는 빈 문자열로 호출돼요
  • 모든 입력이 채워짐. 예를 들어 withSeconds prop이 설정되고 사용자가 12:34:56을 입력하면 onChange가 12:34:56으로 호출돼요. 하지만 사용자가 12:34를 입력하면 초 값이 없으므로 onChange가 호출되지 않아요
import { useState } from 'react';
import { TimePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState('');
  return <TimePicker value={value} onChange={setValue} />;
}

초 포함 (With seconds)

withSeconds prop을 설정하면 초 입력을 활성화해요. 이 prop을 사용하면 초를 포함한 모든 입력이 채워질 때까지 onChange가 호출되지 않는다는 점에 주의해요. 시간과 분만 입력하는 것은 불가능해요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker withSeconds />;
}

지속 시간 유형 (Duration type)

type="duration"을 설정하면 24시간을 초과하는 지속 시간(duration)을 입력할 수 있어요. 이 모드에서는 시간 필드에 상한이 없고 입력 너비가 입력된 값에 따라 동적으로 조정돼요. format prop은 무시되고(항상 24시간), 드롭다운은 비활성화돼요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker type="duration" />;
}

최소 시간 자릿수 (Min hours digits)

minHoursDigits prop을 사용해 시간 입력에 표시되는 최소 자릿수를 설정할 수 있어요. 이 prop은 type="duration"이 설정된 경우에만 적용돼요. 기본 최솟값은 2예요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <TimePicker type="duration" minHoursDigits={3} />
  );
}

12시간 형식 (12-hour format)

format="12h"를 설정하면 12시간 형식을 사용해요. am/pm 입력을 포함한 모든 입력이 채워질 때만 onChange가 호출된다는 점에 주의해요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker format="12h" />;
}

am/pm 라벨 변경 (Change am/pm labels)

am/pm 라벨을 바꾸려면 amPmLabels prop을 사용해요. 라벨을 힌디어로 바꾸는 예시:

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker format="12h" amPmLabels={['पूर्वाह्न', 'अपराह्न']} />;
}

최소·최대 값 (Min and max values)

min과 max props로 사용 가능한 시간 범위를 제한할 수 있어요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <>
      <TimePicker label="Enter time (24h format)" min="08:00" max="18:00" />
      <TimePicker label="Enter time (12h format)" format="12h" min="08:00" max="18:00" />
    </>
  );
}

드롭다운 포함 (With dropdown)

withDropdown prop을 설정하면 시간·분·초와 am/pm 선택이 있는 드롭다운을 표시해요. 기본적으로 드롭다운은 입력 중 하나에 포커스가 있을 때 표시돼요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <>
      <TimePicker label="Enter time (24h format)" withDropdown withSeconds />
      <TimePicker label="Enter time (12h format)" format="12h" withDropdown withSeconds />
    </>
  );
}

시간/분/초 스텝 (Hours/minutes/seconds step)

hoursStep, minutesStep, secondsStep props로 각 입력의 스텝을 제어할 수 있어요. 이 props는 위/아래 화살표 키를 누를 때 입력이 증감되는 값과 드롭다운에서 해당 값 범위를 생성하는 데 사용돼요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker hoursStep={2} minutesStep={5} secondsStep={10} withSeconds />;
}

드롭다운 열림 상태 제어 (Control dropdown opened state)

popoverProps를 사용해 기반 Popover 컴포넌트에 props를 전달해요.

import { useState } from 'react';
import { ClockIcon } from '@phosphor-icons/react';
import { ActionIcon } from '@mantine/core';
import { TimePicker } from '@mantine/dates';

function Demo() {
  const [dropdownOpened, setDropdownOpened] = useState(false);
  const [value, setValue] = useState('');

  return (
    <ActionIcon onClick={() => setDropdownOpened(true)} variant="default">
      <ClockIcon size={16} />
    </ActionIcon>
    <TimePicker
      value={value}
      onChange={(val) => {
        setValue(val);
        if (value === '') {
          setDropdownOpened(false);
        }
      }}
      popoverProps={{
        opened: dropdownOpened,
        onChange: (_opened) => !_opened && setDropdownOpened(false),
      }}
    />
  );
}

시간 사전 설정 (Time presets)

presets prop으로 시간 사전 설정을 정의할 수 있어요. 사전 설정은 드롭다운에 표시되고 클릭해 선택할 수 있어요. 사전 설정의 시간 값은 hh:mm:ss 또는 hh:mm 24시간 형식이어야 해요. 사전 설정의 표시 값은 format, amPmLabels, withSeconds props에 따라 생성돼요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <TimePicker
      withDropdown
      presets={[{ label: 'Morning', time: '08:00' }, { label: 'Noon', time: '12:00' }, { label: 'Night', time: '22:00' }]}
    />
  );
}

시간 사전 설정 그룹 (Time presets groups)

사전 설정을 그룹화하려면 label과 values 키가 있는 객체 배열을 사용해요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <TimePicker
      withDropdown
      presets={[
        { label: 'Morning', values: [{ label: '7 AM', time: '07:00' }, { label: '8 AM', time: '08:00' }] },
        { label: 'Evening', values: [{ label: '7 PM', time: '19:00' }, { label: '8 PM', time: '20:00' }] },
      ]}
    />
  );
}

시간 사전 설정 범위 (Time presets range)

시간 값의 범위를 생성해야 한다면 @mantine/dates 패키지에서 내보내는 getTimeRange 함수를 사용해요. 이 함수는 시작·끝 시간과 간격을 hh:mm:ss 형식으로 받아요.

import { getTimeRange, TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <TimePicker
      withDropdown
      presets={getTimeRange('08:00', '20:00', '01:00').map((time) => ({
        label: time,
        time,
      }))}
    />
  );
}

사전 설정 선택 시 드롭다운 닫기 (Close dropdown on preset select)

closeDropdownOnPresetSelect prop을 설정하면 사전 설정 목록에서 값을 선택했을 때 드롭다운을 닫아요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker withDropdown closeDropdownOnPresetSelect presets={[]} />;
}

드롭다운 위치 (Dropdown position)

기본적으로 드롭다운은 공간이 충분하면 입력 아래에 표시되고, 그렇지 않으면 입력 위에 표시돼요. position과 middlewares props를 설정해 이 동작을 바꿀 수 있어요. 이 props는 기반 Popover 컴포넌트로 전달돼요.

항상 입력 위에 표시되는 드롭다운 예시:

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker withDropdown position="top" />;
}

드롭다운 너비 (Dropdown width)

드롭다운 너비를 바꾸려면 comboboxProps에서 width prop을 설정해요. 기본적으로 드롭다운 너비는 모든 콘텐츠에 맞게 조정돼요. 드롭다운 너비를 입력 너비로 설정하는 예시:

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker comboboxProps={{ width: 'input' }} withDropdown />;
}

붙여넣기 이벤트 (Paste events)

기본적으로 TimePicker는 붙여넣기 이벤트에 대해 24시간 형식의 시간만 처리해요(예: 17:33:43 또는 19:22). pasteSplit prop으로 커스텀 붙여넣기 시간 파서를 만들 수 있어요.

import { Code, Text } from '@mantine/core';
import { TimePicker, TimePickerPasteSplit } from '@mantine/dates';

const re = /^(1[0-2]|0?[1-9]):[0-5][0-9](?::[0-5][0-9])?\s?(AM|PM)$/;

const customPasteSplit: TimePickerPasteSplit = ({ time }) => {
  if (!re.test(time)) {
    return { hours: null, minutes: null, seconds: null, amPm: null };
  }

  const [hours, minutes, second] = time.split(':').map((part) => part.replace(/AM|PM/g, ''));
  const isPm = time.toLowerCase().includes('pm');

  return {
    hours: typeof hours === 'string' ? Number(hours) : null,
    minutes: typeof minutes === 'string' ? Number(minutes) : null,
    seconds: typeof second === 'string' ? Number(second) : 0,
    amPm: isPm ? 'PM' : 'AM',
  };
};

function Demo() {
  return (
    <TimePicker
      format="12h"
      pasteSplit={customPasteSplit}
      description="Try pasting time in 12h format in any input. For example, try pasting 12:34 PM or 8:56:45 AM"
    />
  );
}

지우기 가능 (Clearable)

clearable prop을 설정하면 입력 오른쪽 섹션에 지우기 버튼을 표시해요. 지우기 버튼은 필드 중 하나에 값이 있을 때 보여요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker clearable defaultValue="12:00" />;
}

지우기 섹션 모드 (Clear section mode)

clearSectionMode prop은 지우기 버튼과 rightSection이 어떻게 렌더링되는지 결정해요.

  • 'both' (기본) – 지우기 버튼과 rightSection 모두 렌더링해요
  • 'rightSection' – 사용자가 제공한 rightSection만 렌더링하고 지우기 버튼을 무시해요
  • 'clear' – 지우기 버튼만 렌더링하고 rightSection을 무시해요
import { CaretDownIcon } from '@phosphor-icons/react';
import { Stack } from '@mantine/core';
import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <Stack>
      <TimePicker clearable rightSection={<CaretDownIcon size={16} />} clearSectionMode="both" />
      <TimePicker clearable rightSection={<CaretDownIcon size={16} />} clearSectionMode="rightSection" />
      <TimePicker clearable rightSection={<CaretDownIcon size={16} />} clearSectionMode="clear" />
    </Stack>
  );
}

비활성 (Disabled)

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker disabled />;
}

읽기 전용 (Read only)

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker readOnly />;
}

Input props

TimePicker 컴포넌트는 Input과 Input.Wrapper 컴포넌트의 기능과 모든 div 요소 props를 지원해요. TimePicker 문서에는 컴포넌트가 지원하는 모든 기능이 포함되어 있지 않아요. 사용 가능한 모든 기능은 Input 문서에서 확인할 수 있어요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker label="Input label" description="Input description" placeholder="Enter time" />;
}

내부 입력 ref 가져오기 (Get refs of inner inputs)

hoursRef, minutesRef, secondsRef, amPmRef props로 내부 입력의 ref를 가져올 수 있어요.

import { useRef } from 'react';
import { TimePicker } from '@mantine/dates';

function Demo() {
  const hoursRef = useRef<HTMLInputElement>(null);
  const minutesRef = useRef<HTMLInputElement>(null);
  const secondsRef = useRef<HTMLInputElement>(null);
  const amPmRef = useRef<HTMLInputElement>(null);

  return <TimePicker hoursRef={hoursRef} minutesRef={minutesRef} secondsRef={secondsRef} amPmRef={amPmRef} />;
}

onFocus와 onBlur 이벤트

onFocus 이벤트는 첫 번째 입력이 포커스될 때, onBlur 이벤트는 마지막 입력이 블러될 때 호출돼요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return <TimePicker onFocus={() => console.log('Focused')} onBlur={() => console.log('Blurred')} />;
}

접근성 (Accessibility)

시간·분·초와 am/pm 입력 및 지우기 버튼에 해당 props로 aria 라벨을 설정할 수 있어요.

import { TimePicker } from '@mantine/dates';

function Demo() {
  return (
    <TimePicker
      hoursLabel="Hours"
      minutesLabel="Minutes"
      secondsLabel="Seconds"
      amPmLabel="AM/PM"
    />
  );
}

키보드 상호작용:

키 (Key) 설명 (Description)
ArrowDown 현재 값을 스텝만큼 감소시켜요
ArrowUp 현재 값을 스텝만큼 증가시켜요
Home 현재 값을 가능한 최솟값으로 설정해요
End 현재 값을 가능한 최댓값으로 설정해요
Backspace 현재 값을 지워요
ArrowRight 다음 입력으로 포커스를 이동해요
ArrowLeft 이전 입력으로 포커스를 이동해요

더 알아보기 (Learn more)