週間カレンダーWeekViewExperimental

週単位の時間グリッドに予定を配置し、重なった予定を横並びで表示します。

プレビュー

22
23
24
25
26
8:00
9:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00

撮影

進行中

6/24 15:00-18:00 / スタジオ 2

キャンペーン用キービジュアルと商品カットを撮影します。

担当
担当: 撮影チーム
表示範囲
平日表示

状態とバリエーション

平日表示

dayCount=5 と weekStartsOn=1 で月曜始まりの平日表示にします。

22
23
24
25
26
8:00
9:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00

撮影

進行中

6/24 15:00-18:00 / スタジオ 2

キャンペーン用キービジュアルと商品カットを撮影します。

担当
担当: 撮影チーム
表示範囲
平日表示

7日表示

週末も含める場合は dayCount=7 を使います。

22
23
24
25
26
27
28
8:00
9:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00

撮影

進行中

6/24 15:00-18:00 / スタジオ 2

キャンペーン用キービジュアルと商品カットを撮影します。

担当
担当: 撮影チーム
表示範囲
7日表示

重なり予定

同時間帯の予定は列内で横並びになります。

22
23
24
25
26
8:00
9:00
10:00
11:00
12:00

編集会議

議題確定

6/22 09:00-10:30 / 編集室 A

週次企画の優先順位と公開枠を確認します。

担当
担当: 青井
表示範囲
午前の重なり

プロパティ

表は横にスクロールできます
プロパティ初期値説明
weekOfstring | Date-表示する週に含まれる日付です。
eventsWeekEvent[]-開始、終了、ラベル、toneを持つ予定です。重なりは横並びになります。
dayCountnumber7表示する日数です。5で平日表示になります。
weekStartsOn0 | 10週の開始曜日です。
startHour / endHournumber8 / 21表示する時間帯です。
weekdayLabels / daySuffixstring[] / string-曜日ヘッダーと読み上げ用の曜日接尾辞です。
formatEventAriaLabelfunction-予定ボタンの読み上げ名を上書きします。関数propのため Client Component からのみ渡すこと(Server Component から渡すと next build が落ちる)。event+context から合成するため serializable な代替は無く、RSC からは "use client" ラッパーで包む。(#338)
onSelectEvent(event: WeekEvent) => void-予定を選択した時に呼ばれます。

使い方

import * as React from "react";
import { Badge, WeekView, type WeekEvent } from "@gunjo/ui";

const events: WeekEvent[] = [
  { id: "e1", start: "2026-06-22T09:00", end: "2026-06-22T10:30", label: "編集会議", tone: "info" },
  { id: "e2", start: "2026-06-22T10:00", end: "2026-06-22T11:00", label: "1on1", tone: "primary" },
  { id: "e3", start: "2026-06-23T13:00", end: "2026-06-23T15:00", label: "素材レビュー", tone: "warning" },
  { id: "e4", start: "2026-06-24T15:00", end: "2026-06-24T18:00", label: "撮影", tone: "success" },
  { id: "e5", start: "2026-06-26T10:00", end: "2026-06-26T11:30", label: "公開判定", tone: "destructive" },
];

const details = {
  e1: { time: "6/22 09:00-10:30", location: "編集室 A", owner: "担当: 青井", status: "議題確定", summary: "週次企画の優先順位と公開枠を確認します。" },
  e2: { time: "6/22 10:00-11:00", location: "オンライン", owner: "担当: 田中", status: "準備済み", summary: "進行中タスクとレビュー待ちの相談枠です。" },
  e3: { time: "6/23 13:00-15:00", location: "レビュー卓", owner: "担当: 佐藤", status: "確認中", summary: "公開前素材の差し替え候補と権利表記を確認します。" },
  e4: { time: "6/24 15:00-18:00", location: "スタジオ 2", owner: "担当: 撮影チーム", status: "進行中", summary: "キャンペーン用キービジュアルと商品カットを撮影します。" },
  e5: { time: "6/26 10:00-11:30", location: "会議室 C", owner: "担当: 公開判定会", status: "要承認", summary: "公開可否、影響範囲、未解決タスクを最終確認します。" },
};

export function WeeklySchedule() {
  const [selectedEventId, setSelectedEventId] = React.useState("e4");
  const selectedEvent = events.find((event) => event.id === selectedEventId)!;
  const detail = details[selectedEventId as keyof typeof details];

  return (
    <div className="flex w-full max-w-5xl flex-col gap-3 rounded-lg border bg-card p-4">
      <WeekView weekOf="2026-06-24" today="2026-06-24" events={events} weekStartsOn={1} dayCount={5} startHour={8} endHour={19} label="週表示カレンダー" onSelectEvent={(event) => setSelectedEventId(event.id)} />
      <section className="grid min-w-0 gap-3 rounded-md border bg-background p-3" aria-live="polite" aria-label="選択中予定の詳細">
        <div className="min-w-0 space-y-1.5">
          <div className="flex flex-wrap items-center gap-2">
            <h3 className="text-sm font-semibold text-foreground">{selectedEvent.label}</h3>
            <Badge variant="secondary">{detail.status}</Badge>
          </div>
          <p className="text-xs text-muted-foreground">{detail.time} / {detail.location}</p>
          <p className="text-sm text-foreground">{detail.summary}</p>
        </div>
        <dl className="grid min-w-0 gap-2 rounded-md bg-muted/40 p-3 text-xs">
          <div><dt className="text-muted-foreground">担当</dt><dd className="font-medium text-foreground">{detail.owner}</dd></div>
          <div><dt className="text-muted-foreground">表示範囲</dt><dd className="font-medium text-foreground">平日表示</dd></div>
        </dl>
      </section>
    </div>
  );
}

使用コンポーネント