react-calendar-agenda 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +392 -0
- package/dist/Calendar.d.ts +4 -0
- package/dist/Calendar.d.ts.map +1 -0
- package/dist/CalendarHeader.d.ts +2 -0
- package/dist/CalendarHeader.d.ts.map +1 -0
- package/dist/CalendarProvider.d.ts +35 -0
- package/dist/CalendarProvider.d.ts.map +1 -0
- package/dist/DayView.d.ts +2 -0
- package/dist/DayView.d.ts.map +1 -0
- package/dist/MonthView.d.ts +2 -0
- package/dist/MonthView.d.ts.map +1 -0
- package/dist/TimeSelectionOverlay.d.ts +14 -0
- package/dist/TimeSelectionOverlay.d.ts.map +1 -0
- package/dist/WeekView.d.ts +2 -0
- package/dist/WeekView.d.ts.map +1 -0
- package/dist/__tests__/components/EventHandlersTestComponent.d.ts +3 -0
- package/dist/__tests__/components/EventHandlersTestComponent.d.ts.map +1 -0
- package/dist/components/CurrentTimeLine.d.ts +9 -0
- package/dist/components/CurrentTimeLine.d.ts.map +1 -0
- package/dist/components/DayHeader.d.ts +7 -0
- package/dist/components/DayHeader.d.ts.map +1 -0
- package/dist/components/EventCard.d.ts +10 -0
- package/dist/components/EventCard.d.ts.map +1 -0
- package/dist/components/EventView.d.ts +8 -0
- package/dist/components/EventView.d.ts.map +1 -0
- package/dist/components/HourCell.d.ts +18 -0
- package/dist/components/HourCell.d.ts.map +1 -0
- package/dist/components/HourLabel.d.ts +8 -0
- package/dist/components/HourLabel.d.ts.map +1 -0
- package/dist/components/WeekHeader.d.ts +6 -0
- package/dist/components/WeekHeader.d.ts.map +1 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/constants.d.ts +27 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/contexts/CalendarRecordContext.d.ts +14 -0
- package/dist/contexts/CalendarRecordContext.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useCalendarNavigation.d.ts +13 -0
- package/dist/hooks/useCalendarNavigation.d.ts.map +1 -0
- package/dist/hooks/useCalendarUtils.d.ts +32 -0
- package/dist/hooks/useCalendarUtils.d.ts.map +1 -0
- package/dist/hooks/useEventHandlers.d.ts +14 -0
- package/dist/hooks/useEventHandlers.d.ts.map +1 -0
- package/dist/hooks/useScrollToCurrentTime.d.ts +13 -0
- package/dist/hooks/useScrollToCurrentTime.d.ts.map +1 -0
- package/dist/hooks/useTimeSelection.d.ts +31 -0
- package/dist/hooks/useTimeSelection.d.ts.map +1 -0
- package/dist/index.cjs.js +11 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +2878 -0
- package/dist/index.es.js.map +1 -0
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/stories/InteractiveCalendarWrapper.d.ts +8 -0
- package/dist/stories/InteractiveCalendarWrapper.d.ts.map +1 -0
- package/dist/stories/ThemeWrapper.d.ts +8 -0
- package/dist/stories/ThemeWrapper.d.ts.map +1 -0
- package/dist/stories/components/AddEventButton.d.ts +9 -0
- package/dist/stories/components/AddEventButton.d.ts.map +1 -0
- package/dist/stories/components/CalendarEventDialog.d.ts +2 -0
- package/dist/stories/components/CalendarEventDialog.d.ts.map +1 -0
- package/dist/stories/components/EventDialog.d.ts +12 -0
- package/dist/stories/components/EventDialog.d.ts.map +1 -0
- package/dist/stories/components/index.d.ts +4 -0
- package/dist/stories/components/index.d.ts.map +1 -0
- package/dist/stories/hooks/index.d.ts +2 -0
- package/dist/stories/hooks/index.d.ts.map +1 -0
- package/dist/stories/hooks/useEventManagement.d.ts +12 -0
- package/dist/stories/hooks/useEventManagement.d.ts.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/calculateAvailableDurations.d.ts +26 -0
- package/dist/utils/calculateAvailableDurations.d.ts.map +1 -0
- package/dist/utils/conflictUtils.d.ts +10 -0
- package/dist/utils/conflictUtils.d.ts.map +1 -0
- package/dist/utils/dateUtils.d.ts +16 -0
- package/dist/utils/dateUtils.d.ts.map +1 -0
- package/dist/utils/dateValidation.d.ts +42 -0
- package/dist/utils/dateValidation.d.ts.map +1 -0
- package/dist/utils/eventUtils.d.ts +6 -0
- package/dist/utils/eventUtils.d.ts.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/layoutUtils.d.ts +35 -0
- package/dist/utils/layoutUtils.d.ts.map +1 -0
- package/package.json +102 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Your Name
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# React Material Calendar
|
|
2
|
+
|
|
3
|
+
A modern, customizable React calendar component library built with Material-UI and TypeScript.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- 🎨 **Material-UI Integration** - Beautiful, consistent design with Material-UI components
|
|
13
|
+
- 📱 **Responsive** - Works perfectly on desktop, tablet, and mobile devices
|
|
14
|
+
- 🎯 **Multiple Views** - Month, Week, and Day view support
|
|
15
|
+
- ⚡ **TypeScript** - Full TypeScript support with comprehensive type definitions
|
|
16
|
+
- 🎛️ **Customizable** - Highly customizable themes and styling
|
|
17
|
+
- 📅 **Event Management** - Built-in event creation, editing, and management
|
|
18
|
+
- 🕐 **Time Selection** - Interactive time selection with conflict detection
|
|
19
|
+
- 🧪 **Well Tested** - Comprehensive test suite with Jest and Cypress
|
|
20
|
+
- 📚 **Storybook** - Interactive documentation and component playground
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install react-calendar-agenda
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Peer Dependencies
|
|
29
|
+
|
|
30
|
+
This library requires the following peer dependencies:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import React, { useState } from 'react';
|
|
40
|
+
import { Calendar } from './Calendar';
|
|
41
|
+
import { CalendarEvent } from './types';
|
|
42
|
+
import { EventDialog } from './EventDialog'; // Required for interactions
|
|
43
|
+
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
|
44
|
+
|
|
45
|
+
const theme = createTheme();
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
const [events, setEvents] = useState<CalendarEvent[]>([
|
|
49
|
+
{
|
|
50
|
+
id: '1',
|
|
51
|
+
title: 'Meeting with Team',
|
|
52
|
+
description: 'Weekly team standup',
|
|
53
|
+
startTime: '10:00',
|
|
54
|
+
endTime: '11:00',
|
|
55
|
+
date: '2024-01-15',
|
|
56
|
+
color: '#1976d2'
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: '2',
|
|
60
|
+
title: 'Project Review',
|
|
61
|
+
description: 'Quarterly project review',
|
|
62
|
+
startTime: '14:30',
|
|
63
|
+
endTime: '15:30',
|
|
64
|
+
date: '2024-01-16',
|
|
65
|
+
color: '#4caf50'
|
|
66
|
+
}
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
const handleEventAdd = async (event: CalendarEvent): Promise<boolean> => {
|
|
70
|
+
setEvents(prev => [...prev, event]);
|
|
71
|
+
console.log('New event created:', event);
|
|
72
|
+
return true;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const handleEventEdit = async (event: CalendarEvent, previousEvent?: CalendarEvent): Promise<boolean> => {
|
|
76
|
+
setEvents(prev => prev.map(e => e.id === event.id ? event : e));
|
|
77
|
+
console.log('Event updated:', { previous: previousEvent, current: event });
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const handleEventDelete = (eventId: string) => {
|
|
82
|
+
setEvents(prev => prev.filter(e => e.id !== eventId));
|
|
83
|
+
console.log('Event deleted:', eventId);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<ThemeProvider theme={theme}>
|
|
88
|
+
<Calendar
|
|
89
|
+
events={events}
|
|
90
|
+
onEventAdd={handleEventAdd}
|
|
91
|
+
onEventEdit={handleEventEdit}
|
|
92
|
+
onEventDelete={handleEventDelete}
|
|
93
|
+
dialog={<EventDialog />} // REQUIRED for interactions
|
|
94
|
+
/>
|
|
95
|
+
</ThemeProvider>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default App;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
> 📖 **Para uso detalhado, consulte o [Guia Completo de Uso](./HOW_TO_USE_COMPONENT.md)**
|
|
103
|
+
|
|
104
|
+
## API Reference
|
|
105
|
+
|
|
106
|
+
### Calendar
|
|
107
|
+
|
|
108
|
+
The main calendar component that renders the calendar interface with integrated event management.
|
|
109
|
+
|
|
110
|
+
#### Props
|
|
111
|
+
|
|
112
|
+
| Prop | Type | Required | Description |
|
|
113
|
+
|------|------|----------|-------------|
|
|
114
|
+
| `events` | `CalendarEvent[]` | No | Array of calendar events (default: `[]`) |
|
|
115
|
+
| `isLoading` | `boolean` | No | Loading state indicator (default: `false`) |
|
|
116
|
+
| `onEventAdd` | `(event: CalendarEvent) => Promise<boolean>` | No | Callback when adding a new event |
|
|
117
|
+
| `onEventEdit` | `(event: CalendarEvent, previousEvent?: CalendarEvent) => Promise<boolean>` | No | Callback when editing an event |
|
|
118
|
+
| `onEventDelete` | `(eventId: string) => void` | No | Callback when deleting an event |
|
|
119
|
+
| `onDateRangeChange` | `(range: DateRange) => void` | No | Callback when date range changes |
|
|
120
|
+
| `headerActions` | `ReactNode` | No | Custom actions in the calendar header |
|
|
121
|
+
| `dialog` | `ReactNode` | **Yes** (for interactions) | **REQUIRED** dialog component for event management |
|
|
122
|
+
|
|
123
|
+
> ⚠️ **Critical**: The `dialog` prop is **MANDATORY** when using interactive features. Without it, users cannot create, edit, or delete events through the UI.
|
|
124
|
+
|
|
125
|
+
### CalendarEvent
|
|
126
|
+
|
|
127
|
+
Event data structure:
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
interface CalendarEvent<TCustomData = Record<string, unknown>> {
|
|
131
|
+
id: string; // Unique event identifier
|
|
132
|
+
title: string; // Event title
|
|
133
|
+
description: string; // Event description
|
|
134
|
+
startTime: string; // Start time (HH:MM format)
|
|
135
|
+
endTime: string; // End time (HH:MM format)
|
|
136
|
+
date: string; // Event date (YYYY-MM-DD format)
|
|
137
|
+
color?: string; // Event color (hex format)
|
|
138
|
+
customData?: TCustomData; // Custom data for extensibility
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### DateRange
|
|
143
|
+
|
|
144
|
+
Date range structure:
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
interface DateRange {
|
|
148
|
+
startDate: string; // Start date (YYYY-MM-DD format)
|
|
149
|
+
endDate: string; // End date (YYYY-MM-DD format)
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Views
|
|
154
|
+
|
|
155
|
+
The calendar supports three main views that can be switched dynamically:
|
|
156
|
+
|
|
157
|
+
### Month View
|
|
158
|
+
- Grid layout showing the entire month
|
|
159
|
+
- Event indicators on calendar cells
|
|
160
|
+
- Click to navigate to day/week view
|
|
161
|
+
- Compact event display
|
|
162
|
+
|
|
163
|
+
### Week View
|
|
164
|
+
- Detailed week layout with hourly slots
|
|
165
|
+
- Event cards positioned by time
|
|
166
|
+
- Scrollable timeline
|
|
167
|
+
- Time selection for creating events
|
|
168
|
+
|
|
169
|
+
### Day View
|
|
170
|
+
- Single day detailed view
|
|
171
|
+
- Hourly time slots
|
|
172
|
+
- Detailed event information
|
|
173
|
+
- Precise time selection and event management
|
|
174
|
+
|
|
175
|
+
## Customization
|
|
176
|
+
|
|
177
|
+
### Theme Customization
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { createTheme } from '@mui/material/styles';
|
|
181
|
+
|
|
182
|
+
const customTheme = createTheme({
|
|
183
|
+
palette: {
|
|
184
|
+
primary: {
|
|
185
|
+
main: '#1976d2',
|
|
186
|
+
},
|
|
187
|
+
secondary: {
|
|
188
|
+
main: '#dc004e',
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
components: {
|
|
192
|
+
MuiCalendar: {
|
|
193
|
+
styleOverrides: {
|
|
194
|
+
root: {
|
|
195
|
+
// Custom calendar styles
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Event Colors
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
const events = [
|
|
207
|
+
{
|
|
208
|
+
id: '1',
|
|
209
|
+
title: 'Important Meeting',
|
|
210
|
+
start: new Date(),
|
|
211
|
+
end: new Date(),
|
|
212
|
+
color: '#f44336', // Red for important events
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: '2',
|
|
216
|
+
title: 'Team Standup',
|
|
217
|
+
start: new Date(),
|
|
218
|
+
end: new Date(),
|
|
219
|
+
color: '#4caf50', // Green for regular meetings
|
|
220
|
+
}
|
|
221
|
+
];
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Interactive Features
|
|
225
|
+
|
|
226
|
+
### Creating Events
|
|
227
|
+
- **Click on empty cell**: Opens dialog with time pre-filled
|
|
228
|
+
- **Drag to select time**: Creates event with selected time range
|
|
229
|
+
- **Automatic validation**: Ensures valid time ranges and required fields
|
|
230
|
+
|
|
231
|
+
### Editing Events
|
|
232
|
+
- **Click on existing event**: Opens dialog with event data pre-filled
|
|
233
|
+
- **Real-time updates**: Changes are reflected immediately
|
|
234
|
+
- **Conflict detection**: Warns about overlapping events
|
|
235
|
+
|
|
236
|
+
### Event Management
|
|
237
|
+
- **Color coding**: 8 preset colors for easy categorization
|
|
238
|
+
- **Time selection**: 30-minute intervals for precise scheduling
|
|
239
|
+
- **Form validation**: Built-in validation for all fields
|
|
240
|
+
- **Loading states**: Visual feedback during async operations
|
|
241
|
+
|
|
242
|
+
## Advanced Usage
|
|
243
|
+
|
|
244
|
+
### Custom Header Actions
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { Button } from '@mui/material';
|
|
248
|
+
|
|
249
|
+
const CustomCalendar = () => {
|
|
250
|
+
const headerActions = (
|
|
251
|
+
<Button variant="contained" onClick={handleAddEvent}>
|
|
252
|
+
Quick Add Event
|
|
253
|
+
</Button>
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
return (
|
|
257
|
+
<Calendar
|
|
258
|
+
events={events}
|
|
259
|
+
headerActions={headerActions}
|
|
260
|
+
dialog={<EventDialog />} // REQUIRED for interactions
|
|
261
|
+
/>
|
|
262
|
+
);
|
|
263
|
+
};
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Custom Dialog
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
import { Dialog, DialogContent } from '@mui/material';
|
|
270
|
+
|
|
271
|
+
const CustomEventDialog = ({ open, onClose, event, isEditing }) => {
|
|
272
|
+
return (
|
|
273
|
+
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
|
|
274
|
+
<DialogContent>
|
|
275
|
+
{/* Your custom event form */}
|
|
276
|
+
</DialogContent>
|
|
277
|
+
</Dialog>
|
|
278
|
+
);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const MyCalendar = () => {
|
|
282
|
+
return (
|
|
283
|
+
<Calendar
|
|
284
|
+
events={events}
|
|
285
|
+
dialog={<CustomEventDialog />} // REQUIRED for interactions
|
|
286
|
+
/>
|
|
287
|
+
);
|
|
288
|
+
};
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### API Integration
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
const ApiCalendar = () => {
|
|
295
|
+
const handleEventAdd = async (event: CalendarEvent): Promise<boolean> => {
|
|
296
|
+
try {
|
|
297
|
+
const response = await fetch('/api/events', {
|
|
298
|
+
method: 'POST',
|
|
299
|
+
headers: { 'Content-Type': 'application/json' },
|
|
300
|
+
body: JSON.stringify(event)
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
if (response.ok) {
|
|
304
|
+
const newEvent = await response.json();
|
|
305
|
+
setEvents(prev => [...prev, newEvent]);
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return false;
|
|
310
|
+
} catch (error) {
|
|
311
|
+
console.error('Error creating event:', error);
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<Calendar
|
|
318
|
+
events={events}
|
|
319
|
+
onEventAdd={handleEventAdd}
|
|
320
|
+
dialog={<EventDialog />} // REQUIRED for interactions
|
|
321
|
+
/>
|
|
322
|
+
);
|
|
323
|
+
};
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Development
|
|
327
|
+
|
|
328
|
+
### Prerequisites
|
|
329
|
+
|
|
330
|
+
- Node.js 16+
|
|
331
|
+
- npm 8+
|
|
332
|
+
|
|
333
|
+
### Setup
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
# Clone the repository
|
|
337
|
+
git clone https://github.com/calendar-dev/react-material-calendar.git
|
|
338
|
+
cd react-material-calendar
|
|
339
|
+
|
|
340
|
+
# Install dependencies
|
|
341
|
+
npm install
|
|
342
|
+
|
|
343
|
+
# Start development server
|
|
344
|
+
npm run dev
|
|
345
|
+
|
|
346
|
+
# Run tests
|
|
347
|
+
npm test
|
|
348
|
+
|
|
349
|
+
# Run Storybook
|
|
350
|
+
npm run storybook
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Testing
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Run Jest tests
|
|
357
|
+
npm test
|
|
358
|
+
|
|
359
|
+
# Run Cypress component tests
|
|
360
|
+
npm run test:cypress
|
|
361
|
+
|
|
362
|
+
# Run all tests with coverage
|
|
363
|
+
npm run test:coverage
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Contributing
|
|
367
|
+
|
|
368
|
+
1. Fork the repository
|
|
369
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
370
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
371
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
372
|
+
5. Open a Pull Request
|
|
373
|
+
|
|
374
|
+
## License
|
|
375
|
+
|
|
376
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
377
|
+
|
|
378
|
+
## Support
|
|
379
|
+
|
|
380
|
+
- 📖 [Documentation](https://github.com/calendar-dev/react-material-calendar#readme)
|
|
381
|
+
- 🐛 [Report Bug](https://github.com/calendar-dev/react-material-calendar/issues)
|
|
382
|
+
- 💡 [Request Feature](https://github.com/calendar-dev/react-material-calendar/issues)
|
|
383
|
+
|
|
384
|
+
## Changelog
|
|
385
|
+
|
|
386
|
+
### v1.0.0
|
|
387
|
+
- Initial release
|
|
388
|
+
- Month, Week, and Day views
|
|
389
|
+
- Event management
|
|
390
|
+
- Material-UI integration
|
|
391
|
+
- TypeScript support
|
|
392
|
+
- Comprehensive testing suite
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CalendarProps } from './types';
|
|
2
|
+
|
|
3
|
+
export declare const Calendar: <TCustomData = Record<string, unknown>, _T = never>({ events, isLoading, onEventAdd, onEventEdit, onEventDelete, onDateRangeChange, headerActions, dialog, }: CalendarProps<TCustomData>) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
//# sourceMappingURL=Calendar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../src/Calendar.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAoDvC,eAAO,MAAM,QAAQ,GAAI,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,KAAK,EAAE,0GASzE,aAAa,CAAC,WAAW,CAAC,4CAW5B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarHeader.d.ts","sourceRoot":"","sources":["../src/CalendarHeader.tsx"],"names":[],"mappings":"AAOA,eAAO,MAAM,cAAc,+CAgD1B,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { CalendarEvent, CalendarEventFormData, CalendarView, DateRange } from './types';
|
|
3
|
+
|
|
4
|
+
interface CalendarContextType<TCustomData = Record<string, unknown>> {
|
|
5
|
+
currentDate: Date;
|
|
6
|
+
setCurrentDate: (date: Date | ((prev: Date) => Date)) => void;
|
|
7
|
+
view: CalendarView;
|
|
8
|
+
setView: (view: CalendarView) => void;
|
|
9
|
+
isEventDialogOpen: boolean;
|
|
10
|
+
setIsEventDialogOpen: (open: boolean) => void;
|
|
11
|
+
isEditing: boolean;
|
|
12
|
+
setIsEditing: (editing: boolean) => void;
|
|
13
|
+
selectedEvent: CalendarEvent<TCustomData> | null;
|
|
14
|
+
setSelectedEvent: (event: CalendarEvent<TCustomData> | null) => void;
|
|
15
|
+
eventForm: CalendarEventFormData<TCustomData>;
|
|
16
|
+
setEventForm: (form: CalendarEventFormData<TCustomData> | ((prev: CalendarEventFormData<TCustomData>) => CalendarEventFormData<TCustomData>)) => void;
|
|
17
|
+
events: Array<CalendarEvent<TCustomData>>;
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
onEventAdd?: (event: CalendarEvent<TCustomData>) => Promise<boolean>;
|
|
20
|
+
onEventEdit?: (event: CalendarEvent<TCustomData>, previousEvent?: CalendarEvent<TCustomData>) => Promise<boolean>;
|
|
21
|
+
onEventDelete?: (eventId: string) => void;
|
|
22
|
+
}
|
|
23
|
+
interface CalendarProviderProps<TCustomData = Record<string, unknown>> {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
events?: Array<CalendarEvent<TCustomData>>;
|
|
26
|
+
isLoading?: boolean;
|
|
27
|
+
onEventAdd?: (event: CalendarEvent<TCustomData>) => Promise<boolean>;
|
|
28
|
+
onEventEdit?: (event: CalendarEvent<TCustomData>, previousEvent?: CalendarEvent<TCustomData>) => Promise<boolean>;
|
|
29
|
+
onEventDelete?: (eventId: string) => void;
|
|
30
|
+
onDateRangeChange?: (range: DateRange) => void;
|
|
31
|
+
}
|
|
32
|
+
export declare const CalendarProvider: <TCustomData = Record<string, unknown>>({ children, events, isLoading, onEventAdd, onEventEdit, onEventDelete, onDateRangeChange, }: CalendarProviderProps<TCustomData>) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare const useCalendar: () => CalendarContextType<any>;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=CalendarProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarProvider.d.ts","sourceRoot":"","sources":["../src/CalendarProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAAoD,MAAM,OAAO,CAAA;AAElG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAGvF,UAAU,mBAAmB,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjE,WAAW,EAAE,IAAI,CAAA;IACjB,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,KAAK,IAAI,CAAA;IAC7D,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IAGrC,iBAAiB,EAAE,OAAO,CAAA;IAC1B,oBAAoB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7C,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACxC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,IAAI,CAAA;IAChD,gBAAgB,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IACpE,SAAS,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAA;IAC7C,YAAY,EAAE,CACZ,IAAI,EACA,qBAAqB,CAAC,WAAW,CAAC,GAClC,CAAC,CAAC,IAAI,EAAE,qBAAqB,CAAC,WAAW,CAAC,KAAK,qBAAqB,CAAC,WAAW,CAAC,CAAC,KACnF,IAAI,CAAA;IAGT,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAA;IACzC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACpE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACjH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC1C;AAID,UAAU,qBAAqB,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACnE,QAAQ,EAAE,SAAS,CAAA;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAA;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACpE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACjH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;CAC/C;AAED,eAAO,MAAM,gBAAgB,GAAI,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAG,6FAQtE,qBAAqB,CAAC,WAAW,CAAC,4CA+DpC,CAAA;AAED,eAAO,MAAM,WAAW,gCAMvB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DayView.d.ts","sourceRoot":"","sources":["../src/DayView.tsx"],"names":[],"mappings":"AAQA,eAAO,MAAM,OAAO,+CA8GnB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonthView.d.ts","sourceRoot":"","sources":["../src/MonthView.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,SAAS,+CA4HrB,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface TimeSelectionOverlayProps {
|
|
2
|
+
selection: {
|
|
3
|
+
startHour: number;
|
|
4
|
+
startMinute: number;
|
|
5
|
+
endHour: number;
|
|
6
|
+
endMinute: number;
|
|
7
|
+
isSelecting: boolean;
|
|
8
|
+
} | null;
|
|
9
|
+
hourHeight?: number;
|
|
10
|
+
currentHour?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare const TimeSelectionOverlay: ({ selection, hourHeight, currentHour }: TimeSelectionOverlayProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=TimeSelectionOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeSelectionOverlay.d.ts","sourceRoot":"","sources":["../src/TimeSelectionOverlay.tsx"],"names":[],"mappings":"AAEA,UAAU,yBAAyB;IACjC,SAAS,EAAE;QACT,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;QACnB,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,OAAO,CAAA;KACrB,GAAG,IAAI,CAAA;IACR,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,eAAO,MAAM,oBAAoB,GAAI,wCAA6C,yBAAyB,mDAmH1G,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeekView.d.ts","sourceRoot":"","sources":["../src/WeekView.tsx"],"names":[],"mappings":"AAQA,eAAO,MAAM,QAAQ,+CA4GpB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventHandlersTestComponent.d.ts","sourceRoot":"","sources":["../../../src/__tests__/components/EventHandlersTestComponent.tsx"],"names":[],"mappings":"AAIA,QAAA,MAAM,0BAA0B,+CAmH/B,CAAC;AAEF,eAAe,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface CurrentTimeLineProps {
|
|
2
|
+
hourHeight: number;
|
|
3
|
+
limitToDay?: boolean;
|
|
4
|
+
currentDayIndex?: number;
|
|
5
|
+
totalDays?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const CurrentTimeLine: ({ hourHeight, limitToDay, currentDayIndex, totalDays, }: CurrentTimeLineProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=CurrentTimeLine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CurrentTimeLine.d.ts","sourceRoot":"","sources":["../../src/components/CurrentTimeLine.tsx"],"names":[],"mappings":"AAIA,UAAU,oBAAoB;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,eAAe,GAAI,yDAK7B,oBAAoB,4CAgFtB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DayHeader.d.ts","sourceRoot":"","sources":["../../src/components/DayHeader.tsx"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACtB,GAAG,EAAE,IAAI,CAAA;IACT,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,SAAS,GAAI,mBAAuB,cAAc,4CA8B9D,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CalendarEvent } from '../types';
|
|
2
|
+
|
|
3
|
+
interface EventCardProps {
|
|
4
|
+
event: CalendarEvent;
|
|
5
|
+
hourHeight: number;
|
|
6
|
+
onClick: (event: CalendarEvent) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const EventCard: ({ event, hourHeight, onClick }: EventCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=EventCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventCard.d.ts","sourceRoot":"","sources":["../../src/components/EventCard.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,UAAU,cAAc;IACtB,KAAK,EAAE,aAAa,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CACxC;AAkBD,eAAO,MAAM,SAAS,GAAI,gCAAgC,cAAc,4CA0FvE,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
interface EventViewProps {
|
|
4
|
+
customFields?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const EventView: ({ customFields }: EventViewProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=EventView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventView.d.ts","sourceRoot":"","sources":["../../src/components/EventView.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGjC,UAAU,cAAc;IACtB,YAAY,CAAC,EAAE,SAAS,CAAA;CACzB;AAED,eAAO,MAAM,SAAS,GAAI,kBAAkB,cAAc,mDAuDzD,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TimeSelection } from '../hooks/useTimeSelection';
|
|
2
|
+
import { CalendarEvent } from '../types';
|
|
3
|
+
|
|
4
|
+
interface HourCellProps {
|
|
5
|
+
hour: number;
|
|
6
|
+
events: Array<CalendarEvent>;
|
|
7
|
+
hourHeight: number;
|
|
8
|
+
selection: TimeSelection | null;
|
|
9
|
+
date: string;
|
|
10
|
+
onMouseDown: (e: React.MouseEvent) => void;
|
|
11
|
+
onClick?: () => void;
|
|
12
|
+
onEventClick: (event: CalendarEvent) => void;
|
|
13
|
+
gridSize?: number;
|
|
14
|
+
showRightBorder?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const HourCell: ({ hour, events, hourHeight, selection, date, onMouseDown, onClick, onEventClick, gridSize, showRightBorder, }: HourCellProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=HourCell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HourCell.d.ts","sourceRoot":"","sources":["../../src/components/HourCell.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAA;IAC1C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,eAAO,MAAM,QAAQ,GAAI,+GAWtB,aAAa,4CAoDf,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface HourLabelProps {
|
|
2
|
+
hour: number;
|
|
3
|
+
hourHeight?: number;
|
|
4
|
+
gridSize?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const HourLabel: ({ hour, hourHeight, gridSize }: HourLabelProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=HourLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HourLabel.d.ts","sourceRoot":"","sources":["../../src/components/HourLabel.tsx"],"names":[],"mappings":"AAEA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,SAAS,GAAI,gCAAyC,cAAc,4CAmBhF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeekHeader.d.ts","sourceRoot":"","sources":["../../src/components/WeekHeader.tsx"],"names":[],"mappings":"AAGA,UAAU,eAAe;IACvB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;CAClB;AAED,eAAO,MAAM,UAAU,GAAI,UAAU,eAAe,4CAsDnD,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { CurrentTimeLine } from './CurrentTimeLine';
|
|
2
|
+
export { DayHeader } from './DayHeader';
|
|
3
|
+
export { EventCard } from './EventCard';
|
|
4
|
+
export { EventView } from './EventView';
|
|
5
|
+
export { HourCell } from './HourCell';
|
|
6
|
+
export { HourLabel } from './HourLabel';
|
|
7
|
+
export { WeekHeader } from './WeekHeader';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA"}
|