-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
316 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from shiny import * | ||
|
||
app_ui = ui.page_fluid( | ||
ui.layout_sidebar( | ||
ui.panel_sidebar( | ||
ui.input_action_button("add", "Add 'Dynamic' tab"), | ||
ui.input_action_button("removeFoo", "Remove 'Foo' tabs"), | ||
ui.input_action_button("addFoo", "Add New 'Foo' tab"), | ||
), | ||
ui.panel_main( | ||
ui.navs_tab( | ||
ui.nav("Hello", "This is the hello tab"), | ||
ui.nav("Foo", "This is the Foo tab", value="Foo"), | ||
ui.nav_menu( | ||
"Static", | ||
ui.nav("Static 1", "Static 1", value="s1"), | ||
ui.nav("Static 2", "Static 2", value="s2"), | ||
value="Menu", | ||
), | ||
id="tabs", | ||
), | ||
), | ||
) | ||
) | ||
|
||
|
||
def server(input: Inputs, output: Outputs, session: Session): | ||
@reactive.Effect() | ||
@event(input.add) | ||
def _(): | ||
id = "Dynamic-" + str(input.add()) | ||
ui.nav_insert( | ||
"tabs", | ||
ui.nav(id, id), | ||
target="s2", | ||
position="before", | ||
) | ||
|
||
@reactive.Effect() | ||
@event(input.removeFoo) | ||
def _(): | ||
ui.nav_remove("tabs", target="Foo") | ||
|
||
@reactive.Effect() | ||
@event(input.addFoo) | ||
def _(): | ||
n = str(input.addFoo()) | ||
ui.nav_insert( | ||
"tabs", | ||
ui.nav("Foo-" + n, "This is the new Foo-" + n + " tab", value="Foo"), | ||
target="Menu", | ||
position="before", | ||
select=True, | ||
) | ||
|
||
|
||
app = App(app_ui, server, debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from shiny import * | ||
|
||
app_ui = ui.page_navbar( | ||
ui.nav( | ||
"Home", | ||
ui.input_action_button("hideTab", "Hide 'Foo' tab"), | ||
ui.input_action_button("showTab", "Show 'Foo' tab"), | ||
ui.input_action_button("hideMenu", "Hide 'More' nav_menu"), | ||
ui.input_action_button("showMenu", "Show 'More' nav_menu"), | ||
), | ||
ui.nav("Foo", "This is the foo tab"), | ||
ui.nav("Bar", "This is the bar tab"), | ||
ui.nav_menu( | ||
"More", | ||
ui.nav("Table", "Table page"), | ||
ui.nav("About", "About page"), | ||
"------", | ||
"Even more!", | ||
ui.nav("Email", "Email page"), | ||
), | ||
title="Navbar page", | ||
id="tabs", | ||
) | ||
|
||
|
||
def server(input: Inputs, output: Outputs, session: Session): | ||
@reactive.Effect() | ||
@event(input.hideTab) | ||
def _(): | ||
ui.nav_hide("tabs", target="Foo") | ||
|
||
@reactive.Effect() | ||
@event(input.showTab) | ||
def _(): | ||
ui.nav_show("tabs", target="Foo") | ||
|
||
@reactive.Effect() | ||
@event(input.hideMenu) | ||
def _(): | ||
ui.nav_hide("tabs", target="More") | ||
|
||
@reactive.Effect() | ||
@event(input.showMenu) | ||
def _(): | ||
ui.nav_show("tabs", target="More") | ||
|
||
|
||
app = App(app_ui, server) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
__all__ = ( | ||
"nav_insert", | ||
"nav_remove", | ||
"nav_hide", | ||
"nav_show", | ||
) | ||
|
||
import sys | ||
from typing import Optional | ||
|
||
if sys.version_info >= (3, 8): | ||
from typing import Literal | ||
else: | ||
from typing_extensions import Literal | ||
|
||
from htmltools import JSXTag | ||
|
||
from .._docstring import add_example | ||
from ._input_update import update_navs | ||
from ._navs import navs_hidden | ||
from ..session import Session, require_active_session | ||
from .._utils import run_coro_sync | ||
|
||
|
||
@add_example() | ||
def nav_insert( | ||
id: str, | ||
nav: JSXTag, | ||
target: Optional[str] = None, | ||
position: Literal["after", "before"] = "after", | ||
select: bool = False, | ||
session: Optional[Session] = None, | ||
) -> None: | ||
""" | ||
Insert a new nav item into a navigation container. | ||
Parameters | ||
---------- | ||
id | ||
The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | ||
nav | ||
The navigation item to insert (typically a :func:`shiny.ui.nav` or | ||
:func:`shiny.ui.nav_menu`). | ||
target | ||
The ``value`` of an existing :func:`shiny.ui.nav` item, next to which tab will | ||
be added. | ||
position | ||
The position of the new nav item relative to the target nav item. | ||
select | ||
Whether the nav item should be selected upon insertion. | ||
session | ||
A :class:`~shiny.Session` instance. If not provided, it is inferred via | ||
:func:`~shiny.session.get_current_session`. | ||
See Also | ||
-------- | ||
~nav_remove | ||
~nav_show | ||
~nav_hide | ||
~shiny.ui.nav | ||
""" | ||
|
||
session = require_active_session(session) | ||
|
||
# The currrent JSX implementation of nav items is not smart enough to know how to | ||
# render without a navs container (maybe it could, but I don't think that'd simplify | ||
# things overall), so we wrap in one and also notify the JSX logic to not generate | ||
# active classes in the HTML markup (shiny.js handles that part via the select | ||
# parameter in the message). This way, the shiny.js logic can just render the JSXTag | ||
# verbatim and use the historical HTML code path to insert the nav item. | ||
jsx_tag = navs_hidden(nav, selected=False) # type: ignore | ||
|
||
msg = { | ||
"inputId": session.ns(id), | ||
"menuName": None, | ||
"target": target, | ||
"position": position, | ||
"select": select, | ||
"jsxTag": session._process_ui(jsx_tag), | ||
} | ||
|
||
def callback() -> None: | ||
run_coro_sync(session._send_message({"shiny-insert-tab": msg})) | ||
|
||
session.on_flush(callback, once=True) | ||
|
||
|
||
def nav_remove(id: str, target: str, session: Optional[Session] = None) -> None: | ||
""" | ||
Remove a nav item from a navigation container. | ||
Parameters | ||
---------- | ||
id | ||
The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | ||
target | ||
The ``value`` of an existing :func:`shiny.ui.nav` item to remove. | ||
session | ||
A :class:`~shiny.Session` instance. If not provided, it is inferred via | ||
:func:`~shiny.session.get_current_session`. | ||
See Also | ||
-------- | ||
~nav_insert | ||
~nav_show | ||
~nav_hide | ||
~shiny.ui.nav | ||
""" | ||
|
||
session = require_active_session(session) | ||
|
||
msg = {"inputId": session.ns(id), "target": target} | ||
|
||
def callback() -> None: | ||
run_coro_sync(session._send_message({"shiny-remove-tab": msg})) | ||
|
||
session.on_flush(callback, once=True) | ||
|
||
|
||
def nav_show( | ||
id: str, target: str, select: bool = False, session: Optional[Session] = None | ||
) -> None: | ||
""" | ||
Show a navigation item | ||
Parameters | ||
---------- | ||
id | ||
The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | ||
target | ||
The ``value`` of an existing :func:`shiny.ui.nav` item to show. | ||
select | ||
Whether the nav item's content should also be shown. | ||
session | ||
A :class:`~shiny.Session` instance. If not provided, it is inferred via | ||
:func:`~shiny.session.get_current_session`. | ||
Note | ||
---- | ||
For ``nav_show()`` to be relevant/useful, a :func:`shiny.ui.nav` item must | ||
have been hidden using :func:`~nav_hide`. | ||
See Also | ||
-------- | ||
~nav_hide | ||
~nav_insert | ||
~nav_remove | ||
~shiny.ui.nav | ||
""" | ||
|
||
session = require_active_session(session) | ||
|
||
if select: | ||
update_navs(id, selected=target) | ||
|
||
msg = {"inputId": session.ns(id), "target": target, "type": "show"} | ||
|
||
def callback() -> None: | ||
run_coro_sync(session._send_message({"shiny-change-tab-visibility": msg})) | ||
|
||
session.on_flush(callback, once=True) | ||
|
||
|
||
def nav_hide(id: str, target: str, session: Optional[Session] = None) -> None: | ||
""" | ||
Hide a navigation item | ||
Parameters | ||
---------- | ||
id | ||
The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | ||
target | ||
The ``value`` of an existing :func:`shiny.ui.nav` item to hide. | ||
session | ||
A :class:`~shiny.Session` instance. If not provided, it is inferred via | ||
:func:`~shiny.session.get_current_session`. | ||
See Also | ||
-------- | ||
~nav_show | ||
~nav_insert | ||
~nav_remove | ||
~shiny.ui.nav | ||
""" | ||
|
||
session = require_active_session(session) | ||
|
||
msg = {"inputId": session.ns(id), "target": target, "type": "hide"} | ||
|
||
def callback() -> None: | ||
run_coro_sync(session._send_message({"shiny-change-tab-visibility": msg})) | ||
|
||
session.on_flush(callback, once=True) |