From 1a962f1b067d7e4a80e2d410c6f214a19e70cde3 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sat, 7 Dec 2024 13:15:29 -0800 Subject: [PATCH 01/11] Update to use dmc 0.15.1 --- vizro-core/examples/dev/app.py | 14 ++++----- vizro-core/pyproject.toml | 2 +- vizro-core/src/vizro/_vizro.py | 6 ++++ .../models/_components/form/date_picker.py | 30 +++++-------------- vizro-core/src/vizro/models/_dashboard.py | 8 ++++- .../src/vizro/static/js/models/dashboard.js | 10 ++++--- 6 files changed, 34 insertions(+), 36 deletions(-) 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; } From 7ff1b736b7e8bfc934c49b77c76000ecded4ebc2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Dec 2024 21:21:11 +0000 Subject: [PATCH 02/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- vizro-core/src/vizro/_vizro.py | 2 +- vizro-core/src/vizro/models/_components/form/date_picker.py | 1 - vizro-core/src/vizro/models/_dashboard.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/vizro-core/src/vizro/_vizro.py b/vizro-core/src/vizro/_vizro.py index 4ac7e032b..5f6e21bf0 100644 --- a/vizro-core/src/vizro/_vizro.py +++ b/vizro-core/src/vizro/_vizro.py @@ -52,7 +52,7 @@ def __init__(self, **kwargs): 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 + 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 2ee038310..65d2896da 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -9,7 +9,6 @@ from pydantic import Field, PrivateAttr, validator -import datetime from datetime import date import dash_bootstrap_components as dbc diff --git a/vizro-core/src/vizro/models/_dashboard.py b/vizro-core/src/vizro/models/_dashboard.py index 6f90b66e7..23b6eb5f7 100644 --- a/vizro-core/src/vizro/models/_dashboard.py +++ b/vizro-core/src/vizro/models/_dashboard.py @@ -157,7 +157,7 @@ def build(self): State("collapsable-left-side", "is_open"), ) - layout= html.Div( + layout = html.Div( id="dashboard-container", children=[ html.Div(id="vizro_version", children=vizro.__version__, hidden=True), From efbd8011e9d545b7dbab319ffa26212f47419530 Mon Sep 17 00:00:00 2001 From: Ann Marie Ward <72614349+AnnMarieW@users.noreply.github.com> Date: Thu, 12 Dec 2024 06:13:44 -0800 Subject: [PATCH 03/11] Apply suggestions from code review Co-authored-by: Li Nguyen <90609403+huong-li-nguyen@users.noreply.github.com> --- vizro-core/examples/dev/app.py | 4 ++-- vizro-core/src/vizro/_vizro.py | 9 ++++++--- .../src/vizro/models/_components/form/date_picker.py | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/vizro-core/examples/dev/app.py b/vizro-core/examples/dev/app.py index 3cc4a42a3..4d6390652 100644 --- a/vizro-core/examples/dev/app.py +++ b/vizro-core/examples/dev/app.py @@ -821,12 +821,12 @@ def multiple_cards(data_frame: pd.DataFrame, n_rows: Optional[int] = 1) -> html. if __name__ == "__main__": app = Vizro().build(dashboard) - new_link = dbc.NavLink( + banner = 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] + app.dash.layout.children = [app.dash.layout.children, banner] server = app.dash.server app.run() diff --git a/vizro-core/src/vizro/_vizro.py b/vizro-core/src/vizro/_vizro.py index 5f6e21bf0..2588a462d 100644 --- a/vizro-core/src/vizro/_vizro.py +++ b/vizro-core/src/vizro/_vizro.py @@ -50,10 +50,13 @@ 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, ) + + # Ensure external_stylesheets is a list and append the additional stylesheet + external_stylesheets = self.dash.config.external_stylesheets + self.dash.config.external_stylesheets = external_stylesheets if isinstance(external_stylesheets, list) else [ + external_stylesheets] + self.dash.config.external_stylesheets.append(dmc.styles.DATES) # When Vizro is used as a framework, we want to include the library and framework resources. # Dash serves resources in the order 1. external_stylesheets/scripts; 2. library resources from the 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 65d2896da..222572342 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -26,7 +26,7 @@ class DatePicker(VizroBaseModel): [`dmc.DateRangePicker`](https://www.dash-mantine-components.com/components/datepicker#daterangepicker). Args: - type (Literal["default", "range", "multiple"]): Defaults to A single date picker allowing the selection of one date. + type (Literal["date_picker"]): Defaults to `"date_picker"`. 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`. @@ -36,7 +36,7 @@ class DatePicker(VizroBaseModel): """ - type: Literal["default", "range", "multiple"] = "default" + type: Literal["date_picker"] = "date_picker" 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") From 7e1ff1ce617d2256372d6d20b3fa2a18a6d0ab3a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:14:08 +0000 Subject: [PATCH 04/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- vizro-core/src/vizro/_vizro.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vizro-core/src/vizro/_vizro.py b/vizro-core/src/vizro/_vizro.py index 2588a462d..170e47aeb 100644 --- a/vizro-core/src/vizro/_vizro.py +++ b/vizro-core/src/vizro/_vizro.py @@ -51,11 +51,12 @@ def __init__(self, **kwargs): title="Vizro", use_pages=True, ) - + # Ensure external_stylesheets is a list and append the additional stylesheet external_stylesheets = self.dash.config.external_stylesheets - self.dash.config.external_stylesheets = external_stylesheets if isinstance(external_stylesheets, list) else [ - external_stylesheets] + self.dash.config.external_stylesheets = ( + external_stylesheets if isinstance(external_stylesheets, list) else [external_stylesheets] + ) self.dash.config.external_stylesheets.append(dmc.styles.DATES) # When Vizro is used as a framework, we want to include the library and framework resources. From 4a091d2c7e12753ae5d7ad46aba60e16af6c287e Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sun, 15 Dec 2024 09:58:59 -0800 Subject: [PATCH 05/11] Update after review --- vizro-core/examples/dev/app.py | 2 +- vizro-core/src/vizro/_vizro.py | 1 + .../models/_components/form/date_picker.py | 17 +----------- .../src/vizro/static/js/models/date_picker.js | 27 ------------------- 4 files changed, 3 insertions(+), 44 deletions(-) delete mode 100644 vizro-core/src/vizro/static/js/models/date_picker.js diff --git a/vizro-core/examples/dev/app.py b/vizro-core/examples/dev/app.py index 4d6390652..74ade57b7 100644 --- a/vizro-core/examples/dev/app.py +++ b/vizro-core/examples/dev/app.py @@ -821,7 +821,7 @@ def multiple_cards(data_frame: pd.DataFrame, n_rows: Optional[int] = 1) -> html. if __name__ == "__main__": app = Vizro().build(dashboard) - banner = dbc.NavLink( + banner = 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", diff --git a/vizro-core/src/vizro/_vizro.py b/vizro-core/src/vizro/_vizro.py index 170e47aeb..f2fa41a27 100644 --- a/vizro-core/src/vizro/_vizro.py +++ b/vizro-core/src/vizro/_vizro.py @@ -18,6 +18,7 @@ from vizro.managers import data_manager, model_manager from vizro.models import Dashboard, Filter +# this can be removed when Dash uses React 18 as a default (likely V3.0 https://github.com/plotly/dash/pull/3093) dash._dash_renderer._set_react_version("18.2.0") logger = logging.getLogger(__name__) 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 222572342..07c931c6c 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -1,7 +1,7 @@ from typing import Literal, Optional, Union import dash_mantine_components as dmc -from dash import ClientsideFunction, Input, Output, State, clientside_callback, dcc, html +from dash import Input, Output, State, dcc, html try: from pydantic.v1 import Field, PrivateAttr, validator @@ -58,20 +58,6 @@ def build(self): init_value = self.value or ([self.min, self.max] if self.range else self.min) # type: ignore[list-item] date_range_picker_kwargs = {"allowSingleDateInRange": True} if self.range else {} - output = [ - Output(self.id, "value"), - Output(f"{self.id}_input_store", "data"), - ] - inputs = [ - Input(self.id, "value"), - State(f"{self.id}_input_store", "data"), - ] - - clientside_callback( - ClientsideFunction(namespace="date_picker", function_name="update_date_picker_values"), - output=output, - inputs=inputs, - ) date_picker = dmc.DatePickerInput( id=self.id, @@ -89,6 +75,5 @@ def build(self): children=[ dbc.Label(children=self.title, html_for=self.id) if self.title else None, date_picker, - dcc.Store(id=f"{self.id}_input_store", storage_type="session", data=init_value), ], ) diff --git a/vizro-core/src/vizro/static/js/models/date_picker.js b/vizro-core/src/vizro/static/js/models/date_picker.js deleted file mode 100644 index 1073acacb..000000000 --- a/vizro-core/src/vizro/static/js/models/date_picker.js +++ /dev/null @@ -1,27 +0,0 @@ -function update_date_picker_values(value, input_store) { - if ( - value === null || - dash_clientside.callback_context.triggered.length === 0 - ) { - return [input_store, input_store]; - } - return [value, value]; -} - -function update_date_picker_position(clicks) { - var element_id = window.dash_clientside.callback_context.inputs_list[0]["id"]; - var element = document.getElementById(element_id); - var rect = element.getBoundingClientRect(); - var position = - rect.y + 360 > window.innerHeight ? "top-start" : "bottom-start"; - - return position; -} - -window.dash_clientside = { - ...window.dash_clientside, - date_picker: { - update_date_picker_values: update_date_picker_values, - update_date_picker_position: update_date_picker_position, - }, -}; From fd2aeff57a887ef1367c2b7c37058fb8c7211be4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 17:59:37 +0000 Subject: [PATCH 06/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- vizro-core/src/vizro/models/_components/form/date_picker.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 07c931c6c..80f884abb 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -1,7 +1,7 @@ from typing import Literal, Optional, Union import dash_mantine_components as dmc -from dash import Input, Output, State, dcc, html +from dash import html try: from pydantic.v1 import Field, PrivateAttr, validator @@ -58,7 +58,6 @@ def build(self): init_value = self.value or ([self.min, self.max] if self.range else self.min) # type: ignore[list-item] date_range_picker_kwargs = {"allowSingleDateInRange": True} if self.range else {} - date_picker = dmc.DatePickerInput( id=self.id, minDate=self.min, From 4189fa8ed5ef24d3fdcb44ac0ecf30403076ca7b Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Mon, 16 Dec 2024 09:12:55 -0800 Subject: [PATCH 07/11] added example app --- vizro-core/examples/scratch_dev/app.py | 81 +++----------------------- 1 file changed, 8 insertions(+), 73 deletions(-) diff --git a/vizro-core/examples/scratch_dev/app.py b/vizro-core/examples/scratch_dev/app.py index 56413e831..43c7c57e5 100644 --- a/vizro-core/examples/scratch_dev/app.py +++ b/vizro-core/examples/scratch_dev/app.py @@ -1,89 +1,24 @@ """Dev app to try things out.""" - from vizro import Vizro import vizro.models as vm import vizro.plotly.express as px -df = px.data.gapminder() -gapminder_data = ( - df.groupby(by=["continent", "year"]).agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index() -) -first_page = vm.Page( - title="First Page", - layout=vm.Layout(grid=[[0, 0], [1, 2], [1, 2], [1, 2]]), - components=[ - vm.Card( - text=""" - # First dashboard page - This pages shows the inclusion of markdown text in a page and how components - can be structured using Layout. - """, - ), - vm.Graph( - id="box_cont", - figure=px.box( - gapminder_data, - x="continent", - y="lifeExp", - color="continent", - labels={"lifeExp": "Life Expectancy", "continent": "Continent"}, - ), - ), - vm.Graph( - id="line_gdp", - figure=px.line( - gapminder_data, - x="year", - y="gdpPercap", - color="continent", - labels={"year": "Year", "continent": "Continent", "gdpPercap": "GDP Per Cap"}, - ), - ), - ], - controls=[ - vm.Filter(column="continent", targets=["box_cont", "line_gdp"]), - ], -) +stocks = px.data.stocks(datetimes=True) -iris_data = px.data.iris() -second_page = vm.Page( - title="Second Page", +page = vm.Page( + title="Page", components=[ vm.Graph( - id="scatter_iris", - figure=px.scatter( - iris_data, - x="sepal_width", - y="sepal_length", - color="species", - color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"}, - labels={"sepal_width": "Sepal Width", "sepal_length": "Sepal Length", "species": "Species"}, - ), - ), - vm.Graph( - id="hist_iris", - figure=px.histogram( - iris_data, - x="sepal_width", - color="species", - color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"}, - labels={"sepal_width": "Sepal Width", "count": "Count", "species": "Species"}, - ), + figure=px.line(stocks, x="date", y="GOOG", title="Stocks Data"), ), ], controls=[ - vm.Parameter( - targets=["scatter_iris.color_discrete_map.virginica", "hist_iris.color_discrete_map.virginica"], - selector=vm.Dropdown(options=["#ff5267", "#3949ab"], multi=False, value="#3949ab", title="Color Virginica"), - ), - vm.Parameter( - targets=["scatter_iris.opacity"], - selector=vm.Slider(min=0, max=1, value=0.8, title="Opacity"), - ), + vm.Filter(column="GOOG"), + vm.Filter(column="date", selector=vm.DatePicker(title="Date Picker (Stocks - date)")), ], ) -dashboard = vm.Dashboard(pages=[first_page, second_page]) +dashboard = vm.Dashboard(pages=[page]) if __name__ == "__main__": - Vizro().build(dashboard).run() + Vizro().build(dashboard).run() \ No newline at end of file From cfb1c3bc3bb1283eb66f2718a1480a46a948efd8 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Mon, 16 Dec 2024 09:14:40 -0800 Subject: [PATCH 08/11] example of mantine style --- .../models/_components/form/date_picker.py | 2 + vizro-core/src/vizro/models/_dashboard.py | 2 +- .../src/vizro/static/css/datepicker.css | 109 ------------------ 3 files changed, 3 insertions(+), 110 deletions(-) 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 80f884abb..d487ca9e6 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -67,6 +67,8 @@ def build(self): persistence_type="session", type="range" if self.range else "default", className="datepicker", + # removes the default red color for weekend days + styles={"day": {"color": "var(--mantine-color-text"}}, **date_range_picker_kwargs, ) diff --git a/vizro-core/src/vizro/models/_dashboard.py b/vizro-core/src/vizro/models/_dashboard.py index 23b6eb5f7..62e1f12be 100644 --- a/vizro-core/src/vizro/models/_dashboard.py +++ b/vizro-core/src/vizro/models/_dashboard.py @@ -175,7 +175,7 @@ def build(self): 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 = {...} + theme = {"primaryColor": "gray"} ) def _validate_logos(self): diff --git a/vizro-core/src/vizro/static/css/datepicker.css b/vizro-core/src/vizro/static/css/datepicker.css index 3e167d5d0..e69de29bb 100644 --- a/vizro-core/src/vizro/static/css/datepicker.css +++ b/vizro-core/src/vizro/static/css/datepicker.css @@ -1,109 +0,0 @@ -.datepicker .mantine-Input-wrapper { - font-family: unset; - height: 2rem; -} - -.datepicker .mantine-DateRangePicker-input, -.datepicker .mantine-DatePicker-input { - background-color: var(--field-enabled); - border: none; - border-radius: 0; - box-shadow: var(--elevation-0); - color: var(--text-secondary); - font-size: 0.875rem; - height: 2rem; - line-height: 1rem; - min-height: 2rem; - padding: 0 0.5rem; -} - -.datepicker .mantine-DateRangePicker-input:hover, -.datepicker .mantine-DatePicker-input:hover { - color: var(--text-primary); -} - -.datepicker .mantine-DateRangePicker-dropdown, -.datepicker .mantine-DatePicker-dropdown { - background: var(--field-enabled); - border: none; - border-radius: 0; - box-shadow: var(--elevation-1); - padding: 1rem 11px; /* 11px otherwise not aligned with controls */ -} - -.datepicker .mantine-UnstyledButton-root { - border-radius: 0; - color: var(--text-secondary); - font-family: unset; - font-weight: 400; -} - -.datepicker .mantine-UnstyledButton-root:hover { - background: var(--stateOverlays-hover); - color: var(--text-primary); -} - -.datepicker .mantine-DateRangePicker-weekday, -.datepicker .mantine-DatePicker-weekday { - color: var(--text-secondary); - font-family: unset; - padding: 0.5rem; -} - -.datepicker .mantine-DateRangePicker-cell, -.datepicker .mantine-DatePicker-cell { - border: none; -} - -.datepicker .mantine-DateRangePicker-day, -.datepicker .mantine-DatePicker-day { - background: var(--field-enabled); - border-radius: 0; - color: var(--text-secondary); - font-family: unset; -} - -.datepicker .mantine-DateRangePicker-day[data-outside], -.datepicker .mantine-DateRangePicker-day:disabled, -.datepicker .mantine-DatePicker-day[data-outside], -.datepicker .mantine-DatePicker-day:disabled, -.datepicker .mantine-UnstyledButton-root:disabled { - color: var(--text-disabled); -} - -.datepicker .mantine-DateRangePicker-day:hover, -.datepicker .mantine-DateRangePicker-day:focus-visible, -.datepicker .mantine-DatePicker-day:hover, -.datepicker .mantine-DatePicker-day:focus-visible { - background: var(--stateOverlays-hover); - border: none; - color: var(--text-primary); - outline: none; - text-decoration: none; -} - -.datepicker .mantine-DateRangePicker-day[data-in-range] { - background: var(--stateOverlays-selected); - color: var(--text-primary); -} - -.datepicker .mantine-DateRangePicker-day[data-selected], -.datepicker .mantine-DateRangePicker-yearPickerControlActive, -.datepicker .mantine-DateRangePicker-monthPickerControlActive, -.datepicker .mantine-DatePicker-day[data-selected], -.datepicker .mantine-DatePicker-yearPickerControlActive, -.datepicker .mantine-DatePicker-monthPickerControlActive { - background: var(--stateOverlays-selected-inverted); - color: var(--text-primary-inverted); - text-decoration: underline; -} - -.datepicker - .mantine-DateRangePicker-calendarHeader - .mantine-UnstyledButton-root:hover, -.datepicker - .mantine-DatePicker-calendarHeader - .mantine-UnstyledButton-root:hover { - background: transparent; - color: var(--text-primary); -} From 40aba6da2406b519eb95d86b83ce087271e8e564 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Mon, 6 Jan 2025 11:03:06 -0800 Subject: [PATCH 09/11] update after review --- vizro-core/src/vizro/models/_components/form/date_picker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 d487ca9e6..951d2c2ae 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -56,7 +56,7 @@ class DatePicker(VizroBaseModel): def build(self): init_value = self.value or ([self.min, self.max] if self.range else self.min) # type: ignore[list-item] - date_range_picker_kwargs = {"allowSingleDateInRange": True} if self.range else {} + date_range_picker_kwargs = {} date_picker = dmc.DatePickerInput( id=self.id, @@ -66,6 +66,7 @@ def build(self): persistence=True, persistence_type="session", type="range" if self.range else "default", + allowSingleDateInRange= True, className="datepicker", # removes the default red color for weekend days styles={"day": {"color": "var(--mantine-color-text"}}, From c216c98b8714dd1057b0e58a4e10b76065a606c3 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Mon, 6 Jan 2025 11:03:30 -0800 Subject: [PATCH 10/11] fixed tests --- .../_components/form/test_date_picker.py | 18 +++++++++--------- .../tests/unit/vizro/models/test_dashboard.py | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py b/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py index 4c794541b..c13d1faaf 100644 --- a/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py +++ b/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py @@ -117,25 +117,25 @@ def test_datepicker_build(self, range, value): min="2023-01-01", max="2023-07-01", range=range, value=value, id="datepicker_id", title="Test title" ).build() - date_picker_class = dmc.DateRangePicker if range else dmc.DatePicker - additional_kwargs = {"allowSingleDateInRange": True} if range else {} + additional_kwargs = {} expected_datepicker = html.Div( [ + dbc.Label("Test title", html_for="datepicker_id"), - date_picker_class( + dmc.DatePickerInput( id="datepicker_id", minDate="2023-01-01", - maxDate="2023-07-02", value=value, + maxDate="2023-07-01", persistence=True, persistence_type="session", - dropdownPosition="bottom-start", - disabledDates="2023-07-02", - clearable=False, + type="range" if range else "default", + allowSingleDateInRange=True, className="datepicker", + # removes the default red color for weekend days + styles={"day": {"color": "var(--mantine-color-text"}}, **additional_kwargs, - ), - dcc.Store(id="datepicker_id_input_store", storage_type="session", data=value), + ) ], ) assert_component_equal(date_picker, expected_datepicker) diff --git a/vizro-core/tests/unit/vizro/models/test_dashboard.py b/vizro-core/tests/unit/vizro/models/test_dashboard.py index 7d9ca5f08..d3e6d06da 100644 --- a/vizro-core/tests/unit/vizro/models/test_dashboard.py +++ b/vizro-core/tests/unit/vizro/models/test_dashboard.py @@ -2,6 +2,7 @@ import dash import dash_bootstrap_components as dbc +import dash_mantine_components as dmc import plotly.io as pio import pytest from asserts import assert_component_equal @@ -275,7 +276,7 @@ def test_dashboard_build(self, vizro_app, page_1, page_2): layout={"title": {"pad_l": 0, "pad_r": 0}, "margin_l": 24, "margin_t": 24, "margin_b": 16} ) - expected_dashboard_container = html.Div( + expected_dashboard_container = dmc.MantineProvider(html.Div( id="dashboard-container", children=[ html.Div(id="vizro_version", children=vizro.__version__, hidden=True), @@ -289,7 +290,7 @@ def test_dashboard_build(self, vizro_app, page_1, page_2): ActionLoop._create_app_callbacks(), dash.page_container, ], - ) + ), theme = {"primaryColor": "gray"}) assert_component_equal(dashboard.build(), expected_dashboard_container) From e3d446cc44829f0031f813acbcf51909cd7df97c Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Wed, 8 Jan 2025 06:19:35 -0800 Subject: [PATCH 11/11] update after review --- vizro-core/src/vizro/models/_components/form/date_picker.py | 2 -- .../unit/vizro/models/_components/form/test_date_picker.py | 3 --- 2 files changed, 5 deletions(-) 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 951d2c2ae..99b1db107 100644 --- a/vizro-core/src/vizro/models/_components/form/date_picker.py +++ b/vizro-core/src/vizro/models/_components/form/date_picker.py @@ -56,7 +56,6 @@ class DatePicker(VizroBaseModel): def build(self): init_value = self.value or ([self.min, self.max] if self.range else self.min) # type: ignore[list-item] - date_range_picker_kwargs = {} date_picker = dmc.DatePickerInput( id=self.id, @@ -70,7 +69,6 @@ def build(self): className="datepicker", # removes the default red color for weekend days styles={"day": {"color": "var(--mantine-color-text"}}, - **date_range_picker_kwargs, ) return html.Div( diff --git a/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py b/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py index c13d1faaf..90e03e2df 100644 --- a/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py +++ b/vizro-core/tests/unit/vizro/models/_components/form/test_date_picker.py @@ -117,10 +117,8 @@ def test_datepicker_build(self, range, value): min="2023-01-01", max="2023-07-01", range=range, value=value, id="datepicker_id", title="Test title" ).build() - additional_kwargs = {} expected_datepicker = html.Div( [ - dbc.Label("Test title", html_for="datepicker_id"), dmc.DatePickerInput( id="datepicker_id", @@ -134,7 +132,6 @@ def test_datepicker_build(self, range, value): className="datepicker", # removes the default red color for weekend days styles={"day": {"color": "var(--mantine-color-text"}}, - **additional_kwargs, ) ], )