# Playground

> Drive the major Event Calendar props live with Dash Mantine Components inputs.

**Site index:** [https://muischeduler.2plot.dev/llms.txt](https://muischeduler.2plot.dev/llms.txt) — every page on this site, as Markdown.  
**Network index:** [https://2plot.dev/llms.txt](https://2plot.dev/llms.txt) — The 2plot network; start here to discover sibling sites.  
**Sibling sites:** 13 more in The 2plot network — listed in the site index above.  
**Sitemap:** https://muischeduler.2plot.dev/sitemap.xml  


---



### Try the props live

Every control below is a plain **Dash Mantine Components** input wired to an
`EventCalendar` prop with a normal Dash callback — change one and the calendar
updates instantly. It doubles as a demonstration of how `dash-mui-scheduler`
**pairs with DMC**: the calendar follows the Mantine color scheme (toggle dark
mode in the header), and DMC `Select` / `Switch` / `SegmentedControl` inputs map
cleanly onto the scheduler's props.



    Each input drives a prop through a callback — e.g. a `dmc.SegmentedControl`
    sets `view`, a `dmc.Select` sets `eventColor` / `displayTimezone`, and the
    six preference `dmc.Switch`es are collected into the `preferences` dict.
    `view` is two-way bound, so clicking the calendar's own view buttons keeps
    the control in sync. The `lastAction` output feeds the readout under the
    calendar.

### Source


```python
# File: docs/playground/playground.py

import datetime

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

# A live playground: every Dash Mantine Components input below is wired to a
# major EventCalendar prop, so you can see exactly how each one behaves. This is
# also a demonstration of how dash-mui-scheduler pairs with DMC — the calendar
# follows the Mantine color scheme, and DMC inputs drive its props.

# Anchor events to *today* (with UTC "Z" instants) so the Display controls have
# something to act on:
#   - the current-time line is visible (we are looking at this week),
#   - `displayTimezone` shifts the rendered times (Z instants are re-projected),
#   - and with NO per-event `color`, `eventColor` recolours every event live
#     (a per-event color would otherwise override the component default).
_TODAY = datetime.date.today()


def _ev(eid, title, day_offset, hour, minute, dur_min):
    start = datetime.datetime.combine(
        _TODAY + datetime.timedelta(days=day_offset), datetime.time(hour, minute)
    )
    end = start + datetime.timedelta(minutes=dur_min)
    fmt = "%Y-%m-%dT%H:%M:%SZ"  # trailing Z = UTC instant
    return {"id": eid, "title": title, "start": start.strftime(fmt), "end": end.strftime(fmt)}


EVENTS = [
    _ev("1", "Standup", 0, 13, 0, 30),
    _ev("2", "Design review", 0, 15, 30, 60),
    _ev("3", "Workshop", 1, 14, 0, 90),
    _ev("4", "1:1", 2, 16, 0, 30),
    _ev("5", "Retro", -1, 17, 0, 60),
]

COLORS = ["red", "pink", "purple", "indigo", "blue", "teal", "green", "lime", "amber", "orange", "grey"]
WEEKDAYS = [
    {"label": "Sunday", "value": "0"}, {"label": "Monday", "value": "1"}, {"label": "Tuesday", "value": "2"},
    {"label": "Wednesday", "value": "3"}, {"label": "Thursday", "value": "4"}, {"label": "Friday", "value": "5"},
    {"label": "Saturday", "value": "6"},
]
TIMEZONES = ["default", "UTC", "America/New_York", "Europe/Paris", "Asia/Tokyo"]


def _labeled(label, control):
    return dmc.Stack([dmc.Text(label, size="sm", fw=600), control], gap=4)


_controls = dmc.SimpleGrid(
    cols={"base": 1, "md": 2},
    spacing="lg",
    children=[
        dmc.Fieldset(
            legend="View & creation",
            children=dmc.Stack([
                _labeled("View", dmc.SegmentedControl(id="pg-view", value="week", fullWidth=True, data=[
                    {"label": "Day", "value": "day"}, {"label": "Week", "value": "week"},
                    {"label": "Month", "value": "month"}, {"label": "Agenda", "value": "agenda"}])),
                _labeled("Event editor", dmc.SegmentedControl(id="pg-dialog", value="drawer", data=[
                    {"label": "Drawer", "value": "drawer"}, {"label": "Dialog", "value": "dialog"}])),
                dmc.Switch(id="pg-creation", label="Allow event creation", checked=True),
            ], gap="sm"),
        ),
        dmc.Fieldset(
            legend="Interaction",
            children=dmc.Stack([
                dmc.Switch(id="pg-drag", label="Events draggable", checked=True),
                _labeled("Resizable", dmc.SegmentedControl(id="pg-resize", value="true", data=[
                    {"label": "Both", "value": "true"}, {"label": "Start", "value": "start"},
                    {"label": "End", "value": "end"}, {"label": "Off", "value": "false"}])),
                dmc.Switch(id="pg-readonly", label="Read-only", checked=False),
            ], gap="sm"),
        ),
        dmc.Fieldset(
            legend="Display",
            children=dmc.Stack([
                dmc.Select(id="pg-color", label="Default event color", value="teal", data=COLORS, allowDeselect=False),
                dmc.Select(id="pg-tz", label="Display timezone", value="default", data=TIMEZONES, allowDeselect=False),
                dmc.Switch(id="pg-nowline", label="Current-time line", checked=True),
                dmc.Switch(id="pg-scrollnow", label="Scroll to current time on load", checked=False),
            ], gap="sm"),
        ),
        dmc.Fieldset(
            legend="Preferences",
            children=dmc.Stack([
                dmc.Group([
                    dmc.Switch(id="pg-ampm", label="12-hour clock", checked=True),
                    dmc.Switch(id="pg-weekends", label="Weekends", checked=True),
                ], gap="lg"),
                dmc.Group([
                    dmc.Switch(id="pg-weeknum", label="Week numbers", checked=False),
                    dmc.Switch(id="pg-sidepanel", label="Side panel", checked=True),
                ], gap="lg"),
                dmc.Switch(id="pg-emptyagenda", label="Empty days in agenda", checked=True),
                dmc.Select(id="pg-weekstart", label="Week starts on", value="0", data=WEEKDAYS, allowDeselect=False),
            ], gap="sm"),
        ),
    ],
)

component = dmc.Stack(
    [
        dmc.Paper(_controls, withBorder=True, p="md", radius="md"),
        dms.EventCalendar(
            id="playground-cal",
            events=EVENTS,
            defaultVisibleDate=_TODAY.isoformat(),
            height=620,
            view="week",
            eventColor="teal",
            displayTimezone="default",
            areEventsDraggable=True,
            areEventsResizable=True,
            readOnly=False,
            eventCreation=True,
            showCurrentTimeIndicator=True,
            scrollToCurrentTime=False,
            eventDialogVariant="drawer",
            preferences={"ampm": True, "weekStartsOn": 0, "showWeekends": True,
                         "showWeekNumber": False, "isSidePanelOpen": True, "showEmptyDaysInAgenda": True},
        ),
        dmc.Code(id="pg-readout", block=True),
    ],
    gap="md",
)


# --- View (two-way: control <-> the calendar's own view buttons) ------------
@callback(Output("playground-cal", "view"), Input("pg-view", "value"), prevent_initial_call=True)
def set_view(value):
    return value


@callback(Output("pg-view", "value"), Input("playground-cal", "view"), prevent_initial_call=True)
def read_view(value):
    return value


# --- Display / interaction / editor settings --------------------------------
@callback(
    Output("playground-cal", "eventColor"),
    Output("playground-cal", "displayTimezone"),
    Output("playground-cal", "showCurrentTimeIndicator"),
    Output("playground-cal", "scrollToCurrentTime"),
    Output("playground-cal", "areEventsDraggable"),
    Output("playground-cal", "areEventsResizable"),
    Output("playground-cal", "readOnly"),
    Output("playground-cal", "eventCreation"),
    Output("playground-cal", "eventDialogVariant"),
    Input("pg-color", "value"),
    Input("pg-tz", "value"),
    Input("pg-nowline", "checked"),
    Input("pg-scrollnow", "checked"),
    Input("pg-drag", "checked"),
    Input("pg-resize", "value"),
    Input("pg-readonly", "checked"),
    Input("pg-creation", "checked"),
    Input("pg-dialog", "value"),
)
def settings(color, tz, nowline, scroll_now, drag, resize, read_only, creation, dialog):
    resize_val = {"true": True, "false": False, "start": "start", "end": "end"}[resize]
    return color, tz, nowline, scroll_now, drag, resize_val, read_only, creation, dialog


# --- Preferences ------------------------------------------------------------
@callback(
    Output("playground-cal", "preferences"),
    Input("pg-ampm", "checked"),
    Input("pg-weekstart", "value"),
    Input("pg-weekends", "checked"),
    Input("pg-weeknum", "checked"),
    Input("pg-sidepanel", "checked"),
    Input("pg-emptyagenda", "checked"),
)
def preferences(ampm, week_start, weekends, week_number, side_panel, empty_agenda):
    return {
        "ampm": ampm,
        "weekStartsOn": int(week_start),
        "showWeekends": weekends,
        "showWeekNumber": week_number,
        "isSidePanelOpen": side_panel,
        "showEmptyDaysInAgenda": empty_agenda,
    }


# --- Live readout -----------------------------------------------------------
@callback(
    Output("pg-readout", "children"),
    Input("playground-cal", "events"),
    Input("playground-cal", "lastAction"),
)
def readout(events, last_action):
    count = len(events or [])
    if not last_action:
        return f"{count} events · interact with the calendar to see the last action"
    title = (last_action.get("event") or {}).get("title")
    suffix = f" — {title}" if title else ""
    return f"{count} events · last action: {last_action.get('type')}{suffix}"
```

    :defaultExpanded: false
    :withExpandedButton: true

### All Event Calendar 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: /playground*
