AgentSkillsCN

dmc-py

为使用 Dash Mantine Components (DMC) v2.4.0 构建 Dash 应用提供专业指导。 适用于使用 DMC 创建仪表板、表单、数据可视化应用。 涵盖:MantineProvider 主题化、样式属性(m、p、c、bg、w、h)、Styles API, 回调函数(基础回调、模式匹配 ALL/MATCH/ALLSMALLER、客户端回调、后台回调), 支持多页面 Dash 应用、各类图表(折线图、柱状图、甜甜圈图), 日期选择器、模态框,以及全部 90 多种组件。 触发条件:dash-mantine-components、DMC、MantineProvider、dmc.Button、dmc.Select, dmc.Modal、dmc.BarChart、Mantine 主题、Dash UI 组件、Dash 回调函数, 多页面 Dash 应用、模式匹配回调、客户端回调、AppShell。

SKILL.md
--- frontmatter
name: dmc-py
description: |
  Expert guidance for building Dash applications with Dash Mantine Components (DMC) v2.4.0.
  Use when creating dashboards, forms, data visualization apps with DMC.
  Covers: MantineProvider theming, style props (m, p, c, bg, w, h), Styles API,
  callbacks (basic, pattern-matching ALL/MATCH/ALLSMALLER, clientside, background),
  multi-page apps with Dash Pages, charts (LineChart, BarChart, DonutChart),
  date pickers, modals, and all 90+ components.
  Triggers on: dash-mantine-components, DMC, MantineProvider, dmc.Button, dmc.Select,
  dmc.Modal, dmc.BarChart, Mantine theme, Dash UI components, Dash callbacks,
  multi-page Dash app, pattern-matching callbacks, clientside callbacks, AppShell.

Dash Mantine Components (DMC) v2.4.0

Build modern Dash applications with 90+ Mantine UI components.

Quick Start

Minimal DMC app requiring MantineProvider wrapper:

python
from dash import Dash, callback, Input, Output
import dash_mantine_components as dmc

app = Dash(__name__)

app.layout = dmc.MantineProvider([
    dmc.Container([
        dmc.Title("My DMC App", order=1),
        dmc.TextInput(label="Name", id="name-input", placeholder="Enter name"),
        dmc.Button("Submit", id="submit-btn", mt="md"),
        dmc.Text(id="output", mt="md"),
    ], size="sm", py="xl")
])

@callback(Output("output", "children"), Input("submit-btn", "n_clicks"), Input("name-input", "value"))
def update_output(n_clicks, name):
    if not n_clicks:
        return ""
    return f"Hello, {name or 'World'}!"

if __name__ == "__main__":
    app.run(debug=True)

Critical: All DMC components MUST be inside dmc.MantineProvider.


Workflow Decision Tree

Select components by use case:

Form Inputs

NeedComponentKey Props
Text inputTextInputlabel, placeholder, value, debounce
DropdownSelectdata, value, searchable, clearable
Multi-selectMultiSelectdata, value, searchable
CheckboxCheckboxlabel, checked
ToggleSwitchlabel, checked, onLabel, offLabel
NumberNumberInputvalue, min, max, step
DateDatePickerInputvalue, type, minDate, maxDate
Rich textTextarealabel, value, autosize, minRows
File uploadFileInputvalue, accept, multiple

Layout

NeedComponentKey Props
Content wrapperContainersize, px, py
Vertical stackStackgap, align, justify
Horizontal rowGroupgap, justify, wrap
CSS GridGrid, GridColcolumns, gutter, span
Full app shellAppShellheader, navbar, aside, footer
Card containerCardshadow, padding, radius, withBorder
Flex layoutFlexdirection, wrap, gap, align

Navigation

NeedComponentKey Props
Nav itemNavLinklabel, href, active, leftSection
TabsTabs, TabsList, TabsPanelvalue, orientation
BreadcrumbBreadcrumbsseparator
StepperStepper, StepperStepactive, onStepClick
PaginationPaginationvalue, total, siblings

Feedback & Overlays

NeedComponentKey Props
Modal dialogModalopened, onClose, title, centered
Side panelDraweropened, onClose, position, size
ToastNotificationtitle, message, color, icon
Alert bannerAlerttitle, color, variant, icon
LoadingLoader, LoadingOverlaysize, type, visible
ProgressProgress, RingProgressvalue, size, sections
TooltipTooltiplabel, position, withArrow

Data Display

NeedComponentKey Props
Data tableTabledata, striped, highlightOnHover
AccordionAccordion, AccordionItemvalue, multiple, variant
TimelineTimeline, TimelineItemactive, bulletSize
BadgeBadgecolor, variant, size

Charts

NeedComponentKey Props
LineLineChartdata, dataKey, series
BarBarChartdata, dataKey, series, orientation
AreaAreaChartdata, dataKey, series
Pie/DonutDonutChart, PieChartdata, chartLabel
ScatterScatterChartdata, dataKey, series

→ Full component reference: references/components-quick-ref.md


Core Patterns

Theming

Configure theme via MantineProvider:

python
theme = {
    "primaryColor": "blue",
    "fontFamily": "Inter, sans-serif",
    "defaultRadius": "md",
    "colors": {
        "brand": ["#f0f9ff", "#e0f2fe", "#bae6fd", "#7dd3fc", "#38bdf8",
                  "#0ea5e9", "#0284c7", "#0369a1", "#075985", "#0c4a6e"]
    },
    "components": {
        "Button": {"defaultProps": {"size": "md", "radius": "md"}},
        "TextInput": {"defaultProps": {"size": "sm"}},
    }
}

app.layout = dmc.MantineProvider(
    theme=theme,
    forceColorScheme="light",  # or "dark", or None for auto
    children=[...]
)

Theme Toggle Pattern (clientside callback):

python
from dash import clientside_callback, ClientsideFunction

app.layout = dmc.MantineProvider(
    id="mantine-provider",
    children=[
        dcc.Store(id="theme-store", storage_type="local", data="light"),
        dmc.Switch(id="theme-switch", label="Dark mode", checked=False),
        # ... rest of layout
    ]
)

clientside_callback(
    """(checked) => checked ? "dark" : "light" """,
    Output("mantine-provider", "forceColorScheme"),
    Input("theme-switch", "checked"),
)

→ Full theming guide: references/theming-patterns.md

Styling

Style Props - Universal props on all DMC components:

PropCSS PropertyValues
m, mt, mb, ml, mr, mx, mymarginxs, sm, md, lg, xl or number (px)
p, pt, pb, pl, pr, px, pypaddingsame as margin
ccolor"blue", "red.6", "dimmed", "var(--mantine-color-text)"
bgbackgroundsame as color
w, hwidth, height"100%", "50vw", number (px)
maw, mah, miw, mihmax/min width/heightsame as w, h
fwfont-weight400, 500, 700
fzfont-sizexs, sm, md, lg, xl or number
tatext-align"left", "center", "right"
tdtext-decoration"underline", "line-through"

Responsive Values - Dict with breakpoints:

python
dmc.Button("Click", w={"base": "100%", "sm": "auto", "lg": 200})
dmc.Stack(gap={"base": "xs", "md": "lg"})

Styles API - Target nested elements:

python
dmc.Select(
    data=["A", "B", "C"],
    classNames={"input": "my-input", "dropdown": "my-dropdown"},
    styles={"label": {"fontWeight": 700}, "input": {"borderColor": "blue"}},
)

→ Full styling guide: references/styling-guide.md

Callbacks

Basic Pattern:

python
from dash import callback, Input, Output, State

@callback(
    Output("output", "children"),
    Input("button", "n_clicks"),
    State("input", "value"),
    prevent_initial_call=True,
)
def update(n_clicks, value):
    return f"Clicked {n_clicks} times with value: {value}"

Pattern-Matching (dynamic components):

python
from dash import ALL, MATCH, callback_context as ctx

# ALL: Respond to any button with type "dynamic-btn"
@callback(
    Output("output", "children"),
    Input({"type": "dynamic-btn", "index": ALL}, "n_clicks"),
)
def handle_all(n_clicks_list):
    triggered = ctx.triggered_id  # {"type": "dynamic-btn", "index": X}
    return f"Button {triggered['index']} clicked"

# MATCH: Update the output matching the triggered input
@callback(
    Output({"type": "item-output", "index": MATCH}, "children"),
    Input({"type": "item-btn", "index": MATCH}, "n_clicks"),
    prevent_initial_call=True,
)
def handle_match(n):
    return f"Clicked {n} times"

Clientside Callback (browser-side JavaScript):

python
from dash import clientside_callback

clientside_callback(
    """(n) => n ? `Clicked ${n} times` : "Not clicked" """,
    Output("output", "children"),
    Input("button", "n_clicks"),
)

DMC-Specific Props:

  • debounce=300 - Delay callback trigger (ms) for TextInput, Textarea
  • persistence=True - Persist value across page reloads
  • persistence_type="local" - Storage type: memory, local, session

→ Full callbacks reference: references/callbacks-advanced.md


Multi-Page Apps

Use Dash Pages with DMC AppShell:

python
# app.py
import dash
from dash import Dash
import dash_mantine_components as dmc

app = Dash(__name__, use_pages=True, pages_folder="pages")

app.layout = dmc.MantineProvider([
    dmc.AppShell(
        [
            dmc.AppShellHeader(dmc.Group([
                dmc.Title("My App", order=3),
                dmc.Switch(id="theme-switch"),
            ], h="100%", px="md")),
            dmc.AppShellNavbar([
                dmc.NavLink(label=page["name"], href=page["path"], active=page["path"] == "/")
                for page in dash.page_registry.values()
            ], p="md"),
            dmc.AppShellMain(dash.page_container),
        ],
        header={"height": 60},
        navbar={"width": 250, "breakpoint": "sm", "collapsed": {"mobile": True}},
        padding="md",
    )
])

if __name__ == "__main__":
    app.run(debug=True)
python
# pages/home.py
import dash
import dash_mantine_components as dmc

dash.register_page(__name__, path="/", name="Home")

layout = dmc.Container([
    dmc.Title("Welcome", order=2),
    dmc.Text("Home page content"),
], py="xl")
python
# pages/analytics.py
import dash
import dash_mantine_components as dmc

dash.register_page(__name__, path="/analytics", name="Analytics")

layout = dmc.Container([
    dmc.Title("Analytics", order=2),
    # Charts, tables, etc.
], py="xl")

Variable Paths:

python
# pages/user.py
dash.register_page(__name__, path_template="/user/<user_id>")

def layout(user_id=None):
    return dmc.Container([
        dmc.Title(f"User: {user_id}", order=2),
    ])

→ Full multi-page guide: references/multi-page-apps.md


Component Categories

Quick links to reference documentation:

CategoryComponentsReference
All Components90+ components with props/eventscomponents-quick-ref.md
ThemingMantineProvider, theme object, colorstheming-patterns.md
StylingStyle props, Styles API, CSS variablesstyling-guide.md
CallbacksPattern-matching, clientside, backgroundcallbacks-advanced.md
Multi-PageDash Pages, routing, AppShellmulti-page-apps.md
ChartsData formats, series configcharts-data-formats.md
Date PickersDatePicker, DatesProvider, localizationdate-pickers-guide.md
Dash Coredcc.Store, caching, performancedash-fundamentals.md
Migrationv1.x to v2.x breaking changesmigration-v2.md

Asset Templates

Copy and adapt these templates:

TemplateDescription
app_single_page.pyComplete single-page DMC app with theme toggle
app_multi_page.pyMulti-page app with Dash Pages and AppShell
callbacks_patterns.pyAll callback pattern examples
theme_presets.pyPre-built theme configurations

Utility Scripts

ScriptUsage
scaffold_app.pypython scaffold_app.py myapp --type multi --shell
generate_theme.pypython generate_theme.py --primary "#0ea5e9"
component_search.pypython component_search.py "select"

Common Tasks

Form with Validation

python
@callback(
    Output("submit-btn", "disabled"),
    Output("error-text", "children"),
    Input("email-input", "value"),
    Input("password-input", "value"),
)
def validate_form(email, password):
    errors = []
    if not email or "@" not in email:
        errors.append("Valid email required")
    if not password or len(password) < 8:
        errors.append("Password must be 8+ characters")
    return bool(errors), ", ".join(errors)

Modal Open/Close

python
app.layout = dmc.MantineProvider([
    dmc.Button("Open Modal", id="open-modal-btn"),
    dmc.Modal(
        id="my-modal",
        title="Confirm Action",
        children=[
            dmc.Text("Are you sure?"),
            dmc.Group([
                dmc.Button("Cancel", id="cancel-btn", variant="outline"),
                dmc.Button("Confirm", id="confirm-btn", color="red"),
            ], justify="flex-end", mt="md"),
        ],
    ),
])

@callback(
    Output("my-modal", "opened"),
    Input("open-modal-btn", "n_clicks"),
    Input("cancel-btn", "n_clicks"),
    Input("confirm-btn", "n_clicks"),
    prevent_initial_call=True,
)
def toggle_modal(open_clicks, cancel, confirm):
    from dash import ctx
    if ctx.triggered_id == "open-modal-btn":
        return True
    return False

Loading State

python
from dash import dcc

app.layout = dmc.MantineProvider([
    dmc.Button("Load Data", id="load-btn"),
    dcc.Loading(
        id="loading",
        type="circle",
        children=dmc.Container(id="data-container"),
    ),
])

@callback(Output("data-container", "children"), Input("load-btn", "n_clicks"))
def load_data(n):
    import time
    time.sleep(2)  # Simulate slow operation
    return dmc.Text("Data loaded!")

Chart with Data

python
data = [
    {"month": "Jan", "sales": 100, "profit": 20},
    {"month": "Feb", "sales": 150, "profit": 35},
    {"month": "Mar", "sales": 120, "profit": 25},
]

dmc.BarChart(
    data=data,
    dataKey="month",
    series=[
        {"name": "sales", "color": "blue.6"},
        {"name": "profit", "color": "green.6"},
    ],
    h=300,
    withLegend=True,
    withTooltip=True,
)

Troubleshooting

Common Errors

ErrorCauseFix
MantineProvider is requiredComponent outside providerWrap entire layout in dmc.MantineProvider([...])
Invalid theme colorColor not in themeUse built-in colors (blue, red) or add to theme["colors"]
Callback output not foundComponent not in layoutEnsure component with ID exists in layout
Circular callback detectedOutput also used as InputUse State instead of Input for non-triggering values
Pattern-matching ID mismatchDict keys don't matchEnsure type and index keys match exactly
Duplicate callback outputsSame output in multiple callbacksAdd allow_duplicate=True to additional callbacks

Debug Tips

  1. Check browser console for JavaScript errors
  2. Use debug=True in app.run() for detailed Python errors
  3. Print ctx.triggered_id to see which input fired
  4. Validate JSON-serializable callback returns (no Python objects)
  5. Test with prevent_initial_call=True to avoid startup errors

DMC v2.x Gotchas

  • DateTimePicker: Use timePickerProps not timeInputProps
  • Carousel: Embla options need {"containScroll": "trimSnaps"} wrapper
  • Default reuseTargetNode=True may cause Portal issues - set to False if overlays misbehave
  • Use MantineProvider not MantineProviderV2 (deprecated)

→ Full migration guide: references/migration-v2.md