Skip to content

Commit 3fe8c64

Browse files
authored
feat: Move navbar_options into single argument with helper navbar_options() (#1822)
1 parent f8be541 commit 3fe8c64

File tree

12 files changed

+583
-100
lines changed

12 files changed

+583
-100
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [UNRELEASED]
99

10+
### Breaking changes
11+
12+
* 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.
13+
14+
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).
15+
1016
### New features
1117

1218
* Added a new `ui.MarkdownStream()` component for performantly streaming in chunks of markdown/html strings into the UI. This component is primarily useful for text-based generative AI where responses are received incrementally. (#1782)

docs/_quartodoc-core.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ quartodoc:
8383
- ui.navset_card_underline
8484
- ui.navset_pill_list
8585
- ui.navset_hidden
86+
- ui.navbar_options
8687
- title: UI panels
8788
desc: Visually group together a section of UI components.
8889
contents:

docs/_quartodoc-express.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ quartodoc:
7777
- express.ui.navset_underline
7878
- express.ui.navset_pill_list
7979
- express.ui.navset_hidden
80+
- express.ui.navbar_options
8081
- title: Chat interface
8182
desc: Build a chatbot interface
8283
contents:
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from shiny import App, render, ui
2+
3+
app_ui = ui.page_fluid(
4+
ui.navset_bar(
5+
ui.nav_panel("A", "Panel A content"),
6+
ui.nav_panel("B", "Panel B content"),
7+
ui.nav_panel("C", "Panel C content"),
8+
ui.nav_menu(
9+
"Other links",
10+
ui.nav_panel("D", "Panel D content"),
11+
"----",
12+
"Description:",
13+
ui.nav_control(
14+
ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
15+
),
16+
),
17+
id="selected_navset_bar",
18+
title="Navset Bar",
19+
navbar_options=ui.navbar_options(
20+
bg="#B73A85",
21+
theme="dark",
22+
underline=False,
23+
),
24+
),
25+
ui.h5("Selected:"),
26+
ui.output_code("selected"),
27+
)
28+
29+
30+
def server(input, output, session):
31+
@render.code
32+
def selected():
33+
return input.selected_navset_bar()
34+
35+
36+
app = App(app_ui, server)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from shiny.express import input, render, ui
2+
3+
with ui.navset_bar(
4+
title="Navset Bar",
5+
id="selected_navset_bar",
6+
navbar_options=ui.navbar_options(
7+
bg="#B73A85",
8+
theme="dark",
9+
underline=False,
10+
),
11+
):
12+
with ui.nav_panel("A"):
13+
"Panel A content"
14+
15+
with ui.nav_panel("B"):
16+
"Panel B content"
17+
18+
with ui.nav_panel("C"):
19+
"Panel C content"
20+
21+
with ui.nav_menu("Other links"):
22+
with ui.nav_panel("D"):
23+
"Page D content"
24+
25+
"----"
26+
"Description:"
27+
with ui.nav_control():
28+
ui.a("Shiny", href="https://shiny.posit.co", target="_blank")
29+
ui.h5("Selected:")
30+
31+
32+
@render.code
33+
def _():
34+
return input.selected_navset_bar()

shiny/express/ui/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
notification_show,
108108
notification_remove,
109109
nav_spacer,
110+
navbar_options,
110111
Progress,
111112
Theme,
112113
value_box_theme,
@@ -288,6 +289,7 @@
288289
"navset_pill_list",
289290
"navset_tab",
290291
"navset_underline",
292+
"navbar_options",
291293
"value_box",
292294
"panel_well",
293295
"panel_conditional",

shiny/express/ui/_cm_components.py

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,19 @@
88

99
from ... import ui
1010
from ..._docstring import add_example, no_example
11-
from ...types import MISSING, MISSING_TYPE
11+
from ...types import DEPRECATED, MISSING, MISSING_TYPE
1212
from ...ui._accordion import AccordionPanel
1313
from ...ui._card import CardItem
1414
from ...ui._layout_columns import BreakpointsUser
15-
from ...ui._navs import NavMenu, NavPanel, NavSet, NavSetBar, NavSetCard
15+
from ...ui._navs import (
16+
NavbarOptions,
17+
NavbarOptionsPositionType,
18+
NavMenu,
19+
NavPanel,
20+
NavSet,
21+
NavSetBar,
22+
NavSetCard,
23+
)
1624
from ...ui._sidebar import SidebarOpenSpec, SidebarOpenValue
1725
from ...ui.css import CssUnit
1826
from .._recall_context import RecallContextManager
@@ -1067,17 +1075,16 @@ def navset_bar(
10671075
fillable: bool | list[str] = True,
10681076
gap: Optional[CssUnit] = None,
10691077
padding: Optional[CssUnit | list[CssUnit]] = None,
1070-
position: Literal[
1071-
"static-top", "fixed-top", "fixed-bottom", "sticky-top"
1072-
] = "static-top",
10731078
header: TagChild = None,
10741079
footer: TagChild = None,
1075-
bg: Optional[str] = None,
1076-
# TODO: default to 'auto', like we have in R (parse color via webcolors?)
1077-
inverse: bool = False,
1078-
underline: bool = True,
1079-
collapsible: bool = True,
1080+
navbar_options: Optional[NavbarOptions] = None,
10801081
fluid: bool = True,
1082+
# Deprecated ----
1083+
position: NavbarOptionsPositionType | MISSING_TYPE = DEPRECATED,
1084+
bg: str | None | MISSING_TYPE = DEPRECATED,
1085+
inverse: bool | MISSING_TYPE = DEPRECATED,
1086+
underline: bool | MISSING_TYPE = DEPRECATED,
1087+
collapsible: bool | MISSING_TYPE = DEPRECATED,
10811088
) -> RecallContextManager[NavSetBar]:
10821089
"""
10831090
Context manager for a set of nav items as a tabset inside a card container.
@@ -1095,16 +1102,15 @@ def navset_bar(
10951102
Choose a particular nav item to select by default value (should match it's
10961103
``value``).
10971104
sidebar
1098-
A :class:`~shiny.ui.Sidebar` component to display on every
1099-
:func:`~shiny.ui.nav_panel` page.
1105+
A :class:`~shiny.ui.Sidebar` component to display on every :func:`~shiny.ui.nav_panel` page.
11001106
fillable
11011107
Whether or not to allow fill items to grow/shrink to fit the browser window. If
11021108
`True`, all `nav()` pages are fillable. A character vector, matching the value
11031109
of `nav()`s to be filled, may also be provided. Note that, if a `sidebar` is
11041110
provided, `fillable` makes the main content portion fillable.
11051111
gap
11061112
A CSS length unit defining the gap (i.e., spacing) between elements provided to
1107-
`*args`.
1113+
`*args`. This value is only used when the navbar is `fillable`.
11081114
padding
11091115
Padding to use for the body. This can be a numeric vector (which will be
11101116
interpreted as pixels) or a character vector with valid CSS lengths. The length
@@ -1113,26 +1119,45 @@ def navset_bar(
11131119
the second value will be used for left and right. If three, then the first will
11141120
be used for top, the second will be left and right, and the third will be
11151121
bottom. If four, then the values will be interpreted as top, right, bottom, and
1116-
left respectively.
1122+
left respectively. This value is only used when the navbar is `fillable`.
1123+
header
1124+
UI to display above the selected content.
1125+
footer
1126+
UI to display below the selected content.
1127+
fluid
1128+
``True`` to use fluid layout; ``False`` to use fixed layout.
1129+
navbar_options
1130+
Configure the appearance and behavior of the navbar using
1131+
:func:`~shiny.ui.navbar_options` to set properties like position, background
1132+
color, and more.
1133+
1134+
`navbar_options` was added in v1.3.0 and replaces deprecated arguments
1135+
`position`, `bg`, `inverse`, `collapsible`, and `underline`.
11171136
position
1137+
Deprecated in v1.3.0. Please use `navbar_options` instead; see
1138+
:func:`~shiny.ui.navbar_options` for details.
1139+
11181140
Determines whether the navbar should be displayed at the top of the page with
11191141
normal scrolling behavior ("static-top"), pinned at the top ("fixed-top"), or
11201142
pinned at the bottom ("fixed-bottom"). Note that using "fixed-top" or
11211143
"fixed-bottom" will cause the navbar to overlay your body content, unless you
11221144
add padding (e.g., ``tags.style("body {padding-top: 70px;}")``).
1123-
header
1124-
UI to display above the selected content.
1125-
footer
1126-
UI to display below the selected content.
11271145
bg
1146+
Deprecated in v1.3.0. Please use `navbar_options` instead; see
1147+
:func:`~shiny.ui.navbar_options` for details.
1148+
11281149
Background color of the navbar (a CSS color).
11291150
inverse
1151+
Deprecated in v1.3.0. Please use `navbar_options` instead; see
1152+
:func:`~shiny.ui.navbar_options` for details.
1153+
11301154
Either ``True`` for a light text color or ``False`` for a dark text color.
11311155
collapsible
1132-
``True`` to automatically collapse the navigation elements into an expandable
1133-
menu on mobile devices or narrow window widths.
1134-
fluid
1135-
``True`` to use fluid layout; ``False`` to use fixed layout.
1156+
Deprecated in v1.3.0. Please use `navbar_options` instead; see
1157+
:func:`~shiny.ui.navbar_options` for details.
1158+
1159+
``True`` to automatically collapse the elements into an expandable menu on
1160+
mobile devices or narrow window widths.
11361161
"""
11371162
return RecallContextManager(
11381163
ui.navset_bar,
@@ -1144,14 +1169,16 @@ def navset_bar(
11441169
fillable=fillable,
11451170
gap=gap,
11461171
padding=padding,
1147-
position=position,
11481172
header=header,
11491173
footer=footer,
1174+
fluid=fluid,
1175+
navbar_options=navbar_options,
1176+
# Deprecated -- v1.3.0 2025-01 ----
1177+
position=position,
11501178
bg=bg,
11511179
inverse=inverse,
11521180
underline=underline,
11531181
collapsible=collapsible,
1154-
fluid=fluid,
11551182
),
11561183
)
11571184

shiny/types.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,17 @@
3636
if TYPE_CHECKING:
3737
from matplotlib.figure import Figure
3838

39+
T = TypeVar("T")
40+
3941

4042
# Sentinel value - indicates a missing value in a function call.
4143
class MISSING_TYPE:
4244
pass
4345

4446

4547
MISSING: MISSING_TYPE = MISSING_TYPE()
48+
DEPRECATED: MISSING_TYPE = MISSING_TYPE() # A MISSING that communicates deprecation
4649

47-
48-
T = TypeVar("T")
4950
ListOrTuple = Union[List[T], Tuple[T, ...]]
5051

5152

shiny/ui/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
nav_menu,
117117
nav_panel,
118118
nav_spacer,
119+
navbar_options,
119120
navset_bar,
120121
navset_card_pill,
121122
navset_card_tab,
@@ -295,6 +296,7 @@
295296
"navset_pill_list",
296297
"navset_hidden",
297298
"navset_bar",
299+
"navbar_options",
298300
# _notification
299301
"notification_show",
300302
"notification_remove",

0 commit comments

Comments
 (0)