はじめに
react-big-calendarについて学んでいきます!
成果物
ソースコード
~/develop/my-calendar-app (main)$ tree -I node_modules/
.
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── README.md
├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── declarations.d.ts
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
└── tsconfig.json
3 directories, 20 files
package.json
{
"name": "my-calendar-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.126",
"@types/react": "^19.1.4",
"@types/react-dom": "^19.1.5",
"date-fns": "^4.1.0",
"react": "^19.1.0",
"react-big-calendar": "^1.18.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^19.1.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
src/App.tsx
import { useState } from "react";
import { Calendar, dateFnsLocalizer } from "react-big-calendar";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import withDragAndDrop from "react-big-calendar/lib/addons/dragAndDrop";
import { format, parse, startOfWeek, getDay } from "date-fns";
import { ja } from "date-fns/locale";
import "react-big-calendar/lib/css/react-big-calendar.css";
import "react-big-calendar/lib/addons/dragAndDrop/styles.css";
// DnD対応カレンダーに拡張
const DragAndDropCalendar = withDragAndDrop(Calendar);
// date-fns ローカライザー設定
const locales = {
ja: ja,
};
const localizer = dateFnsLocalizer({
format,
parse,
startOfWeek,
getDay,
locales,
locale: "ja",
});
type EventType = {
id: number;
title: string;
start: Date;
end: Date;
};
const initialEvents: EventType[] = [
{
id: 0,
title: "会議A",
start: new Date(),
end: new Date(new Date().getTime() + 60 * 60 * 1000), // +1時間
},
];
type EventDropArgs = {
event: EventType;
start: Date;
end: Date;
};
export default function App() {
const [events, setEvents] = useState<EventType[]>(initialEvents);
const onEventDrop = ({ event, start, end }: EventDropArgs) => {
const updated = events.map((e) =>
e.id === event.id ? { ...e, start, end } : e,
);
setEvents(updated);
};
return (
<DndProvider backend={HTML5Backend}>
<div style={{ height: "100vh", padding: 20 }}>
<DragAndDropCalendar
localizer={localizer}
events={events}
startAccessor="start"
endAccessor="end"
onEventDrop={onEventDrop}
resizable
onEventResize={onEventDrop}
style={{ height: "100%" }}
/>
</div>
</DndProvider>
);
}