diff --git a/vizro-core/examples/dev/app.py b/vizro-core/examples/dev/app.py index 1265ab20c..3cc4a42a3 100644 --- a/vizro-core/examples/dev/app.py +++ b/vizro-core/examples/dev/app.py @@ -820,13 +820,13 @@ def multiple_cards(data_frame: pd.DataFrame, n_rows: Optional[int] = 1) -> html. if __name__ == "__main__": app = Vizro().build(dashboard) - app.dash.layout.children.append( - dbc.NavLink( - ["Made with ", html.Img(src=get_asset_url("logo.svg"), id="banner", alt="Vizro logo"), "vizro"], - href="https://github.com/mckinsey/vizro", - target="_blank", - className="anchor-container", - ) + + new_link = dbc.NavLink( + ["Made with ", html.Img(src=get_asset_url("logo.svg"), id="banner", alt="Vizro logo"), "vizro"], + href="https://github.com/mckinsey/vizro", + target="_blank", + className="anchor-container", ) + app.dash.layout.children = [app.dash.layout.children, new_link] server = app.dash.server app.run() diff --git a/vizro-core/pyproject.toml b/vizro-core/pyproject.toml index 1bf2b9577..11cce50b3 100644 --- a/vizro-core/pyproject.toml +++ b/vizro-core/pyproject.toml @@ -21,7 +21,7 @@ dependencies = [ "pandas>=2", "plotly>=5.12.0", "pydantic>=1.10.16", # must be synced with pre-commit mypy hook manually - "dash_mantine_components<0.13.0", # 0.13.0 is not compatible with 0.12, + "dash_mantine_components==0.15.1", # 0.13.0 is not compatible with 0.12, "flask_caching>=2", "wrapt>=1", "black", diff --git a/vizro-core/src/vizro/_vizro.py b/vizro-core/src/vizro/_vizro.py index f648d053f..4ac7e032b 100644 --- a/vizro-core/src/vizro/_vizro.py +++ b/vizro-core/src/vizro/_vizro.py @@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, TypedDict, cast import dash +import dash_mantine_components as dmc import plotly.io as pio from dash.development.base_component import ComponentRegistry from flask_caching import SimpleCache @@ -17,6 +18,8 @@ from vizro.managers import data_manager, model_manager from vizro.models import Dashboard, Filter +dash._dash_renderer._set_react_version("18.2.0") + logger = logging.getLogger(__name__) if TYPE_CHECKING: @@ -47,6 +50,9 @@ def __init__(self, **kwargs): suppress_callback_exceptions=True, title="Vizro", use_pages=True, + # This is added here temporarily for testing. These stylesheets are required for certain dmc components. + # It may be better to include these stylesheets in the css folder. + external_stylesheets=dmc.styles.ALL ) # When Vizro is used as a framework, we want to include the library and framework resources. diff --git a/vizro-core/src/vizro/models/_components/form/date_picker.py b/vizro-core/src/vizro/models/_components/form/date_picker.py index b3dc416fd..2ee038310 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -27,7 +27,7 @@ class DatePicker(VizroBaseModel): [`dmc.DateRangePicker`](https://www.dash-mantine-components.com/components/datepicker#daterangepicker). Args: - type (Literal["date_picker"]): Defaults to `"date_picker"`. + type (Literal["default", "range", "multiple"]): Defaults to A single date picker allowing the selection of one date. min (Optional[date]): Start date for date picker. Defaults to `None`. max (Optional[date]): End date for date picker. Defaults to `None`. value (Union[list[date], date]): Default date/dates for date picker. Defaults to `None`. @@ -37,11 +37,13 @@ class DatePicker(VizroBaseModel): """ - type: Literal["date_picker"] = "date_picker" + type: Literal["default", "range", "multiple"] = "default" min: Optional[date] = Field(None, description="Start date for date picker.") max: Optional[date] = Field(None, description="End date for date picker.") value: Optional[Union[list[date], date]] = Field(None, description="Default date for date picker") title: str = Field("", description="Title to be displayed.") + + # Could probably delete the `range` arg, but keeping it makes it backwards compatible range: bool = Field(True, description="Boolean flag for displaying range picker.") actions: list[Action] = [] @@ -71,33 +73,15 @@ def build(self): output=output, inputs=inputs, ) - # clientside callback is required as a workaround when the date-picker is overflowing its parent container - # if there is not enough space. Caused by another workaround for this issue: - # https://github.com/snehilvj/dash-mantine-components/issues/219 - clientside_callback( - ClientsideFunction(namespace="date_picker", function_name="update_date_picker_position"), - output=Output(self.id, "dropdownPosition"), - inputs=Input(self.id, "n_clicks"), - ) - - date_picker_class = dmc.DateRangePicker if self.range else dmc.DatePicker - # dropdownPosition must be set to bottom-start as a workaround for issue: - # https://github.com/snehilvj/dash-mantine-components/issues/219 - # clearable must be set to False as a workaround for issue: - # https://github.com/snehilvj/dash-mantine-components/issues/212 - # maxDate must be increased by one day, and later on disabledDates must be set as maxDate + 1 day - # as a workaround for issue: https://github.com/snehilvj/dash-mantine-components/issues/230 - date_picker = date_picker_class( + date_picker = dmc.DatePickerInput( id=self.id, minDate=self.min, value=init_value, - maxDate=self.max + datetime.timedelta(days=1) if self.max else None, + maxDate=self.max, persistence=True, persistence_type="session", - dropdownPosition="bottom-start", - clearable=False, - disabledDates=self.max + datetime.timedelta(days=1) if self.max else None, + type="range" if self.range else "default", className="datepicker", **date_range_picker_kwargs, ) diff --git a/vizro-core/src/vizro/models/_dashboard.py b/vizro-core/src/vizro/models/_dashboard.py index b635b8e95..6f90b66e7 100644 --- a/vizro-core/src/vizro/models/_dashboard.py +++ b/vizro-core/src/vizro/models/_dashboard.py @@ -8,6 +8,7 @@ import dash import dash_bootstrap_components as dbc +import dash_mantine_components as dmc import plotly.io as pio from dash import ( ClientsideFunction, @@ -156,7 +157,7 @@ def build(self): State("collapsable-left-side", "is_open"), ) - return html.Div( + layout= html.Div( id="dashboard-container", children=[ html.Div(id="vizro_version", children=vizro.__version__, hidden=True), @@ -171,6 +172,11 @@ def build(self): dash.page_container, ], ) + return dmc.MantineProvider( + layout, + # Use the `theme` to style all Mantine components with a Vizro theme. For more info see https://www.dash-mantine-components.com/components/mantineprovider + # theme = {...} + ) def _validate_logos(self): logo_img = self._infer_image(filename="logo") diff --git a/vizro-core/src/vizro/static/js/models/dashboard.js b/vizro-core/src/vizro/static/js/models/dashboard.js index e04084788..5a278e1ac 100644 --- a/vizro-core/src/vizro/static/js/models/dashboard.js +++ b/vizro-core/src/vizro/static/js/models/dashboard.js @@ -1,8 +1,10 @@ function update_dashboard_theme(theme_selector_checked) { - document.documentElement.setAttribute( - "data-bs-theme", - theme_selector_checked ? "light" : "dark", - ); + const theme = theme_selector_checked ? "light" : "dark"; + + // Update theme attributes for Bootstrap and Mantine + document.documentElement.setAttribute("data-bs-theme", theme); + document.documentElement.setAttribute("data-mantine-color-scheme", theme); + return window.dash_clientside.no_update; }