MUI Scheduler

View MUI Scheduler

.. toc::

.. llms_copy::MUI Scheduler

📚 Full documentation: [dash-mui-scheduler.onrender.com](https://dash-mui-scheduler.onrender.com) — the dedicated docs site with every calendar/timeline component, live examples, and props tables. This page is the quick-start overview.

Installation

[Visit GitHub Repo](https://github.com/pip-install-python/dash-mui-scheduler) · [PyPI](https://pypi.org/project/dash-mui-scheduler/)

``bash pip install dash-mui-scheduler ``

Introduction

dash-mui-scheduler is the successor to dash-fullcalendar — it replaces it in this catalogue. It wraps the [MUI X Scheduler](https://mui.com/x/react-scheduler/) for Plotly Dash, so you can build event calendars and resource timelines in pure Python.

Events cross the Dash ↔ Python boundary as plain dictionaries with ISO-string dates, and every user interaction (create / move / resize / delete) round-trips straight back into your callbacks. Dark mode is automatic — the components follow the surrounding Dash Mantine Components color scheme.

The suite includes:

| Component | Plan | What it is | |:----------|:-----|:-----------| | EventCalendar | Community (MIT) | Day / week / month / agenda calendar with drag-and-drop, resizing, resources, and an editing dialog. No license key. | | EventCalendarPremium | Premium | The calendar plus the recurrence engine (RRULE events + exception dates). | | EventTimeline | Premium | A resource-row, Gantt-style timeline across configurable zoom presets. | | RadialLineChart | Premium (preview) | Polar line/area charts for trends along periodic values. | | RadialBarChart | Premium (preview) | Polar bar charts for comparing values along periodic categories. |

The underlying MUI X Scheduler is in beta (@mui/x-scheduler@9.0.0-beta.0); this wrapper pins the beta exactly, so the upstream API may change before its stable release.

Quick Start

Pass a list of event dicts — each needs at least id, title, start, and end (ISO strings). Optional keys include description, color, allDay, resource, and per-event draggable / resizable / readOnly overrides.

.. exec::docs.dash_mui_scheduler.quickstart_example :code: false

```python

File: docs/dash_mui_scheduler/quickstart_example.py

"""Quick-start EventCalendar example with sample events.""" from datetime import datetime, timedelta

import dash_mantine_components as dmc import dash_mui_scheduler as dms

Anchor the sample events to the current week so the calendar

always opens with something to look at.

_monday = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) _monday -= timedelta(days=_monday.weekday())

def _iso(day_offset: int, hour: int, minute: int = 0) -> str: return (_monday + timedelta(days=day_offset, hours=hour, minutes=minute)).isoformat()

Events are plain dicts with ISO-string dates.

Required keys: id, title, start, end. Everything else is optional.

events = [ { "id": "1", "title": "Team Standup", "start": _iso(0, 9), "end": _iso(0, 9, 30), "color": "blue", }, { "id": "2", "title": "Design Review", "start": _iso(1, 13), "end": _iso(1, 14, 30), "color": "purple", "description": "Review the new dashboard mockups.", }, { "id": "3", "title": "Client Call", "start": _iso(2, 10), "end": _iso(2, 11), "color": "teal", }, { "id": "4", "title": "Sprint Demo", "start": _iso(3, 15), "end": _iso(3, 16), "color": "green", }, { "id": "5", "title": "Conference Day", "start": _iso(4, 0), "end": _iso(4, 23, 59), "allDay": True, "color": "orange", }, ]

component = dmc.Paper( dms.EventCalendar( id="mui-scheduler-quickstart-cal", events=events, defaultView="week", height=620, ), withBorder=True, p="md", ) ```

Events & Callbacks

The events prop is both an input and an output. Seed it with your data; the calendar writes the full new array back whenever the user creates, moves, resizes, or deletes an event. For a lighter-weight signal, lastAction reports just the most recent change:

``python {"type": "create" | "update" | "delete" | "move" | "resize" | "change", "event": {...}, # the affected event (or None) "event_timestamp": ...} ``

Other stateful props (view, visibleDate, preferences, visibleResources) each come as a controlled prop plus an uncontrolled defaultX variant, and are written back on change — so you can read the active view or the date the user navigated to in a callback.

.. exec::docs.dash_mui_scheduler.interactive_example :code: false

```python

File: docs/dash_mui_scheduler/interactive_example.py

"""Interactive example: round-tripping event edits through callbacks.

events is BOTH an input and an output — the calendar writes the full array back on every create / move / resize / delete. lastAction is a convenience output describing just the most recent change. """ import json from datetime import datetime, timedelta

import dash_mantine_components as dmc import dash_mui_scheduler as dms from dash import callback, Input, Output

_monday = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) _monday -= timedelta(days=_monday.weekday())

def _iso(day_offset: int, hour: int, minute: int = 0) -> str: return (_monday + timedelta(days=day_offset, hours=hour, minutes=minute)).isoformat()

events = [ {"id": "a", "title": "Drag me around", "start": _iso(0, 10), "end": _iso(0, 11), "color": "indigo"}, {"id": "b", "title": "Resize my edges", "start": _iso(2, 13), "end": _iso(2, 15), "color": "pink"}, {"id": "c", "title": "Click to edit or delete", "start": _iso(4, 9), "end": _iso(4, 10), "color": "amber"}, ]

component = dmc.Stack( [ dms.EventCalendar( id="mui-scheduler-interactive-cal", events=events, defaultView="week", height=560, eventCreation={"interaction": "click", "duration": 60}, ), dmc.Group( [ dmc.Badge("try it", color="teal", variant="light"), dmc.Text( "Drag, resize, create (click an empty slot), edit, or delete an event — " "every change lands in a Dash callback.", size="sm", c="dimmed", ), ], gap="xs", ), dmc.SimpleGrid( cols={"base": 1, "md": 2}, children=[ dmc.Paper( [ dmc.Text("lastAction", fw=600, size="sm", mb="xs"), dmc.Code( "Interact with the calendar…", id="mui-scheduler-last-action-output", block=True, ), ], withBorder=True, p="md", ), dmc.Paper( [ dmc.Text("events (round-tripped)", fw=600, size="sm", mb="xs"), dmc.Text( f"{len(events)} events", id="mui-scheduler-event-count-output", size="sm", c="dimmed", ), ], withBorder=True, p="md", ), ], ), ], gap="md", )

@callback( Output("mui-scheduler-last-action-output", "children"), Input("mui-scheduler-interactive-cal", "lastAction"), prevent_initial_call=True, ) def show_last_action(last_action): if not last_action: return "Interact with the calendar…" # lastAction = {"type": "create"|"update"|"delete"|"move"|"resize"|"change", # "event": {...}, "event_timestamp": ...} return json.dumps( {"type": last_action.get("type"), "event": last_action.get("event")}, indent=2, default=str, )

@callback( Output("mui-scheduler-event-count-output", "children"), Input("mui-scheduler-interactive-cal", "events"), prevent_initial_call=True, ) def show_event_count(current_events): current_events = current_events or [] titles = ", ".join(e.get("title", "?") for e in current_events) return f"{len(current_events)} events — {titles}" ```

Premium Components

EventCalendarPremium, EventTimeline, and the radial charts wrap MUI X Premium packages. They all accept a licenseKey prop; without a valid MUI X Premium license key they still render, but with a watermark. All Premium components share the same @mui/x-license singleton, so a single key covers everything. The Dash wrapper code in this package is MIT-licensed; the underlying MUI X Premium libraries are not.

EventCalendarPremium — recurrence

Same API as EventCalendar, plus licenseKey and support for recurring events via rrule (an RFC-5545 RRULE string or an object) and exDates (exception dates):

```python import os import dash_mui_scheduler as dms

dms.EventCalendarPremium( id="mui-scheduler-premium-cal", licenseKey=os.environ["MUI_X_LICENSE_KEY"], events=[{ "id": 1, "title": "Standup", "start": "2026-07-06T09:00:00", "end": "2026-07-06T09:15:00", "rrule": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR", }], defaultVisibleDate="2026-07-06", ) ```

EventTimeline

A Gantt-style timeline that lays events out in resource rows across configurable zoom presets. It shares the calendar's event/resource model (events, resources, lastAction, drag/resize props) and swaps the view/views props for preset / defaultPreset / presets, plus a resourceColumnLabel for the resource column header.

Radial Charts (Premium preview)

RadialLineChart and RadialBarChart are polar charts from @mui/x-charts-premium. Pass row-oriented dataset rows plus series that reference columns via dataKey; rotationAxis replaces the cartesian x-axis and radiusAxis replaces the y-axis. Clicking the chart reports the hit axis item via the clickData output. They are Unstable_ previews — production-ready, but their API may shift.

.. exec::docs.dash_mui_scheduler.radial_chart_example :code: false

```python

File: docs/dash_mui_scheduler/radial_chart_example.py

"""RadialLineChart example (Premium preview).

Renders with a watermark unless a MUI X Premium licenseKey is provided. Set the MUI_X_LICENSE_KEY environment variable to remove it. """ import os

import dash_mantine_components as dmc import dash_mui_scheduler as dms from dash import callback, Input, Output

Row-oriented data; each series references a column via dataKey.

dataset = [ {"month": "Jan", "london": 49, "paris": 51}, {"month": "Feb", "london": 38, "paris": 41}, {"month": "Mar", "london": 40, "paris": 47}, {"month": "Apr", "london": 44, "paris": 52}, {"month": "May", "london": 49, "paris": 63}, {"month": "Jun", "london": 45, "paris": 49}, {"month": "Jul", "london": 45, "paris": 62}, {"month": "Aug", "london": 50, "paris": 53}, {"month": "Sep", "london": 49, "paris": 47}, {"month": "Oct", "london": 69, "paris": 61}, {"month": "Nov", "london": 59, "paris": 55}, {"month": "Dec", "london": 56, "paris": 58}, ]

component = dmc.Paper( dmc.Stack( [ dms.RadialLineChart( id="mui-scheduler-radial-lines", height=420, licenseKey=os.environ.get("MUI_X_LICENSE_KEY", ""), dataset=dataset, # rotationAxis = angular (x-like) axis, radiusAxis = radial (y-like) axis series=[ {"dataKey": "london", "label": "London (mm)", "curve": "natural", "showMark": True}, {"dataKey": "paris", "label": "Paris (mm)", "curve": "natural", "showMark": True}, ], rotationAxis=[{"scaleType": "point", "dataKey": "month", "disableLine": True}], radiusAxis=[{"disableLine": True}], grid={"rotation": True, "radius": True}, ), dmc.Text( "Click the chart to inspect an axis item.", id="mui-scheduler-radial-click-output", size="sm", c="dimmed", ta="center", ), ], gap="xs", ), withBorder=True, p="md", )

@callback( Output("mui-scheduler-radial-click-output", "children"), Input("mui-scheduler-radial-lines", "clickData"), prevent_initial_call=True, ) def show_click(click_data): if not click_data: return "Click the chart to inspect an axis item." return ( f"Clicked {click_data.get('axisValue')} — " f"series values: {click_data.get('seriesValues')}" ) ```

EventCalendar Properties

| Property | Type | Default | Description | |:---------|:-----|:--------|:------------| | id | string | - | Component ID for Dash callbacks. | | events | list of dicts | - | The events to render. Each needs id, title, start, end (ISO strings); optional description, timezone, resource, rrule, exDates, allDay, readOnly, color, draggable, resizable, className. Input AND output — written back on every edit. | | lastAction | dict | - | Output. The most recent change: {type, event, event_timestamp}. | | view | 'day' \| 'week' \| 'month' \| 'agenda' | - | Controlled active view. Also an output (updated on view change). | | defaultView | string | 'week' | Uncontrolled initial view. | | views | list of strings | ['day','week','month','agenda'] | Which views are offered. | | visibleDate | string | - | Controlled visible date (ISO string). Also an output on navigation. | | defaultVisibleDate | string | today | Uncontrolled initial visible date. | | eventColor | string | 'teal' | Default event palette: red, pink, purple, indigo, blue, teal, green, lime, amber, orange, grey. Overridden per resource and per event. | | eventCreation | bool \| dict | - | False disables creation; a dict sets {interaction: 'click'\|'double-click', duration} (minutes). | | resources | list of dicts | - | Resources events can be assigned to (supports nested children). | | visibleResources | dict | - | Controlled resource visibility map {resourceId: bool}. Also an output. | | defaultVisibleResources | dict | {} | Uncontrolled initial resource visibility (all visible). | | shouldEventRequireResource | boolean | False | Require every event to be assigned to a resource. | | areEventsDraggable | boolean | True | Allow drag-to-reschedule. | | areEventsResizable | bool \| 'start' \| 'end' | True | Allow resize (or restrict to one edge). | | canDragEventsFromTheOutside | boolean | False | Allow external events to be dragged in. | | canDropEventsToTheOutside | boolean | False | Allow events to be dragged out of the calendar. | | readOnly | boolean | - | Global read-only mode (disables create / drag / resize / dialog). | | showCurrentTimeIndicator | boolean | True | Show the current-time indicator line in time views. | | scrollToCurrentTime | boolean | False | Scroll day/week views so the current time is centered on first render. | | displayTimezone | string | 'default' | Render timezone: IANA name, 'default', 'locale', or 'UTC'. Render-only. | | preferences | dict | - | Controlled user preferences {ampm, weekStartsOn, showWeekends, showWeekNumber, isSidePanelOpen, showEmptyDaysInAgenda}. Also an output. | | defaultPreferences | dict | - | Uncontrolled initial preferences (same shape). | | preferencesMenuConfig | False \| dict | - | Which items appear in the preferences menu, or False to hide it. | | localeText | dict | - | Override UI label strings (partial map of translation keys). | | eventDialogVariant | 'drawer' \| 'dialog' | 'drawer' | Event editor presentation: responsive drawer or floating dialog. | | eventDialogTopOffset | number | 0 | Desktop drawer inset from the top (px) — e.g. your fixed header height. | | responsiveSidePanel | boolean | True | Side panel opens on wide screens, collapses below mobileBreakpoint. | | mobileBreakpoint | number | 768 | Width (px) below which the UI switches to its mobile layout. | | height | number \| string | 600 | Height of the wrapping container. | | className | string | - | CSS class applied to the wrapping div. | | sx | dict | - | MUI sx styling object (object form only). |

Note: EventCalendarPremium accepts all of the above plus licenseKey. EventTimeline accepts licenseKey, preset / defaultPreset / presets, and resourceColumnLabel in place of the view props; the radial charts take dataset, series, rotationAxis, radiusAxis, grid, axisHighlight, colors, hideLegend, margin, showToolbar, slotProps, and the clickData output. See the component docstrings for full details.

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: