活動タイムラインカードActivityTimelineCardExperimental

活動量、睡眠、業務負荷などの時間帯別データを、概要値・タイムライン・内訳バーでまとめるカードです。

プレビュー

データ

対象: 12時

状態とバリエーション

標準表示

概要値、タイムライン、内訳バーを一枚のカードで表示します。

活動量タイムライン

時間帯別の活動量

+18%
+23%
昨日比
760 kcal
消費
253 kcal
日平均
6時8時10時12時14時16時

選択中の時間帯

selectedSlot と showSlotValues で、確認中の時間帯と値を明示します。

選択中の時間帯

12時の活動量

+18%
+23%
昨日比
760 kcal
消費
253 kcal
日平均
4284581569246
6時8時10時12時14時16時

コンパクト表示

狭いカードやサイドパネルでは variant="compact" で密度を上げます。

コンパクト表示

+23%
昨日比
760 kcal
消費
253 kcal
日平均
6時8時10時12時14時16時

プロパティ

表は横にスクロールできます
プロパティ初期値説明
metrics{ label: ReactNode; value: ReactNode; description?: ReactNode; tooltip?: ReactNode }[]-タイムライン上部に表示する概要メトリクスです。tooltip で計算根拠を補足できます。
slots{ label: ReactNode; value: number; color?: ChartColor; segments?: ActivityTimelineSegment[]; description?: ReactNode }[]-時間帯ごとの値です。任意の segments を渡すと、同じ内訳を縦棒の中にも積み上げ表示します。
segments{ label: ReactNode; value: number; color?: ChartColor; description?: ReactNode }[]-下部の積み上げバーと統計行に表示する内訳値です。
variant"default" | "compact""default"カード密度を切り替える生成済みデザインバリアントです。
selectedSlotnumber-確認中の時間帯スロットを強調します。
onSlotSelect(slot: ActivityTimelineSlot, index: number) => void-タイムラインの棒がクリックされたときに呼ばれます。
showSlotValuesbooleanfalseタイムラインの棒の中にフォーマット済みの値を表示します。
maxnumber-タイムラインの棒の高さを正規化するための最大値です。
formatValue(value: number) => ReactNode-タイムライン、内訳、ツールチップに表示する値のフォーマット関数です。 関数propのため Client Component からのみ渡すこと(Server Component から渡すと next build が落ちる)。RSC 安全な整形には valueFormat を使う。
valueFormat"number" | "compact" | "integer" | Intl.NumberFormatOptions-シリアライズ可能な数値フォーマット=formatValue の RSC 安全な代替。formatValue 指定時は無視。en-US ロケール固定。(#338)

使い方

import { ActivityTimelineCard } from "@gunjo/ui";

const metrics = [
    { label: "昨日比", value: "+23%" },
    { label: "消費", value: "760 kcal" },
    { label: "日平均", value: "253 kcal" },
];

const segments = [
    { label: "ウォーク", value: 127 },
    { label: "ラン", value: 384 },
    { label: "ワークアウト", value: 249 },
];

const slots = [
    { label: "6時", value: 42 },
    { label: "8時", value: 84 },
    { label: "10時", value: 58 },
    { label: "12時", value: 156 },
    { label: "14時", value: 92 },
    { label: "16時", value: 46 },
];

export function ActivityTimelineCardUsage() {
    return (
        <div className="grid gap-8">
            <ActivityTimelineCard
                metrics={metrics}
                slots={slots}
                segments={segments}
            />
            <ActivityTimelineCard
                metrics={metrics}
                slots={slots}
                segments={segments}
                selectedSlot={3}
            />
            <ActivityTimelineCard
                metrics={metrics}
                slots={slots}
                segments={segments}
                showSlotValues
            />
            <ActivityTimelineCard
                metrics={metrics}
                slots={slots}
                segments={segments}
                variant="compact"
            />
        </div>
    );
}

設計の判断

  • 1枚に3つの領域を重ねた。資料はカードの責務を「1つのエンティティを伝えて次の行動へ導く」と定めています。この部品は上から metrics(数値3つ)・時間帯の棒・segments の凡例を1枚に載せていますが、これは3件のエンティティではなく、同じ1つの活動を粗さの違う3段で見せたものです。だから3枚に割らず、カードの中にカードを入れることもしていません。
  • 押せるのは中の印だけで、外枠は押せない。資料は「カード全体を押せるようにするなら、中にボタンを入れない」を挙げています。GUNJO はこの部品でカードの外枠に何も付けず、時間帯の棒と凡例の行だけを本物の button にしました。1枚から選べる対象が複数あるので、外枠まで押せるようにすると入れ子になります。
  • 棒の高さの基準を呼ぶ側に開けた。max を渡さなければ、いちばん高い棒はそのデータの最大値です。カードを2枚並べて比べるときは、同じ max を渡して基準をそろえます。値の書式は formatValue(関数)と valueFormat(文字列で渡せる形)の2本立てで、サーバーコンポーネントから渡せるのは後者だけです(#338)。
    一般のカードの設計は UIXHERO の「カード」にあります。

いつ・なぜ使うか(UIXHERO)

「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。