過去と未来の時間の目盛りTimelineScrubberExperimental
過去の実測値(実況)から未来の予測値(予報)までを、1本の目盛りで行き来します。中央の印は動かず、目盛りのほうが動きます。実況と予報の境目があり、再生もできます。
プレビュー
実況
状態とバリエーション
予報の側にいる
境目より先のコマを見ているときは、上のラベルが「予報」になり、中央の印と目盛りの色が変わります。
予報
まだ読み込んでいないコマ
pending のコマは目盛りを薄く描きます。選ぶことはできます。届いた順に濃くなるので、どこまで見られるかが分かります。
実況
目盛りだけ
時刻と再生ボタンを画面の別の場所に置くなら、showHeader={false} で上の行を外します。境目が無ければ lastObservedIndex を渡しません。
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| steps | TimelineScrubberStep[] | - | 古い順に並べたコマ(1つの時刻ぶんのデータ)。{ label, major?, pending? }。 |
| value | number | - | いま見せているコマの番号。 |
| onValueChange | (index: number) => void | - | 見ているコマが変わったとき(ドラッグ・キー操作・再生のどれでも)に呼ばれます。 |
| lastObservedIndex | number | - | 実況の最後のコマ。その先は予報として描きます。 |
| playing | boolean | - | 再生中か。渡さなければコンポーネントの内部で管理します。 |
| onPlayingChange | (playing: boolean) => void | - | 再生・停止が変わったとき。 |
| stepInterval | number | 300 | 再生で1コマ進める間隔(ms)。 |
| playable | boolean | true | 再生ボタンを出すか。 |
| stepWidth | number | 28 | 目盛りの間隔(px)。 |
| pageStep | number | 6 | PageUp / PageDown で動くコマ数。 |
| showHeader | boolean | true | 上の行(実況か予報かのラベル・時刻・再生ボタン)を出すか。 |
| labels | TimelineScrubberLabels | - | スクリーンリーダーが読み上げる名前と、画面に出す語(実況・予報・再生など)。 |
使い方
"use client";
import * as React from "react";
import { TimelineScrubber } from "@gunjo/ui";
// 09:00 から 13:00 まで5分ごと(49コマ)。30分ごとに字を出します。
const STEPS = Array.from({ length: 49 }, (_, i) => {
const minutes = 9 * 60 + i * 5;
const label = `${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}`;
return { label, major: minutes % 30 === 0 };
});
export function RainTimeline() {
// 11:00(24番目)までが実況、その先が予報です。
const [value, setValue] = React.useState(24);
return (
<TimelineScrubber
steps={STEPS}
value={value}
onValueChange={setValue}
lastObservedIndex={24}
labels={{ scrubber: "時刻", observed: "実況", forecast: "予報", play: "再生", pause: "一時停止" }}
/>
);
}設計の判断
- 中央の印は動かさず、目盛りのほうを動かします。見ている時刻が、いつも目を置いている場所にあります。両端はぼかして、まだ先があることを示します。
- 実況と予報は3つの手がかりで分けます。上のラベルの語・境目の点線・色の3つです。
- 端末の時計(現在時刻)は参照しません。自分で進めるのは、再生中のコマ送りだけです。「いま」がどのコマかは呼び出し側が渡します。
- 縦にスワイプすると、ページがスクロールします。横の動きだけを目盛りが受け取ります(touch-action: pan-y)。
使用コンポーネント
関連コンポーネント
- TimeTransport
時刻を連続で動かし、再生速度を切り替えられる。TimelineScrubber はコマ単位で動く。
- DayBand
1日の帯の上でつまみが動く。中央固定ではない。
- Slider
値を1つ選ぶだけ。実況と予報の境目も再生も無い。
いつ・なぜ使うか(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。