はじめに
Ant Design は、React用の UIフレームワークの一つで、洗練されたデザインと豊富なコンポーネントが特徴だが、あまり日本語の記事がない。
その中でも DatePicker
は、日付を選択するためのコンポーネントになる。
ラップしたカスタム部品を作成する機会があったのでメモ書きとして残しておく。
Ant Design の DatePicker とは?
DatePicker
は、カレンダー UI を提供し、ユーザーが日付を選択できるようにするコンポーネントで以下のように簡単に導入できる。
import React, { useState } from 'react';
import { DatePicker } from 'antd';
import dayjs, { Dayjs } from 'dayjs';
const BasicDatePicker: React.FC = () => {
const [date, setDate] = useState<Dayjs | null>(null);
return <DatePicker value={date} onChange={setDate} format="YYYY/MM/DD" />;
};
export default BasicDatePicker;
しかし、 YYYYMMDD
形式で入力された日付がフォーカスアウトされたタイミングで
YYYY/MM/DD
形式に変換する必要があり DatePicker
をラップした CustomDatePicker
部品を作成した。
実装
CustomDatePicker
の要件
-
YYYYMMDD
の入力を受け付ける - ユーザーがフォーカスアウトした際にフォーマットを適用
- デフォルトのフォーマットは
YYYY/MM/DD
- カレンダー選択時はそのまま反映
- 無効な日付入力は
null
をセット
実装コード
以下のコードは CustomDatePicker
の実装です。
import React from 'react';
import { DatePicker } from 'antd';
import dayjs, { Dayjs } from 'dayjs';
// DatePicker のプロパティを定義
export interface CustomDatePickerProps {
value?: Dayjs | null; // 選択された日付(null 許容)
onChange?: (date: Dayjs | null) => void; // 値の変更時に呼ばれるコールバック関数
placeholder?: string; // プレースホルダー
format?: string; // 日付のフォーマット
disabled?: boolean; // 無効化フラグ
}
// Ant Design の DatePicker をカスタマイズしたコンポーネント
const CustomDatePicker: React.FC<CustomDatePickerProps> = ({
value,
onChange,
placeholder = '日付の入力・選択をしてください', // デフォルトのプレースホルダー
format = 'YYYY/MM/DD', // デフォルトのフォーマット
disabled = false, // デフォルトで有効
}) => {
// カレンダーで日付を選択したときに実行
const handleChange = (date: Dayjs | null) => {
onChange?.(date); // 選択した日付を親コンポーネントに渡す
};
// フォーカスアウト時に入力値を検証・変換する処理
const handleBlur = (e: React.FocusEvent<HTMLElement>) => {
if (!(e.target instanceof HTMLInputElement)) return; // 入力フィールドでない場合は処理しない
if (!onChange) return; // onChange が渡されていない場合は処理しない
const inputValue = e.target.value.trim(); // ユーザー入力を取得し、前後の空白を削除
// YYYYMMDD(例: 20240131)形式で入力された場合
if (/^\d{8}$/.test(inputValue)) {
const formattedDate = dayjs(inputValue, 'YYYYMMDD').format(format); // 指定フォーマットへ変換
onChange(dayjs(formattedDate, format));
}
// ユーザーが指定フォーマット (YYYY/MM/DD など) で入力した場合
else if (dayjs(inputValue, format, true).isValid()) {
onChange(dayjs(inputValue, format));
}
// 無効な日付の場合
else {
onChange(null); // 無効な値は null を設定
}
};
return (
<DatePicker
value={value} // 選択された日付
format={format} // フォーマットを適用
inputReadOnly={false} // 手動入力を許可
placeholder={placeholder} // プレースホルダーの表示
onBlur={handleBlur} // フォーカスアウト時の処理
onChange={handleChange} // 日付選択時の処理
disabled={disabled} // 無効化の設定
/>
);
};
export default CustomDatePicker;
CustomDatePicker
の動作確認
-
YYYYMMDD
形式で入力すると、自動でYYYY/MM/DD
にフォーマットされる - 無効な日付を入力すると
null
になる(画面上は非表示) -
DatePicker
のカレンダー UI から選択すると、そのまま値がセットされる
理想は、Ant Design の仕様をそのまま利用する要件にすることがいいと思うのですが、
そうもいかないのがシステム開発・・・