The three commands and ten props no other example reaches — the leftovers of the prop surface, in one runnable place.

Coverage

The three commands and ten props no other example reaches — the leftovers of the prop surface, in one runnable place.


Why this page exists

Every other page here demonstrates a feature. This one covers the leftovers.

The component ships 38 props and 12 command types. Sweeping every example module for the commands it dispatches — both the {"type": "X"} dict form and the _cmd("X", …) helper form — and for every prop reached either as a constructor keyword or through an Input/Output/State, three commands and ten props came back untouched. A reader could find them in the component reference and nowhere else.

That is the gap this page closes. It is not a tutorial; it is the part of the surface that would otherwise be documented only as a table row.

The three commands

typeWhat it does hereHow you see it
addFilesRegisters one 1×1 PNG as raw BinaryFileDataThe readout's registered file ids grows
exportToCanvasExports the scene through a canvas elementThe preview appears, tagged with the dispatched id
updateLibraryMerges a two-rectangle item into the libraryThe library panel opens with the item in it

addFiles registers bytes, not a visible element. Excalidraw draws an image only when a scene element references the file id, so the file appearing in the readout while the canvas stays empty is correct, not a failure — see File uploads for the flow that pairs the two.

exportToCanvas returns a data: URL, where exportToSvg returns markup. Both land on lastExport carrying the id you dispatched, which is what lets you tell two in-flight exports apart. Export round-trip covers the correlation.

The ten props

PropDefaultWhat it doesLive?
langCode"en"Excalidraw's UI languageYes
name(unset)Scene name, used by the export dialogYes
width"100%"CSS width of the containerYes
detectScrollTrueCanvas handles wheel eventsYes
handleKeyboardGloballyTrueKey handling on document, not the canvasYes
hideExcalidrawLinksTrueHides the GitHub/Discord/X menu groupOne-way — see below
autoFocusTrueFocus the canvas on mountMount only
libraryReturnUrl(unset)Where the Browse Library trip returns toMount only, in effect
appStateFull serializable app stateRead-only
sceneVersionMonotonic scene counterRead-only

autoFocus is read by Excalidraw when the canvas mounts. A switch for it would be theatre — this page sets it to False and that takes effect on page load, nowhere else. Reload to change it.

appState and sceneVersion are written out by the component. Setting them from Python does nothing; the readout on the right is what they are for. sceneVersion is a single integer and far cheaper to compare than diffing elements, which is the reason it exists.

One thing that does not turn off again

hideExcalidrawLinks is one-way within a page load. Switching it on injects a stylesheet; switching it back off does not remove it, so the links stay hidden until you reload.

That is deliberate in the sense that the stylesheet is shared by every canvas on the page — removing it for one component would unhide the links under all of them — but the effect is that the prop is not symmetric, and nothing in the API says so. Set it once at mount and treat it as fixed; if you need the links back, reload with hideExcalidrawLinks=False.

The switch below is left live rather than disabled, because watching it fail to reverse is a more useful thing to know than being prevented from trying.

Live demo

Source

# File: docs/coverage/coverage.py

"""Coverage: the three commands and ten props no other example page reaches.

Measured, not guessed — an AST sweep of every `docs/*/*.py` for command types
(both the `{"type": "X"}` dict literal and the `_cmd("X", ...)` helper form)
and for props reached via a constructor kwarg or an Input/Output/State
dependency. What was left over is what this page exists to exercise.
"""

import time
import uuid

import dash_mantine_components as dmc
from dash import Input, Output, State, callback, html, no_update

from dash_excalidraw import DashExcalidraw
from docs._shared import canvas_frame, code_block, json_panel, sync_canvas_theme, two_column

sync_canvas_theme("coverage-canvas")

# A real 1x1 PNG. Small enough to read inline, valid enough that Excalidraw
# accepts it as BinaryFileData rather than silently dropping the entry.
PNG_1PX = (
    "data:image/png;base64,"
    "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8"
    "z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
)

CODE = """
# The three commands no other page dispatches.

# addFiles — RAW BinaryFileData list. You supply `created` and `mimeType`;
# an entry missing either is ignored, so a bad payload is a silent no-op.
{'id': cmd_id, 'type': 'addFiles',
 'payload': [{'id': file_id, 'mimeType': 'image/png',
              'dataURL': PNG_1PX, 'created': int(time.time() * 1000)}]}

# exportToCanvas — async; the result arrives on `lastExport`, carrying the
# id you dispatched. A data: URL, not an SVG string.
{'id': cmd_id, 'type': 'exportToCanvas', 'payload': {'mimeType': 'image/png'}}

# updateLibrary — merge items into the user's library.
{'id': cmd_id, 'type': 'updateLibrary',
 'payload': {'libraryItems': [item], 'merge': True, 'openLibraryMenu': True}}
"""


def _rect(x: int, y: int, colour: str, bg: str) -> dict:
    now = int(time.time())
    return {
        "id": f"cov-{uuid.uuid4()}",
        "type": "rectangle",
        "x": x,
        "y": y,
        "width": 120,
        "height": 80,
        "angle": 0,
        "strokeColor": colour,
        "backgroundColor": bg,
        "fillStyle": "solid",
        "strokeWidth": 2,
        "roughness": 1,
        "opacity": 100,
        "seed": now % 100000,
        "version": 1,
        "versionNonce": now % 100000,
        "isDeleted": False,
        "groupIds": [],
        "frameId": None,
        "boundElements": [],
        "updated": 1,
        "link": None,
        "locked": False,
    }


def _btn(btn_id: str, label: str, colour: str) -> dmc.Button:
    return dmc.Button(label, id=btn_id, color=colour, size="sm", variant="light")


LANGS = ["en", "fr-FR", "de-DE", "zh-CN", "es-ES"]

controls = dmc.Paper(
    withBorder=True,
    p="md",
    radius="md",
    children=dmc.Stack(
        gap="sm",
        children=[
            dmc.Text("Props no other page sets", size="sm", fw=600, c="dimmed"),
            dmc.SimpleGrid(
                cols={"base": 1, "sm": 2, "md": 3},
                spacing="sm",
                children=[
                    dmc.Select(
                        id="cov-lang",
                        label="langCode",
                        description="Excalidraw UI language",
                        data=LANGS,
                        value="en",
                        size="xs",
                    ),
                    dmc.Select(
                        id="cov-name",
                        label="name",
                        description="Scene name in the export dialog",
                        data=["coverage-scene", "renamed-scene"],
                        value="coverage-scene",
                        size="xs",
                    ),
                    dmc.Select(
                        id="cov-width",
                        label="width",
                        description="CSS width of the container",
                        data=["100%", "75%", "50%"],
                        value="100%",
                        size="xs",
                    ),
                    dmc.Switch(
                        id="cov-detectscroll",
                        label="detectScroll",
                        description="Canvas handles wheel events",
                        checked=True,
                        size="sm",
                    ),
                    dmc.Switch(
                        id="cov-keyboard",
                        label="handleKeyboardGlobally",
                        description="Key handling on document, not canvas",
                        checked=True,
                        size="sm",
                    ),
                    dmc.Switch(
                        id="cov-hidelinks",
                        label="hideExcalidrawLinks",
                        description="Hides the GitHub/Discord/X menu group",
                        checked=True,
                        size="sm",
                    ),
                ],
            ),
        ],
    ),
)

component = dmc.Stack(
    gap="md",
    children=[
        dmc.Alert(
            color="blue",
            variant="light",
            title="What this page is for",
            children=(
                "Every other example page demonstrates a feature. This one "
                "exists to cover the leftovers: the three command types and "
                "ten props that no other page reaches. If a prop is listed "
                "in the component reference but you cannot find it exercised "
                "anywhere, it is here."
            ),
        ),
        code_block(CODE),
        dmc.Group(
            gap="sm",
            children=[
                _btn("cov-addfiles", "addFiles", "grape"),
                _btn("cov-exportcanvas", "exportToCanvas", "teal"),
                _btn("cov-updatelibrary", "updateLibrary", "indigo"),
            ],
        ),
        controls,
        two_column(
            canvas_frame(
                DashExcalidraw(
                    id="coverage-canvas",
                    height="520px",
                    width="100%",
                    name="coverage-scene",
                    langCode="en",
                    detectScroll=True,
                    handleKeyboardGlobally=True,
                    hideExcalidrawLinks=True,
                    # autoFocus is read by Excalidraw at MOUNT only, so a
                    # switch for it would be theatre — it is set here and
                    # takes effect on page load, nowhere else.
                    autoFocus=False,
                    # Only observable by taking the Browse Library round trip;
                    # it is where that trip returns to.
                    libraryReturnUrl="https://excalidraw.2plot.dev/coverage",
                )
            ),
            dmc.Stack(
                gap="sm",
                children=[
                    html.Div(id="cov-readout"),
                    html.Div(id="cov-export-out"),
                ],
            ),
        ),
    ],
)


@callback(
    Output("coverage-canvas", "langCode"),
    Output("coverage-canvas", "name"),
    Output("coverage-canvas", "width"),
    Output("coverage-canvas", "detectScroll"),
    Output("coverage-canvas", "handleKeyboardGlobally"),
    Output("coverage-canvas", "hideExcalidrawLinks"),
    Input("cov-lang", "value"),
    Input("cov-name", "value"),
    Input("cov-width", "value"),
    Input("cov-detectscroll", "checked"),
    Input("cov-keyboard", "checked"),
    Input("cov-hidelinks", "checked"),
)
def _drive_props(lang, name, width, detect, keyboard, hidelinks):
    return lang, name, width, bool(detect), bool(keyboard), bool(hidelinks)


@callback(
    Output("coverage-canvas", "command"),
    Input("cov-addfiles", "n_clicks"),
    Input("cov-exportcanvas", "n_clicks"),
    Input("cov-updatelibrary", "n_clicks"),
    prevent_initial_call=True,
)
def _dispatch(_add, _export, _library):
    import dash

    trigger = dash.ctx.triggered_id
    cmd_id = str(uuid.uuid4())

    if trigger == "cov-addfiles":
        return {
            "id": cmd_id,
            "type": "addFiles",
            "payload": [
                {
                    "id": f"cov-file-{cmd_id[:8]}",
                    "mimeType": "image/png",
                    "dataURL": PNG_1PX,
                    "created": int(time.time() * 1000),
                }
            ],
        }

    if trigger == "cov-exportcanvas":
        return {
            "id": cmd_id,
            "type": "exportToCanvas",
            "payload": {"mimeType": "image/png"},
        }

    if trigger == "cov-updatelibrary":
        return {
            "id": cmd_id,
            "type": "updateLibrary",
            "payload": {
                "libraryItems": [
                    {
                        "id": f"cov-lib-{cmd_id[:8]}",
                        "status": "unpublished",
                        "created": int(time.time() * 1000),
                        "elements": [
                            _rect(100, 100, "#5f3dc4", "#d0bfff"),
                            _rect(240, 100, "#0b7285", "#99e9f2"),
                        ],
                    }
                ],
                "merge": True,
                "openLibraryMenu": True,
            },
        }

    return no_update


@callback(
    Output("cov-readout", "children"),
    Input("coverage-canvas", "sceneVersion"),
    State("coverage-canvas", "appState"),
    State("coverage-canvas", "files"),
)
def _readout(scene_version, app_state, files):
    state = app_state or {}
    return json_panel(
        "sceneVersion + appState (both read-only)",
        {
            "sceneVersion": scene_version,
            "registered file ids": sorted((files or {}).keys()),
            "appState.zoom": (state.get("zoom") or {}).get("value"),
            "appState.scrollX": state.get("scrollX"),
            "appState.scrollY": state.get("scrollY"),
            "appState.viewBackgroundColor": state.get("viewBackgroundColor"),
            "appState.activeTool": (state.get("activeTool") or {}).get("type"),
        },
        height=200,
    )


@callback(
    Output("cov-export-out", "children"),
    Input("coverage-canvas", "lastExport"),
    prevent_initial_call=True,
)
def _show_export(export):
    if not export:
        return no_update
    if export.get("error"):
        return dmc.Alert(
            f"{export['type']} (id {export['id']}) failed: {export['error']}",
            color="red",
            variant="light",
        )
    result = export.get("result") or ""
    return dmc.Stack(
        gap="xs",
        children=[
            dmc.Text(
                f"lastExport carries id {export.get('id')} for {export.get('type')}",
                size="sm",
                fw=600,
            ),
            dmc.Image(src=result, h=120, fit="contain")
            if result.startswith("data:image")
            else dmc.Code(result[:200], block=True),
        ],
    )

:defaultExpanded: false :withExpandedButton: true


Source: /coverage

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: