@hectorbliss/denik-calendar 0.0.2 → 0.0.4
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/README.md +137 -47
- package/dist/index.cjs +306 -57
- package/dist/index.d.cts +146 -2
- package/dist/index.d.ts +146 -2
- package/dist/index.js +306 -59
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,6 @@ function App() {
|
|
|
24
24
|
<Calendar
|
|
25
25
|
events={events}
|
|
26
26
|
onEventMove={(eventId, newStart) => {
|
|
27
|
-
// Handle event move
|
|
28
27
|
setEvents(prev =>
|
|
29
28
|
prev.map(e => (e.id === eventId ? { ...e, start: newStart } : e))
|
|
30
29
|
);
|
|
@@ -43,84 +42,175 @@ function App() {
|
|
|
43
42
|
}
|
|
44
43
|
```
|
|
45
44
|
|
|
46
|
-
##
|
|
45
|
+
## Resource Mode (Day View)
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
Display resources (courts, rooms, employees) as columns instead of weekdays:
|
|
49
48
|
|
|
50
49
|
```tsx
|
|
51
|
-
import {
|
|
50
|
+
import { Calendar, useCalendarControls } from "@hectorbliss/denik-calendar";
|
|
51
|
+
|
|
52
|
+
const courts = [
|
|
53
|
+
{ id: "court-1", name: "Cancha 1", icon: <PadelIcon /> },
|
|
54
|
+
{ id: "court-2", name: "Cancha 2", icon: <PadelIcon /> },
|
|
55
|
+
{ id: "court-3", name: "Cancha 3", icon: <TennisIcon /> },
|
|
56
|
+
{ id: "court-4", name: "Cancha 4", icon: <TennisIcon /> },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
// Events with resourceId
|
|
60
|
+
const events = [
|
|
61
|
+
{ id: "1", start: new Date(), duration: 90, title: "Match", resourceId: "court-1" },
|
|
62
|
+
{ id: "2", start: new Date(), duration: 60, title: "Training", resourceId: "court-2" },
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
function CourtSchedule() {
|
|
66
|
+
return (
|
|
67
|
+
<Calendar
|
|
68
|
+
events={events}
|
|
69
|
+
date={selectedDay}
|
|
70
|
+
resources={courts}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Navigation Controls
|
|
52
77
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
Use the headless hook for complete control:
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { Calendar, useCalendarControls, CalendarControls } from "@hectorbliss/denik-calendar";
|
|
82
|
+
|
|
83
|
+
function App() {
|
|
84
|
+
const controls = useCalendarControls();
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<>
|
|
88
|
+
{/* Pre-built controls */}
|
|
89
|
+
<CalendarControls controls={controls} />
|
|
90
|
+
|
|
91
|
+
{/* Or build your own */}
|
|
92
|
+
<div>
|
|
93
|
+
<button onClick={controls.goToToday}>HOY</button>
|
|
94
|
+
<button onClick={controls.goToPrev}>←</button>
|
|
95
|
+
<button onClick={controls.goToNext}>→</button>
|
|
96
|
+
<span>{controls.label}</span>
|
|
97
|
+
<button onClick={controls.toggleView}>
|
|
98
|
+
{controls.view === "week" ? "DÍA" : "SEMANA"}
|
|
99
|
+
</button>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<Calendar
|
|
103
|
+
date={controls.date}
|
|
104
|
+
events={events}
|
|
105
|
+
resources={controls.view === "day" ? courts : undefined}
|
|
106
|
+
/>
|
|
107
|
+
</>
|
|
108
|
+
);
|
|
73
109
|
}
|
|
74
110
|
```
|
|
75
111
|
|
|
112
|
+
## Visual Overlaps
|
|
113
|
+
|
|
114
|
+
Events at the same time are displayed side-by-side automatically.
|
|
115
|
+
|
|
116
|
+
## Headless Hooks
|
|
117
|
+
|
|
118
|
+
### useCalendarEvents
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { useCalendarEvents } from "@hectorbliss/denik-calendar";
|
|
122
|
+
|
|
123
|
+
const {
|
|
124
|
+
canMove, // Check if event can move to new time
|
|
125
|
+
hasOverlap, // Check if time slot has conflicts
|
|
126
|
+
findConflicts, // Get all conflicting events
|
|
127
|
+
getEventsForDay, // Filter events by day
|
|
128
|
+
getEventsForWeek, // Filter events by week
|
|
129
|
+
findAvailableSlots // Get available time slots
|
|
130
|
+
} = useCalendarEvents(events);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### useCalendarControls
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { useCalendarControls } from "@hectorbliss/denik-calendar";
|
|
137
|
+
|
|
138
|
+
const {
|
|
139
|
+
date, // Current date
|
|
140
|
+
view, // "week" | "day"
|
|
141
|
+
week, // Array of 7 dates (Mon-Sun)
|
|
142
|
+
label, // Formatted date label
|
|
143
|
+
isToday, // Boolean
|
|
144
|
+
goToToday, // Navigate to today
|
|
145
|
+
goToPrev, // Navigate back (7 days or 1 day)
|
|
146
|
+
goToNext, // Navigate forward
|
|
147
|
+
toggleView, // Switch between week/day
|
|
148
|
+
setDate, // Set specific date
|
|
149
|
+
setView, // Set specific view
|
|
150
|
+
} = useCalendarControls({ locale: "es-MX" });
|
|
151
|
+
```
|
|
152
|
+
|
|
76
153
|
## Props
|
|
77
154
|
|
|
78
155
|
### Calendar
|
|
79
156
|
|
|
80
157
|
| Prop | Type | Description |
|
|
81
158
|
|------|------|-------------|
|
|
82
|
-
| `events` | `CalendarEvent[]` | Array of events
|
|
83
|
-
| `date` | `Date` | Current
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
|
|
91
|
-
|
|
159
|
+
| `events` | `CalendarEvent[]` | Array of events |
|
|
160
|
+
| `date` | `Date` | Current date (default: today) |
|
|
161
|
+
| `resources` | `Resource[]` | Resources for day view mode |
|
|
162
|
+
| `onEventMove` | `(eventId, newStart) => void` | Drag handler |
|
|
163
|
+
| `onAddBlock` | `(start) => void` | Block creation |
|
|
164
|
+
| `onRemoveBlock` | `(eventId) => void` | Block removal |
|
|
165
|
+
| `onEventClick` | `(event) => void` | Click handler |
|
|
166
|
+
| `onNewEvent` | `(start) => void` | Empty slot click |
|
|
167
|
+
| `config` | `CalendarConfig` | Configuration |
|
|
168
|
+
|
|
169
|
+
### Types
|
|
92
170
|
|
|
93
171
|
```typescript
|
|
94
172
|
interface CalendarEvent {
|
|
95
173
|
id: string;
|
|
96
174
|
start: Date;
|
|
97
|
-
duration: number;
|
|
175
|
+
duration: number; // minutes
|
|
98
176
|
title?: string;
|
|
99
177
|
type?: "BLOCK" | "EVENT";
|
|
178
|
+
resourceId?: string; // For resource mode
|
|
100
179
|
service?: { name: string };
|
|
101
180
|
}
|
|
102
|
-
```
|
|
103
181
|
|
|
104
|
-
|
|
182
|
+
interface Resource {
|
|
183
|
+
id: string;
|
|
184
|
+
name: string;
|
|
185
|
+
icon?: ReactNode;
|
|
186
|
+
}
|
|
105
187
|
|
|
106
|
-
```typescript
|
|
107
188
|
interface CalendarConfig {
|
|
108
|
-
locale?: string;
|
|
109
|
-
icons?: {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
189
|
+
locale?: string;
|
|
190
|
+
icons?: { trash?, edit?, close? };
|
|
191
|
+
renderColumnHeader?: (props: ColumnHeaderProps) => ReactNode;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
interface ColumnHeaderProps {
|
|
195
|
+
date: Date;
|
|
196
|
+
index: number;
|
|
197
|
+
isToday: boolean;
|
|
198
|
+
locale: string;
|
|
199
|
+
resource?: Resource;
|
|
114
200
|
}
|
|
115
201
|
```
|
|
116
202
|
|
|
117
203
|
## Features
|
|
118
204
|
|
|
119
|
-
- Drag & drop events
|
|
120
|
-
-
|
|
205
|
+
- Drag & drop events
|
|
206
|
+
- Visual overlap rendering
|
|
207
|
+
- Resource/day view mode
|
|
208
|
+
- Week view mode
|
|
209
|
+
- Navigation controls (hook + component)
|
|
121
210
|
- Block time slots
|
|
122
|
-
- Week navigation
|
|
123
211
|
- Auto-scroll to current hour
|
|
212
|
+
- Custom column headers
|
|
213
|
+
- Horizontal scroll for many resources
|
|
124
214
|
- Customizable icons
|
|
125
215
|
- Locale support
|
|
126
216
|
- TypeScript support
|