Skip to content
Merged
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* `playwright.controller.InputActionButton` gains a `expect_icon()` method. As a result, the already existing `expect_label()` no longer includes the icon. (#2020)

### Changes

* `express.ui.insert_accordion_panel()`'s function signature has changed to be more ergonomic. Now you can pass the `panel_title` and `panel_contents` directly instead of `ui.hold()`ing the `ui.accordion_panel()` context manager. (#2042)

### Improvements

* Improved the styling and readability of markdown tables rendered by `ui.Chat()` and `ui.MarkdownStream()`. (#1973)
Expand Down
23 changes: 12 additions & 11 deletions shiny/api-examples/insert_accordion_panel/app-express.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import random

from shiny import reactive, ui
from shiny.express import input


def make_panel(letter):
return ui.accordion_panel(
f"Section {letter}", f"Some narrative for section {letter}"
)

from shiny import reactive
from shiny.express import input, ui

ui.input_action_button("add_panel", "Add random panel", class_="mt-3 mb-3")
ui.accordion(*[make_panel(letter) for letter in "ABCDE"], id="acc", multiple=True)

with ui.accordion(id="acc", multiple=True):
for letter in "ABCDE":
with ui.accordion_panel(f"Section {letter}"):
f"Some narrative for section {letter}"


@reactive.effect
@reactive.event(input.add_panel)
def _():
ui.insert_accordion_panel("acc", make_panel(str(random.randint(0, 10000))))
ui.insert_accordion_panel(
"acc",
f"Section {random.randint(0, 10000)}",
f"Some narrative for section {random.randint(0, 10000)}",
)
117 changes: 52 additions & 65 deletions shiny/express/ui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
from __future__ import annotations


from htmltools import (
TagList,
HTML,
Tag,
TagChild,
TagAttrs,
TagAttrValue,
tags,
HTML,
head_content,
TagChild,
TagList,
a,
br,
code,
Expand All @@ -21,116 +18,113 @@
h4,
h5,
h6,
head_content,
hr,
img,
p,
pre,
span,
strong,
)

from ...ui import (
fill,
)

from ...ui import (
busy_indicators,
tags,
)

from ...ui import (
AccordionPanel,
AnimationOptions,
CardItem,
Progress,
ShowcaseLayout,
Sidebar,
SliderStepArg,
SliderValueArg,
Theme,
ValueBoxTheme,
bind_task_button,
brush_opts,
busy_indicators,
click_opts,
dblclick_opts,
fill,
help_text,
hover_opts,
include_css,
include_js,
input_bookmark_button,
input_action_button,
input_action_link,
input_bookmark_button,
input_checkbox,
input_checkbox_group,
input_switch,
input_radio_buttons,
input_dark_mode,
input_date,
input_date_range,
input_file,
input_numeric,
input_password,
input_radio_buttons,
input_select,
input_selectize,
input_slider,
bind_task_button,
input_switch,
input_task_button,
input_text,
input_text_area,
insert_ui,
js_eval,
markdown,
modal,
modal_button,
modal_remove,
modal_show,
nav_spacer,
navbar_options,
notification_remove,
notification_show,
panel_title,
insert_accordion_panel,
remove_accordion_panel,
remove_nav_panel,
remove_ui,
update_accordion,
update_accordion_panel,
update_sidebar,
update_action_button,
update_action_link,
update_checkbox,
update_switch,
update_checkbox_group,
update_radio_buttons,
update_dark_mode,
update_date,
update_date_range,
update_nav_panel,
update_navs,
update_numeric,
update_popover,
update_radio_buttons,
update_select,
update_selectize,
update_sidebar,
update_slider,
update_switch,
update_task_button,
update_text,
update_text_area,
update_navs,
update_tooltip,
update_popover,
insert_ui,
remove_ui,
markdown,
modal_button,
modal,
modal_show,
modal_remove,
notification_show,
notification_remove,
nav_spacer,
navbar_options,
remove_nav_panel,
update_nav_panel,
Progress,
Theme,
value_box_theme,
js_eval,
)

from ...ui._chat import ChatExpress as Chat
from ...ui._markdown_stream import (
ExpressMarkdownStream as MarkdownStream,
)
from ._cm_components import (
sidebar,
layout_sidebar,
layout_column_wrap,
layout_columns,
accordion,
accordion_panel,
card,
card_body,
card_header,
card_footer,
accordion,
accordion_panel,
nav_panel,
card_header,
layout_column_wrap,
layout_columns,
layout_sidebar,
nav_control,
nav_menu,
nav_panel,
navset_bar,
navset_card_pill,
navset_card_tab,
Expand All @@ -140,32 +134,25 @@
navset_pill_list,
navset_tab,
navset_underline,
value_box,
panel_well,
panel_absolute,
panel_conditional,
panel_fixed,
panel_absolute,
tooltip,
panel_well,
popover,
sidebar,
tooltip,
value_box,
)

from ...ui._chat import ChatExpress as Chat

from ...ui._markdown_stream import (
ExpressMarkdownStream as MarkdownStream,
)

from ._page import (
page_opts,
)

from ._hold import (
hold,
)

from ._insert import (
insert_accordion_panel,
insert_nav_panel,
)
from ._page import (
page_opts,
)

__all__ = (
# Imports from htmltools
Expand Down
74 changes: 72 additions & 2 deletions shiny/express/ui/_insert.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,82 @@
@ui.hold() pass the UI as a value without displaying it.
"""

from typing import Literal, Optional
from typing import Literal, Optional, Union

from htmltools import TagChild
from htmltools import TagAttrs, TagChild

from ..._docstring import add_example
from ...session import Session
from ...types import MISSING, MISSING_TYPE


@add_example()
def insert_accordion_panel(
id: str,
panel_title: str,
*panel_contents: Union[TagChild, TagAttrs],
panel_value: Union[str, MISSING_TYPE, None] = MISSING,
panel_icon: TagChild = None,
target: Optional[str] = None,
position: Literal["after", "before"] = "after",
session: Optional[Session] = None,
) -> None:
"""
Insert an accordion panel into an existing accordion.

Parameters
----------
id
A string that matches an existing :func:`~shiny.ui.express.accordion`'s `id`.
panel_title
The title to appear in the panel header.
panel_contents
UI elements for the panel's body. Can also be a dict of tag attributes for the
body's HTML container.
panel_value
A character string that uniquely identifies this panel. If `MISSING`, the
`title` will be used.
panel_icon
A :class:`~htmltools.TagChild` which is positioned just before the `title`.
target
The `value` of an existing panel to insert next to.
position
Should `panel` be added before or after the target? When `target=None`,
`"after"` will append after the last panel and `"before"` will prepend before
the first panel.
session
A Shiny session object (the default should almost always be used).

References
----------
[Bootstrap Accordion](https://getbootstrap.com/docs/5.3/components/accordion/)

See Also
--------
* :func:`~shiny.ui.express.accordion`
* :func:`~shiny.ui.express.accordion_panel`
* :func:`~shiny.ui.express.update_accordion`
"""

from ...ui import AccordionPanel, accordion_panel, insert_accordion_panel

if isinstance(panel_title, AccordionPanel):
# If the user passed an AccordionPanel, we can just use it as is.
# This isn't recommended, but we support it for backwards compatibility
# with the old API.
panel = panel_title
else:
panel = accordion_panel(
panel_title, *panel_contents, value=panel_value, icon=panel_icon
)

insert_accordion_panel(
id=id,
panel=panel,
target=target,
position=position,
session=session,
)


@add_example()
Expand Down
10 changes: 5 additions & 5 deletions shiny/ui/_accordion.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,17 +315,17 @@ def accordion_panel(
Parameters
----------
title
A title to appear in the :func:`~shiny.ui.accordion_panel`'s header.
A title to appear in the panel's header.
*args
Contents to the accordion panel body. Or tag attributes that are supplied to the
returned :class:`~htmltools.Tag` object.
UI elements for the panel's body. Can also be a dict of tag attributes for the
body's HTML container.
value
A character string that uniquely identifies this panel. If `MISSING`, the
`title` will be used.
icon
A :class:`~htmltools.Tag` which is positioned just before the `title`.
A :class:`~htmltools.TagChild` which is positioned just before the `title`.
**kwargs
Tag attributes to the `accordion-body` div Tag.
Tag attributes for the body's HTML container.

Returns
-------
Expand Down
Loading
Loading