|  | 
|  | 1 | +__all__ = ( | 
|  | 2 | +    "nav_insert", | 
|  | 3 | +    "nav_remove", | 
|  | 4 | +    "nav_hide", | 
|  | 5 | +    "nav_show", | 
|  | 6 | +) | 
|  | 7 | + | 
|  | 8 | +import sys | 
|  | 9 | +from typing import Optional, Union | 
|  | 10 | + | 
|  | 11 | +if sys.version_info >= (3, 8): | 
|  | 12 | +    from typing import Literal | 
|  | 13 | +else: | 
|  | 14 | +    from typing_extensions import Literal | 
|  | 15 | + | 
|  | 16 | +from .._docstring import add_example | 
|  | 17 | +from ._input_update import update_navs | 
|  | 18 | +from ._navs import menu_string_as_nav | 
|  | 19 | +from ..types import NavsArg | 
|  | 20 | +from ..session import Session, require_active_session | 
|  | 21 | +from .._utils import run_coro_sync | 
|  | 22 | + | 
|  | 23 | + | 
|  | 24 | +@add_example() | 
|  | 25 | +def nav_insert( | 
|  | 26 | +    id: str, | 
|  | 27 | +    nav: Union[NavsArg, str], | 
|  | 28 | +    target: Optional[str] = None, | 
|  | 29 | +    position: Literal["after", "before"] = "after", | 
|  | 30 | +    select: bool = False, | 
|  | 31 | +    session: Optional[Session] = None, | 
|  | 32 | +) -> None: | 
|  | 33 | +    """ | 
|  | 34 | +    Insert a new nav item into a navigation container. | 
|  | 35 | +
 | 
|  | 36 | +    Parameters | 
|  | 37 | +    ---------- | 
|  | 38 | +    id | 
|  | 39 | +        The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | 
|  | 40 | +    nav | 
|  | 41 | +        The navigation item to insert (typically a :func:`~shiny.ui.nav` or | 
|  | 42 | +        :func:`~shiny.ui.nav_menu`). A :func:`~shiny.ui.nav_menu` isn't allowed when the | 
|  | 43 | +        ``target`` references an :func:`~shiny.ui.nav_menu` (or an item within it). A | 
|  | 44 | +        string is only allowed when the ``target`` references a | 
|  | 45 | +        :func:`~shiny.ui.nav_menu`. | 
|  | 46 | +    target | 
|  | 47 | +        The ``value`` of an existing :func:`shiny.ui.nav` item, next to which tab will | 
|  | 48 | +        be added. | 
|  | 49 | +    position | 
|  | 50 | +        The position of the new nav item relative to the target nav item. | 
|  | 51 | +    select | 
|  | 52 | +        Whether the nav item should be selected upon insertion. | 
|  | 53 | +    session | 
|  | 54 | +        A :class:`~shiny.Session` instance. If not provided, it is inferred via | 
|  | 55 | +        :func:`~shiny.session.get_current_session`. | 
|  | 56 | +
 | 
|  | 57 | +    See Also | 
|  | 58 | +    -------- | 
|  | 59 | +    ~nav_remove | 
|  | 60 | +    ~nav_show | 
|  | 61 | +    ~nav_hide | 
|  | 62 | +    ~shiny.ui.nav | 
|  | 63 | +    """ | 
|  | 64 | + | 
|  | 65 | +    session = require_active_session(session) | 
|  | 66 | + | 
|  | 67 | +    # N.B. this is only sensible if the target is a menu, but we don't know that, | 
|  | 68 | +    # which could cause confusion of we decide to support top-level strings at some | 
|  | 69 | +    # in the future. | 
|  | 70 | +    if isinstance(nav, str): | 
|  | 71 | +        nav = menu_string_as_nav(nav) | 
|  | 72 | + | 
|  | 73 | +    # N.B. shiny.js' is smart enough to know how to add active classes and href/id attrs | 
|  | 74 | +    li_tag, div_tag = nav.resolve(selected=None) | 
|  | 75 | + | 
|  | 76 | +    msg = { | 
|  | 77 | +        "inputId": session.ns(id), | 
|  | 78 | +        "liTag": session._process_ui(li_tag), | 
|  | 79 | +        "divTag": session._process_ui(div_tag), | 
|  | 80 | +        "menuName": None, | 
|  | 81 | +        "target": target, | 
|  | 82 | +        "position": position, | 
|  | 83 | +        "select": select, | 
|  | 84 | +    } | 
|  | 85 | + | 
|  | 86 | +    def callback() -> None: | 
|  | 87 | +        run_coro_sync(session._send_message({"shiny-insert-tab": msg})) | 
|  | 88 | + | 
|  | 89 | +    session.on_flush(callback, once=True) | 
|  | 90 | + | 
|  | 91 | + | 
|  | 92 | +def nav_remove(id: str, target: str, session: Optional[Session] = None) -> None: | 
|  | 93 | +    """ | 
|  | 94 | +    Remove a nav item from a navigation container. | 
|  | 95 | +
 | 
|  | 96 | +    Parameters | 
|  | 97 | +    ---------- | 
|  | 98 | +    id | 
|  | 99 | +        The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | 
|  | 100 | +    target | 
|  | 101 | +        The ``value`` of an existing :func:`shiny.ui.nav` item to remove. | 
|  | 102 | +    session | 
|  | 103 | +        A :class:`~shiny.Session` instance. If not provided, it is inferred via | 
|  | 104 | +        :func:`~shiny.session.get_current_session`. | 
|  | 105 | +
 | 
|  | 106 | +    See Also | 
|  | 107 | +    -------- | 
|  | 108 | +    ~nav_insert | 
|  | 109 | +    ~nav_show | 
|  | 110 | +    ~nav_hide | 
|  | 111 | +    ~shiny.ui.nav | 
|  | 112 | +    """ | 
|  | 113 | + | 
|  | 114 | +    session = require_active_session(session) | 
|  | 115 | + | 
|  | 116 | +    msg = {"inputId": session.ns(id), "target": target} | 
|  | 117 | + | 
|  | 118 | +    def callback() -> None: | 
|  | 119 | +        run_coro_sync(session._send_message({"shiny-remove-tab": msg})) | 
|  | 120 | + | 
|  | 121 | +    session.on_flush(callback, once=True) | 
|  | 122 | + | 
|  | 123 | + | 
|  | 124 | +def nav_show( | 
|  | 125 | +    id: str, target: str, select: bool = False, session: Optional[Session] = None | 
|  | 126 | +) -> None: | 
|  | 127 | +    """ | 
|  | 128 | +    Show a navigation item | 
|  | 129 | +
 | 
|  | 130 | +    Parameters | 
|  | 131 | +    ---------- | 
|  | 132 | +    id | 
|  | 133 | +        The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | 
|  | 134 | +    target | 
|  | 135 | +        The ``value`` of an existing :func:`shiny.ui.nav` item to show. | 
|  | 136 | +    select | 
|  | 137 | +        Whether the nav item's content should also be shown. | 
|  | 138 | +    session | 
|  | 139 | +        A :class:`~shiny.Session` instance. If not provided, it is inferred via | 
|  | 140 | +        :func:`~shiny.session.get_current_session`. | 
|  | 141 | +
 | 
|  | 142 | +    Note | 
|  | 143 | +    ---- | 
|  | 144 | +    For ``nav_show()`` to be relevant/useful, a :func:`shiny.ui.nav` item must | 
|  | 145 | +    have been hidden using :func:`~nav_hide`. | 
|  | 146 | +
 | 
|  | 147 | +    See Also | 
|  | 148 | +    -------- | 
|  | 149 | +    ~nav_hide | 
|  | 150 | +    ~nav_insert | 
|  | 151 | +    ~nav_remove | 
|  | 152 | +    ~shiny.ui.nav | 
|  | 153 | +    """ | 
|  | 154 | + | 
|  | 155 | +    session = require_active_session(session) | 
|  | 156 | + | 
|  | 157 | +    if select: | 
|  | 158 | +        update_navs(id, selected=target) | 
|  | 159 | + | 
|  | 160 | +    msg = {"inputId": session.ns(id), "target": target, "type": "show"} | 
|  | 161 | + | 
|  | 162 | +    def callback() -> None: | 
|  | 163 | +        run_coro_sync(session._send_message({"shiny-change-tab-visibility": msg})) | 
|  | 164 | + | 
|  | 165 | +    session.on_flush(callback, once=True) | 
|  | 166 | + | 
|  | 167 | + | 
|  | 168 | +def nav_hide(id: str, target: str, session: Optional[Session] = None) -> None: | 
|  | 169 | +    """ | 
|  | 170 | +    Hide a navigation item | 
|  | 171 | +
 | 
|  | 172 | +    Parameters | 
|  | 173 | +    ---------- | 
|  | 174 | +    id | 
|  | 175 | +        The ``id`` of the relevant navigation container (i.e., ``navs_*()`` object). | 
|  | 176 | +    target | 
|  | 177 | +        The ``value`` of an existing :func:`shiny.ui.nav` item to hide. | 
|  | 178 | +    session | 
|  | 179 | +        A :class:`~shiny.Session` instance. If not provided, it is inferred via | 
|  | 180 | +        :func:`~shiny.session.get_current_session`. | 
|  | 181 | +
 | 
|  | 182 | +    See Also | 
|  | 183 | +    -------- | 
|  | 184 | +    ~nav_show | 
|  | 185 | +    ~nav_insert | 
|  | 186 | +    ~nav_remove | 
|  | 187 | +    ~shiny.ui.nav | 
|  | 188 | +    """ | 
|  | 189 | + | 
|  | 190 | +    session = require_active_session(session) | 
|  | 191 | + | 
|  | 192 | +    msg = {"inputId": session.ns(id), "target": target, "type": "hide"} | 
|  | 193 | + | 
|  | 194 | +    def callback() -> None: | 
|  | 195 | +        run_coro_sync(session._send_message({"shiny-change-tab-visibility": msg})) | 
|  | 196 | + | 
|  | 197 | +    session.on_flush(callback, once=True) | 
0 commit comments