# Events > Define calendar events as plain dictionaries with ISO-string dates — including colors, all-day events, and creation controls. --- .. llms_copy::Events .. toc:: ### Events An event is just a Python `dict`. You pass a list of them to the `events` prop, and the calendar renders one block per event. Dates cross the boundary as **ISO strings**, never Python `datetime` objects. The `events` prop is both an **input and an output**: when a user creates, moves, resizes, or deletes an event, the component writes the *entire* new array back to `events`. You don't diff anything yourself — read `events` for the full picture, or read `lastAction` for just-what-changed. .. exec::docs.events.events_basic ```python # File: docs/events/events_basic.py import dash_mui_scheduler as dms from dash import html, dcc, Input, Output, callback # Each event is a plain dict. Dates are ISO strings (no "Z" = wall time). # Required keys: id, title, start, end. Everything else is optional. events = [ { "id": "kickoff", "title": "Project Kickoff", "start": "2024-01-15T09:00:00", "end": "2024-01-15T10:00:00", "description": "Align on goals for the quarter.", }, { "id": "standup", "title": "Daily Standup", "start": "2024-01-16T09:30:00", "end": "2024-01-16T09:45:00", }, { "id": "review", "title": "Design Review", "start": "2024-01-17T14:00:00", "end": "2024-01-17T15:30:00", "description": "Walk through the new dashboard mockups.", }, { "id": "1on1", "title": "1:1", "start": "2024-01-18T11:00:00", "end": "2024-01-18T11:30:00", }, ] component = html.Div( [ dms.EventCalendar( id="events-basic-cal", events=events, defaultVisibleDate="2024-01-15", height=600, ), dcc.Markdown(id="events-basic-out", style={"marginTop": "0.75rem"}), ] ) @callback( Output("events-basic-out", "children"), Input("events-basic-cal", "events"), ) def show_count(current_events): return f"**{len(current_events or [])}** events currently on the calendar." ``` The callback above only *reads* `events` to display a count. The calendar is fully interactive **without any callback** — drag, create, and delete all persist on their own through Dash's normal `setProps` round-trip. Add a callback only when you want to *display* an output (`events`, `lastAction`, `view`, or `visibleDate`). ### Event fields Every event needs four required keys; the rest are optional. | Key | Type | Notes | |---|---|---| | `id` | str \| int | Unique per event. **Required.** | | `title` | str | Shown on the event block. **Required.** | | `start` | ISO str | e.g. `"2024-01-15T10:00:00"`. **Required.** | | `end` | ISO str | e.g. `"2024-01-15T11:00:00"`. **Required.** | | `description` | str | Free-text shown in the event dialog. | | `resource` | str | Id of a resource this event belongs to. | | `allDay` | bool | Render in the all-day row (see below). | | `color` | str | One of the 11 palette names (see below). | | `timezone` | str | IANA name, e.g. `"America/New_York"`. | | `draggable` | bool | Override drag for this one event. | | `resizable` | bool \| `'start'` \| `'end'` | Override resize for this one event. | | `readOnly` | bool | Make this event non-editable. | | `className` | str | CSS class on the event element. | .. admonition::ISO strings, not datetimes :color: yellow Dates must be ISO **strings**. A string without a `Z` suffix (`"2024-01-15T10:00:00"`) is treated as wall-clock time; a string with `Z` (`"2024-01-15T10:00:00Z"`) is UTC. Never pass a Python `datetime` — it is not JSON-serializable across the Dash boundary. ### Colors Set a per-event `color` to any of the **11 palette names**: `red` · `pink` · `purple` · `indigo` · `blue` · `teal` *(default)* · `green` · `lime` · `amber` · `orange` · `grey` The calendar-wide `eventColor` prop sets the default color for any event that does **not** carry its own `color` key. A per-event `color` always overrides `eventColor`. .. exec::docs.events.event_colors ```python # File: docs/events/event_colors.py import dash_mui_scheduler as dms from dash import html # The 11-color palette. Set a per-event "color" with any of these names. PALETTE = [ "red", "pink", "purple", "indigo", "blue", "teal", "green", "lime", "amber", "orange", "grey", ] # One event per palette color, laid across the week so each is visible. events = [] for i, name in enumerate(PALETTE): day = 15 + (i % 5) # Mon–Fri of the week of 2024-01-15 hour = 8 + (i // 5) * 3 # stagger rows so they don't overlap events.append( { "id": f"color-{name}", "title": name.capitalize(), "start": f"2024-01-{day:02d}T{hour:02d}:00:00", "end": f"2024-01-{day:02d}T{hour:02d}:45:00", "color": name, } ) # This event has no "color" of its own, so it falls back to eventColor below. events.append( { "id": "color-default", "title": "Uses eventColor", "start": "2024-01-19T13:00:00", "end": "2024-01-19T14:00:00", } ) component = html.Div( dms.EventCalendar( id="events-colors-cal", events=events, # eventColor is the calendar-wide default for any event without its # own "color" key. Per-event "color" always wins over this. eventColor="purple", defaultVisibleDate="2024-01-15", height=620, ) ) ``` ### All-day events Mark an event `allDay: True` to place it in the calendar's all-day row, spanning whole days instead of a time slot. All-day and timed events mix freely in the same `events` list. .. exec::docs.events.all_day ```python # File: docs/events/all_day.py import dash_mui_scheduler as dms from dash import html # allDay events render in the calendar's all-day row, spanning whole days. # Mix them freely with ordinary timed events. events = [ # All-day events: allDay=True. The time portion of start/end is ignored, # but keep them as valid ISO strings. end is exclusive of its last instant, # so a single-day all-day event ends the same day. { "id": "allday-holiday", "title": "Company Holiday", "start": "2024-01-15T00:00:00", "end": "2024-01-15T23:59:59", "allDay": True, "color": "green", }, { "id": "allday-conference", "title": "Conference (3 days)", "start": "2024-01-17T00:00:00", "end": "2024-01-19T23:59:59", "allDay": True, "color": "indigo", }, # Ordinary timed events sit in the day grid below the all-day row. { "id": "allday-call", "title": "Client Call", "start": "2024-01-16T10:00:00", "end": "2024-01-16T10:30:00", "color": "blue", }, { "id": "allday-lunch", "title": "Team Lunch", "start": "2024-01-18T12:00:00", "end": "2024-01-18T13:00:00", "color": "amber", }, ] component = html.Div( dms.EventCalendar( id="events-allday-cal", events=events, defaultVisibleDate="2024-01-15", height=600, ) ) ``` .. admonition::All-day spans :color: blue For an all-day event the time portion of `start`/`end` is ignored, but keep them as valid ISO strings. A multi-day span (`"2024-01-17"` → `"2024-01-19"`) shows as a single bar across those days. ### Controlling creation The `eventCreation` prop decides whether — and how — users can create new events by interacting with empty space. - **`eventCreation=True`** *(default)* — creation is on with the component's default gesture. - **`eventCreation=False`** — disable click/drag-to-create entirely (existing events can still be edited unless you also set `readOnly=True`). - **`eventCreation={...}`** — fine-tune the gesture with two keys: - `interaction`: `'click'` or `'double-click'` — how a new event is started. - `duration`: minutes (int) — the length of an event created by a single click. ```python # A double-click creates a 30-minute event in empty space. dms.EventCalendar( id="events-creation-cal", events=events, eventCreation={"interaction": "double-click", "duration": 30}, defaultVisibleDate="2024-01-15", height=600, ) ``` When a user creates an event, the new block is appended to `events` and `lastAction` reports `{"type": "create", "event": {...}, "event_timestamp": ...}`. ### EventCalendar props .. kwargs::dash_mui_scheduler.EventCalendar --- *Source: /events*