rdz-react-scheduler
v1.0.0
Published
Theme-agnostic React scheduler with Tailwind v3/v4, TypeScript and JavaScript support
Maintainers
Readme
rdz-react-scheduler
✨ Why this scheduler?
| | rdz-react-scheduler |
|---|---------------------|
| Views | Month, week, and day — switch via dropdown |
| Styling | CSS variables — plug into MUI, Chakra, Ant Design, or your own design system |
| Tailwind | Works with Tailwind v3 and v4 — include in content and go |
| Stack | React + date-fns only — no MUI or Emotion |
| Types | Full TypeScript types; use from JS or TS |
| UI | Colorful default theme, view dropdown, border styles, slot padding |
🚀 Quick start
1. Install
npm i rdz-react-scheduler date-fnsPeer dependencies: react, react-dom (≥17).
2. Import styles first
Import the scheduler CSS before Tailwind directives so @import stays valid:
/* src/index.css – @import must be first */
@import "rdz-react-scheduler/styles.css";
@tailwind base;
@tailwind components;
@tailwind utilities;Or in JS/TS entry:
import "rdz-react-scheduler/styles.css";3. Add to Tailwind content
Tailwind v3 (tailwind.config.js):
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/rdz-react-scheduler/dist/**/*.js",
],Tailwind v4 (in your main CSS):
@import "tailwindcss";
@source "../node_modules/rdz-react-scheduler/dist/**/*.js";4. Use it
import { Scheduler } from "rdz-react-scheduler";
<Scheduler
view="week"
events={[
{ event_id: 1, title: "Meeting", start: new Date(), end: new Date() },
]}
onEventClick={(e) => console.log(e)}
onCellClick={(start, end) => console.log(start, end)}
/>📋 Features
- Month, week, day views with prev/next, Today, and view dropdown (theme-adaptive)
- Themes:
default(colorful nav),minimal,card - Border styles:
light,thick,thin,dashed,light-dashed - Slot padding: configurable inner padding for slots/cells (px)
- Theme-agnostic: override
--rdz-*CSS variables for any UI library - Tailwind v3 & v4 — utility classes + optional
@theme/theme.extend - TypeScript & JavaScript — full type exports (
ProcessedEvent,BorderStyle, etc.) - date-fns for dates — no MUI/Emotion
- Accessible — keyboard and ARIA-friendly
- Custom event renderer —
eventRendererprop
📦 API
Scheduler props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| view | "month" \| "week" \| "day" | "week" | Initial view |
| height | number | 600 | Min height (px) |
| selectedDate | Date | today | Controlled selected date |
| events | ProcessedEvent[] | [] | Events to display |
| month | MonthViewProps | — | Month view options (weekStartOn, etc.) |
| week | WeekViewProps | — | Week view options (startHour, endHour, step, etc.) |
| day | DayViewProps | — | Day view options |
| navigation | boolean | true | Show nav bar (arrows, date, Today, view dropdown) |
| editable | boolean | true | Allow edit (UI hint) |
| deletable | boolean | true | Allow delete (UI hint) |
| draggable | boolean | false | Allow drag (UI hint) |
| loading | boolean | false | Show loading state |
| translations | Translations | — | Override labels (navigation, form, event, etc.) |
| locale | Locale (date-fns) | — | Locale for dates |
| hourFormat | "12" \| "24" | "24" | Time format |
| theme | "default" \| "minimal" \| "card" | "default" | Built-in theme variant |
| borderStyle | BorderStyle | "thin" | Grid/cell border: light, thick, thin, dashed, light-dashed |
| slotPadding | number | — | Inner padding for slots/cells (px). Omit to use default. |
| log | "console" \| "json" \| false | — | Log actions to console: "console" (object) or "json" (stringified). Omit to disable. |
| getRemoteEvents | (query: RemoteQuery) => Promise<ProcessedEvent[]> | — | Load events from API. Called with { start, end, view } on view/date change. |
| onConfirm | (event: ProcessedEvent, action: "add" \| "edit") => void \| Promise<...> | — | Called when user adds or updates an event (from your form/modal). |
| onDelete | (eventId) => void \| Promise<...> | — | Called when user deletes an event (from your UI). |
| formats | DateFormats | — | Date/time format strings (date-fns). See Date formats. |
| className | string | — | Extra class on root |
| onEventClick | (event: ProcessedEvent) => void | — | Event click |
| onCellClick | (start: Date, end: Date) => void | — | Cell/slot click (use to open “Add event” with start/end) |
| onSelectedDateChange | (date: Date) => void | — | When date changes (e.g. nav) |
| onViewChange | (view: ViewType) => void | — | When view changes |
| eventRenderer | (event: ProcessedEvent) => ReactNode | — | Custom event content |
ProcessedEvent
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| event_id | number \| string | ✓ | Unique id |
| title | string | ✓ | Title |
| start | Date | ✓ | Start time |
| end | Date | ✓ | End time |
| subtitle | string | | Subtitle |
| notes | string | | Notes, description, or links shown in the event preview popover (URLs become clickable). |
| color | string | | Event block background (e.g. #6366f1) |
| textColor | string | | Event block text color |
| allDay | boolean | | All-day event |
| editable | boolean | | Override global editable |
| deletable | boolean | | Override global deletable |
| draggable | boolean | | Override global draggable |
| disabled | boolean | | Disabled |
Other fields are allowed for custom use.
Exports (TypeScript)
import {
Scheduler,
defaultTranslations,
} from "rdz-react-scheduler";
import type {
SchedulerProps,
ProcessedEvent,
ViewType,
BorderStyle,
RemoteQuery,
DateFormats,
EventAction,
MonthViewProps,
WeekViewProps,
DayViewProps,
Translations,
} from "rdz-react-scheduler";
import type { Locale } from "date-fns";📟 Logging
Set log="console" to log scheduler actions as objects, or log="json" to log stringified JSON (dates as ISO). Logged events: eventClick, cellClick, selectedDateChange, viewChange, getRemoteEvents (when using remote data).
<Scheduler events={events} log="json" />📡 Load remote data
Provide getRemoteEvents. It receives { start, end, view } and must return a Promise<ProcessedEvent[]>. The scheduler calls it when the view or selected date changes and shows a loading state while fetching.
<Scheduler
getRemoteEvents={async ({ start, end, view }) => {
const res = await fetch(`/api/events?start=${start.toISOString()}&end=${end.toISOString()}&view=${view}`);
const data = await res.json();
return data.events.map((e) => ({ ...e, start: new Date(e.start), end: new Date(e.end) }));
}}
/>When getRemoteEvents is set, the events prop is ignored; events come only from the remote call.
✏️ Add event, update event, delete
The scheduler does not include a built-in form or modal. You implement add/edit/delete in your app and wire it with callbacks:
- Add: Use
onCellClick(start, end)to open your “Add event” form with that range. On submit, add the event to your state (or call your API) and optionally callonConfirm(newEvent, "add")if you use remote state. - Edit: Use
onEventClick(event)to open your “Edit event” form. On save, update your state/API and optionallyonConfirm(updatedEvent, "edit"). - Delete: From your UI (e.g. edit form), call your delete API and optionally
onDelete(eventId)so remote state can be refreshed.
onConfirm and onDelete are optional; use them when you need to sync with a remote source or internal state after the user adds, edits, or deletes.
📅 Date formats
Use the formats prop to override how dates and times are displayed. Values are date-fns format strings.
| Key | Default | Used for |
|-----|--------|----------|
| monthTitle | "MMMM yyyy" | Month view title (e.g. “March 2025”) |
| weekTitle | "MMM d" | Week view title range (e.g. “Mar 10 – Mar 16”) |
| dayTitle | "EEEE, MMMM d, yyyy" | Day view title |
| time | "HH:mm" | Time column when hourFormat="24" |
| time12 | "h a" | Time column when hourFormat="12" (or add custom key and use in your format) |
| date | "MMM d" | Short date |
Example:
<Scheduler
events={events}
formats={{
monthTitle: "MMMM yyyy",
weekTitle: "MMM d",
dayTitle: "EEEE, MMM d, yyyy",
time: "HH:mm",
}}
/>🎨 Theming
Root class: .rdz-scheduler. Override these CSS variables to match your app:
Core
| Variable | Purpose |
|----------|---------|
| --rdz-bg | Background |
| --rdz-bg-muted | Muted / secondary background |
| --rdz-border | General borders |
| --rdz-text | Primary text |
| --rdz-text-muted | Secondary text |
| --rdz-accent | Accent (Today, active dropdown item) |
| --rdz-accent-hover | Accent hover |
| --rdz-event-bg | Event block background |
| --rdz-event-text | Event block text |
| --rdz-today | Today cell highlight |
| --rdz-radius | Border radius |
| --rdz-radius-sm | Small radius |
| --rdz-font-sans | Font family |
Nav bar
| Variable | Purpose |
|----------|---------|
| --rdz-nav-bg | Nav background (default: gradient) |
| --rdz-nav-text | Nav text color |
| --rdz-nav-btn-hover | Nav button hover |
View dropdown (theme-adaptive)
| Variable | Purpose |
|----------|---------|
| --rdz-dropdown-bg | Dropdown panel background |
| --rdz-dropdown-border | Dropdown border |
| --rdz-dropdown-text | Dropdown text |
| --rdz-dropdown-item-hover | Item hover background |
| --rdz-dropdown-shadow | Panel shadow |
Grid borders & slots
| Variable | Purpose |
|----------|---------|
| --rdz-border-color | Grid/cell border color |
| --rdz-border-width | Grid border width (set by borderStyle) |
| --rdz-border-style | Grid border style (solid/dashed) |
| --rdz-slot-padding | Inner padding for slots/cells (set by slotPadding prop) |
Example (Tailwind v3):
.rdz-scheduler {
--rdz-accent: theme("colors.blue.600");
--rdz-event-bg: theme("colors.primary.500");
}Example (design system):
.rdz-scheduler {
--rdz-accent: var(--your-primary);
--rdz-event-bg: var(--your-primary);
}📐 Theme variants
default— Colorful nav (gradient), white dropdown panel, indigo accent.minimal— Light gray nav, no gradient; dropdown uses standard panel styling.card— Same as default with larger radius and stronger shadow; rounded nav top.
🧩 Demo
The demo app (demo/) is a Vite + React app that showcases the scheduler with Ant Design for the add/edit event modal.
Run the demo:
npm run build
cd demo && npm install && npm run devDemo features:
- Add event — “Add event” button or click a time-slot cell to open an Ant Design Modal with a form (title, subtitle, notes, start/end datetime, color). Save adds the event to the list.
- Edit event — Click an event (or use “Edit” in the hover preview) to open the same modal pre-filled; save updates the event.
- Themes, border style, slot padding, view dropdown, log mode, remote data toggle, and 12/24h time format.
Demo stack: React, Tailwind, @uidotdev/usehooks (e.g. useMediaQuery for responsive layout), antd + dayjs (Modal, Form, DatePicker for add/edit).
📄 License
MIT.
