## Version 2.1.0 Release announcement for Dash Mantine Components v2.1.0 Category: Releases Released July 1, 2025 ### What's New * New `ModalStack` and `DrawerStack` components * Function support expanded across more components and props * Custom rendering options for calendar and tree views * UI refinements and new props across the board * Based on [Mantine 8.1.2](https://mantine.dev/changelog/8-1-0/) ### New ModalStack and DrawerStack components Use [ModalStack](/components/modal) or [DrawerStack](/components/drawer) to render and manage multiple modals or drawers at once. These components handle focus, z-index stacking, and Escape key closing automatically. ```python import dash_mantine_components as dmc from dash import html, Output, Input, callback, ctx, no_update component = dmc.Center([ dmc.ModalStack( id="modal-stack", children=[ dmc.ManagedModal( id="delete-page", title="Delete this page?", children=[ dmc.Text("Are you sure you want to delete this page? This action cannot be undone."), dmc.Group( mt="lg", justify="flex-end", children=[ dmc.Button("Cancel", id="cancel-1", variant="default"), dmc.Button("Delete", id="delete", color="red"), ], ), ], ), dmc.ManagedModal( id="confirm-action", title="Confirm action", children=[ dmc.Text("Are you sure you want to perform this action? This action cannot be undone. If you are sure, press confirm button below."), dmc.Group( mt="lg", justify="flex-end", children=[ dmc.Button("Cancel", id="cancel-2", variant="default"), dmc.Button("Confirm", id="confirm", color="red"), ], ), ], ), dmc.ManagedModal( id="really-confirm-action", title="Really confirm action", children=[ dmc.Text("Jokes aside. You have confirmed this action. This is your last chance to cancel it. After you press confirm button below, action will be performed and cannot be undone. For real this time. Are you sure you want to proceed?"), dmc.Group( mt="lg", justify="flex-end", children=[ dmc.Button("Cancel", id="cancel-3", variant="default"), dmc.Button("Confirm", id="final-confirm", color="red"), ], ), ], ), ] ), dmc.Button("Open modal", id="open") ]) @callback( Output("modal-stack", "open"), Output("modal-stack", "closeAll"), Input("open", "n_clicks"), Input("cancel-1", "n_clicks"), Input("cancel-2", "n_clicks"), Input("cancel-3", "n_clicks"), Input("delete", "n_clicks"), Input("confirm", "n_clicks"), Input("final-confirm", "n_clicks"), prevent_initial_call=True, ) def control_modals(*_): trigger = ctx.triggered_id if trigger == "open": return "delete-page", False if trigger in ("cancel-1", "cancel-2", "cancel-3", "final-confirm"): return None, True if trigger == "delete": return "confirm-action", False if trigger == "confirm": return "really-confirm-action", False return no_update, no_update ``` ### Calendar headerControlsOrder prop Calendar-based components like [DatePicker](/components/datepicker) now support the `headerControlsOrder` prop, which lets you customize the layout of header buttons. The value is a dictionary using keys `'previous'`, `'next'`, and `'level'`. ```python import dash_mantine_components as dmc component = dmc.DatePicker( value="2025-02-01", headerControlsOrder = ['level', 'previous', 'next'], styles = { "calendarHeaderLevel": { "justifyContent": 'flex-start', "paddingInlineStart": 8, }, } ) ``` ### Slider Domain prop [Slider](/components/slider) component now supports `domain` prop that allows setting the possible range of values independently of the min and max values: ```python import dash_mantine_components as dmc component = dmc.Slider( domain=[0, 100], min=10, max=90, value=25, marks=[ { "value": 10, "label": 'min' }, { "value": 90, "label": 'max' }, ] ) ``` ### RangeSlider pushOnOverlap prop [RangeSlider](/components/range-slider) component now supports `pushOnOverlap` prop that defines whether the slider should push the overlapping thumb when the user drags it. This examples shows `pushOnOverlap=False` (The default is `True`) ```python import dash_mantine_components as dmc component = dmc.RangeSlider( pushOnOverlap=False, minRange=20, value=[25, 65] ) ``` ### Additional Props Now Support Functions Function props were introduced in DMC v2.0, allowing you to pass JavaScript functions to certain component props for dynamic formatting, styling, and rendering. In v2.1, this support has been expanded to include even more components and props — such as calendar inputs, AutoComplete, and Tree. You can now customize things like: * Highlighting or disabling specific dates, months, or years in the calendar, month and year pickers * Modifying how AutoComplete options are rendered or filtered * Fully controlling how each node in a Tree is displayed For a complete list of newly supported function props, [see the table in the docs](/functions-as-props#supported-props-in-v2-1). And for guidance on writing these functions — or generating them from Python using AI — see the [Functions as Props docs](/functions-as-props). #### Example: Add an indicator to a calendar day ```python from dash import Dash import dash_mantine_components as dmc # Adding dayjs as external script to make it available to the function # app = Dash(external_scripts=["https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"]) component = dmc.DatePicker( id="custom-day-render", renderDay={"function": "highlightSixteenthWithDot"} ) ``` ```javascript var dmcfuncs = window.dashMantineFunctions = window.dashMantineFunctions || {}; var dmc = window.dash_mantine_components; var dayjs = window.dayjs; dmcfuncs.highlightSixteenthWithDot = function (dateStr) { const day = dayjs(dateStr).date(); return React.createElement( dmc.Indicator, { size: 9, color: "red", offset: -5, disabled: day !== 16, // displays indicator only on the the 16th doy of the month }, React.createElement("div", null, day) ); }; ``` #### Example: Add props to year and month control Customize the year, month, and day controls using `getYearControlProps`, `getMonthControlProps`, and `getDayProps`. Each function receives a date and returns props to apply to that control. This example: * Highlights every Friday the 13th using `getDayProps` * Disables June and highlights February using `getMonthControlProps` (In the month picker) * Disables 2026 and highlights 2025 using `getYearControlProps` (In the year picker) ```python import dash_mantine_components as dmc # Adding dayjs as external script to make it available to the function # app = Dash(external_scripts=["https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/dayjs.min.js"]) component = dmc.DatePicker( defaultDate="2025-06-01", getDayProps={"function": "highlightFriday13"}, getYearControlProps={"function": "yearControlProps"}, getMonthControlProps={"function": "monthControlProps"}, my="lg" ) ``` ```javascript var dmcfuncs = window.dashMantineFunctions = window.dashMantineFunctions || {}; // dayjs is loaded globally via Dash external_scripts. // For details, see DatesProvider docs: https://www.dash-mantine-components.com/components/datesprovider var dayjs = window.dayjs; dmcfuncs.highlightFriday13 = function (dateStr) { const d = dayjs(dateStr); if (d.day() === 5 && d.date() === 13) { return { style: { backgroundColor: 'var(--mantine-color-red-filled)', color: 'var(--mantine-color-white)', }, }; } return {}; }; dmcfuncs.yearControlProps = function (dateStr) { const d = dayjs(dateStr); const currentYear = new Date().getFullYear(); if (d.year() === currentYear) { return { style: { color: 'var(--mantine-color-blue-filled)', fontWeight: 700, }, }; } if (d.year() === currentYear + 1) { return { disabled: true }; } return {}; }; dmcfuncs.monthControlProps = function (dateStr) { const d = dayjs(dateStr); if (d.month() === 1) { return { style: { color: 'var(--mantine-color-blue-filled)', fontWeight: 700, }, }; } if (d.month() === 5) { return { disabled: true }; } return {}; }; ``` #### Example: Custom Rendering of Tree component You can fully control how each node is rendered in the [Tree](/components/tree) component using the `renderNode` function. This allows custom icons, layout, or complex styling beyond the built-in options. ```python import dash_mantine_components as dmc import dash_iconify # required in order to use DashIconify in the renderNode function from .data import data component = dmc.Tree( data=data, renderNode={"function": "myLeaf"}, expanded=[ "node_modules", "node_modules/react", ] ) ``` ```javascript var dmcfuncs = window.dashMantineFunctions = window.dashMantineFunctions || {}; dmcfuncs.myLeaf = function (payload) { const dmc = window.dash_mantine_components; const iconify = window.dash_iconify; function getIcon(name, isFolder, expanded) { const size = 14; if (name.endsWith('package.json')) { return React.createElement(iconify.DashIconify, { icon: 'logos:npm-icon', width: size, height: size }); } if ( name.endsWith('.ts') || name.endsWith('.tsx') || name.endsWith('tsconfig.json') ) { return React.createElement(iconify.DashIconify, { icon: 'logos:typescript-icon', width: size, height: size }); } if (name.endsWith('.css')) { return React.createElement(iconify.DashIconify, { icon: 'vscode-icons:file-type-css', width: size, height: size }); } if (isFolder) { return React.createElement(iconify.DashIconify, { icon: expanded ? 'tabler:folder-open' : 'tabler:folder', width: size, height: size, color: '#f59f00' // Mantine yellow-9 }); } return null; } const { node, expanded, hasChildren, elementProps } = payload; return React.createElement( dmc.Group, { key: payload.node.value, gap: 5, ...elementProps }, getIcon(node.value, hasChildren, expanded), React.createElement('span', null, node.label) ); }; ``` ### AutoComplete improvements Thanks to first-time contributor @ihor-lazariev for adding the following features in [PR #604](https://github.com/snehilvj/dash-mantine-components/pull/604): * Support for functions in `renderOption` and `filter` props * New `clearButtonProps` and `clearable` props ```python import dash_mantine_components as dmc from dash_iconify import DashIconify component = dmc.Autocomplete( label="Select with renderOption", placeholder="Select text align", data=[ { "value": 'left', "label": 'left' }, { "value": 'center', "label": 'center' }, { "value": 'right', "label": 'right' }, { "value": 'justify', "label": 'justify' }, ], renderOption={"function": "renderOptionSelect"}, clearable=True ) ``` ### Other Changes See the [Mantine Changelog](https://mantine.dev/changelog/8-1-0/#other-changes) for more. * [`presets` for DatePicker](https://mantine.dev/changelog/8-1-0/#datepicker-presets): Adds predefined date ranges next to the calendar * [Popover behavior improvements](https://mantine.dev/changelog/8-1-0/#popover-middlewares-improvements): More consistent dropdown positioning with dynamic content * All components now support the `bdrs` style prop for border radius * `Tooltip` now supports the `autoContrast` prop for improved legibility --- ### Quick Start Just a reminder: * With Dash ≥ 3.0.0, there’s no need to manually set the React version. * With DMC ≥ 1.2.0, you no longer need to include optional stylesheets such as `dmc.styles.ALL`. Here’s a minimal app to get started: ```python import dash_mantine_components as dmc from dash import Dash app = Dash() app.layout = dmc.MantineProvider( dmc.Alert( "Welcome to Dash Mantine Components", title="Hello!", color="violet", ) ) if __name__ == "__main__": app.run(debug=True) ```