Skip to content

Commit f74e938

Browse files
committed
Initial untested module express example
1 parent b350733 commit f74e938

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from shiny import reactive
2+
from shiny.express import render
3+
from .modules import custom_sidebar, add_to_counter_content
4+
5+
tabs_added = reactive.value(0)
6+
7+
8+
def increment_tabs_counter():
9+
tabs_added.set(tabs_added() + 1)
10+
11+
12+
custom_sidebar(
13+
"nav",
14+
_on_click=increment_tabs_counter,
15+
label="Dynamic Sidebar",
16+
)
17+
18+
add_to_counter_content(
19+
"buttonAdder",
20+
_on_click=increment_tabs_counter,
21+
starting_value=0,
22+
label="Add to Counter",
23+
)
24+
25+
26+
@render.code
27+
def out():
28+
return f"Tabs added: {tabs_added()}"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from shiny import reactive
2+
from shiny.express import ui, module
3+
4+
5+
@module
6+
def add_to_counter_content(
7+
input, output, session, _on_click, starting_value, label="Add to Counter"
8+
):
9+
count = reactive.value(starting_value)
10+
ui.input_action_button("add", label)
11+
12+
@reactive.effect
13+
@reactive.event(input.add)
14+
def increment_button():
15+
_on_click()
16+
count.set(count() + 1)
17+
18+
19+
@module
20+
def custom_sidebar(
21+
input, output, session, _on_click, starting_value=0, label="Dynamic Sidebar"
22+
):
23+
count = reactive.value(starting_value)
24+
25+
@reactive.effect
26+
@reactive.event(input.addFoo)
27+
def increment_button():
28+
_on_click()
29+
count.set(count() + 1)
30+
31+
with ui.sidebar():
32+
ui.input_action_button("add", "Add 'Dynamic' tab")
33+
ui.input_action_button("removeFoo", "Remove 'Foo' tabs")
34+
ui.input_action_button("addFoo", "Add New 'Foo' tab")
35+
36+
@reactive.effect()
37+
@reactive.event(input.removeFoo)
38+
def _():
39+
ui.remove_nav_panel("tabs", target="Foo")
40+
41+
@reactive.effect()
42+
@reactive.event(input.addFoo)
43+
def _():
44+
n = str(input.addFoo())
45+
ui.insert_nav_panel(
46+
"tabs",
47+
"Foo-" + n,
48+
"This is the new Foo-" + n + " tab",
49+
value="Foo",
50+
target="Menu",
51+
position="before",
52+
select=True,
53+
)
54+
55+
with ui.navset_tab(id="tabs"):
56+
with ui.nav_panel("Hello", value="Hello"):
57+
"This is the hello tab"
58+
with ui.nav_panel("Foo", value="Foo"):
59+
"This is the Foo tab"
60+
with ui.nav_menu("Static", value="Menu"):
61+
with ui.nav_panel("Static 1", value="s1"):
62+
"Static 1"
63+
with ui.nav_panel("Static 2", value="s2"):
64+
"Static 2"
65+
66+
@reactive.effect()
67+
@reactive.event(input.add)
68+
def _():
69+
id = "Dynamic-" + str(input.add())
70+
ui.insert_nav_panel("tabs", title=id, value=id, target="s2", position="before")
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# import pytest
2+
import pytest
3+
from playwright.sync_api import Page, expect
4+
5+
from shiny.playwright import controller
6+
from shiny.run import ShinyAppProc
7+
8+
9+
@pytest.mark.flaky(reruns=3, reruns_delay=2)
10+
def test_dynamic_navs(page: Page, local_app: ShinyAppProc) -> None:
11+
page.goto(local_app.url)
12+
13+
# Page begins with 2 tabs: "Hello" and "Foo" and a nav menu with 2 static items.
14+
navset_tab = controller.NavsetTab(page, "tabs")
15+
16+
# Click add-foo to add a new Foo tab
17+
addfoo = controller.InputActionButton(page, "addFoo")
18+
addfoo.click()
19+
controller.NavsetTab(page, "tabs").expect_nav_titles(
20+
["Hello", "Foo", "Foo-1", "Static1", "Static2"]
21+
)
22+
# Test Foo-1 tab is added
23+
navpanel = controller.NavPanel(page, "tabs", "Foo").loc.filter(has_text="Foo-1")
24+
expect(navpanel).to_have_text("Foo-1")
25+
26+
# Click hide-tab to hide the Foo tabs
27+
hidetab = controller.InputActionButton(page, "hideTab")
28+
hidetab.click()
29+
30+
# Expect the Foo tabs to be hidden
31+
navpanel = controller.NavPanel(page, "tabs", "Foo").loc.filter(has_text="Foo-1")
32+
expect(navpanel).to_be_hidden()
33+
navpanel = controller.NavPanel(page, "tabs", "Foo").loc.filter(
34+
has_text="This is the Foo tab"
35+
)
36+
expect(navpanel).to_be_hidden()
37+
38+
# Click show-tab to show the Foo tabs again
39+
showtab = controller.InputActionButton(page, "showTab")
40+
showtab.click()
41+
42+
# Expect the Foo tabs to be visible again
43+
navpanel2 = controller.NavPanel(page, "tabs", "Foo").loc.first
44+
expect(navpanel2).to_be_visible()
45+
navpanel3 = controller.NavPanel(page, "tabs", "Foo").loc.last
46+
expect(navpanel3).to_be_visible()
47+
48+
# Click remove-foo to remove the Foo tabs
49+
removefoo = controller.InputActionButton(page, "removeFoo")
50+
removefoo.click()
51+
controller.NavsetTab(page, "tabs").expect_nav_titles(
52+
["Hello", "Static1", "Static2"]
53+
)
54+
55+
# Click add to add a dynamic tab
56+
add = controller.InputActionButton(page, "add")
57+
add.click()
58+
controller.NavsetTab(page, "tabs").expect_nav_titles(
59+
["Hello", "Static1", "Dynamic-1", "Static2"]
60+
)
61+
62+
# Click add again to add another dynamic tab
63+
add.click()
64+
controller.NavsetTab(page, "tabs").expect_nav_titles(
65+
["Hello", "Static1", "Dynamic-1", "Dynamic-2", "Static2"]
66+
)
67+
68+
page.get_by_role("button", name="Menu", exact=True).click()
69+
70+
navpanel3 = controller.NavPanel(page, "tabs", "s1").loc
71+
expect(navpanel3).to_be_visible()
72+
73+
# Click hide-menu to hide the static menu
74+
hidemenu = controller.InputActionButton(page, "hideMenu")
75+
hidemenu.click()
76+
77+
# Expect the Menu to be hidden
78+
navpanel3 = controller.NavPanel(page, "tabs", "s1").loc
79+
expect(navpanel3).to_be_hidden()
80+
81+
# Click show-menu to show the static menu again
82+
showmenu = controller.InputActionButton(page, "showMenu")
83+
showmenu.click()
84+
85+
# Expect the Menu to be visible again
86+
expect(page.get_by_role("button", name="Menu", exact=True)).to_be_visible()
87+
# Click the Menu button to show the static menu
88+
page.get_by_role("button", name="Menu", exact=True).click()
89+
navpanel3 = controller.NavPanel(page, "tabs", "s1").loc
90+
expect(navpanel3).to_be_visible()

0 commit comments

Comments
 (0)