diff --git a/CHANGELOG.md b/CHANGELOG.md index 50ac356..d796d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,16 @@ ### Added - Added `disabled` prop to `Radio` #425 by @namakshenas + +- Added the `add_figure_templates()` function which creates Mantine-styled Plotly figure templates for +both light and dark modes using the default Mantine theme. It registers the templates with plotly.io.templates as +"mantine_light" and "mantine_dark", and optionally sets one of the themes as a default. #431 by @AnnMarie + - Added various props: `acceptValueOnBlur` to `TagsInput`, `gradient` to `LineChart`, `hideWithOnePage` to `Pagination`, `name` to `Avatar`, and `disabled` to `NumberInput`. #440 by @AnnMarieW + - Added `SemiCircleProgress` component #434 by @AnnMarieW + ### Fixed - Fixed closing of Popovers when clicking outside. #423 by @magicmq diff --git a/dash_mantine_components/__init__.py b/dash_mantine_components/__init__.py index 4f8f037..b6be31b 100644 --- a/dash_mantine_components/__init__.py +++ b/dash_mantine_components/__init__.py @@ -12,6 +12,7 @@ from ._imports_ import * from ._imports_ import __all__ from .theme import DEFAULT_THEME +from .figure_templates import add_figure_templates if not hasattr(_dash, "__plotly_dash") and not hasattr(_dash, "development"): print( @@ -64,4 +65,4 @@ setattr(locals()[_component], "_css_dist", _css_dist) -__all__ += [DEFAULT_THEME, styles] +__all__ += [DEFAULT_THEME, styles, add_figure_templates] diff --git a/dash_mantine_components/figure_templates.py b/dash_mantine_components/figure_templates.py new file mode 100644 index 0000000..311ed80 --- /dev/null +++ b/dash_mantine_components/figure_templates.py @@ -0,0 +1,112 @@ +from .theme import DEFAULT_THEME +import plotly.graph_objects as go +import plotly.io as pio +import copy + + +def add_figure_templates(default=None): + + """ + Create and register Plotly figure templates styled to match the Mantine default theme. + + This function generates two custom Plotly templates: + - "mantine_light" for light mode + - "mantine_dark" for dark mode + + Templates are registered with `plotly.io.templates`, allowing you to apply them to Plotly figures + using the template names "mantine_light" or "mantine_dark". These templates include Mantine-inspired + color palettes, background colors, and other layout customizations. + + Parameters: + - default (str): The default template to apply globally. Must be either "mantine_light" or "mantine_dark". + If not set, the default Plotly template remains unchanged. + + Returns: + - None: The templates are registered and optionally set as the default, but no value is returned. + + """ + + colors = DEFAULT_THEME["colors"] + font_family = DEFAULT_THEME["fontFamily"] + # pallet generated from https://www.learnui.design/tools/data-color-picker.html#palette + custom_colorscale = [ + "#1864ab", # blue[9] + "#7065b9", + "#af61b7", + "#e35ea5", + "#ff6587", + "#ff7c63", + "#ff9e3d", + "#fcc419", # yellow[5] + ] + + # Default theme configurations + default_themes = { + "light": { + "colorway": [ + colors[color][6] + for color in ["blue", "red", "green", "violet", "orange", "cyan", "pink", "yellow"] + ], + "paper_bgcolor": "#ffffff", # mantine background color + "plot_bgcolor": "#ffffff", + "gridcolor": "#dee2e6", + }, + "dark": { + "colorway": [ + colors[color][8] + for color in ["blue", "red", "green", "violet", "orange", "cyan", "pink", "yellow"] + ], + "paper_bgcolor": colors["dark"][7], # mantine background color + "plot_bgcolor": colors["dark"][7], + "gridcolor": "#343a40", + } + } + + def make_template(name): + #Start with either a light or dark Plotly template + base = "plotly_white" if name == "light" else "plotly_dark" + template = copy.deepcopy(pio.templates[base]) + + layout = template.layout + theme_config = default_themes[name] + + # Apply theme settings + layout.colorway = theme_config["colorway"] + layout.colorscale.sequential = custom_colorscale + layout.piecolorway = theme_config["colorway"] + layout.paper_bgcolor = theme_config["paper_bgcolor"] + layout.plot_bgcolor = theme_config["plot_bgcolor"] + layout.font.family = font_family + + # Grid settings + for axis in (layout.xaxis, layout.yaxis): + axis.gridcolor = theme_config["gridcolor"] + axis.gridwidth = 0.5 + axis.zerolinecolor = theme_config["gridcolor"] + + # Geo settings + layout.geo.bgcolor = theme_config["plot_bgcolor"] + layout.geo.lakecolor = theme_config["plot_bgcolor"] + layout.geo.landcolor = theme_config["plot_bgcolor"] + + # Hover label settings + layout.hoverlabel.font.family = font_family + + # Scatter plot settings + template.data.scatter = (go.Scatter(marker_line_color=theme_config["plot_bgcolor"]),) + template.data.scattergl = (go.Scattergl(marker_line_color=theme_config["plot_bgcolor"]),) + + return template + + + # #register templates + pio.templates["mantine_light"] = make_template("light") + pio.templates["mantine_dark"] = make_template("dark") + + # set the default + if default in ["mantine_light", "mantine_dark"]: + pio.templates.default = default + elif default: + raise ValueError(f"unrecognized {default=}, allowed values are 'mantine_light' and 'mantine_dark'") + + return None \ No newline at end of file