Skip to content

Commit d8c91ed

Browse files
committed
add capability for navset
1 parent f59adeb commit d8c91ed

File tree

2 files changed

+123
-19
lines changed

2 files changed

+123
-19
lines changed

shiny/ui/_navs.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
tags,
1919
)
2020

21+
from shiny.bookmark._restore_state import restore_input
22+
2123
from .._deprecated import warn_deprecated
2224
from .._docstring import add_example
2325
from .._namespaces import resolve_id_or_none
@@ -393,9 +395,11 @@ def __init__(
393395
header: TagChild = None,
394396
footer: TagChild = None,
395397
) -> None:
398+
id_resolved = resolve_id_or_none(id)
399+
selected = restore_input(id_resolved, selected) if id_resolved else selected
396400
self.args = args
397401
self.ul_class = ul_class
398-
self.id = id
402+
self.id = id_resolved
399403
self.selected = selected
400404
self.header = header
401405
self.footer = footer
@@ -464,11 +468,12 @@ def navset_tab(
464468
-------
465469
See :func:`~shiny.ui.nav_panel`
466470
"""
467-
471+
id_resolved = resolve_id_or_none(id)
472+
selected = restore_input(id_resolved, selected) if id_resolved else selected
468473
return NavSet(
469474
*args,
470475
ul_class="nav nav-tabs",
471-
id=resolve_id_or_none(id),
476+
id=id_resolved,
472477
selected=selected,
473478
header=header,
474479
footer=footer,
@@ -520,11 +525,12 @@ def navset_pill(
520525
-------
521526
See :func:`~shiny.ui.nav_panel`
522527
"""
523-
528+
id_resolved = resolve_id_or_none(id)
529+
selected = restore_input(id_resolved, selected) if id_resolved else selected
524530
return NavSet(
525531
*args,
526532
ul_class="nav nav-pills",
527-
id=resolve_id_or_none(id),
533+
id=id_resolved,
528534
selected=selected,
529535
header=header,
530536
footer=footer,
@@ -576,10 +582,12 @@ def navset_underline(
576582
-------
577583
See :func:`~shiny.ui.nav_panel`
578584
"""
585+
id_resolved = resolve_id_or_none(id)
586+
selected = restore_input(id_resolved, selected) if id_resolved else selected
579587
return NavSet(
580588
*args,
581589
ul_class="nav nav-underline",
582-
id=resolve_id_or_none(id),
590+
id=id_resolved,
583591
selected=selected,
584592
header=header,
585593
footer=footer,
@@ -627,11 +635,12 @@ def navset_hidden(
627635
* :func:`~shiny.ui.navset_card_underline`
628636
* :func:`~shiny.ui.navset_pill_list`
629637
"""
630-
638+
id_resolved = resolve_id_or_none(id)
639+
selected = restore_input(id_resolved, selected) if id_resolved else selected
631640
return NavSet(
632641
*args,
633642
ul_class="nav nav-hidden",
634-
id=resolve_id_or_none(id),
643+
id=id_resolved,
635644
selected=selected,
636645
header=header,
637646
footer=footer,
@@ -655,10 +664,12 @@ def __init__(
655664
footer: TagChild = None,
656665
placement: Literal["above", "below"] = "above",
657666
) -> None:
667+
id_resolved = resolve_id_or_none(id)
668+
selected = restore_input(id_resolved, selected) if id_resolved else selected
658669
super().__init__(
659670
*args,
660671
ul_class=ul_class,
661-
id=id,
672+
id=id_resolved,
662673
selected=selected,
663674
header=header,
664675
footer=footer,
@@ -747,11 +758,12 @@ def navset_card_tab(
747758
-------
748759
See :func:`~shiny.ui.nav_panel`
749760
"""
750-
761+
id_resolved = resolve_id_or_none(id)
762+
selected = restore_input(id_resolved, selected) if id_resolved else selected
751763
return NavSetCard(
752764
*args,
753765
ul_class="nav nav-tabs card-header-tabs",
754-
id=resolve_id_or_none(id),
766+
id=id_resolved,
755767
selected=selected,
756768
title=title,
757769
sidebar=sidebar,
@@ -813,11 +825,12 @@ def navset_card_pill(
813825
-------
814826
See :func:`~shiny.ui.nav_panel`
815827
"""
816-
828+
id_resolved = resolve_id_or_none(id)
829+
selected = restore_input(id_resolved, selected) if id_resolved else selected
817830
return NavSetCard(
818831
*args,
819832
ul_class="nav nav-pills card-header-pills",
820-
id=resolve_id_or_none(id),
833+
id=id_resolved,
821834
selected=selected,
822835
title=title,
823836
sidebar=sidebar,
@@ -879,10 +892,12 @@ def navset_card_underline(
879892
-------
880893
See :func:`~shiny.ui.nav_panel`
881894
"""
895+
id_resolved = resolve_id_or_none(id)
896+
selected = restore_input(id_resolved, selected) if id_resolved else selected
882897
return NavSetCard(
883898
*args,
884899
ul_class="nav nav-underline",
885-
id=resolve_id_or_none(id),
900+
id=id_resolved,
886901
selected=selected,
887902
title=title,
888903
sidebar=sidebar,
@@ -907,10 +922,12 @@ def __init__(
907922
well: bool = True,
908923
widths: tuple[int, int] = (4, 8),
909924
) -> None:
925+
id_resolved = resolve_id_or_none(id)
926+
selected = restore_input(id_resolved, selected) if id_resolved else selected
910927
super().__init__(
911928
*args,
912929
ul_class=ul_class,
913-
id=id,
930+
id=id_resolved,
914931
selected=selected,
915932
header=header,
916933
footer=footer,
@@ -977,11 +994,12 @@ def navset_pill_list(
977994
-------
978995
See :func:`~shiny.ui.nav_panel`
979996
"""
980-
997+
id_resolved = resolve_id_or_none(id)
998+
selected = restore_input(id_resolved, selected) if id_resolved else selected
981999
return NavSetPillList(
9821000
*args,
9831001
ul_class="nav nav-pills nav-stacked",
984-
id=resolve_id_or_none(id),
1002+
id=id_resolved,
9851003
selected=selected,
9861004
header=header,
9871005
footer=footer,
@@ -1566,11 +1584,12 @@ def navset_bar(
15661584
ul_class = "nav navbar-nav"
15671585
if navbar_opts.underline:
15681586
ul_class += " nav-underline"
1569-
1587+
id_resolved = resolve_id_or_none(id)
1588+
selected = restore_input(id_resolved, selected) if id_resolved else selected
15701589
return NavSetBar(
15711590
*new_args,
15721591
ul_class=ul_class,
1573-
id=resolve_id_or_none(id),
1592+
id=id_resolved,
15741593
selected=selected,
15751594
sidebar=sidebar,
15761595
fillable=fillable,
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from typing import Any, Dict
2+
3+
from shiny.express import expressify, module, session, ui
4+
5+
ui.page_opts(
6+
title="Navsets kitchensink App", id="navsets_collection", bookmark_store="url"
7+
)
8+
9+
10+
navset_configs: Dict[str, Dict[str, Dict[str, Any]]] = {
11+
"navset_pill": {
12+
"default": {},
13+
},
14+
"navset_underline": {
15+
"default": {},
16+
},
17+
"navset_tab": {
18+
"default": {},
19+
},
20+
"navset_pill_list": {
21+
"default": {},
22+
},
23+
"navset_card_pill": {
24+
"default": {},
25+
},
26+
"navset_card_tab": {
27+
"default": {},
28+
},
29+
"navset_card_underline": {
30+
"default": {},
31+
},
32+
}
33+
34+
35+
@expressify
36+
def create_navset(navset_type: str) -> None:
37+
navset_function = getattr(ui, navset_type)
38+
39+
for navset_id, params in navset_configs[navset_type].items():
40+
navset_kwargs = params.copy()
41+
42+
if "header" in navset_kwargs:
43+
header_content = navset_kwargs["header"]["content"]
44+
header_id = navset_kwargs["header"]["id"]
45+
navset_kwargs["header"] = ui.tags.div(header_content, id=f"{header_id}")
46+
47+
if "footer" in navset_kwargs:
48+
footer_content = navset_kwargs["footer"]["content"]
49+
footer_id = navset_kwargs["footer"]["id"]
50+
navset_kwargs["footer"] = ui.tags.div(footer_content, id=f"{footer_id}")
51+
52+
with navset_function(id=f"{navset_type}_{navset_id}", **navset_kwargs):
53+
for suffix in ["a", "b", "c"]:
54+
with ui.nav_panel(f"{navset_type}_{suffix}"):
55+
ui.markdown(f"{navset_type}_{suffix} content")
56+
57+
58+
with ui.card():
59+
ui.card_header("Bookmarking Navset Demo")
60+
61+
# Non-modular section
62+
ui.h3("Non-Module Section")
63+
64+
with ui.navset_tab(id="navsets_collection"):
65+
for navset_type in navset_configs.keys():
66+
with ui.nav_panel(navset_type):
67+
create_navset(navset_type)
68+
69+
@module
70+
def navset_module(input, output, session):
71+
ui.h3("Navset Module")
72+
73+
with ui.navset_tab(id="navsets_collection"):
74+
for navset_type in navset_configs.keys():
75+
with ui.nav_panel(navset_type):
76+
create_navset(navset_type)
77+
78+
navset_module("first")
79+
80+
ui.input_bookmark_button()
81+
82+
83+
@session.bookmark.on_bookmarked
84+
async def _(url: str):
85+
await session.bookmark.update_query_string(url)

0 commit comments

Comments
 (0)