Skip to content

Commit

Permalink
Merge branch 'main' into dev/pydantic-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
antonymilne committed Dec 7, 2023
2 parents a5ddf6d + c1e9071 commit 6b3eb45
Show file tree
Hide file tree
Showing 16 changed files with 146 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨
- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Removed
- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
-->

### Added

- Enable tooltips for `NavLink`. ([#186](https://github.com/mckinsey/vizro/pull/186))

<!--
### Changed
- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Deprecated
- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Fixed
- A bullet item for the Fixed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Security
- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified vizro-core/docs/assets/user_guides/navigation/custom_icons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified vizro-core/docs/assets/user_guides/navigation/nav_bar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion vizro-core/docs/pages/user_guides/navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ Another way to group together pages in the navigation is to use a [`NavBar`][viz
[NavBar]: ../../assets/user_guides/navigation/nav_bar.png


Here, the first level of the navigation hierarchy ("Group A" and "Group B") is represented by an icon in a navigation bar, and the second level of the navigation (the pages) is represented by an accordion. By default, the icons are the [`filter` icons from the Google Material icons library](https://fonts.google.com/icons?icon.query=filter).
Here, the first level of the navigation hierarchy ("Group A" and "Group B") is represented by an icon in a navigation bar, and the second level of the navigation (the pages) is represented by an accordion. By default, the icons are the [`filter` icons from the Google Material icons library](https://fonts.google.com/icons?icon.query=filter). The icon label ("Group A" and "Group B") appears as a tooltip on hovering over the icon.

## Customizing the navigation bar

Expand Down
3 changes: 2 additions & 1 deletion vizro-core/examples/default/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,8 @@ def create_home_page():
pages={
"Analysis": ["Homepage", "Variable Analysis", "Relationship Analysis", "Country Analysis"],
"Summary": ["Continent Summary"],
}
},
nav_selector=vm.NavBar(),
),
)

Expand Down
1 change: 1 addition & 0 deletions vizro-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies = [
"pandas",
"pydantic>=1.10.13", # must be synced with pre-commit mypy hook manually
"dash_daq",
"dash_mantine_components",
"ipython>=8.10.0", # not directly required, pinned by Snyk to avoid a vulnerability: https://app.snyk.io/vuln/SNYK-PYTHON-IPYTHON-3318382
"numpy>=1.22.2", # not directly required, pinned by Snyk to avoid a vulnerability: https://security.snyk.io/vuln/SNYK-PYTHON-NUMPY-2321970
"tornado>=6.3.2", # not directly required, pinned by Snyk to avoid a vulnerability: https://security.snyk.io/vuln/SNYK-PYTHON-TORNADO-5537286
Expand Down
1 change: 1 addition & 0 deletions vizro-core/snyk/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ dash_bootstrap_components
pandas
pydantic>=1.10.13
dash_daq
dash_mantine_components
ipython>=8.10.0
numpy>=1.22.2
tornado>=6.3.2
Expand Down
1 change: 1 addition & 0 deletions vizro-core/src/vizro/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

# Please keep alphabetically ordered
__all__ = [
"Accordion",
"Action",
"Button",
"Card",
Expand Down
2 changes: 1 addition & 1 deletion vizro-core/src/vizro/models/_navigation/accordion.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def build(self, *, active_page_id=None):
dbc.AccordionItem(
children=accordion_buttons,
title=page_group.upper(),
class_name="accordion_item",
class_name="accordion-item-header",
)
)

Expand Down
12 changes: 8 additions & 4 deletions vizro-core/src/vizro/models/_navigation/nav_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import dash
import dash_bootstrap_components as dbc
import dash_mantine_components as dmc
from dash import html

try:
Expand Down Expand Up @@ -61,10 +62,13 @@ def build(self, *, active_page_id=None):

button = dbc.Button(
[
html.Span(self.icon, className="material-symbols-outlined"),
# TODO: commented out until we insert styling for the tooltip or find a better way to display it (e.g.
# try dbc.Popover or Dash mantine components tooltip?).
# dbc.Tooltip(html.P(self.label), target=self.id, placement="bottom", className="custom-tooltip"),
dmc.Tooltip(
label=self.label,
offset=4,
withArrow=True,
children=[html.Span(self.icon, className="material-symbols-outlined")],
position="bottom-start",
)
],
id=self.id,
className="icon-button",
Expand Down
44 changes: 20 additions & 24 deletions vizro-core/src/vizro/static/css/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@

.icon-button {
background-color: var(--surfaces-bg-02);
width: 64px;
width: 100%;
height: 64px;
display: flex;
align-items: center;
Expand All @@ -131,32 +131,28 @@ div.dashboard_container .tooltip-inner {
div.dashboard_container .custom-tooltip {
color: var(--text-primary);
}
.icon-text {
font-size: var(--text-size-02);
letter-spacing: var(--letter-spacing-body-edit-01);
color: var(--text-secondary);
padding: 4px;
}

.nav-icon {
filter: var(--fill-accordion-button);
width: 24px;
height: 24px;
}

.nav-icon-text {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
justify-content: center;
}

.icon-button.btn.btn-primary.active {
background-color: var(--state-overlays-selected);
.icon-button.btn.btn-primary.active .material-symbols-outlined {
color: var(--text-active);
}

.loading-container {
height: 100%;
width: 100%;
}

.mantine-Tooltip-tooltip {
font-size: var(--text-size-01);
font-weight: var(--text-weight-light);
line-height: 16px;
letter-spacing: var(--letter-spacing-help-text);
padding: var(--spacing-01) var(--spacing-02);
color: var(--tooltip-text-primary);
background-color: var(--border-selected);
max-width: 180px;
overflow-wrap: break-word;
text-wrap: wrap;
filter: drop-shadow(0px 2px 2px #141721);
border-radius: 0;
box-shadow: var(--box-shadow-elevation-tooltip-hover);
white-space: pre-wrap;
}
4 changes: 4 additions & 0 deletions vizro-core/src/vizro/static/css/slider.css
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,7 @@
justify-content: space-between;
width: 100%;
}

input.dash-input:invalid {
outline: none;
}
6 changes: 6 additions & 0 deletions vizro-core/src/vizro/static/css/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@
--state-overlays-selected-hover: var(
--state-overlays-dark-mode-selected-hover
);
--tooltip-text-primary: rgba(20, 23, 33, 0.88);
--box-shadow-elevation-tooltip-hover: 0px 4px 8px 0px rgba(20, 23, 33, 0.38),
0px 2px 4px -1px rgba(20, 23, 33, 0.88);
}

.vizro_light {
Expand Down Expand Up @@ -143,4 +146,7 @@
--state-overlays-selected-hover: var(
--state-overlays-light-mode-selected-hover
);
--tooltip-text-primary: rgba(255, 255, 255, 0.88);
--box-shadow-elevation-tooltip-hover: 0px 4px 8px 0px rgba(20, 23, 33, 0.12),
0px 2px 4px -1px rgba(20, 23, 33, 0.08);
}
47 changes: 41 additions & 6 deletions vizro-core/tests/unit/vizro/models/_navigation/test_nav_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import re

import dash_bootstrap_components as dbc
import dash_mantine_components as dmc
import pytest
from asserts import assert_component_equal
from dash import html
Expand Down Expand Up @@ -77,11 +78,21 @@ def test_items_with_with_pages_icons(self, pages_as_dict):
class TestNavBarBuildMethod:
"""Tests NavBar model build method."""

common_args = {"offset": 4, "withArrow": True, "position": "bottom-start"}

def test_nav_bar_active_pages_as_dict(self, pages_as_dict):
nav_bar = vm.NavBar(pages=pages_as_dict)
nav_bar.pre_build()
built_nav_bar = nav_bar.build(active_page_id="Page 1")
expected_button = html.Div([dbc.Button(children=[html.Span(children="filter_1")], active=True, href="/")])
expected_button = html.Div(
[
dbc.Button(
children=[dmc.Tooltip(label="Group", children=[html.Span("filter_1")], **self.common_args)],
active=True,
href="/",
)
]
)
assert_component_equal(built_nav_bar["nav_bar_outer"], expected_button)
assert_component_equal(
built_nav_bar["nav_panel_outer"], html.Div(id="nav_panel_outer"), keys_to_strip={"children", "className"}
Expand All @@ -94,8 +105,16 @@ def test_nav_bar_active_pages_as_list(self, pages_as_list):
built_nav_bar = nav_bar.build(active_page_id="Page 1")
expected_buttons = html.Div(
[
dbc.Button(children=[html.Span(children="filter_1")], active=True, href="/"),
dbc.Button(children=[html.Span(children="filter_2")], active=False, href="/page-2"),
dbc.Button(
children=[dmc.Tooltip(label="Page 1", children=[html.Span("filter_1")], **self.common_args)],
active=True,
href="/",
),
dbc.Button(
children=[dmc.Tooltip(label="Page 2", children=[html.Span("filter_2")], **self.common_args)],
active=False,
href="/page-2",
),
]
)
assert_component_equal(built_nav_bar["nav_bar_outer"], expected_buttons)
Expand All @@ -109,7 +128,15 @@ def test_nav_bar_not_active_pages_as_dict(self, pages_as_dict):
nav_bar = vm.NavBar(pages=pages_as_dict)
nav_bar.pre_build()
built_nav_bar = nav_bar.build(active_page_id="Page 3")
expected_button = html.Div([dbc.Button(children=[html.Span(children="filter_1")], active=False, href="/")])
expected_button = html.Div(
[
dbc.Button(
children=[dmc.Tooltip(label="Group", children=[html.Span("filter_1")], **self.common_args)],
active=False,
href="/",
)
]
)
assert_component_equal(built_nav_bar["nav_bar_outer"], expected_button)
assert_component_equal(
built_nav_bar["nav_panel_outer"], html.Div(hidden=True, id="nav_panel_outer"), keys_to_strip={}
Expand All @@ -121,8 +148,16 @@ def test_nav_bar_not_active_pages_as_list(self, pages_as_list):
built_nav_bar = nav_bar.build(active_page_id="Page 3")
expected_buttons = html.Div(
[
dbc.Button(children=[html.Span(children="filter_1")], active=False, href="/"),
dbc.Button(children=[html.Span(children="filter_2")], active=False, href="/page-2"),
dbc.Button(
children=[dmc.Tooltip(label="Page 1", children=[html.Span("filter_1")], **self.common_args)],
active=False,
href="/",
),
dbc.Button(
children=[dmc.Tooltip(label="Page 2", children=[html.Span("filter_2")], **self.common_args)],
active=False,
href="/page-2",
),
]
)
assert_component_equal(built_nav_bar["nav_bar_outer"], expected_buttons)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import re

import dash_bootstrap_components as dbc
import dash_mantine_components as dmc
import pytest
from asserts import assert_component_equal
from dash import html
Expand Down Expand Up @@ -72,12 +73,18 @@ def test_nav_link(self, pages_as_dict):
class TestNavLinkBuildMethod:
"""Tests NavLink model build method."""

common_args = {"offset": 4, "withArrow": True, "position": "bottom-start"}

def test_nav_link_active(self, pages, request):
pages = request.getfixturevalue(pages)
nav_link = vm.NavLink(id="nav_link", label="Label", icon="icon", pages=pages)
nav_link.pre_build()
built_nav_link = nav_link.build(active_page_id="Page 1")
expected_button = dbc.Button(id="nav_link", children=[html.Span("icon")], active=True, href="/")
expected_button = dbc.Button(
children=[dmc.Tooltip(label="Label", children=[html.Span("icon")], **self.common_args)],
active=True,
href="/",
)
assert_component_equal(built_nav_link["nav_link"], expected_button)
assert all(isinstance(child, dbc.Accordion) for child in built_nav_link["nav_panel_outer"].children)

Expand All @@ -86,6 +93,10 @@ def test_nav_link_not_active(self, pages, request):
nav_link = vm.NavLink(id="nav_link", label="Label", icon="icon", pages=pages)
nav_link.pre_build()
built_nav_link = nav_link.build(active_page_id="Page 3")
expected_button = dbc.Button(id="nav_link", children=[html.Span("icon")], active=False, href="/")
expected_button = dbc.Button(
children=[dmc.Tooltip(label="Label", children=[html.Span("icon")], **self.common_args)],
active=False,
href="/",
)
assert_component_equal(built_nav_link["nav_link"], expected_button)
assert "nav_panel_outer" not in built_nav_link

0 comments on commit 6b3eb45

Please sign in to comment.