react-smart-scheduler 0.1.0 → 0.1.2
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 +162 -27
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +3 -3
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +3 -3
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -12,14 +12,27 @@ Day · Week · Month views · Drag & drop · Resize · TypeScript · Zero UI fra
|
|
|
12
12
|
[](LICENSE)
|
|
13
13
|
[](https://www.typescriptlang.org/)
|
|
14
14
|
|
|
15
|
-
[**Live Demo →**](https://
|
|
16
|
-
[**GitHub →**](https://github.com/
|
|
15
|
+
[**Live Demo →**](https://scheduler.hazhtech.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
|
|
@@ -279,7 +427,7 @@ The `prepublishOnly` hook ensures the published package is always a fresh, type-
|
|
|
279
427
|
|
|
280
428
|
## 📸 Demo
|
|
281
429
|
|
|
282
|
-
**[👉 Open live demo](https://
|
|
430
|
+
**[👉 Open live demo](https://scheduler.hazhtech.com/)**
|
|
283
431
|
|
|
284
432
|
Features you can try:
|
|
285
433
|
|
|
@@ -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
|
@@ -80,7 +80,7 @@ export declare interface SchedulerProps {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/** Library version — matches package.json version field. */
|
|
83
|
-
export declare const VERSION: "0.1.
|
|
83
|
+
export declare const VERSION: "0.1.2";
|
|
84
84
|
|
|
85
85
|
export declare type ViewType = 'day' | 'week' | 'month';
|
|
86
86
|
|
package/dist/index.es.js
CHANGED
|
@@ -2,10 +2,10 @@ import { jsxs as L, jsx as b } from "react/jsx-runtime";
|
|
|
2
2
|
import B, { useRef as C, useMemo as F, useLayoutEffect as vr, useEffect as A, useCallback as I, useState as W, memo as yr, useReducer as br, useContext as kt, createContext as oe, cloneElement as pr, forwardRef as wr } from "react";
|
|
3
3
|
import { unstable_batchedUpdates as he, createPortal as Dr } from "react-dom";
|
|
4
4
|
/*!
|
|
5
|
-
* react-smart-scheduler v0.1.
|
|
5
|
+
* react-smart-scheduler v0.1.2
|
|
6
6
|
* (c) 2026 react-smart-scheduler contributors
|
|
7
7
|
* Released under the MIT License
|
|
8
|
-
* https://github.com/
|
|
8
|
+
* https://github.com/satthish/react-smart-scheduler
|
|
9
9
|
*/
|
|
10
10
|
const Se = typeof window < "u" && typeof window.document < "u" && typeof window.document.createElement < "u";
|
|
11
11
|
function Ht(t) {
|
|
@@ -4932,7 +4932,7 @@ const Bi = 64, $i = 0, zi = 24, _i = ({
|
|
|
4932
4932
|
}
|
|
4933
4933
|
)
|
|
4934
4934
|
] });
|
|
4935
|
-
}, Vi = "0.1.
|
|
4935
|
+
}, Vi = "0.1.2";
|
|
4936
4936
|
export {
|
|
4937
4937
|
xe as EVENT_COLORS,
|
|
4938
4938
|
_i as Scheduler,
|