feat: add locale support
parent
50ea538717
commit
cca9b10a45
@ -0,0 +1,135 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Year } from '../components/calendar/Year';
|
||||||
|
import { Controls } from '../components/calendar/Controls';
|
||||||
|
import { HeaderStyle, MonthCutoffType, DaySize } from '../types/calendar';
|
||||||
|
import styles from './Examples.module.scss';
|
||||||
|
import { Locale } from 'date-fns';
|
||||||
|
import {
|
||||||
|
enUS,
|
||||||
|
es,
|
||||||
|
fr,
|
||||||
|
de,
|
||||||
|
it,
|
||||||
|
pt,
|
||||||
|
ja,
|
||||||
|
ko,
|
||||||
|
zhCN,
|
||||||
|
ru,
|
||||||
|
ar,
|
||||||
|
nl,
|
||||||
|
pl,
|
||||||
|
tr,
|
||||||
|
sv,
|
||||||
|
nb
|
||||||
|
} from 'date-fns/locale';
|
||||||
|
|
||||||
|
export const LocaleSupport: React.FC = () => {
|
||||||
|
const [dayHeaderStyle, setDayHeaderStyle] = useState<HeaderStyle>('tiny');
|
||||||
|
const [monthCutoff, setMonthCutoff] = useState<MonthCutoffType>('truncate');
|
||||||
|
const [size, setSize] = useState<DaySize>('l');
|
||||||
|
const [fontProportion, setFontProportion] = useState<number>(100);
|
||||||
|
const [magnify, setMagnify] = useState<boolean>(false);
|
||||||
|
const [selectedLocale, setSelectedLocale] = useState<string>('enUS');
|
||||||
|
|
||||||
|
const locales: Record<string, { locale: Locale; name: string }> = {
|
||||||
|
enUS: { locale: enUS, name: 'English (US)' },
|
||||||
|
es: { locale: es, name: 'Español' },
|
||||||
|
fr: { locale: fr, name: 'Français' },
|
||||||
|
de: { locale: de, name: 'Deutsch' },
|
||||||
|
it: { locale: it, name: 'Italiano' },
|
||||||
|
pt: { locale: pt, name: 'Português' },
|
||||||
|
ja: { locale: ja, name: '日本語' },
|
||||||
|
ko: { locale: ko, name: '한국어' },
|
||||||
|
zhCN: { locale: zhCN, name: '中文 (简体)' },
|
||||||
|
ru: { locale: ru, name: 'Русский' },
|
||||||
|
ar: { locale: ar, name: 'العربية' },
|
||||||
|
nl: { locale: nl, name: 'Nederlands' },
|
||||||
|
pl: { locale: pl, name: 'Polski' },
|
||||||
|
tr: { locale: tr, name: 'Türkçe' },
|
||||||
|
sv: { locale: sv, name: 'Svenska' },
|
||||||
|
nb: { locale: nb, name: 'Norsk' }
|
||||||
|
};
|
||||||
|
|
||||||
|
const activeDates = [
|
||||||
|
new Date(2025, 0, 1), // New Year's Day
|
||||||
|
new Date(2025, 3, 21), // Spring
|
||||||
|
new Date(2025, 6, 14), // Bastille Day / Summer
|
||||||
|
new Date(2025, 9, 31), // Halloween
|
||||||
|
new Date(2025, 11, 25) // Christmas
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={styles.section}>
|
||||||
|
<h2 className={styles.sectionTitle}>International Locale Support</h2>
|
||||||
|
<p className={styles.sectionDescription}>
|
||||||
|
The calendar supports multiple languages through the date-fns locale system.
|
||||||
|
Day names, month names, and date formats are automatically localized.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className={styles.controlRow}>
|
||||||
|
<label className={styles.control}>
|
||||||
|
Language:
|
||||||
|
<select
|
||||||
|
value={selectedLocale}
|
||||||
|
onChange={(e) => setSelectedLocale(e.target.value)}
|
||||||
|
style={{ marginLeft: '8px', padding: '4px 8px' }}
|
||||||
|
>
|
||||||
|
{Object.entries(locales).map(([key, { name }]) => (
|
||||||
|
<option key={key} value={key}>{name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Controls
|
||||||
|
headerStyle={dayHeaderStyle}
|
||||||
|
monthCutoff={monthCutoff}
|
||||||
|
size={size}
|
||||||
|
fontProportion={fontProportion}
|
||||||
|
magnify={magnify}
|
||||||
|
onHeaderStyleChange={setDayHeaderStyle}
|
||||||
|
onMonthCutoffChange={setMonthCutoff}
|
||||||
|
onSizeChange={setSize}
|
||||||
|
onFontProportionChange={setFontProportion}
|
||||||
|
onMagnifyChange={setMagnify}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className={styles.demoContainer}>
|
||||||
|
<Year
|
||||||
|
year={2025}
|
||||||
|
dayHeaderStyle={dayHeaderStyle}
|
||||||
|
monthCutoff={monthCutoff}
|
||||||
|
weekendDays={[6, 0]}
|
||||||
|
size={size}
|
||||||
|
fontProportion={fontProportion}
|
||||||
|
magnify={magnify}
|
||||||
|
locale={locales[selectedLocale].locale}
|
||||||
|
activeDates={activeDates}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.info}>
|
||||||
|
<h4>Localized Elements:</h4>
|
||||||
|
<ul>
|
||||||
|
<li>Month names (e.g., January, Janvier, Januar, 一月)</li>
|
||||||
|
<li>Day names in headers (Monday, Lundi, Montag, 月曜日)</li>
|
||||||
|
<li>Day abbreviations (Mon, Lun, Mo, 月)</li>
|
||||||
|
<li>Single letter days (M, L, M, 月)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4 style={{ marginTop: '20px' }}>Header Style Examples:</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Expanded:</strong> Full day names (e.g., MONDAY, LUNDI, MONTAG)</li>
|
||||||
|
<li><strong>Compacted:</strong> 3-letter abbreviations (e.g., MON, LUN, MO)</li>
|
||||||
|
<li><strong>Tiny:</strong> Single letters with special handling for conflicts</li>
|
||||||
|
<li><strong>None:</strong> No day headers, only numbers</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p style={{ marginTop: '20px', fontSize: '0.9em', color: '#666' }}>
|
||||||
|
Note: Some languages may show squares or incorrect characters if the required fonts
|
||||||
|
are not installed on your system (especially for Arabic, Chinese, Japanese, and Korean).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue