atama plus techblog
🙆

期間選択UIを統一するために自社デザインシステムにコントリビュートした話

2024/12/17に公開

はじめに

こんにちは!atama plusの@sekkenです。
今回は、atama plusで運用しているデザインシステムについてご紹介します。

背景

atama plusでは、生徒・先生には「一貫した体験」のために、プロダクト開発チームには「意思決定の速度と開発効率、精度向上」を目指して、uniformというデザインシステムを開発・運用しています。
汎用的なコンポーネントを用意しておくのではなく、関心が似たコンポーネントが増えてきたら後からデザインシステムのコンポーネントとする流れで開発しています。
https://note.com/n_m_ta/n/n87891a4ce380

課題

atama+には日々の生徒のがんばりをサマリー表示する画面があり、サマリー表示する期間を絞り込む「期間を選択するUI」があります。
この「期間を選択するUI」はプロダクトの様々な画面で使われているため、共通のコンポーネントとして実装されていたのですが、オプションの自由度が高く統一感のない表示になっていました。

  • 何曜日から週を表示するかがバラバラ
    月曜日始まりの表示になっている例
    日曜日始まりの表示になっている例

  • 年月日の表記がバラバラ
    日付形式がバラバラの例

上記の画像では、MM月YYYY年という表記とYYYY/MM/DDという表記が混在しています。
uniformでは「生徒・先生の認知負荷を下げる」「プロダクト開発チームの意思決定を早くする」ために、プロダクト内で利用する日付のフォーマットと利用シーンを定義していますが、オプションの自由度が高いコンポーネントでは、このような表記を統一することが非常に難しいです。
日付のフォーマットと利用シーン定義

オプションと表記の見直しをすることで、あるべき姿になるようコンポーネントを作り替えます。

解決策

これまでエンジニアが自分たちで作っていたコンポーネントを、uniformのDateRangePickerコンポーネントとして再定義し、誰が開発しても「一貫した体験」を提供できる日付範囲選択コンポーネントとして刷新しました。

既存のDateRangeコンポーネント

以下のようなPropsで、どの曜日からカレンダーUIの週を始めるかコンポーネントの利用側が指定できました。

export type Props = {
  dateRangeMin: Date;
  dateRangeMax?: Date;
  isPrint?: boolean;
  limitOfRangeDay?: number;
  weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
};

上述のように年月日のフォーマットがMM月YYYY年という表示とYYYY/MM/DDという表記が混在していました。
さらに、内部構造としてはコンポーネントの外で利用するContextをセットするという責務を負っていました。

const { dateRange, setDateRange } = useDateRangeFilter();
・・・
const handleSubmit = (range: DateRange) => {
    setDateRange(range);
}

作り直したDateRangeコンポーネント

以下のようなPropsに変更。日付表記もYYYY年M月に統一しました。

type Props = {
  initialDateRange?: DateRange;
  disableDatesBefore?: Date;
  disableDatesAfter?: Date;
  limitOfRangeDay?: number;
  multiMonth?: boolean;
  onChange?: (dateRange: DateRange) => void;
  onError?: () => void;
  onClearError?: () => void;
};

修正後のコンポーネント表示

工夫した点

週始まりの曜日をコンポーネント内部で指定するよう修正しました。
この修正で画面によって月曜始まりと日曜始まりが混在することを防ぐことができるようになりました。

コンポーネントの外で利用するContextをセットする処理をコンポーネントの利用する側の責務として整理しました。
現状のアプリケーションではformの中で使われるユースケースは存在していませんが、Contextに期間をセットしてデータをフィルタする以外のユースケースでも対応しやすい作りになりました。

プロパティを検討する上ではShopifyのデザインシステムであるPolarisを参考にさせていただきました。
https://polaris.shopify.com/components/selection-and-input/date-picker?example=date-picker-ranged

弊社のデザインシステムには、見た目のバリエーションは必要になったら増やす。ない時点で考慮しない。というのコードレビュー観点があり、オプションを検討する上でも迷うことなく検討できました。

終わりに

デザインシステムの利用者としては、コンポーネントを利用することで早く実装できたり、ガイドラインを参考にすることで迷いなく実装できてありがたいと思っていました。デザインシステムの提供者目線で実装してみると、アプリケーションを横断的にみる必要があり、統一感のあるデザインにするにはどうすれば良いか、どうすればより利用者が使いやすいインターフェースになるかを考えることになるので、また違った頭の使い方をする必要がありとても勉強になりました。

uniformについてはこちらのnoteもぜひご覧ください!
https://note.com/atamaplusdesign/m/maf499180d11c

atama plus techblog
atama plus techblog

Discussion