diff --git a/CHANGELOG.md b/CHANGELOG.md index 24d64d85a..56774871f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * The `.get_latest_stream_result()` method on `ui.MarkdownStream()` was deprecated in favor of the new `.latest_stream` property. Call `.result()` on the property to get the latest result, `.status` to check the status, and `.cancel()` to cancel the stream. +* `ui.page_navbar()` and `ui.navset_bar()` now correctly apply `theme` and additional attributes from `navbar_options` created with `ui.navbar_options()`. (#1942) + ### Bug fixes * Fixed an issue where the `
` areas of `ui.page_sidebar()` and `ui.page_navbar()` (with a `sidebar`) were made to be a fillable containers even when `fillable=False`. (#1816) @@ -62,12 +64,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking changes -* The navbar-related style options of `ui.page_navbar()` and `ui.navset_bar()` have been consolidated into a single `navbar_options` argument that pairs with a new `ui.navbar_options()` helper. Using the direct `position`, `bg`, `inverse`, `collapsible`, and `underline` arguments will continue to work with a deprecation message. +* The navbar-related style options of `ui.page_navbar()` and `ui.navset_bar()` have been consolidated into a single `navbar_options` argument that pairs with a new `ui.navbar_options()` helper. Using the direct `position`, `bg`, `inverse`, `collapsible`, and `underline` arguments will continue to work with a deprecation message. (#1822) Related to this change, `ui.navset_bar()` now defaults to using `underline=True` so that it uses the same set of default `ui.navbar_options()` as the page variant. In `ui.navbar_options()`, `inverse` is replaced by `theme`, which takes values `"light"` (dark text on a **light** background), `"dark"` (light text on a **dark** background), or `"auto"` (follow page settings). -* The Shiny Core component `shiny.ui.Chat()` no longer has a `.ui()` method. This method -was never intended to be used in Shiny Core (in that case, use `shiny.ui.chat_ui()`) to create the UI element. Note that the `shiny.express.ui.Chat()` class still has a `.ui()` method. (#1840) +* The Shiny Core component `shiny.ui.Chat()` no longer has a `.ui()` method. This method was never intended to be used in Shiny Core (in that case, use `shiny.ui.chat_ui()`) to create the UI element. Note that the `shiny.express.ui.Chat()` class still has a `.ui()` method. (#1840) ### Bug fixes diff --git a/shiny/ui/_navs.py b/shiny/ui/_navs.py index 700e58780..4beb2a1a0 100644 --- a/shiny/ui/_navs.py +++ b/shiny/ui/_navs.py @@ -1320,7 +1320,12 @@ def layout(self, nav: Tag, content: Tag) -> TagList: nav = div(nav, id=collapse_id, class_="collapse navbar-collapse") nav_container.append(nav) - nav_final = tags.nav({"class": "navbar navbar-expand-md"}, nav_container) + nav_final = tags.nav( + {"class": "navbar navbar-expand-md"}, + nav_container, + {"data-bs-theme": self.navbar_options.theme}, + **self.navbar_options.attrs, + ) if self.navbar_options.position != "static-top": nav_final.add_class(self.navbar_options.position) diff --git a/tests/playwright/shiny/components/nav/navset_bar_options/app.py b/tests/playwright/shiny/components/nav/navset_bar_options/app.py new file mode 100644 index 000000000..4fdab5ed0 --- /dev/null +++ b/tests/playwright/shiny/components/nav/navset_bar_options/app.py @@ -0,0 +1,23 @@ +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_navbar( + ui.nav_panel( + "Page 1", + ui.navset_bar( + ui.nav_panel("Inner 1", "Inner content"), + title="Inner navbar", + id="inner_navset_bar", + navbar_options=ui.navbar_options(class_="bg-light", theme="light"), + ), + ), + title="Title", + id="page_navbar", + navbar_options=ui.navbar_options(class_="bg-primary", theme="dark"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) diff --git a/tests/playwright/shiny/components/nav/navset_bar_options/test_navset_bar_options.py b/tests/playwright/shiny/components/nav/navset_bar_options/test_navset_bar_options.py new file mode 100644 index 000000000..1fff16971 --- /dev/null +++ b/tests/playwright/shiny/components/nav/navset_bar_options/test_navset_bar_options.py @@ -0,0 +1,18 @@ +import re + +from playwright.sync_api import Page, expect + +from shiny.playwright import controller +from shiny.run import ShinyAppProc + + +def test_navset_bar_options(page: Page, local_app: ShinyAppProc) -> None: + page.goto(local_app.url) + + page_navbar = controller.PageNavbar(page, "page_navbar") + expect(page_navbar._loc_navbar).to_have_class(re.compile(r"(^|\s)bg-primary(\s|$)")) + expect(page_navbar._loc_navbar).to_have_attribute("data-bs-theme", "dark") + + inner_navbar = controller.NavsetBar(page, "inner_navset_bar") + expect(inner_navbar._loc_navbar).to_have_class(re.compile(r"(^|\s)bg-light(\s|$)")) + expect(inner_navbar._loc_navbar).to_have_attribute("data-bs-theme", "light") diff --git a/tests/pytest/test_navs.py b/tests/pytest/test_navs.py index e1e6c9f4b..d017c0355 100644 --- a/tests/pytest/test_navs.py +++ b/tests/pytest/test_navs.py @@ -157,7 +157,7 @@ def test_navset_bar_markup(): assert TagList(x).render()["html"] == textwrap.dedent( """\ -