dmc-py
Dash Mantine Components (DMC) v2.x
Build modern Dash applications with 100+ Mantine UI components.
Quick Start
Minimal DMC app requiring MantineProvider wrapper:
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.
Version Note: This skill targets DMC 2.x (Mantine 8.x). Run
pip show dash-mantine-componentsto check your installed version. For the latest features and API changes, usefetch_docs.pyto query the official documentation at https://www.dash-mantine-components.com/assets/llms.txt
Workflow Decision Tree
Select components by use case:
Form Inputs
| Need | Component | Key Props |
|---|---|---|
| Text input | TextInput |
label, placeholder, value, debounce |
| Dropdown | Select |
data, value, searchable, clearable |
| Multi-select | MultiSelect |
data, value, searchable |
| Checkbox | Checkbox |
label, checked |
| Toggle | Switch |
label, checked, onLabel, offLabel |
| Number | NumberInput |
value, min, max, step |
| Date | DatePickerInput |
value, type, minDate, maxDate |
| Rich text | Textarea |
label, value, autosize, minRows |
| File upload | FileInput |
value, accept, multiple |
Layout
| Need | Component | Key Props |
|---|---|---|
| Content wrapper | Container |
size, px, py |
| Vertical stack | Stack |
gap, align, justify |
| Horizontal row | Group |
gap, justify, wrap |
| CSS Grid | Grid, GridCol |
columns, gutter, span |
| Full app shell | AppShell |
header, navbar, aside, footer |
| Card container | Card |
shadow, padding, radius, withBorder |
| Flex layout | Flex |
direction, wrap, gap, align |
Navigation
| Need | Component | Key Props |
|---|---|---|
| Nav item | NavLink |
label, href, active, leftSection |
| Tabs | Tabs, TabsList, TabsPanel |
value, orientation |
| Breadcrumb | Breadcrumbs |
separator |
| Stepper | Stepper, StepperStep |
active, onStepClick |
| Pagination | Pagination |
value, total, siblings |
| Table of contents | TableOfContents |
links, variant, active |
Feedback & Overlays
| Need | Component | Key Props |
|---|---|---|
| Modal dialog | Modal |
opened, onClose, title, centered |
| Side panel | Drawer |
opened, onClose, position, size |
| Toast | Notification |
title, message, color, icon |
| Alert banner | Alert |
title, color, variant, icon |
| Loading | Loader, LoadingOverlay |
size, type, visible |
| Progress | Progress, RingProgress |
value, size, sections |
| Tooltip | Tooltip |
label, position, withArrow |
| Copy button | CopyButton |
value, timeout |
Data Display
| Need | Component | Key Props |
|---|---|---|
| Data table | Table |
data, striped, highlightOnHover |
| Accordion | Accordion, AccordionItem |
value, multiple, variant |
| Timeline | Timeline, TimelineItem |
active, bulletSize |
| Badge | Badge |
color, variant, size |
Charts
| Need | Component | Key Props |
|---|---|---|
| Line | LineChart |
data, dataKey, series |
| Bar | BarChart |
data, dataKey, series, orientation |
| Area | AreaChart |
data, dataKey, series |
| Pie/Donut | DonutChart, PieChart |
data, chartLabel |
| Scatter | ScatterChart |
data, dataKey, series |
What's New in Recent Versions
v2.5.x:
TableOfContents- Auto-generated table of contents from headingsselectFirstOptionOnDropdownOpenprop for Select/MultiSelect/AutocompleteopenOnFocusprop for Combobox components- AppShell
mode="static"for nested shells window.MantineCore/window.MantineHooksfor custom component building
v2.4.x:
CopyButton/CustomCopyButton- Clipboard operationsgetEditor(id)- Access RichTextEditor TipTap instance in clientside callbacks- Function props for chart axis/grid customization
v2.3.x:
MiniCalendar- Compact calendar componentScrollAreaAutoheight- Auto-sizing scroll areaDirectionProvider- RTL text direction support
→ Full component reference: references/components-quick-ref.md
Core Patterns
Theming
Configure theme via MantineProvider:
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):
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:
| Prop | CSS Property | Values |
|---|---|---|
m, mt, mb, ml, mr, mx, my |
margin | xs, sm, md, lg, xl or number (px) |
p, pt, pb, pl, pr, px, py |
padding | same as margin |
c |
color | "blue", "red.6", "dimmed", "var(--mantine-color-text)" |
bg |
background | same as color |
w, h |
width, height | "100%", "50vw", number (px) |
maw, mah, miw, mih |
max/min width/height | same as w, h |
fw |
font-weight | 400, 500, 700 |
fz |
font-size | xs, sm, md, lg, xl or number |
ta |
text-align | "left", "center", "right" |
td |
text-decoration | "underline", "line-through" |
Responsive Values - Dict with breakpoints:
dmc.Button("Click", w={"base": "100%", "sm": "auto", "lg": 200})
dmc.Stack(gap={"base": "xs", "md": "lg"})
Styles API - Target nested elements:
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:
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):
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):
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, Textareapersistence=True- Persist value across page reloadspersistence_type="local"- Storage type: memory, local, session
→ Full callbacks reference: references/callbacks-advanced.md
Multi-Page Apps
Use Dash Pages with DMC AppShell:
# 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)
# 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")
# 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:
# 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:
| Category | Components | Reference |
|---|---|---|
| All Components | 90+ components with props/events | components-quick-ref.md |
| Theming | MantineProvider, theme object, colors | theming-patterns.md |
| Styling | Style props, Styles API, CSS variables | styling-guide.md |
| Callbacks | Pattern-matching, clientside, background | callbacks-advanced.md |
| Multi-Page | Dash Pages, routing, AppShell | multi-page-apps.md |
| Charts | Data formats, series config | charts-data-formats.md |
| Date Pickers | DatePicker, DatesProvider, localization | date-pickers-guide.md |
| Dash Core | dcc.Store, caching, performance | dash-fundamentals.md |
| Migration | v1.x to v2.x breaking changes | migration-v2.md |
Asset Templates
Copy and adapt these templates:
| Template | Description |
|---|---|
| app_single_page.py | Complete single-page DMC app with theme toggle |
| app_multi_page.py | Multi-page app with Dash Pages and AppShell |
| callbacks_patterns.py | All callback pattern examples |
| theme_presets.py | Pre-built theme configurations |
Utility Scripts
| Script | Usage |
|---|---|
| fetch_docs.py | python fetch_docs.py "Select" - Fetch/search official llms.txt |
| scaffold_app.py | python scaffold_app.py myapp --type multi --shell |
| generate_theme.py | python generate_theme.py --primary "#0ea5e9" |
| component_search.py | python component_search.py "select" |
Common Tasks
Form with Validation
@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
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
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
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
| Error | Cause | Fix |
|---|---|---|
MantineProvider is required |
Component outside provider | Wrap entire layout in dmc.MantineProvider([...]) |
Invalid theme color |
Color not in theme | Use built-in colors (blue, red) or add to theme["colors"] |
Callback output not found |
Component not in layout | Ensure component with ID exists in layout |
Circular callback detected |
Output also used as Input | Use State instead of Input for non-triggering values |
Pattern-matching ID mismatch |
Dict keys don't match | Ensure type and index keys match exactly |
Duplicate callback outputs |
Same output in multiple callbacks | Add allow_duplicate=True to additional callbacks |
Debug Tips
- Check browser console for JavaScript errors
- Use
debug=Trueinapp.run()for detailed Python errors - Print
ctx.triggered_idto see which input fired - Validate JSON-serializable callback returns (no Python objects)
- Test with
prevent_initial_call=Trueto avoid startup errors
DMC v2.x Gotchas
DateTimePicker: UsetimePickerPropsnottimeInputPropsCarousel: Embla options need{"containScroll": "trimSnaps"}wrapper- Default
reuseTargetNode=Truemay cause Portal issues - set toFalseif overlays misbehave - Use
MantineProvidernotMantineProviderV2(deprecated)
→ Full migration guide: references/migration-v2.md
More from bjornmelin/dev-skills
streamdown
|
13notebook-ml-architect
>
5opensrc-inspect
Fetch, inspect, and manage local opensrc source snapshots for packages and GitHub repositories. Use when you need dependency or upstream repo source code locally for deeper implementation review, API edge-case analysis, or version-aligned source inspection. Do not use as a general web-research skill.
1dash-audit
Audit Dash apps for callback hazards, state flow risks, layout and accessibility issues, and Dash-specific UX regressions. Use when the user asks for a Dash callback review, Dash UI audit, Dash web-interface audit, or a read-first remediation plan for a Dash app. Do not use for generic React or Next.js UI review.
1gh-pr-review-fix
Fetch unresolved GitHub PR review threads, normalize them, fix them end-to-end, verify the results, and re-check until the PR is clean or blocked. Use when the user wants GitHub PR comments resolved with minimal verified fixes. Do not use for local review files, Codex reviews, or Zen reviews; review-remediation owns those.
1bun-audit
Shared Bun audit/remediation router. Use when auditing a repo for Bun-first correctness, explaining Bun audit findings, listing Bun audit rules, planning safe Bun fixes, applying low-risk remediations, or validating Bun-related changes. This skill delegates to the shared engine in bun-dev/scripts.
1