月間カレンダービュー
:LiTarget: 用途
月間カレンダーUI。各日にイベント数・タイトル表示。クリックで詳細。
:LiSparkle: 特徴
- 月切替
- イベントドット/タイトル
- 今日強調
- ホバー詳細
:LiCode: コード(コピペ用)
'use client';
import { useState } from 'react';
export function MonthView({ events }: { events: { date: string; title: string }[] }) {
const [cur, setCur] = useState(new Date());
const year = cur.getFullYear();
const month = cur.getMonth();
const firstDay = new Date(year, month, 1).getDay();
const lastDate = new Date(year, month + 1, 0).getDate();
const cells = [...Array(firstDay).fill(null), ...Array.from({ length: lastDate }, (_, i) => i + 1)];
return (
<div>
<button onClick={() => setCur(new Date(year, month - 1))}>‹</button>
<span>{year}年{month + 1}月</span>
<button onClick={() => setCur(new Date(year, month + 1))}>›</button>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)' }}>
{['日','月','火','水','木','金','土'].map(d => <div key={d}>{d}</div>)}
{cells.map((d, i) => {
if (!d) return <div key={i} />;
const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
const dayEvents = events.filter(e => e.date === dateStr);
return (
<div key={i} style={{ minHeight: 80, border: '1px solid #333', padding: 4 }}>
<div>{d}</div>
{dayEvents.slice(0, 3).map((e, j) => <div key={j} style={{ fontSize: 11, opacity: .7 }}>{e.title}</div>)}
</div>
);
})}
</div>
</div>
);
}
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加