ingred-ui icon indicating copy to clipboard operation
ingred-ui copied to clipboard

DateRangePickerのリニューアル

Open maktak1995 opened this issue 2 years ago • 14 comments

背景

  • momentjsreact-dates の置き換えをする過程で DateRangePicker そのものに不満があるという話が上がってきた
  • そもそも現状の DateRangePicker が急ごしらえのもので、理想形ではない
  • なので理想形のDateRangePickerを作る方向ですすめることにした

デザイン

https://xd.adobe.com/view/a2977fa3-990f-4e0b-7eb7-1f835cc8c42a-d4a6/screen/baa54a33-a87a-4fa4-9fea-b8c26bac63e7/

  • DatePickerもデザインはほぼ同じものを使う

関連issue

maktak1995 avatar Sep 08 '22 06:09 maktak1995

まずはデザインを見せてDstメンにユーザーヒアリングする たぶんDstメンがほしいっていうとみんなほしいと思うので

maktak1995 avatar Sep 08 '22 06:09 maktak1995

@maktak1995 とりあえずプロトタイプ作ったんだけど、XDの都合上うまく表現できない部分もあるんで口頭で説明しますね

noronaoki avatar Sep 09 '22 01:09 noronaoki

プロトタイプの動作補足説明

キーボード入力

  • 必要な桁数入力されたら自動で隣にフォーカスが移動する
  • Enter押下でも同じ挙動

カレンダー入力

  • カレンダー左上に同様の入力欄

  • カレンダーは縦スクロール

  • スティッキーな日付表示はスクロールすると月が切り替わる

  • クリックすると各月へのショートカットが表示される

  • 縦スクロールなのは一般的に横スクロールはしづらいものだから

maktak1995 avatar Sep 12 '22 04:09 maktak1995

仕様Doc: https://docs.google.com/document/d/1xCYGOcgtyQfXsAi0Tv_OW1XrdkyDqE8f2hBI87uRIbc/edit#

maktak1995 avatar Sep 12 '22 08:09 maktak1995

背景の整理

今回のタスクは複数のやりたいことが絡まっているのでそれを解きほぐした上でタスクをブレイクダウンしたい

momentjs を除去したい

  • 公式がサポート終了するから

React-dates を除去したい

  • momentjs に依存しているライブラリだから
  • 更新が滞っており react v18 への対応が見込めないから

DateRangePicker のデザインをリニューアルしたい

  • 現状のデザインは仮のもの
  • ちゃんとしたデザイン案に沿ったものとしたい

目的

1. momentjs と react-dates を剥がす

  • 現実的な候補として dayjs がある
    • interface が momentjs と同じなので置換をやりやすい
    • 様々なライブラリ候補のなかで一番小さい
  • dayjs であれば react-dates の置換先として dayjs ネイティブなものではなくても momentjs 用のライブラリをfolkして置き換えて使うという選択肢も出てくる
  • ステップ2を考慮したライブラリでまずはそのままの置換をすすめる?

2. DateRangePicker のデザインを変更する

  • デザインと仕様はすでに固まっている
  • いいライブラリがなければフルスクラッチもありうるが、難易度は跳ね上がる
  • spectrum など参考になりそうな実装はある

maktak1995 avatar Sep 15 '22 09:09 maktak1995

muiのdateRangePickerがdayjs使っててUIがreact-datesと同じなので最初の置き換えにはいいかもしれない https://mui.com/x/react-date-pickers/date-range-picker/

maktak1995 avatar Sep 20 '22 09:09 maktak1995

最初のステップとしてmuiを使った置き換えを検討したが、muiのDateRangePickerは有料版限定のコンポーネントであった。 なのでアウト。

maktak1995 avatar Oct 13 '22 09:10 maktak1995

他の置き換え候補

react-suite DateRangePicker

  • 更新が活発でReact v18への対応も進んでいる
  • 中華製で他に比べると利用率は高くない
  • デザインシステム全部をインストールする必要があるためバンドルの肥大化が懸念される

daterangepicker-dayjs

  • momentjsを利用したdaterangepickerを個人でフォークしてdayjsに対応させたもの。
  • jqueryを使用しておりレガシーな実装
  • Reactでの利用は考慮されていない
  • 更新が1年前で止まっている

momentjsを使っている他の開発が活発なDateRangePicker

  • react-datesしか見つからなかった

maktak1995 avatar Oct 13 '22 09:10 maktak1995

date-fns だと react-date-range といういい感じのライブラリがある

maktak1995 avatar Oct 13 '22 10:10 maktak1995

案1: react-suite をインストールして使用する

  • 活発なライブラリなので安定した利用が見込める
  • ライブラリのコンポーネント全部インストールしないといけないのでバンドルが肥大化する

案2: react-date-range を使う

  • かなり柔軟なライブラリなので今後来る新しいデザインにもそのまま使い回せるかも
  • dayjsでもmomentjsでもないのでingred-uiを導入しているプロダクト側の大規模な対応が必要になる

案3: react-datesをfolkしてきてdayjsとReact18に対応できるよう改修して使う

  • ぱっとコードを見た感じそこまで難しいことでもまあなさそう
  • 完全に自分たちで管理することにはなる
  • うまくいけばingred-ui側の変更を最小限にして置き換えることが可能になる

maktak1995 avatar Oct 13 '22 10:10 maktak1995

案3かなー 結局デザインは(いつ変えるかはわからないが) あとから変わるんだし、応急手当的な処理でもまあいいんじゃないか、という気はする

maktak1995 avatar Oct 13 '22 10:10 maktak1995

いろいろしてみたがやっぱりreact-datesの手直しは全体的に古くなってるせいで余計に難しく、現実的ではなかった date-fnsであれば使えるライブラリがいくつか存在しているので、移行先をdayjsからdate-fnsに変えられないか、変えた場合はどんな影響が出るのかを調査して可能そうであればdate-fnsに変える方向に倒したい。

maktak1995 avatar Oct 14 '22 09:10 maktak1995

@takurinton がdayjsでのカレンダー自作の検証をしてくれた。良さそうなので最終的にはdayjsでフルスクラッチする方針とする。 https://dev.takurinton.com/tech/frontend/calender-ui-prototype.html https://github.com/takurinton/calender/pull/2

maktak1995 avatar Oct 24 '22 08:10 maktak1995

最終的な実装方針は以下の通り。

  1. react-dates の moment.js の部分を dayjs に変換するラッパーを作る
  2. 一旦リリースして各プロダクト置き換え
  3. 置き換えてる間に新しいカレンダーをフルスクラッチ + dayjs で実装
  4. なんかこれ用のリリースブランチ(v11.0.0-beta-1 とか)作るか、コンポーネントの名前を <DatePickerNext /> とかに変えて試験運用してみる
  5. 良さそうだったらいよいよ置き換え

maktak1995 avatar Oct 24 '22 08:10 maktak1995

@maktak1995

どのように誰に引き継いだのかを書いておいてもらえると:pray:

youchann avatar Dec 21 '22 09:12 youchann

上から順にやります。 それぞれのコンポーネントを export して、使う側で組み合わせることも可能な状態にする(実際、社内でそういうユースケースがありそうなので)

  • [x] Calendar コンポーネントの追加 https://github.com/voyagegroup/ingred-ui/pull/1361
  • [x] DateField コンポーネントの追加 https://github.com/voyagegroup/ingred-ui/pull/1362
  • [x] DatePicker の追加 https://github.com/voyagegroup/ingred-ui/pull/1363
  • [x] CalendarRange コンポーネントの追加 https://github.com/voyagegroup/ingred-ui/pull/1365
  • [x] DateRangeField コンポーネントの追加 https://github.com/voyagegroup/ingred-ui/pull/1367
  • [x] DateRangePicker コンポーネントの追加 https://github.com/voyagegroup/ingred-ui/pull/1369
  • [x] スタイルの細かい修正
  • [x] インターフェイスの整理 https://github.com/voyagegroup/ingred-ui/issues/975#issuecomment-1683372939
  • [x] 年選択の実装 https://github.com/voyagegroup/ingred-ui/issues/975#issuecomment-1685744375
  • [x] (リファクタ) https://github.com/voyagegroup/ingred-ui/pull/1372

takurinton avatar Aug 14 '23 05:08 takurinton

snapshot テストは style やインターフェイス調整するタイミングで入れる(Calendar と DateField を組み合わせて DatePicker 作るし、その段階で都度更新するのは疲れるので)

takurinton avatar Aug 14 '23 05:08 takurinton

ここまでやってきたこと

  • issues
    • https://github.com/voyagegroup/ingred-ui/issues/871
    • https://github.com/voyagegroup/ingred-ui/issues/856
  • prototype
    • https://github.com/takurinton/dateinput
    • https://github.com/takurinton/calendar (微調整ののち採用)
    • https://github.com/takurinton/datepicker-integration
    • https://github.com/takurinton/date (採用)
  • memo
    • https://memo.takur.in/tech/frontend/calender-ui-prototype.html
    • https://memo.takur.in/tech/frontend/calender-ui-prototype-with-scroll.html
    • https://memo.takur.in/tech/frontend/calender-ui-prototype-with-scroll-performance-improvement.html
    • https://memo.takur.in/tech/frontend/dateinput-components.html
    • https://memo.takur.in/tech/frontend/datefield.html

細かいデザインやドキュメントは社外向けに書いてないので一旦載せない。後で整理して出す。

takurinton avatar Aug 14 '23 05:08 takurinton

DateRangeField について 現状だと format prop は1つしか渡すことができず、開始日と終了日に共通のフォオーマットを当てる形にしてるけど、それぞれ独立させたいケースがあるかもしれない。 image

例として、広告の配信期間を指定する際

  • 開始日時は HH時00分00秒 を指定したい
  • 終了日時は HH時59分59秒 を指定したい

みたいなケースがありそうで、それを format で縛ろうとするとそれぞれ独立していた方がやりやすい 最悪、format に HH時mm分ss秒 と入れれば可能ではあるけど、分や秒はユーザーに触らせたくないみたいなのもそれなりに存在するという想定。

takurinton avatar Aug 15 '23 21:08 takurinton

date prop に null を含めるかどうか検討したい。 ユースケースを見る限り、null を入れたいケースはありそう ~(例えば終了日時を指定せずに submit する時など)~ → null じゃなかった、ということは実質なさそう。

となると、インターフェイス的には

type Props = {
  date: Dayjs
  onDateChange: (newDate: Dayjs) => void
}

という感じになりそう。しかし、一般論的には null 許容しているライブラリが多いことを頭の片隅に入れておくべき(今回のケースだと、ingred-ui は社内用ライブラリなので社内でのユースケースに特化させても問題ない)

他の props の整理に関してはインターフェイスの整理をする PR で議論、相談する。

takurinton avatar Aug 15 '23 22:08 takurinton

思慮が浅かった、dayjs 自体が null を返してくる可能性があるのか...。

takurinton avatar Aug 15 '23 23:08 takurinton

既知のバグとしてこれがある https://github.com/voyagegroup/ingred-ui/pull/1367#pullrequestreview-1579729227

takurinton avatar Aug 16 '23 03:08 takurinton

TODO カレンダーを閉じる用のバツボタンを実装していないのでする

追記

done https://github.com/voyagegroup/ingred-ui/pull/1370

takurinton avatar Aug 16 '23 05:08 takurinton

DateRangePicker、Actions が多重定義されてる。 後で修正する。 

追記

done https://github.com/voyagegroup/ingred-ui/pull/1371

takurinton avatar Aug 16 '23 08:08 takurinton

インターフェイスの整理をする。 それぞれのコンポーネントに以下の props を追加する。

  • DatePicker/DateRangePicker
    • errorText #1377
    • disable #1376
    • isOutsideRange #1375
  • Calendar/CalendarRange
    • isOutsideRange #1375
  • DateField/DateRangeField
    • errorText #1377
    • disable #1376

takurinton avatar Aug 18 '23 05:08 takurinton

年選択のスクロールについてやる。 これは

  • [x] カレンダーの無限スクロールを担っている useScroll を useScrollCalendar にリネーム https://github.com/voyagegroup/ingred-ui/pull/1384
  • [x] 年選択の無限スクロールを担う useScrollYear を追加 https://github.com/voyagegroup/ingred-ui/pull/1385
  • [ ] ~Intersection Observer API を扱う部分を抽象化した useIntersecion の定義~ → 一旦不要

という流れでやる。

takurinton avatar Aug 21 '23 06:08 takurinton

年選択のスクロールの前に一旦リリースかけてもいいかもな。プロダクト側で使う期間が欲しい。 最低限のインターフェイスさえ揃えば問題なく使えるので(現在追加してるインターフェイスはプロダクト側のコードをベースに定義してるので特段困らないはず)

takurinton avatar Aug 21 '23 06:08 takurinton

memo errorText prop の必要性とデザインを野呂さんに確認する。 https://github.com/voyagegroup/ingred-ui/pull/1377#issuecomment-1687238377

takurinton avatar Aug 22 '23 01:08 takurinton

一旦リリースかける。 残タスクは以下。

  • errorText prop の相談 → (追記)確認の結果、現行のまま行く
  • 年選択 → https://github.com/voyagegroup/ingred-ui/issues/975#issuecomment-1685744375 で対応
  • スタイルの細かい修正 → https://github.com/voyagegroup/ingred-ui/pull/1395

takurinton avatar Aug 22 '23 07:08 takurinton

ひとまず v14.5.0 リリース。 https://github.com/voyagegroup/ingred-ui/releases/tag/v14.5.0

今後の流れとしては、

  • 14.6.0 → 残タスク(errorText の相談、style の修正(デザイナーレビュー)、年選択)の実装
  • (追記) 14.7.0 → i18n 対応
  • 15.0.0 → DatePicker を完全に新しいものにする

という形でやっていく。v14.6.0 と v15.0.0 の間で小さいバグであったり、運用上の不具合の修正はしていく。

takurinton avatar Aug 22 '23 07:08 takurinton