Editing
Create and edit events in dash-mui-scheduler — the edit dialog, event creation config, and read-only calendars or events.
Editing events
dms.EventCalendar is interactive out of the box. With no callback at all, a user can create, drag, resize, and delete events — Dash's own setProps round-trip persists each change into the events prop. The component treats events as both input and output: on every create, move, resize, or delete it writes the full new array back. Dates inside events are always ISO strings (e.g. "2024-01-15T10:00:00" for wall time, or a trailing Z for UTC) — never Python datetime objects.
Add a callback only when you want to observe what changed: read events for the new state, or read lastAction — an output-only dict shaped {type, event, event_timestamp} where type is one of create, update, delete, move, resize, or change.
The edit dialog
Clicking an existing event opens the built-in edit dialog where the title, time, color, and description can be changed; saving writes the updated event back into events. Interacting with an empty slot starts event creation (see below). You do not wire any of this up yourself — it is part of the component.
The MUI X Scheduler is in beta. The edit dialog's exact fields and styling may change in future releases. The Dash data boundary described here (events in/out, lastAction, ISO strings) is stable.
Configuring event creation
The eventCreation prop controls how new events are drawn:
eventCreation=True(default) — creation is enabled with the default gesture.eventCreation=False— creation is disabled entirely; users can still
move or resize existing events (unless those are locked too).
eventCreation={"interaction": "double-click", "duration": 45}— an object
where interaction is "click" or "double-click", and duration is the new event's length in minutes.
In the example below, double-clicking an empty slot creates a 45-minute event. The lastAction output is echoed underneath so you can see each change.
# File: docs/editing/event_creation.py
from dash import Input, Output, callback
import dash_mantine_components as dmc
import dash_mui_scheduler as dms
# Dates are ISO strings (wall time, no "Z"). The component writes the
# full new array back to `events` on every create / move / resize / delete.
events = [
{
"id": "kickoff",
"title": "Project kickoff",
"start": "2024-01-15T10:00:00",
"end": "2024-01-15T11:30:00",
"color": "indigo",
},
{
"id": "review",
"title": "Design review",
"start": "2024-01-17T14:00:00",
"end": "2024-01-17T15:00:00",
"color": "teal",
},
]
component = dmc.Stack(
[
dmc.Text(
"Double-click an empty slot to create a 45-minute event. "
"Existing events stay draggable and resizable.",
size="sm",
c="dimmed",
),
dms.EventCalendar(
id="editing-creation-cal",
events=events,
# interaction: 'click' | 'double-click'; duration is in minutes.
eventCreation={"interaction": "double-click", "duration": 45},
defaultVisibleDate="2024-01-15",
defaultView="week",
height=600,
),
dmc.Code(id="editing-creation-action", block=True),
],
gap="sm",
)
@callback(
Output("editing-creation-action", "children"),
Input("editing-creation-cal", "lastAction"),
)
def show_action(last_action):
if not last_action:
return "No action yet — double-click an empty slot to create an event."
event = last_action.get("event") or {}
return f"{last_action.get('type')}: {event.get('title', '(none)')}"
Read-only: whole calendar vs. one event
Locking works at two levels:
- Globally —
readOnly=Trueon the calendar disables all creating,
moving, resizing, and deleting. The calendar becomes a pure display.
- Per event — add
"readOnly": Trueto a single event dict to freeze
just that event while the rest of the calendar stays editable.
The example shows both: a fully read-only calendar on the left, and an editable calendar on the right where only the red all-hands event is locked.
# File: docs/editing/editing_readonly.py
import dash_mantine_components as dmc
import dash_mui_scheduler as dms
# Even with readOnly=False, one event is locked via its own `readOnly` key.
events = [
{
"id": "standup",
"title": "Daily standup",
"start": "2024-01-15T09:00:00",
"end": "2024-01-15T09:30:00",
"color": "blue",
},
{
"id": "frozen",
"title": "Locked: company all-hands (readOnly)",
"start": "2024-01-16T13:00:00",
"end": "2024-01-16T14:00:00",
"color": "red",
"readOnly": True,
},
{
"id": "demo",
"title": "Sprint demo",
"start": "2024-01-18T11:00:00",
"end": "2024-01-18T12:00:00",
"color": "green",
},
]
component = dmc.Stack(
[
dmc.Text(
"Left: a fully read-only calendar (readOnly=True) — no create, move, "
"resize, or delete. Right: an editable calendar where only the red "
"all-hands event is locked via its per-event readOnly key.",
size="sm",
c="dimmed",
),
dmc.SimpleGrid(
cols={"base": 1, "md": 2},
spacing="md",
children=[
dms.EventCalendar(
id="editing-readonly-cal",
events=events,
readOnly=True,
defaultVisibleDate="2024-01-15",
defaultView="week",
height=580,
),
dms.EventCalendar(
id="editing-perevent-cal",
events=events,
defaultVisibleDate="2024-01-15",
defaultView="week",
height=580,
),
],
),
],
gap="sm",
)
To keep events editable but stop new ones from being drawn, set eventCreation=False rather than readOnly=True. readOnly locks everything; eventCreation=False locks creation alone.
EventCalendar props
EventCalendar props
| prop | type | description | |||||
|---|---|---|---|---|---|---|---|
id | string; optional | The id used to identify this component in Dash callbacks. | |||||
areEventsDraggable | boolean; optional | Allow drag-to-reschedule. Default True. | |||||
areEventsResizable | boolean \ | a value equal to: 'start', 'end'; optional | Allow resize (bool, or restrict to "start"/"end"). Default True. | ||||
canDragEventsFromTheOutside | boolean; optional | Allow external events to be dragged in. Default False. | |||||
canDropEventsToTheOutside | boolean; optional | Allow events to be dragged out of the calendar. Default False. | |||||
className | string; optional | CSS class applied to the wrapping div. | |||||
defaultPreferences | dict; optional | Uncontrolled initial preferences (same shape as preferences). defaultPreferences is a dict with keys: - ampm (boolean; optional) - weekStartsOn (a value equal to: 0, 1, 2, 3, 4, 5, 6; optional) - showWeekends (boolean; optional) - showWeekNumber (boolean; optional) - isSidePanelOpen (boolean; optional) - showEmptyDaysInAgenda (boolean; optional) | |||||
defaultView | a value equal to: 'day', 'week', 'month', 'agenda'; optional | Uncontrolled initial view. Default "week". | |||||
defaultVisibleDate | string; optional | Uncontrolled initial visible date (ISO string). Default today. | |||||
defaultVisibleResources | dict; optional | Uncontrolled initial resource visibility map. Default {} (all visible). | |||||
displayTimezone | string; optional | Timezone used to render events: an IANA name ("America/New_York"), or "default" / "locale" / "UTC". Render-only — events keep their own data timezone. Default "default". | |||||
eventColor | a value equal to: 'red', 'pink', 'purple', 'indigo', 'blue', 'teal', 'green', 'lime', 'amber', 'orange', 'grey'; optional | The default color palette used for all events. Overridden per resource (eventColor) and per event (color). Default "teal". | |||||
eventCreation | dict; optional | Configures event creation. False disables it; True enables it with defaults; an object sets the interaction and default duration (minutes). eventCreation is a boolean \ | dict with keys: - interaction (a value equal to: 'click', 'double-click'; optional) - duration (number; optional) | ||||
eventDialogTopOffset | number; optional | On desktop, inset the event drawer this many px from the top — e.g. set it to your fixed app header's height so the drawer lines up with a sidebar instead of covering the header. Default 0. | |||||
eventDialogVariant | a value equal to: 'drawer', 'dialog'; default 'drawer' | How the event editor is presented. "drawer" (default) restyles the built-in dialog into a responsive drawer — right-anchored on desktop, an 80%-height bottom sheet on mobile (below mobileBreakpoint), with a scrollable body and pinned header/actions. "dialog" keeps the library's default floating, draggable dialog. | |||||
events | list of dicts; optional | The events to render. Each event is a dict with at least id, title, start and end (ISO strings). This is BOTH an input and an output: the calendar writes the full array back on every create / edit / move / resize / delete. events is a list of dicts with keys: - id (string \ | number; required): Unique id (string or number). - title (string; required): Event title. - start (string; required): Start date-time, ISO string. "Z" suffix = UTC instant. - end (string; required): End date-time, ISO string. "Z" suffix = UTC instant. - description (string; optional): Optional longer description (shown in the event dialog). - timezone (string; optional): IANA timezone the wall-time start/end are interpreted in. - resource (string \ | number; optional): Id of the resource this event belongs to. - rrule (string \ | dict; optional): Recurrence rule — an RFC-5545 RRULE string ("FREQ=WEEKLY;INTERVAL=2;BYDAY=TH") or an object {freq, interval, byDay, byMonthDay, byMonth, count, until}. Recurrence is a Premium feature (use EventCalendarPremium). - exDates (list of strings; optional): Exception dates (ISO strings) excluded from the recurrence. - allDay (boolean; optional): Whether the event spans the whole day. - readOnly (boolean; optional): Whether the event cannot be edited / dragged / resized. - color (a value equal to: 'red', 'pink', 'purple', 'indigo', 'blue', 'teal', 'green', 'lime', 'amber', 'orange', 'grey'; optional): Event color (overrides resource + component color). - draggable (boolean; optional): Per-event drag override. - resizable (boolean \ | a value equal to: 'start', 'end'; optional): Per-event resize override (bool or which edge). - className (string; optional): Custom CSS class for the event element. - extractedFromId (string \ | number; optional): Id of the event this one was split from. |
height | number \ | string; default 600 | Height of the wrapping container (the calendar fills it). Default 600. | ||||
lastAction | dict; optional | Convenience OUTPUT describing the most recent change to events: {type: "create"\ | "update"\ | "delete"\ | "move"\ | "resize"\ | "change", event: the affected event (or None), event_timestamp}. lastAction is a dict with keys: - type (string; optional) - event (dict; optional) - event_timestamp (number; optional) |
localeText | dict; optional | Override UI label strings (a partial map of translation keys). | |||||
mobileBreakpoint | number; default 768 | Width (px) below which the UI switches to its mobile layout. Default 768. | |||||
preferences | dict; optional | Controlled user preferences. Also an OUTPUT. {ampm, weekStartsOn (0=Sun..6=Sat), showWeekends, showWeekNumber, isSidePanelOpen, showEmptyDaysInAgenda}. preferences is a dict with keys: - ampm (boolean; optional) - weekStartsOn (a value equal to: 0, 1, 2, 3, 4, 5, 6; optional) - showWeekends (boolean; optional) - showWeekNumber (boolean; optional) - isSidePanelOpen (boolean; optional) - showEmptyDaysInAgenda (boolean; optional) | |||||
preferencesMenuConfig | dict; optional | Which items appear in the preferences menu, or False to hide the menu. preferencesMenuConfig is a a value equal to: false \ | dict with keys: - toggleWeekendVisibility (boolean; optional) - toggleWeekNumberVisibility (boolean; optional) - toggleAmpm (boolean; optional) - toggleEmptyDaysInAgenda (boolean; optional) - toggleWeekStartsOn (boolean; optional) | ||||
readOnly | boolean; optional | Global read-only mode (disables create / drag / resize / dialog). | |||||
resources | list of dicts; optional | Resources events can be assigned to (supports nested children). | |||||
responsiveSidePanel | boolean; default True | When True (default), the side panel starts open on wide screens and collapsed below mobileBreakpoint on first render — unless you pin isSidePanelOpen via preferences / defaultPreferences. | |||||
scrollToCurrentTime | boolean; default False | In the day / week views, scroll the time grid on first render (and on view change) so the current-time indicator is centered in view. Pairs with showCurrentTimeIndicator. Default False. | |||||
shouldEventRequireResource | boolean; optional | Require every event to be assigned to a resource. Default False. | |||||
showCurrentTimeIndicator | boolean; optional | Show the current-time indicator line in time views. Default True. | |||||
sx | dict; optional | MUI sx styling object applied to the calendar (object form only). | |||||
view | a value equal to: 'day', 'week', 'month', 'agenda'; optional | Controlled active view. Also an OUTPUT (updated on view change). | |||||
views | list of a value equal to: 'day', 'week', 'month', 'agenda's; optional | Which views are offered. Default ["day","week","month","agenda"]. | |||||
visibleDate | string; optional | Controlled visible date (ISO string). Drives which date range is shown. Also an OUTPUT — written back (ISO string) when the user navigates. | |||||
visibleResources | dict; optional | Controlled resource visibility map {resourceId: bool}. Also an OUTPUT. |
Source: /editing
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:
- /editing/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt