showPickerを使ってフィールドのどこをクリックしても日付Pickerが開くようにする
はじめに
この記事ではHTML5の<input type="date">
を拡張して、本来はカレンダーアイコンをクリックすることでしか開けない日付Picker(date picker)を、フィールドのどこをクリックしても開くようにする方法を紹介します。
showPicker()を使用する
HTMLInputElement.showPicker()
は、実行するとinput要素のブラウザのPickerを表示することができます。
今回はshowPickerメソッドを使用してonClickイベント時にshowPickerを呼び出し、クリックイベントから日付Pickerを直接表示するようにします。そうすることで入力欄全体をPickerのトリガーにすることができます。
実装コード
私が実装した主な環境は以下の通りです。
- React(v17.0.2)
- TypeScript(v4.3.5)
- styled-components(v6.0.5)
必要なモジュールのインポート
Reactを使用するための基本モジュールをインポートしています。ForwardedRefとforwardRefは親コンポーネントから子コンポーネントにrefを渡すことができ、フォームの制御やDOM操作に使用しています。
import React, { ForwardedRef, forwardRef } from 'react';
import styled from 'styled-components';
型定義
defaultValueには任意で日付フィールドの初期値を指定するためにstringで定義をしていて、onChangeは任意で日付が変更されたときに呼び出されるコールバック関数を型React.ChangeEvent<HTMLInputElement> で定義しています。
type CalendarProps = {
defaultValue?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
};
Propsの受け取り
forwardRefを使用してrefを渡すことでこのコンポーネントを使用する親コンポーネントから直接input要素への参照を取得できます。
const Calendar = forwardRef((
{ defaultValue, onChange }: CalendarProps,
ref: ForwardedRef<HTMLInputElement>
): JSX.Element => {
handleClickの処理
後述のinputタグがクリックされたときにhandleClickを呼び出します。型アサーションを使って、currentTarget が HTMLInputElement であり、showPicker メソッドを持つことを明示しています。
const handleClick = (event: React.MouseEvent<HTMLInputElement>) => {
(event.currentTarget as HTMLInputElement & { showPicker: () => void }).showPicker();
};
return内の構造
inputタグに処理に必要なプロパティ、属性を追加しています。onClickプロパティでhandleClickをバインドしてクリック時に日付Pickerを表示するようにしています。
return (
<StyledCalendar>
<img src={任意のカレンダーアイコンのパス} alt="カレンダーアイコン" />
<input
ref={ref}
type="date"
defaultValue={defaultValue}
onChange={onChange}
onClick={handleClick}
/>
</StyledCalendar>
);
全体のコード
全体のコードはこちら
import React, { ForwardedRef, forwardRef } from 'react';
import styled from 'styled-components';
type CalendarProps = {
defaultValue?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
};
const StyledCalendar = styled.div`
// スタイルは省略
`;
const Calendar = forwardRef((
{ defaultValue, onChange }: CalendarProps,
ref: ForwardedRef<HTMLInputElement>
): JSX.Element => {
const handleClick = (event: React.MouseEvent<HTMLInputElement>) => {
(event.currentTarget as HTMLInputElement & { showPicker: () => void }).showPicker();
};
return (
<StyledCalendar>
<img src={任意のカレンダーアイコンのパス} alt="カレンダーアイコン" />
<input
ref={ref}
type="date"
defaultValue={defaultValue}
onChange={onChange}
onClick={handleClick}
/>
</StyledCalendar>
);
});
export default Calendar;
終わりに
この記事では、HTML5 の showPicker を活用して、入力欄全体をクリックして日付ピッカーを開く方法を紹介しました。
日付Picker(date picker)を入力欄全体にバインドされることでユーザー体験も良くなると思います。もしライブラリ等を使用せずに日付Pickerを実装する時には参考にしてみてください。
実際に就活会議上で以下のように動作しています。
Discussion