Skip to content
Merged
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,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
5 changes: 4 additions & 1 deletion shiny/express/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
input_text,
input_text_area,
panel_title,
insert_accordion_panel,
remove_accordion_panel,
update_accordion,
update_accordion_panel,
Expand Down Expand Up @@ -161,6 +160,10 @@
hold,
)

from ._insert import (
insert_accordion_panel,
)

__all__ = (
# Imports from htmltools
"TagList",
Expand Down
80 changes: 80 additions & 0 deletions shiny/express/ui/_insert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
Shims for `ui.insert_*()`, `ui.update_*()`, etc. functions that lead to a more ergonomic
Express API.

These functions tend to have one issue in common: if they were re-exported verbatim from
Core to Express, they would want to take RecallContextManager(s) as input, which leads
to a somewhat awkward API. That's because, you'd have to know to use something like
@ui.hold() pass the UI as a value without displaying it.
"""

from typing import Literal, Optional

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: TagChild | TagAttrs,
panel_value: 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 accordion_panel, insert_accordion_panel

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,
)
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