DatePicker

Data Input

단일 일자를 캘린더에서 고르는 날짜 입력.

Usage

한 날짜를 입력하거나 팝오버 달력에서 선택하게 할 때 사용한다.

import

import

import { DatePicker } from '@mildang/design-system/DatePicker';

DatePicker 하나만 가져오면 DatePicker.Root · DatePicker.Trigger · DatePicker.Content · DatePicker.Calendar · DatePicker.Footer 를 그 아래에서 쓸 수 있다.

예제를 복사해 쓸 때 필요한 준비

@mildang/styled-system 은 이 저장소에서 Panda 가 생성하는 산출물이다. 저장소 안에서는 turbo run ship 이후 쓸 수 있고, 패키지 소비자는 자기 Panda 산출물이나 다른 레이아웃 수단으로 바꿔야 한다.

Anatomy

tsx

import { DatePicker } from '@mildang/design-system/DatePicker';

export default function Example() {
  return (
    <DatePicker>
      <DatePicker.Trigger />
      <DatePicker.Content>
        <DatePicker.Calendar />
        <DatePicker.Footer />
      </DatePicker.Content>
    </DatePicker>
  );
}

부품

필수 여부

반복

위치

DatePicker.Root

필수

Trigger와 Content를 직접 감싼다.

DatePicker.Trigger

필수

Root 안에 DateInput과 함께 둔다.

DatePicker.Content

필수

Root 안에서 Calendar와 Footer를 감싼다.

DatePicker.Calendar

필수

Content 안에 둔다.

DatePicker.Footer

선택

Content 안에서 Calendar 뒤에 둔다.

  • Root 안에 Trigger와 Content를 배치하고, Content 안에 Calendar를 둔다.
  • Footer가 필요하면 Calendar 뒤에 배치하고 취소·확인 버튼은 caller가 조립한다.

API Reference

DatePicker Props

Prop

Type

Default

aria-label

string

지정 안 함

cancelText

string

지정 안 함

confirmText

string

지정 안 함

disabled

boolean

지정 안 함

error

boolean

지정 안 함

formatDisplay

(iso: string) => string

지정 안 함

getDayClassName

(date: Date) => string

지정 안 함

inputProps

Omit<DateInputProps, "disabled" | "error" | "value" | "placeholder" | "readOnly">

지정 안 함

isDateUnavailable

(date: Date) => boolean

지정 안 함

locale

string

지정 안 함

max

string

지정 안 함

min

string

지정 안 함

monthLabelFormat

(date: Date) => string

지정 안 함

onValueChange

(value: string) => void

지정 안 함

placeholder

string

지정 안 함

startOfWeek

0 | 1 | 4 | 2 | 3 | 5 | 6

지정 안 함

timeZone

string

Asia/Seoul

value

string

지정 안 함

weekdayFormat

"narrow" | "short" | "short-uppercase" | "long"

지정 안 함

DatePicker.Trigger

날짜 입력을 눌러 선택 패널을 여는 트리거 슬롯이다.

공개 Props 없음

DatePicker.Content

날짜 선택 패널의 카드 영역을 담당하는 컨테이너다.

공개 Props 없음

DatePicker.Calendar

날짜를 탐색하고 선택하는 캘린더 그리드다.

공개 Props 없음

DatePicker.Footer

취소·확인 등 선택 완료 동작을 배치하는 영역이다.

공개 Props 없음

같은 패밀리

@mildang/design-system/DatePicker 에서 같이 내보내는 컴포넌트다.

표시 형식

닫힌 입력에 보이는 문자열은 formatDisplay 를 넘기지 않으면 useFormatDateTime({ type: 'fullDate' }) 로 자동 결정된다 (ko-KR → 2026. 07. 01., en-US → 07/01/2026). 날짜 표시는 직접 포맷 함수를 만들지 않고 항상 DS 의 FormatDateTime / useFormatDateTime 를 거친다.

timeZone 은 현재 'Asia/Seoul' 로 하드코드돼 있다 — 루트 TimezoneProvider 가 생기기 전까지의 임시 조치로, 소스에도 그 취지의 TODO 가 남아 있다.

표시 형식 커스터마이즈

formatDisplay로 날짜 표시 문자열을 커스터마이즈합니다.

import { useState } from 'react';
import { DatePicker } from '@mildang/design-system/DatePicker';

export default function DatePickerCustomFormatExample() {
  const [value, setValue] = useState<string | undefined>('2026-06-29');
  const formatKorean = (iso: string) => {
    const [y, m, d] = iso.split('-');
    return `${y}년 ${Number(m)}월 ${Number(d)}일`;
  };
  return (
    <DatePicker
      value={value}
      onValueChange={(v) => setValue(v ?? undefined)}
      formatDisplay={formatKorean}
      inputProps={{ width: '400px' }}
    />
  );
}

Compound API

대부분은 DatePicker convenience wrapper 하나로 충분하지만, 필요하면 아래 primitive 로 직접 조립할 수 있다.

Primitive역할
DatePicker.RootResponsivePopover 래퍼 (위 "화면 크기별 동작" 참고)
DatePicker.Trigger팝오버 트리거 slot. 보통 DateInput 을 넘긴다
DatePicker.Content카드 chrome(배경 · radius · shadow) 을 담당하는 컨테이너
DatePicker.Calendar캘린더 그리드. autoFocus / min / max / isDateUnavailable 등 규칙 prop 을 받는다
DatePicker.Footer취소/확인 버튼을 두는 영역 (버튼은 caller 가 Button 으로 조립)

예제

기본 사용

평상시 모습인 닫힌 날짜 입력입니다. 캘린더만 필요하면 DateCalendar 를 씁니다.

import { DatePicker } from '@mildang/design-system/DatePicker';
import { useState } from 'react';

export default function DatePickerExample() {
  const [value, setValue] = useState<string | undefined>(undefined);
  return (
    <div style={{ display: 'inline-flex', flexDirection: 'column', gap: 12 }}>
      <DatePicker value={value} onValueChange={(v) => setValue(v ?? undefined)} />
      <div style={{ fontSize: 12, color: '#888' }}>선택된 값(ISO): {value ?? '없음'}</div>
    </div>
  );
}

입력과 비활성 상태

기본·오류·비활성을 나란히 둡니다. 값이 든 비활성은 확정된 날짜를 읽기 전용으로 보여줄 때 씁니다.

import { DatePicker } from '@mildang/design-system/DatePicker';
import { VStack } from '@mildang/styled-system/jsx';

export default function DatePickerInputStatesExample() {
  return (
    <VStack alignItems="flex-start" gap="12">
      <DatePicker placeholder="수업 날짜 선택" />
      <DatePicker placeholder="날짜를 확인해 주세요" error />
      <DatePicker value="2026-09-03" disabled />
    </VStack>
  );
}

초기값

초기 선택값이 있는 날짜 입력입니다.

import { useState } from 'react';
import { DatePicker } from '@mildang/design-system/DatePicker';

export default function DatePickerWithInitialValueExample() {
  const [value, setValue] = useState<string | undefined>('2026-06-29');
  return <DatePicker value={value} onValueChange={(v) => setValue(v ?? undefined)} />;
}

최소·최대 날짜

min/max 범위 안에서만 날짜를 선택합니다.

import { useState } from 'react';
import { DatePicker } from '@mildang/design-system/DatePicker';

export default function DatePickerMinMaxExample() {
  const [value, setValue] = useState<string | undefined>(undefined);
  return (
    <DatePicker
      value={value}
      onValueChange={(v) => setValue(v ?? undefined)}
      min="2026-06-01"
      max="2026-06-30"
      placeholder="6월만 선택 - min/max 값 설정"
    />
  );
}

선택 불가 날짜

주말을 선택 불가 날짜로 처리합니다.

import { useState } from 'react';
import { DatePicker } from '@mildang/design-system/DatePicker';

export default function DatePickerUnavailableExample() {
  const [value, setValue] = useState<string | undefined>(undefined);
  return (
    <DatePicker
      value={value}
      onValueChange={(v) => setValue(v ?? undefined)}
      isDateUnavailable={(date) => {
        const day = date.getDay();
        return day === 0 || day === 6;
      }}
      placeholder="주말 제외"
    />
  );
}

비활성 전환

열린 날짜 입력을 disabled 상태로 전환하는 동작을 확인합니다.

코드

import { useState } from 'react';
import { DatePicker } from '@mildang/design-system/DatePicker';

export default function DatePickerDisabledTransitionExample() {
  const [value, setValue] = useState<string | undefined>(undefined);
  const [disabled, setDisabled] = useState(false);
  return (
    <div style={{ display: 'inline-flex', flexDirection: 'column', gap: 12 }}>
      <label style={{ fontSize: 12, cursor: 'pointer' }}>
        <input type="checkbox" checked={disabled} onChange={(e) => setDisabled(e.currentTarget.checked)} />{' '}
        disabled
      </label>
      <DatePicker value={value} onValueChange={(v) => setValue(v ?? undefined)} disabled={disabled} />
    </div>
  );
}

비활성

선택할 수 없는 날짜 입력을 표시합니다.

import { DatePicker } from '@mildang/design-system/DatePicker';

const DatePickerDisabledExample = () => <DatePicker value="2026-06-29" disabled />;

export default DatePickerDisabledExample;

오류

오류 상태의 날짜 입력을 표시합니다.

import { DatePicker } from '@mildang/design-system/DatePicker';

const DatePickerErrorExample = () => <DatePicker error placeholder="에러 상태" />;

export default DatePickerErrorExample;