react-smart-scheduler 0.1.1 → 0.1.3
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 +160 -25
- package/dist/index.d.ts +24 -1
- package/dist/index.es.js +1276 -1227
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/scheduler.css +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -13,13 +13,26 @@ Day · Week · Month views · Drag & drop · Resize · TypeScript · Zero UI fra
|
|
|
13
13
|
[](https://www.typescriptlang.org/)
|
|
14
14
|
|
|
15
15
|
[**Live Demo →**](https://scheduler.hazhtech.com/) |
|
|
16
|
-
[**GitHub →**](https://github.com/
|
|
16
|
+
[**GitHub →**](https://github.com/satthish/react-smart-scheduler) |
|
|
17
17
|
[**npm →**](https://www.npmjs.com/package/react-smart-scheduler)
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
+
## ❤️ Support the project
|
|
24
|
+
|
|
25
|
+
react-smart-scheduler is **free and open-source (MIT)**. If it saves you development time, please consider supporting it — every contribution keeps the project alive and actively maintained.
|
|
26
|
+
|
|
27
|
+
| | |
|
|
28
|
+
|---|---|
|
|
29
|
+
| ☕ **[Buy Me a Coffee](https://buymeacoffee.com/sathish.hazhtech)** | One-time tip — any amount helps |
|
|
30
|
+
| 🩷 **[GitHub Sponsors](https://github.com/sponsors/satthish)** | Monthly support with perks |
|
|
31
|
+
|
|
32
|
+
⭐ [Star the repo](https://github.com/satthish/react-smart-scheduler) · 🐛 [Report a bug](https://github.com/satthish/react-smart-scheduler/issues) · 🔁 Share with a teammate
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
23
36
|
## ✨ Features
|
|
24
37
|
|
|
25
38
|
| Feature | Status |
|
|
@@ -114,23 +127,158 @@ export default function App() {
|
|
|
114
127
|
|
|
115
128
|
### `CalendarEvent` type
|
|
116
129
|
|
|
130
|
+
Every event on the calendar is a plain JavaScript object that satisfies this interface:
|
|
131
|
+
|
|
117
132
|
```ts
|
|
118
133
|
interface CalendarEvent {
|
|
119
|
-
id: string;
|
|
120
|
-
title: string;
|
|
121
|
-
start: Date;
|
|
122
|
-
end: Date;
|
|
123
|
-
color?: string;
|
|
134
|
+
id: string; // unique identifier
|
|
135
|
+
title: string; // text shown on the event chip
|
|
136
|
+
start: Date; // inclusive start — must be earlier than end
|
|
137
|
+
end: Date; // exclusive end — must be later than start
|
|
138
|
+
color?: string; // any valid CSS colour (optional, falls back to palette)
|
|
124
139
|
}
|
|
125
140
|
```
|
|
126
141
|
|
|
127
|
-
|
|
142
|
+
#### Field reference
|
|
143
|
+
|
|
144
|
+
| Field | Type | Required | Notes |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `id` | `string` | ✅ | Must be **unique** across all events. Use `generateId()` for new events or your own UUID/nanoid. |
|
|
147
|
+
| `title` | `string` | ✅ | Displayed on the chip. Long titles are truncated with `…` on short events. |
|
|
148
|
+
| `start` | `Date` | ✅ | JavaScript `Date` object. Must be **strictly before** `end`. Timezone is whatever local time the `Date` represents. |
|
|
149
|
+
| `end` | `Date` | ✅ | JavaScript `Date` object. Must be **strictly after** `start`. Same-day is fine; multi-day is supported in month view. |
|
|
150
|
+
| `color` | `string` | ❌ | Any valid CSS colour string. If omitted, the library picks from `EVENT_COLORS` using `pickColor(id)`. |
|
|
151
|
+
|
|
152
|
+
#### Constraints & rules
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
✅ start < end
|
|
156
|
+
✅ Minimum duration: 1 minute (shorter events still render at minimum chip height)
|
|
157
|
+
✅ Multi-day events: supported in Month view; in Day/Week views only the same-day portion is shown
|
|
158
|
+
✅ Overlapping events are automatically laid out side-by-side
|
|
159
|
+
❌ start === end → undefined behaviour, avoid
|
|
160
|
+
❌ start > end → event will not render
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Creating events
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { generateId } from 'react-smart-scheduler';
|
|
167
|
+
|
|
168
|
+
// From a date + hour offsets
|
|
169
|
+
const event: CalendarEvent = {
|
|
170
|
+
id: generateId(),
|
|
171
|
+
title: 'Team standup',
|
|
172
|
+
start: new Date(2025, 0, 15, 9, 0), // Jan 15 2025 09:00
|
|
173
|
+
end: new Date(2025, 0, 15, 9, 30), // Jan 15 2025 09:30
|
|
174
|
+
color: '#3b82f6',
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// From ISO strings (common when coming from an API / database)
|
|
178
|
+
const fromApi: CalendarEvent = {
|
|
179
|
+
id: apiEvent.id,
|
|
180
|
+
title: apiEvent.title,
|
|
181
|
+
start: new Date(apiEvent.startIso), // new Date('2025-01-15T09:00:00')
|
|
182
|
+
end: new Date(apiEvent.endIso),
|
|
183
|
+
color: apiEvent.color ?? '#8b5cf6',
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// All-day style (midnight-to-midnight)
|
|
187
|
+
const allDay: CalendarEvent = {
|
|
188
|
+
id: generateId(),
|
|
189
|
+
title: 'Company holiday',
|
|
190
|
+
start: new Date(2025, 0, 20, 0, 0, 0),
|
|
191
|
+
end: new Date(2025, 0, 20, 23, 59, 59),
|
|
192
|
+
color: '#10b981',
|
|
193
|
+
};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Color reference
|
|
197
|
+
|
|
198
|
+
`color` accepts any valid CSS colour string:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
color: '#3b82f6' // hex (recommended — predictable across browsers)
|
|
202
|
+
color: '#3b82f680' // hex with alpha (50% transparent)
|
|
203
|
+
color: 'royalblue' // named colour
|
|
204
|
+
color: 'rgb(59,130,246)' // rgb()
|
|
205
|
+
color: 'hsl(217,91%,60%)' // hsl()
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Built-in palette (used when `color` is omitted):
|
|
128
209
|
|
|
129
210
|
```ts
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
211
|
+
import { EVENT_COLORS, pickColor } from 'react-smart-scheduler';
|
|
212
|
+
|
|
213
|
+
// EVENT_COLORS — the full string[] palette
|
|
214
|
+
console.log(EVENT_COLORS);
|
|
215
|
+
// ['#3b82f6', '#8b5cf6', '#10b981', '#f59e0b', '#ef4444', '#06b6d4', ...]
|
|
216
|
+
|
|
217
|
+
// pickColor(id) — deterministic colour assignment so the same event
|
|
218
|
+
// always gets the same colour, even across re-renders
|
|
219
|
+
const color = pickColor(event.id); // returns one of EVENT_COLORS
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Extending with custom fields
|
|
223
|
+
|
|
224
|
+
To attach your own metadata (room ID, attendees, status, etc.) without losing TypeScript safety, **extend** the interface:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
// types.ts
|
|
228
|
+
import type { CalendarEvent } from 'react-smart-scheduler';
|
|
229
|
+
|
|
230
|
+
export interface MyEvent extends CalendarEvent {
|
|
231
|
+
roomId: string;
|
|
232
|
+
attendees: string[];
|
|
233
|
+
status: 'confirmed' | 'tentative' | 'cancelled';
|
|
234
|
+
description: string;
|
|
133
235
|
}
|
|
236
|
+
|
|
237
|
+
// Your component — cast when passing to Scheduler
|
|
238
|
+
const events: MyEvent[] = [...];
|
|
239
|
+
|
|
240
|
+
<Scheduler
|
|
241
|
+
events={events as CalendarEvent[]} // widening cast — safe, Scheduler only reads base fields
|
|
242
|
+
onEventAdd={(partial) => {
|
|
243
|
+
// partial is Omit<CalendarEvent, 'id'> — add your extra fields before saving
|
|
244
|
+
const newEvent: MyEvent = {
|
|
245
|
+
...partial,
|
|
246
|
+
id: generateId(),
|
|
247
|
+
roomId: selectedRoom,
|
|
248
|
+
attendees: [],
|
|
249
|
+
status: 'confirmed',
|
|
250
|
+
description: '',
|
|
251
|
+
};
|
|
252
|
+
setEvents((prev) => [...prev, newEvent]);
|
|
253
|
+
}}
|
|
254
|
+
onEventChange={(updated) =>
|
|
255
|
+
// updated is CalendarEvent — merge back with your extra fields
|
|
256
|
+
setEvents((prev) =>
|
|
257
|
+
prev.map((e) => (e.id === updated.id ? { ...e, ...updated } : e))
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
onEventDelete={(id) =>
|
|
261
|
+
setEvents((prev) => prev.filter((e) => e.id !== id))
|
|
262
|
+
}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### Serialising to / from a database
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
// Saving to DB — convert Date → ISO string
|
|
270
|
+
const toDb = (e: CalendarEvent) => ({
|
|
271
|
+
...e,
|
|
272
|
+
start: e.start.toISOString(),
|
|
273
|
+
end: e.end.toISOString(),
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Loading from DB — convert ISO string → Date
|
|
277
|
+
const fromDb = (row: DbRow): CalendarEvent => ({
|
|
278
|
+
...row,
|
|
279
|
+
start: new Date(row.start),
|
|
280
|
+
end: new Date(row.end),
|
|
281
|
+
});
|
|
134
282
|
```
|
|
135
283
|
|
|
136
284
|
### Exported utilities
|
|
@@ -244,7 +392,7 @@ const useCalendarStore = create<{
|
|
|
244
392
|
|
|
245
393
|
```bash
|
|
246
394
|
# Clone
|
|
247
|
-
git clone https://github.com/
|
|
395
|
+
git clone https://github.com/satthish/react-smart-scheduler.git
|
|
248
396
|
cd react-smart-scheduler/packages/react-smart-scheduler
|
|
249
397
|
|
|
250
398
|
# Install
|
|
@@ -367,19 +515,6 @@ All contributions are welcome — bug fixes, features, docs, tests.
|
|
|
367
515
|
|
|
368
516
|
---
|
|
369
517
|
|
|
370
|
-
## ❤️ Donate / Support
|
|
371
|
-
|
|
372
|
-
react-smart-scheduler is **free and open-source (MIT)**. Maintaining it takes real effort. If it saves you time, please consider:
|
|
373
|
-
|
|
374
|
-
| | |
|
|
375
|
-
|---|---|
|
|
376
|
-
| ☕ **[Buy Me a Coffee](https://buymeacoffee.com/sathish.hazhtech)** | One-time tip — any amount helps |
|
|
377
|
-
| 🩷 **[GitHub Sponsors](https://github.com/sponsors/satthish)** | Monthly support with perks |
|
|
378
|
-
|
|
379
|
-
Every ⭐ star and share also helps the project grow. Thank you 🙏
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
518
|
## 📄 License
|
|
384
519
|
|
|
385
520
|
[MIT](LICENSE) © react-smart-scheduler contributors
|
|
@@ -388,6 +523,6 @@ Every ⭐ star and share also helps the project grow. Thank you 🙏
|
|
|
388
523
|
|
|
389
524
|
<div align="center">
|
|
390
525
|
|
|
391
|
-
Built with ❤️ and TypeScript · If this saves you time, consider [starring ⭐ the repo](https://github.com/
|
|
526
|
+
Built with ❤️ and TypeScript · If this saves you time, consider [starring ⭐ the repo](https://github.com/satthish/react-smart-scheduler)
|
|
392
527
|
|
|
393
528
|
</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { default as default_2 } from 'react';
|
|
2
2
|
|
|
3
|
+
export declare type Breakpoint = 'mobile' | 'tablet' | 'desktop';
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* The shape of a single calendar event.
|
|
5
7
|
*
|
|
@@ -44,6 +46,12 @@ export declare function pickColor(id: string): string;
|
|
|
44
46
|
* 4. Resize is handled entirely in EventItem via Pointer Capture API,
|
|
45
47
|
* completely independent of dnd-kit. EventItem calls onEventResizeEnd
|
|
46
48
|
* after commit; Scheduler forwards to onEventChange.
|
|
49
|
+
*
|
|
50
|
+
* 5. Responsive: uses useBreakpoint() to set the initial default view
|
|
51
|
+
* when no `view` prop is provided (uncontrolled mode).
|
|
52
|
+
* mobile → 'day', tablet/desktop → 'week'.
|
|
53
|
+
* Both PointerSensor and TouchSensor are active so drag & drop works
|
|
54
|
+
* on touch devices out of the box.
|
|
47
55
|
*/
|
|
48
56
|
export declare const Scheduler: default_2.FC<SchedulerProps>;
|
|
49
57
|
|
|
@@ -79,8 +87,23 @@ export declare interface SchedulerProps {
|
|
|
79
87
|
className?: string;
|
|
80
88
|
}
|
|
81
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Returns the current responsive breakpoint and re-renders whenever the
|
|
92
|
+
* window is resized across a threshold.
|
|
93
|
+
*
|
|
94
|
+
* Breakpoints:
|
|
95
|
+
* mobile — < 640 px (phones, small screens)
|
|
96
|
+
* tablet — 640–1023 px (tablets, small laptops)
|
|
97
|
+
* desktop — ≥ 1024 px (standard laptop / desktop)
|
|
98
|
+
*
|
|
99
|
+
* Usage:
|
|
100
|
+
* const bp = useBreakpoint();
|
|
101
|
+
* const isMobile = bp === 'mobile';
|
|
102
|
+
*/
|
|
103
|
+
export declare function useBreakpoint(): Breakpoint;
|
|
104
|
+
|
|
82
105
|
/** Library version — matches package.json version field. */
|
|
83
|
-
export declare const VERSION: "0.1.
|
|
106
|
+
export declare const VERSION: "0.1.3";
|
|
84
107
|
|
|
85
108
|
export declare type ViewType = 'day' | 'week' | 'month';
|
|
86
109
|
|