Calendar

Calendar

커스텀 날짜 선택기를 만들기 위한 기본(basic) 컴포넌트예요. DatePicker 컴포넌트의 모든 props와 그 외 추가 props를 지원해요.

출처: 문서

본문

사용법 (Usage)

DatePicker 컴포넌트로 요구 사항이 충족되지 않을 때 Calendar 컴포넌트를 사용해 커스텀 날짜 선택기를 만들 수 있어요. Calendar는 DatePicker의 모든 props와 props 테이블에 나열된 추가 props를 지원해요. 모든 컴포넌트 기능을 확인하려면 props 테이블을 참고해요.

기본적으로 Calendar는 DatePicker 컴포넌트와 같은 방식으로 동작하지만 날짜 선택 로직은 포함하지 않아요.

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

function Demo() {
  return <Calendar />;
}

커스텀 날짜 선택기 (Custom date pickers)

Calendar를 커스텀 날짜 선택기의 기반으로 사용해요. 예를 들어 사용자가 세 개 이하의 날짜를 선택할 수 있는 선택기를 만들 수 있어요.

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

function Demo() {
  const [selected, setSelected] = useState<string[]>([]);

  const handleSelect = (date: string) => {
    const isSelected = selected.some((s) => dayjs(date).isSame(s, 'date'));
    if (isSelected) {
      setSelected((current) => current.filter((d) => !dayjs(d).isSame(date, 'date')));
    } else if (selected.length < 3) {
      setSelected((current) => [...current, date]);
    }
  };

  return (
    <Calendar
      getDayProps={(date) => ({
        selected: selected.some((s) => dayjs(date).isSame(s, 'date')),
        onClick: () => handleSelect(date),
      })}
    />
  );
}

또 다른 커스텀 날짜 선택기 예시 – 주(week) 선택기:

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

function getDay(date: string) {
  const day = dayjs(date).day();
  return day === 0 ? 6 : day - 1;
}

function startOfWeek(date: string) {
  return dayjs(date).subtract(getDay(date) + 1, 'day').toDate();
}

function endOfWeek(date: string) {
  return dayjs(date).add(6 - getDay(date), 'day').endOf('day').toDate();
}

function isInWeekRange(date: string, value: string | null) {
  return value ? dayjs(date).isBefore(endOfWeek(value)) && dayjs(date).isAfter(startOfWeek(value)) : false;
}

function Demo() {
  const [hovered, setHovered] = useState<string | null>(null);
  const [value, setValue] = useState<string | null>(null);

  return (
    <Calendar
      getDayProps={(date) => {
        const isHovered = isInWeekRange(date, hovered);
        const isSelected = isInWeekRange(date, value);
        const isInRange = isHovered || isSelected;
        return {
          onMouseEnter: () => setHovered(date),
          onMouseLeave: () => setHovered(null),
          inRange: isInRange,
          firstInRange: isInRange && new Date(date).getDay() === 1,
          lastInRange: isInRange && new Date(date).getDay() === 0,
          selected: isSelected,
          onClick: () => setValue(date),
        };
      }}
    />
  );
}

전체 너비 (Full width)

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

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

function Demo() {
  return <Calendar fullWidth />;
}

Static prop

static prop을 설정하면 사용자가 상호작용할 수 없는 캘린더를 표시해요. 캘린더 뷰로 데이터를 표시하되 상호작용은 원하지 않을 때 유용해요.

import dayjs from 'dayjs';
import { Indicator } from '@mantine/core';
import { Calendar } from '@mantine/dates';

function Demo() {
  return (
    <Calendar
      static
      renderDay={(date) => {
        const day = dayjs(date).date();
        return <Indicator size={6} color="red" offset={-2}>{day}</Indicator>;
      }}
    />
  );
}

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

withNativeLevelSelect prop을 설정하면 캘린더 헤더의 레벨 버튼을 네이티브 select 요소로 바꿔요.

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

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

더 알아보기 (Learn more)