다국어 (i18n)
Kalyx는 영어 ARIA 라벨을 기본으로 제공합니다. labels prop으로 컴포넌트별 오버라이드하세요. 별도 i18n 라이브러리 불필요.
동작 방식
모든 Root 컴포넌트(DatePicker, RangePicker, TimePicker, DateTimePicker)가 labels prop을 받습니다. 부분 객체만 넘기면 됩니다. 오버라이드한 키만 교체되고 나머지는 영어 기본값이 유지됩니다.
<DatePicker
value={date}
onChange={setDate}
labels={{
triggerOpen: '캘린더 열기',
prevMonth: '이전 달',
nextMonth: '다음 달',
}}
>
{/* ... */}
</DatePicker>
라벨 키 레퍼런스
DatePicker
| 키 | 기본값 (영어) | 사용 위치 |
|---|---|---|
triggerOpen | "Open calendar" | Trigger aria-label (닫힘) |
triggerClose | "Close calendar" | Trigger aria-label (열림) |
popoverLabel | "Choose date" | Popover aria-label |
prevMonth | "Previous month" | Calendar 이전 달 버튼 |
nextMonth | "Next month" | Calendar 다음 달 버튼 |
prevYear | "Previous year" | Calendar 이전 년 버튼 |
nextYear | "Next year" | Calendar 다음 년 버튼 |
prevDecade | "Previous decade" | YearGrid 이전 10년 버튼 |
nextDecade | "Next decade" | YearGrid 다음 10년 버튼 |
RangePicker (DatePicker 확장)
| 키 | 기본값 | 사용 위치 |
|---|---|---|
popoverLabel | "Choose date range" | Popover aria-label |
startInput | "Start date" | 시작 Input aria-label |
endInput | "End date" | 종료 Input aria-label |
presetsGroup | "Date range presets" | Presets 그룹 aria-label |
TimePicker
| 키 | 기본값 | 사용 위치 |
|---|---|---|
timeInput | "Time" | Input aria-label |
hourList | "Hour" | 시 목록 aria-label |
minuteList | "Minute" | 분 목록 aria-label |
amPmToggle | "AM/PM" | AM/PM 라디오그룹 aria-label |
hourOption(h) | `${h} hours` | 시 옵션 aria-label |
minuteOption(m) | `${m} minutes` | 분 옵션 aria-label |
DateTimePicker (DatePicker + TimePicker 확장)
| 키 | 기본값 | 사용 위치 |
|---|---|---|
dateTimeInput | "Date and time" | Input aria-label |
재사용 가능한 로케일 프리셋
공유 라벨 파일을 만들어 앱 전체에서 import하세요:
import type { DatePickerLabels, RangePickerLabels, TimePickerLabels } from '@kalyx/core';
export const ko: DatePickerLabels = {
triggerOpen: '캘린더 열기',
triggerClose: '캘린더 닫기',
popoverLabel: '날짜 선택',
prevMonth: '이전 달',
nextMonth: '다음 달',
prevYear: '이전 년',
nextYear: '다음 년',
prevDecade: '이전 10년',
nextDecade: '다음 10년',
};
export const koRange: RangePickerLabels = {
...ko,
popoverLabel: '날짜 범위 선택',
startInput: '시작일',
endInput: '종료일',
presetsGroup: '날짜 범위 프리셋',
};
export const koTime: TimePickerLabels = {
timeInput: '시간',
hourList: '시',
minuteList: '분',
amPmToggle: '오전/오후',
hourOption: (h) => `${h}시`,
minuteOption: (m) => `${m}분`,
};
import { ko } from '@/lib/kalyx-labels';
<DatePicker labels={ko} value={date} onChange={setDate}>
{/* ... */}
</DatePicker>
일본어 예제
import type { DatePickerLabels } from '@kalyx/core';
export const ja: DatePickerLabels = {
triggerOpen: 'カレンダーを開く',
triggerClose: 'カレンダーを閉じる',
popoverLabel: '日付を選択',
prevMonth: '前月',
nextMonth: '翌月',
prevYear: '前年',
nextYear: '翌年',
prevDecade: '前の10年',
nextDecade: '次の10年',
};
캘린더 로케일 (요일·월 이름)
요일 헤더와 월 이름은 내부적으로 Intl.DateTimeFormat을 사용합니다. locale prop (BCP 47 태그)을 넘기면 해당 언어로 렌더됩니다:
<DatePicker locale="ko-KR" labels={ko} value={date} onChange={setDate}>
<DatePicker.Input />
<DatePicker.Popover>
<DatePicker.Calendar />
</DatePicker.Popover>
</DatePicker>
locale은 표시 포맷을 제어합니다 (요일 이름, 헤더의 월 이름).labels는 ARIA 속성을 제어합니다 (스크린 리더 텍스트).
둘은 독립적입니다. locale="ko-KR"과 영어 라벨을 함께 쓸 수도 있고, 그 반대도 가능합니다.
오른쪽-왼쪽 (RTL)
RTL 지원은 두 계층이며, 보통 둘 다 필요합니다:
- 시각적 미러링은 문서에서 옵니다. 상위 요소(또는
<html dir="rtl">)에dir="rtl"을 주면 캘린더 그리드·입력·popover가 페이지와 함께 미러링됩니다. Kalyx는 의미론적 HTML을 렌더링하며 자체적으로 레이아웃 방향을 더하지 않으므로 이 부분은 "그냥 동작"합니다. - 키보드 내비게이션은 picker 자신의
dirprop에서 옵니다. 어느 picker Root든(DatePicker,RangePicker,DateTimePicker,MonthPicker,YearPicker,WeekPicker)dir="rtl"을 넘기면 ArrowLeft/ArrowRight가 WAI-ARIA grid 패턴에 따라 시각적 레이아웃을 따르도록 반전됩니다. 즉 시각적으로 왼쪽 셀이 다음 날짜, 오른쪽 셀이 이전 날짜가 됩니다. ArrowUp/Down, PageUp/Down, Home/End는 논리적 방향을 유지합니다. Root는 그리드 요소에dir도 찍어주므로, picker에 지정하면 캘린더의 시각 계층까지 함께 처리됩니다.
아랍어 요일/월 이름을 위해 맞는 locale(예: ar-EG)을 사용하세요.
아래에서 방향을 토글해 같은 picker가 미러링되는 것을 확인하세요:
function RtlToggle() { const [date, setDate] = React.useState(null); const [dir, setDir] = React.useState('rtl'); return ( <div> <button className="kx-live-trigger" style={{ marginBottom: 12 }} onClick={() => setDir((d) => (d === 'rtl' ? 'ltr' : 'rtl'))}> dir = {dir} (토글) </button> <div dir={dir}> <DatePicker dir={dir} value={date} onChange={setDate} locale={dir === 'rtl' ? 'ar-EG' : 'en-US'}> <DatePicker.Input className="kx-live-input" placeholder="YYYY-MM-DD" /> <DatePicker.Popover className="kx-live-popover"> <DatePicker.Calendar classNames={{ header: 'kx-live-header', title: 'kx-live-title', navButton: 'kx-live-nav', grid: 'kx-live-grid', gridCell: 'kx-live-cell', weekdayHeader: 'kx-live-weekday', day: 'live-day', daySelected: 'live-day-selected', dayToday: 'live-day-today', dayOutsideMonth: 'kx-live-outside', }} /> </DatePicker.Popover> </DatePicker> </div> </div> ); }
내비게이션 화살표는 그리드 전체가 dir과 함께 미러링되므로 "이전 / 다음"의 시각적 의미를 그대로 유지합니다. 직접 바꿀 필요가 없습니다. 스크린 리더 안내가 언어와 맞도록 지역화된 labels(위 라벨 키 레퍼런스 참고)를 제공하세요.
상위
<div>에dir을 주면 CSS 미러링이 처리되고,<DatePicker>Root에dir을 주면 화살표 키 내비게이션이 미러링됩니다. 완전히 미러링되고 키보드까지 올바른 picker를 위해서는 위 예시처럼 둘 다 설정하세요.