-
Notifications
You must be signed in to change notification settings - Fork 100
feat: Move navbar_options
into single argument with helper navbar_options()
#1822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0527488
2f4b42b
0309d76
5f50b5a
d29617d
d7827b4
c93a257
b483f31
7f5b578
87e4abb
afc0dd2
7d13df9
15f5562
8844d73
4427769
9b7a62e
f01ece7
a1f497f
6b9274f
c9a242a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from shiny import App, render, ui | ||
|
||
app_ui = ui.page_fluid( | ||
ui.navset_bar( | ||
ui.nav_panel("A", "Panel A content"), | ||
ui.nav_panel("B", "Panel B content"), | ||
ui.nav_panel("C", "Panel C content"), | ||
ui.nav_menu( | ||
"Other links", | ||
ui.nav_panel("D", "Panel D content"), | ||
"----", | ||
"Description:", | ||
ui.nav_control( | ||
ui.a("Shiny", href="https://shiny.posit.co", target="_blank") | ||
), | ||
), | ||
id="selected_navset_bar", | ||
title="Navset Bar", | ||
navbar_options=ui.navbar_options( | ||
bg="#B73A85", | ||
theme="dark", | ||
underline=False, | ||
), | ||
), | ||
ui.h5("Selected:"), | ||
ui.output_code("selected"), | ||
) | ||
|
||
|
||
def server(input, output, session): | ||
@render.code | ||
def selected(): | ||
return input.selected_navset_bar() | ||
|
||
|
||
app = App(app_ui, server) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from shiny.express import input, render, ui | ||
|
||
with ui.navset_bar( | ||
title="Navset Bar", | ||
id="selected_navset_bar", | ||
navbar_options=ui.navbar_options( | ||
bg="#B73A85", | ||
theme="dark", | ||
underline=False, | ||
), | ||
): | ||
with ui.nav_panel("A"): | ||
"Panel A content" | ||
|
||
with ui.nav_panel("B"): | ||
"Panel B content" | ||
|
||
with ui.nav_panel("C"): | ||
"Panel C content" | ||
|
||
with ui.nav_menu("Other links"): | ||
with ui.nav_panel("D"): | ||
"Page D content" | ||
|
||
"----" | ||
"Description:" | ||
with ui.nav_control(): | ||
ui.a("Shiny", href="https://shiny.posit.co", target="_blank") | ||
ui.h5("Selected:") | ||
|
||
|
||
@render.code | ||
def _(): | ||
return input.selected_navset_bar() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,11 +8,19 @@ | |
|
||
from ... import ui | ||
from ..._docstring import add_example, no_example | ||
from ...types import MISSING, MISSING_TYPE | ||
from ...types import DEPRECATED, MISSING, MISSING_TYPE | ||
from ...ui._accordion import AccordionPanel | ||
from ...ui._card import CardItem | ||
from ...ui._layout_columns import BreakpointsUser | ||
from ...ui._navs import NavMenu, NavPanel, NavSet, NavSetBar, NavSetCard | ||
from ...ui._navs import ( | ||
NavbarOptions, | ||
NavbarOptionsPositionType, | ||
NavMenu, | ||
NavPanel, | ||
NavSet, | ||
NavSetBar, | ||
NavSetCard, | ||
) | ||
from ...ui._sidebar import SidebarOpenSpec, SidebarOpenValue | ||
from ...ui.css import CssUnit | ||
from .._recall_context import RecallContextManager | ||
|
@@ -1067,17 +1075,16 @@ def navset_bar( | |
fillable: bool | list[str] = True, | ||
gap: Optional[CssUnit] = None, | ||
padding: Optional[CssUnit | list[CssUnit]] = None, | ||
position: Literal[ | ||
"static-top", "fixed-top", "fixed-bottom", "sticky-top" | ||
] = "static-top", | ||
header: TagChild = None, | ||
footer: TagChild = None, | ||
bg: Optional[str] = None, | ||
# TODO: default to 'auto', like we have in R (parse color via webcolors?) | ||
inverse: bool = False, | ||
underline: bool = True, | ||
collapsible: bool = True, | ||
navbar_options: Optional[NavbarOptions] = None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel somewhat on the fence about this, but would you be open to having There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally open to it and it's certainly a route I thought about taking. It's a little more complicated because there are methods on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It turns out it's a bit more complicated because, unlike Code sample in pyright playground from typing import TypedDict
class NavbarOptions(TypedDict, total = False):
underline: bool
__extra_items__: str
def test(x: NavbarOptions) -> bool:
return x.get("underline", False)
test({"underline": True})
test({"class": "my-class"}) # we want this to be okay
#> Argument of type "dict[str, str]" cannot be assigned to parameter "x" of type "NavbarOptions" in function "test"
#> "class" is an undefined item in type "NavbarOptions" (reportArgumentType)
test({"underline": True, "class": "my-class"})
#> Argument of type "dict[str, bool | str]" cannot be assigned to parameter "x" of type "NavbarOptions" in function "test"
#> "class" is an undefined item in type "NavbarOptions" (reportArgumentType) It turns out there's a PEP for this but it's still in draft mode: https://peps.python.org/pep-0728/ |
||
fluid: bool = True, | ||
# Deprecated ---- | ||
position: NavbarOptionsPositionType | MISSING_TYPE = DEPRECATED, | ||
bg: str | None | MISSING_TYPE = DEPRECATED, | ||
inverse: bool | MISSING_TYPE = DEPRECATED, | ||
underline: bool | MISSING_TYPE = DEPRECATED, | ||
collapsible: bool | MISSING_TYPE = DEPRECATED, | ||
) -> RecallContextManager[NavSetBar]: | ||
""" | ||
Context manager for a set of nav items as a tabset inside a card container. | ||
|
@@ -1095,16 +1102,15 @@ def navset_bar( | |
Choose a particular nav item to select by default value (should match it's | ||
``value``). | ||
sidebar | ||
A :class:`~shiny.ui.Sidebar` component to display on every | ||
:func:`~shiny.ui.nav_panel` page. | ||
A :class:`~shiny.ui.Sidebar` component to display on every :func:`~shiny.ui.nav_panel` page. | ||
fillable | ||
Whether or not to allow fill items to grow/shrink to fit the browser window. If | ||
`True`, all `nav()` pages are fillable. A character vector, matching the value | ||
of `nav()`s to be filled, may also be provided. Note that, if a `sidebar` is | ||
provided, `fillable` makes the main content portion fillable. | ||
gap | ||
A CSS length unit defining the gap (i.e., spacing) between elements provided to | ||
`*args`. | ||
`*args`. This value is only used when the navbar is `fillable`. | ||
padding | ||
Padding to use for the body. This can be a numeric vector (which will be | ||
interpreted as pixels) or a character vector with valid CSS lengths. The length | ||
|
@@ -1113,26 +1119,45 @@ def navset_bar( | |
the second value will be used for left and right. If three, then the first will | ||
be used for top, the second will be left and right, and the third will be | ||
bottom. If four, then the values will be interpreted as top, right, bottom, and | ||
left respectively. | ||
left respectively. This value is only used when the navbar is `fillable`. | ||
header | ||
UI to display above the selected content. | ||
footer | ||
UI to display below the selected content. | ||
fluid | ||
``True`` to use fluid layout; ``False`` to use fixed layout. | ||
navbar_options | ||
Configure the appearance and behavior of the navbar using | ||
:func:`~shiny.ui.navbar_options` to set properties like position, background | ||
color, and more. | ||
|
||
`navbar_options` was added in v1.3.0 and replaces deprecated arguments | ||
`position`, `bg`, `inverse`, `collapsible`, and `underline`. | ||
position | ||
Deprecated in v1.3.0. Please use `navbar_options` instead; see | ||
:func:`~shiny.ui.navbar_options` for details. | ||
|
||
Determines whether the navbar should be displayed at the top of the page with | ||
normal scrolling behavior ("static-top"), pinned at the top ("fixed-top"), or | ||
pinned at the bottom ("fixed-bottom"). Note that using "fixed-top" or | ||
"fixed-bottom" will cause the navbar to overlay your body content, unless you | ||
add padding (e.g., ``tags.style("body {padding-top: 70px;}")``). | ||
header | ||
UI to display above the selected content. | ||
footer | ||
UI to display below the selected content. | ||
bg | ||
Deprecated in v1.3.0. Please use `navbar_options` instead; see | ||
:func:`~shiny.ui.navbar_options` for details. | ||
|
||
Background color of the navbar (a CSS color). | ||
inverse | ||
Deprecated in v1.3.0. Please use `navbar_options` instead; see | ||
:func:`~shiny.ui.navbar_options` for details. | ||
|
||
Either ``True`` for a light text color or ``False`` for a dark text color. | ||
collapsible | ||
``True`` to automatically collapse the navigation elements into an expandable | ||
menu on mobile devices or narrow window widths. | ||
fluid | ||
``True`` to use fluid layout; ``False`` to use fixed layout. | ||
Deprecated in v1.3.0. Please use `navbar_options` instead; see | ||
:func:`~shiny.ui.navbar_options` for details. | ||
|
||
``True`` to automatically collapse the elements into an expandable menu on | ||
mobile devices or narrow window widths. | ||
""" | ||
return RecallContextManager( | ||
ui.navset_bar, | ||
|
@@ -1144,14 +1169,16 @@ def navset_bar( | |
fillable=fillable, | ||
gap=gap, | ||
padding=padding, | ||
position=position, | ||
header=header, | ||
footer=footer, | ||
fluid=fluid, | ||
navbar_options=navbar_options, | ||
# Deprecated -- v1.3.0 2025-01 ---- | ||
position=position, | ||
bg=bg, | ||
inverse=inverse, | ||
underline=underline, | ||
collapsible=collapsible, | ||
fluid=fluid, | ||
), | ||
) | ||
|
||
|
gadenbuie marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the "breaking" change here could be considered more of an improvement than a regression, I'd be in favor of renaming this section to
### Changes
(or even### Improvements
and putting it just after### New features
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the same thought, but we do emit deprecation warnings that say, effectively, "your current code is being deprecated, please update it". I know it's not strictly breaking but I'd personally rather read a changelog that differentiates between "you might need to take action" and "you might want to know about this" items.