Skip to content

fixing mantine provider scheme for local storage#681

Closed
BSd3v wants to merge 3 commits intosnehilvj:masterfrom
BSd3v:fixing-mantine-provider-color-scheme
Closed

fixing mantine provider scheme for local storage#681
BSd3v wants to merge 3 commits intosnehilvj:masterfrom
BSd3v:fixing-mantine-provider-color-scheme

Conversation

@BSd3v
Copy link
Copy Markdown
Contributor

@BSd3v BSd3v commented Dec 31, 2025

No description provided.

@AnnMarieW
Copy link
Copy Markdown
Collaborator

Thanks for the PR!
Should it default to light?

@BSd3v
Copy link
Copy Markdown
Contributor Author

BSd3v commented Dec 31, 2025

I think it defaults to light, shouldnt need to add that.

@AnnMarieW
Copy link
Copy Markdown
Collaborator

So, is this supposed to be used with theme switch components? What problem is this trying to solve? I didn't see any difference when setting the data-mantine-color-scheme attribute like here https://www.dash-mantine-components.com/theme-switch

@BSd3v
Copy link
Copy Markdown
Contributor Author

BSd3v commented Dec 31, 2025

It actually works with the mantine local store, currently this is not the case as it doesn't update properly.

@BSd3v
Copy link
Copy Markdown
Contributor Author

BSd3v commented Jan 2, 2026

eg:

import random
import dash
from dash import Dash, Output, State, Input, dcc, clientside_callback
import dash_mantine_components as dmc

app = Dash(external_stylesheets=dmc.styles.ALL)

app.layout = dmc.MantineProvider(
    forceColorScheme="dark",
    children=dmc.AppShell([
        dcc.Location(id="url"),
        dmc.AppShellMain(
            children=dmc.Stack([
                dmc.Stack([dmc.Anchor(x, href=x) for x in ["/", "/a", "/b"]]),
            ])
        )
    ])
)

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

In the current environment ends up with no mantine key in local storage:
image

The theme switch just manipulates the attribute, but this is not how Mantine is designed, the MantineProvider should set the colorScheme via the function. This then allows queries and setting the attribute before the page is rendered by dash at all.


In the proposed, instead of forcing the color scheme, you dashSetColorScheme to dark:

import dash
from dash import Dash, Output, State, Input, dcc, clientside_callback
import dash_mantine_components as dmc

app = Dash(external_stylesheets=dmc.styles.ALL)

app.layout = dmc.MantineProvider(
    dashSetColorScheme="dark",
    children=dmc.AppShell([
        dcc.Location(id="url"),
        dmc.AppShellMain(
            children=dmc.Stack([
                dmc.Stack([dmc.Anchor(x, href=x) for x in ["/", "/a", "/b"]]),
            ])
        )
    ])
)

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

Results in this:
image

Mantine is designed to listen to the local storage as key, therefore you dont need to worry about persistence of settings since this is already managed by it. In fact, just manually adjusting this store value results in MantineProvider changes the color.

@AnnMarieW
Copy link
Copy Markdown
Collaborator

OK, so for a theme switch should you do this?

Try running it:

import dash_mantine_components as dmc
from dash_iconify import DashIconify
from dash import Dash, Input, Output


theme_toggle = dmc.Switch(
    offLabel=DashIconify(icon="radix-icons:sun", width=15, color=dmc.DEFAULT_THEME["colors"]["yellow"][8]),
    onLabel=DashIconify(icon="radix-icons:moon", width=15, color=dmc.DEFAULT_THEME["colors"]["yellow"][6]),
    id="color-scheme-switch",
    persistence=True,
    color="gray",
)

app = Dash()

app.layout = dmc.MantineProvider(
    [theme_toggle, dmc.Text("Your page content")],
    id="mantine-provider",

)

@app.callback(
    Output("mantine-provider", "dashSetColorScheme"),
    Input("color-scheme-switch", "checked"),
)
def update(checked):
    if checked:
        return "light"
    return "dark"


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

@BSd3v
Copy link
Copy Markdown
Contributor Author

BSd3v commented Jan 2, 2026

@AnnMarieW

Try this app:

import dash_mantine_components as dmc
from dash_iconify import DashIconify
from dash import Dash, Input, Output, State


theme_toggle = dmc.Switch(
    offLabel=DashIconify(icon="radix-icons:sun", width=15, color=dmc.DEFAULT_THEME["colors"]["yellow"][8]),
    onLabel=DashIconify(icon="radix-icons:moon", width=15, color=dmc.DEFAULT_THEME["colors"]["yellow"][6]),
    id="color-scheme-switch",
    color="gray",
    persistence=True
)

app = Dash()

app.layout = dmc.MantineProvider(
    [theme_toggle, dmc.Text("Your page content")],
    id="mantine-provider",
    defaultColorScheme="auto",
)

app.clientside_callback(
    """
    function (checked, colorScheme, defaultColorScheme) {
        const triggered = dash_clientside.callback_context.triggered_id;
        var colorSchemeValue = colorScheme || defaultColorScheme;
        if (colorSchemeValue === 'auto') {
            colorSchemeValue = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
        }
        if (triggered === "mantine-provider") {
            dash_clientside.set_props('color-scheme-switch', {'checked': colorSchemeValue === 'dark'});
            return dash_clientside.no_update;
        }
        return checked ? 'dark' : 'light';
    }
    """,
    Output("mantine-provider", "colorScheme"),
    Input("color-scheme-switch", "checked"),
    Input("mantine-provider", "colorScheme"),
    State("mantine-provider", "defaultColorScheme"),
)



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

This will also sync the app across multiple windows. We may need to allow for adjusting the storage listener and key in the component to allow custom defined stores.

@AnnMarieW
Copy link
Copy Markdown
Collaborator

In the sample app above, I changed the defaultColorScheme and the theme switch component behaved unexpectedly. It might be due to more than one app running.

@AnnMarieW
Copy link
Copy Markdown
Collaborator

Might be better to do this with a separate component. See #693

@AnnMarieW
Copy link
Copy Markdown
Collaborator

closed in favor of #693

@AnnMarieW AnnMarieW closed this Jan 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants