デジタル庁デザインシステム:@internationalized/dateを用いた多国語日付処理の完全実装
グローバル化するWebサービスにおいて、日付処理は多言語・多文化への対応が不可欠です。デジタル庁デザインシステムでは、@internationalized/dateライブラリを活用して柔軟で正確な日付管理を実現しています。本記事では、このライブラリを用いた日付コンポーネントの実装方法を詳しく解説します。
コンポーネントアーキテクチャ
デジタル庁デザインシステムの日付処理コンポーネントは、主に次の2種類の実装が提供されています。
- DatePicker:統合型の日付入力コンポーネント
- SeparatedDatePicker:年月日が個別に分離された入力コンポーネント
これらのコンポーネントは共通して@internationalized/dateライブラリを使用しており、src/components/DatePicker/DatePicker.tsxとsrc/components/SeparatedDatePicker/SeparatedDatePicker.tsxにそれぞれ実装されています。
@internationalized/dateの基本概念
@internationalized/dateは、国際化された日付処理を提供するライブラリで、主に次の機能を提供しています。
- CalendarDate:タイムゾーンに依存しないカレンダー日付の表現
- getLocalTimeZone:ユーザーのローカルタイムゾーンを取得
- today:現在の日付を取得
- parseDate:日付文字列を解析してCalendarDateオブジェクトを生成
これらの機能を使用することで、異なる言語や文化に対応した日付処理を実現できます。
基本的な実装例
日付オブジェクトの生成
import { CalendarDate, getLocalTimeZone, today } from '@internationalized/date';
// 今日の日付を取得
const todayDate = today(getLocalTimeZone());
// 特定の日付を生成
const specificDate = new CalendarDate(2025, 10, 6);
このコードはsrc/components/DatePicker/DatePicker.stories.tsxで使用されているもので、基本的な日付オブジェクトの生成方法を示しています。
DatePickerコンポーネントの使用
<DatePicker>
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear ref={yearRef} {...rest} />
<DatePickerMonth ref={monthRef} {...rest} />
<DatePickerDate ref={dateRef} {...rest} />
</>
)}
</DatePicker>
この例では、DatePickerコンポーネントが年月日の各入力フィールドを提供しています。左右キーを使用してフィールド間を移動することができます。
カレンダーとの連携
日付入力に加えて、カレンダーを使用した直感的な日付選択もサポートされています。次のコードは、カレンダーを表示して日付を選択する機能を実装したものです。
<ReactAriaDatePicker className='flex gap-4'>
{({ state }) => {
const updateCalendarDate = () => {
const year = Number.parseInt(yearInput);
const month = Number.parseInt(monthInput);
const day = Number.parseInt(dayInput);
if (!Number.isNaN(year) && !Number.isNaN(month) && !Number.isNaN(day)) {
state.setValue(new CalendarDate(year, month, day));
} else {
state.setValue(null);
}
};
return (
<>
<DatePicker size={size} {...args}>
{/* 年月日入力フィールド */}
</DatePicker>
<DatePickerCalendarButton
size={size}
aria-haspopup='dialog'
aria-expanded={state.isOpen}
onClick={() => state.setOpen(true)}
/>
<Popover>
<Dialog aria-label='カレンダー'>
<Calendar onChange={handleCalendarChange}>
{/* カレンダーの実装 */}
</Calendar>
</Dialog>
</Popover>
</>
);
}}
</ReactAriaDatePicker>
この実装はsrc/components/DatePicker/DatePicker.stories.tsxのWithCalendarストーリーにあり、入力フィールドとカレンダーの連携を実現しています。
多言語対応のカレンダー表示
デジタル庁デザインシステムでは、曜日の表示など多言語に対応したカレンダーを提供しています。次のコードは、カレンダーのヘッダーに曜日を表示する例です。
<CalendarGridHeader className='[&_th]:p-0'>
{(day) => (
<CalendarHeaderCell className='size-12 text-center font-bold'>
{day}
</CalendarHeaderCell>
)}
</CalendarGridHeader>
このコードは、dayパラメータを通じて多言語化された曜日名を受け取り、表示しています。これにより、アプリケーションの言語設定に応じて自動的に曜日名の言語が切り替わります。
応用例:部分的な日付入力
デジタル庁デザインシステムの日付コンポーネントは、年月日すべてではなく、年月または月日のみの入力にも対応しています。
// 年月のみの入力
<DatePicker>
{({ yearRef, monthRef }) => (
<>
<DatePickerYear ref={yearRef} />
<DatePickerMonth ref={monthRef} />
</>
)}
</DatePicker>
// 月日のみの入力
<DatePicker>
{({ monthRef, dateRef }) => (
<>
<DatePickerMonth ref={monthRef} />
<DatePickerDate ref={dateRef} />
</>
)}
</DatePicker>
この実装はsrc/components/DatePicker/DatePicker.stories.tsxのPartialストーリーで確認できます。
エラーハンドリングとバリデーション
日付入力におけるエラーハンドリングは、次のように実装されています。
<DatePicker isError={true}>
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear
ref={yearRef}
aria-describedby='date-picker-error-text'
{...rest}
/>
<DatePickerMonth ref={monthRef} {...rest} />
<DatePickerDate ref={dateRef} {...rest} />
</>
)}
</DatePicker>
<ErrorText id='date-picker-error-text'>*正しい日付を入力してください。</ErrorText>
このコードはsrc/components/DatePicker/DatePicker.stories.tsxのErroredストーリーにあり、エラー状態を視覚的に表示するとともに、スクリーンリーダーにもエラー情報を提供しています。
まとめ
デジタル庁デザインシステムの日付処理コンポーネントは、@internationalized/dateライブラリを活用することで、多言語・多文化に対応した柔軟な日付入力を実現しています。本記事で紹介した基本的な実装方法を基に、さまざまなユースケースに合わせた日付処理機能を構築できます。
詳細な実装例については、以下のファイルを参照してください。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



