DatePicker

DatePicker

인라인(inline) 날짜, 여러 날짜, 날짜 범위 선택 피커 컴포넌트예요.

출처: 문서

본문

사용법 (Usage)

DatePicker로 단일 날짜, 여러 날짜, 날짜 범위를 인라인으로 선택할 수 있어요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date | null>(null);
  return <DatePicker value={value} onChange={setValue} />;
}

선택 해제 허용 (Allow deselect)

allowDeselect를 설정하면 사용자가 현재 선택된 날짜를 클릭해 선택을 해제할 수 있어요. allowDeselect는 type prop이 range 또는 multiple일 때 무시돼요. 날짜가 선택 해제되면 onChange가 null로 호출돼요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date | null>(null);
  return <DatePicker value={value} onChange={setValue} allowDeselect />;
}

여러 날짜 (Multiple dates)

type="multiple"을 설정하면 사용자가 여러 날짜를 선택할 수 있어요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date[]>([]);
  return <DatePicker type="multiple" value={value} onChange={setValue} />;
}

날짜 범위 (Dates range)

type="range"를 설정하면 사용자가 날짜 범위를 선택할 수 있어요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
  return <DatePicker type="range" value={value} onChange={setValue} />;
}

범위에서 단일 날짜 (Single date in range)

기본적으로 범위로 단일 날짜를 선택하는 것은 허용되지 않아요. 사용자가 같은 날짜를 두 번째로 클릭하면 선택이 해제돼요. 이 동작을 바꾸려면 allowSingleDateInRange prop을 설정해요. allowSingleDateInRange는 type prop이 range가 아닐 때 무시돼요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
  return <DatePicker type="range" allowSingleDateInRange value={value} onChange={setValue} />;
}

사전 설정 (Presets)

presets prop으로 커스텀 날짜 사전 설정을 추가할 수 있어요. 사전 설정은 캘린더 옆에 표시돼요.

import dayjs from 'dayjs';
import { DatePicker } from '@mantine/dates';

function Demo() {
  return (
    <DatePicker
      presets={[
        { label: 'Yesterday', date: dayjs().subtract(1, 'day').toDate() },
        { label: 'Today', date: new Date() },
        { label: 'Tomorrow', date: dayjs().add(1, 'day').toDate() },
        { label: 'Next month', date: dayjs().add(1, 'month').toDate() },
        { label: 'Next year', date: dayjs().add(1, 'year').toDate() },
      ]}
    />
  );
}

type="range"와 함께 presets를 사용하려면 값을 두 날짜의 튜플로 정의해요.

import dayjs from 'dayjs';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const today = dayjs();

  return (
    <DatePicker
      type="range"
      presets={[
        { label: 'Last two days', date: [today.subtract(2, 'day').toDate(), today.toDate()] },
        { label: 'Last 7 days', date: [today.subtract(7, 'day').toDate(), today.toDate()] },
        { label: 'This month', date: [today.startOf('month').toDate(), today.endOf('month').toDate()] },
      ]}
    />
  );
}

기본 날짜 (Default date)

defaultDate prop으로 처음에 어떤 연·월을 표시할지 결정하는 날짜 값을 설정할 수 있어요. 예를 들어 2015 February 달을 표시하려면 defaultDate={new Date(2015, 1)}을 설정해요. 값을 지정하지 않으면 defaultDate는 new Date()를 사용해요. 제공된 날짜 객체에서 일, 분, 초는 무시되고 연·월 데이터만 사용돼요. 어떤 날짜 값이든 지정할 수 있어요.

date prop을 설정하면 defaultDate 값은 무시된다는 점에 주의해요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date | null>(null);
  return <DatePicker defaultDate={new Date(2015, 1)} value={value} onChange={setValue} />;
}

제어된 날짜 (Controlled date)

date와 onDateChange props를 설정하면 현재 표시되는 월·연·십년(decade)을 제어할 수 있어요. 이렇게 하면 날짜 선택 경험을 커스터마이즈할 수 있어요. 예를 들어 사용자가 범위에서 첫 날짜를 선택하면 현재 날짜 값에 한 달을 더할 수 있어요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
  const [date, setDate] = useState(new Date());

  const handleChange = (val: [Date | null, Date | null]) => {
    if (val[0] !== null && val[1] === null) {
      setDate((current) => new Date(current.getFullYear() + 1, 1));
    }

    setValue(val);
  };

  return <DatePicker type="range" date={date} onDateChange={setDate} value={value} onChange={handleChange} />;
}

기본 레벨 (Default level)

defaultLevel prop을 설정해 처음에 표시될 레벨을 구성할 수 있어요. 허용 값은 month, year, decade예요.

import { Group } from '@mantine/core';
import { DatePicker } from '@mantine/dates';

function Demo() {
  return (
    <Group>
      <DatePicker defaultLevel="decade" />
      <DatePicker defaultLevel="year" />
    </Group>
  );
}

밖의 날짜 숨기기 (Hide outside dates)

hideOutsideDates prop을 설정하면 현재 달에 속하지 않는 모든 날짜를 제거해요.

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

function Demo() {
  return <DatePicker hideOutsideDates />;
}

주 번호 표시 (Display week numbers)

withWeekNumbers prop을 설정하면 주 번호를 표시해요.

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

function Demo() {
  return <DatePicker withWeekNumbers />;
}

주의 첫날 (First day of week)

firstDayOfWeek prop을 설정해 주의 첫날을 구성할 수 있어요. 이 prop은 0에서 6 사이의 숫자를 받아요. 0은 일요일, 6은 토요일. 기본값은 1(월요일)이에요. 이 옵션은 모든 컴포넌트에 대해 DatesProvider로도 구성할 수 있어요.

import { Group } from '@mantine/core';
import { DatePicker } from '@mantine/dates';

function Demo() {
  return (
    <Group>
      <DatePicker firstDayOfWeek={0} />
      <DatePicker firstDayOfWeek={6} />
    </Group>
  );
}

요일 숨기기 (Hide weekdays)

hideWeekdays prop을 설정해 요일 이름을 숨길 수 있어요.

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

function Demo() {
  return <DatePicker hideWeekdays />;
}

주말 (Weekend days)

weekendDays prop으로 주말을 구성할 수 있어요. 이 prop은 0에서 6 사이의 숫자 배열을 받아요. 0은 일요일, 6은 토요일. 기본값은 [0, 6](토요일·일요일)이에요. 이 옵션은 모든 컴포넌트에 대해 DatesProvider로도 구성할 수 있어요.

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

function Demo() {
  return <DatePicker weekendDays={[1, 2]} />;
}

날짜 렌더링 함수 (Render day function)

renderDay prop으로 날짜 렌더링을 커스터마이즈할 수 있어요. 예를 들어 특정 날짜에 Indicator를 추가하는 데 사용할 수 있어요.

import dayjs from 'dayjs';
import { Indicator } from '@mantine/core';
import { DatePicker, DatePickerProps } from '@mantine/dates';

const dayRenderer: DatePickerProps['renderDay'] = (date) => {
  const day = dayjs(date).date();
  return (
    <Indicator size={6} color="red" offset={-2}>
      {day}
    </Indicator>
  );
};

최소·최대 날짜 (Min and max date)

minDate와 maxDate props로 최소·최대 날짜를 정의할 수 있어요. 이전/다음 페이지를 사용할 수 없으면 해당 컨트롤이 비활성화돼요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date | null>(null);
  return <DatePicker minDate={new Date('2022-02-01')} maxDate={new Date('2022-02-01')} value={value} onChange={setValue} />;
}

헤더 컨트롤 순서 변경 (Change header controls order)

headerControlsOrder prop을 사용해 헤더 컨트롤의 순서를 바꿀 수 있어요. 이 prop은 'next' | 'previous' | 'level' 배열을 받아요. 각 컨트롤은 배열에서 한 번만 사용할 수 있다는 점에 주의해요.

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

function Demo() {
  return <DatePicker headerControlsOrder={['previous', 'level', 'next']} />;
}

일·연·월 컨트롤에 props 추가 (Add props to day, year and month control)

getYearControlProps, getMonthControlProps, getDayProps 함수로 연·월·일 컨트롤에 props를 추가할 수 있어요. 모든 함수는 날짜를 단일 인자로 받아요. 함수에서 반환된 props가 연/월/일 컨트롤에 추가돼요. 예를 들어 특정 컨트롤을 비활성화하거나 스타일을 추가하는 데 사용할 수 있어요.

import dayjs from 'dayjs';
import { useState } from 'react';
import { DatePicker, DatePickerProps } from '@mantine/dates';

const getDayProps: DatePickerProps['getDayProps'] = (date) => {
  const d = dayjs(date);

  if (d.day() === 5 && d.date() === 13) {
    return {
      style: {
        backgroundColor: 'var(--mantine-color-red-filled)',
        color: 'var(--mantine-color-white)',
      },
    };
  }

  return {};
};

const getYearControlProps: DatePickerProps['getYearControlProps'] = (date) => {
  const d = dayjs(date);

  if (d.year() === new Date().getFullYear()) {
    return { style: { color: 'var(--mantine-color-blue-filled)', fontWeight: 700 } };
  }

  if (d.year() === new Date().getFullYear() + 1) {
    return { disabled: true };
  }

  return {};
};

날짜 제외 (Exclude dates)

특정 날짜를 비활성화하려면 excludeDate prop을 사용해요. 날짜를 인자로 받아 불리언 값을 반환하는 함수를 받아요. true를 반환하면 날짜가 비활성화돼요. 금요일이 아닌 모든 날짜를 비활성화하는 예시:

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

function Demo() {
  return <DatePicker excludeDate={(date) => new Date(date).getDay() !== 5} />;
}

열 수 (Number of columns)

numberOfColumns prop을 설정해 나란히 렌더링할 피커 수를 정의할 수 있어요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<[Date | null, Date | null]>([null, null]);
  return <DatePicker type="range" numberOfColumns={2} value={value} onChange={setValue} />;
}

최대 레벨 (Max level)

import { Group } from '@mantine/core';
import { DatePicker } from '@mantine/dates';

function Demo() {
  return (
    <Group>
      <DatePicker maxLevel="year" />
      <DatePicker maxLevel="month" />
    </Group>
  );
}

전체 너비 (Full width)

fullWidth prop을 설정하면 날짜 피커가 부모 컨테이너 너비의 100%를 채우도록 늘어나요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date | null>(null);
  return <DatePicker fullWidth value={value} onChange={setValue} />;
}

크기 (Size)

import dayjs from 'dayjs';
import { DatePicker } from '@mantine/dates';

function Demo() {
  return <DatePicker size="lg" />;
}

연·월 컨트롤 형식 변경 (Change year and months controls format)

yearsListFormat과 monthsListFormat props를 사용해 연/월 컨트롤의 dayjs format을 바꿀 수 있어요.

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

function Demo() {
  return <DatePicker yearsListFormat="YY" monthsListFormat="MM" />;
}

라벨 형식 변경 (Change label format)

decadeLabelFormat, yearLabelFormat, monthLabelFormat props를 사용해 십년(decade)/연 라벨의 dayjs format을 바꿀 수 있어요.

import { useState } from 'react';
import { DatePicker } from '@mantine/dates';

function Demo() {
  const [value, setValue] = useState<Date | null>(null);
  return <DatePicker decadeLabelFormat="YY" value={value} onChange={setValue} />;
}

로컬라이제이션 (Localization)

보통은 DatesProvider에서 @mantine/dates 패키지의 locale을 지정하는 것이 낫지만, 컴포넌트별로 locale을 덮어쓸 수도 있어요.

import 'dayjs/locale/ru';
import { DatePicker } from '@mantine/dates';

function Demo() {
  return <DatePicker locale="ru" />;
}

네이티브 레벨 선택 (Native level select)

withNativeLevelSelect prop을 설정하면 캘린더 헤더의 레벨 버튼을 네이티브 select 요소로 바꿔요. 월 레벨에서는 월과 연을 위한 두 개의 select가 렌더링되고, 연 레벨에서는 연을 위한 하나의 select가 렌더링돼요.

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

function Demo() {
  return <DatePicker withNativeLevelSelect />;
}

접근성 (Accessibility)

ariaLabels prop으로 이전/다음 컨트롤의 aria-label 속성을 지정할 수 있어요.

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

function Demo() {
  return (
    <DatePicker
      ariaLabels={{
        nextMonth: 'Next month',
        previousMonth: 'Previous month',
      }}
    />
  );
}

getYearControlProps/getMonthControlProps/getDayProps를 사용해 aria-label 속성을 커스터마이즈할 수 있어요.

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

function Demo() {
  return (
    <DatePicker
      getDayProps={(date) => ({
        'aria-label': `Select date ${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`,
      })}
      getYearControlProps={(date) => ({
        'aria-label': `Select year ${date.getFullYear()}`,
      })}
      getMonthControlProps={(date) => ({
        'aria-label': `Select month ${date.getFullYear()}/${date.getMonth()}`,
      })}
    />
  );
}

다음 이벤트는 포커스가 날짜 컨트롤에 있을 때만 트리거된다는 점에 주의해요.

키 (Key) 설명 (Description)
ArrowRight 다음 비활성 날짜에 포커스를 둬요
ArrowLeft 이전 비활성 날짜에 포커스를 둬요
ArrowDown 같은 열의 다음 비활성 날짜에 포커스를 둬요
ArrowUp 같은 열의 이전 비활성 날짜에 포커스를 둬요

더 알아보기 (Learn more)