Skip to content

Commit

Permalink
feat: Export ui.card_body() (#1506)
Browse files Browse the repository at this point in the history
Co-authored-by: Barret Schloerke <barret@posit.co>
  • Loading branch information
gadenbuie and schloerke committed Jul 17, 2024
1 parent 61b6c05 commit 7be5c87
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* `ui.Theme` allows you to create custom themes for your Shiny app by recompiling [Bootstrap](https://getbootstrap.com/) and Shiny's Sass files with your own customizations. Themes created with `ui.Theme` can be passed directly to the `theme` argument of `express.ui.page_opts()` (Shiny Express) or `ui.page_*()` functions (Shiny Core) to apply the theme to the entire app. This feature requires the [libsass package](https://sass.github.io/libsass-python/) which can be installed with `pip install libsass`. (#1358)

* `ui.card_body()` can be used to wrap the contents of elements in `ui.card()`, allowing you to change parameters like `fillable` or `padding` and `gap` for groups of elements in the card. (#1506)

### Bug fixes

* Fixed #1440: When a Shiny Express app with a `www/` subdirectory was deployed to shinyapps.io or a Connect server, it would not start correctly. (#1442)
Expand Down
7 changes: 3 additions & 4 deletions shiny/api-examples/card_body/app-core.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import shiny.experimental as x
from shiny import App, ui

app_ui = ui.page_fluid(
ui.card(
ui.card_header("This is the header"),
x.ui.card_body(
x.ui.card_title("This is the title"),
ui.card_body(
ui.tags.h5("This is the title"),
ui.p("This is the body."),
ui.p("This is still the body."),
),
Expand All @@ -15,7 +14,7 @@
ui.card(
ui.p("These first two elements will be wrapped in `card_body()` together."),
ui.p("These first two elements will be wrapped in `card_body()` together."),
x.ui.card_body(ui.p("A card body.")),
ui.card_body(ui.p("A card body.")),
ui.p("These last two elements will be wrapped in `card_body()` together."),
ui.p("These last two elements will be wrapped in `card_body()` together."),
),
Expand Down
2 changes: 2 additions & 0 deletions shiny/express/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
layout_column_wrap,
layout_columns,
card,
card_body,
card_header,
card_footer,
accordion,
Expand Down Expand Up @@ -264,6 +265,7 @@
"layout_column_wrap",
"layout_columns",
"card",
"card_body",
"card_header",
"card_footer",
"accordion",
Expand Down
86 changes: 86 additions & 0 deletions shiny/express/ui/_cm_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"layout_column_wrap",
"layout_columns",
"card",
"card_body",
"card_header",
"card_footer",
"accordion",
Expand Down Expand Up @@ -476,6 +477,91 @@ def card(
)


@add_example()
def card_body(
*,
fillable: bool = True,
min_height: Optional[CssUnit] = None,
max_height: Optional[CssUnit] = None,
max_height_full_screen: Optional[CssUnit] | MISSING_TYPE = MISSING,
height: Optional[CssUnit] = None,
padding: Optional[CssUnit | list[CssUnit]] = None,
gap: Optional[CssUnit] = None,
fill: bool = True,
class_: Optional[str] = None,
**kwargs: TagAttrValue,
) -> RecallContextManager[CardItem]:
# For a general overview of the :func:`~shiny.ui.card` API, see [this article](https://rstudio.github.io/bslib/articles/cards.html).
"""
Card body container
A general container for the "main content" of a :func:`~shiny.ui.card`. This
component is designed to be provided as direct children to :func:`~shiny.ui.card`.
Parameters
----------
*args
Contents to the card's body. Or tag attributes that are supplied to the
resolved :class:`~htmltools.Tag` object.
fillable
Whether or not the card item should be a fillable (i.e. flexbox) container.
min_height,max_height,max_height_full_screen
Any valid CSS length unit. If `max_height_full_screen` is missing, it is set to
`max_height`.
height
Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made
`full_screen` (in this case, consider setting a `height` in
`card_body()`).
padding
Padding to use for the body. This can be a numeric vector
(which will be interpreted as pixels) or a character vector with valid CSS
lengths. The length can be between one and four. If one, then that value
will be used for all four sides. If two, then the first value will be used
for the top and bottom, while the second value will be used for left and
right. If three, then the first will be used for top, the second will be
left and right, and the third will be bottom. If four, then the values will
be interpreted as top, right, bottom, and left respectively.
gap
A CSS length unit defining the `gap` (i.e., spacing) between elements provided
to `*args`. This argument is only applicable when `fillable = TRUE`.
fill
Whether to allow this element to grow/shrink to fit its `card` container.
class_
Additional CSS classes for the returned Tag.
**kwargs
Additional HTML attributes for the returned Tag.
Returns
-------
:
A :class:`~shiny.ui.CardItem` object.
See Also
--------
* :func:`~shiny.ui.layout_column_wrap` for laying out multiple cards
(or multiple columns inside a card).
* :func:`~shiny.ui.card` for creating a card component.
* :func:`~shiny.ui.card_header` for creating a header within the card.
* :func:`~shiny.ui.card_footer` for creating a footer within the card.
"""

return RecallContextManager(
ui.card_body,
kwargs=dict(
fillable=fillable,
min_height=min_height,
max_height=max_height,
max_height_full_screen=max_height_full_screen,
height=height,
padding=padding,
gap=gap,
fill=fill,
class_=class_,
**kwargs,
),
)


@add_example()
def card_header(
*args: TagChild | TagAttrs,
Expand Down
2 changes: 2 additions & 0 deletions shiny/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
from ._card import (
CardItem,
card,
card_body,
card_footer,
card_header,
)
Expand Down Expand Up @@ -196,6 +197,7 @@
# _card
"CardItem",
"card",
"card_body",
"card_header",
"card_footer",
# _chat
Expand Down
8 changes: 4 additions & 4 deletions shiny/ui/_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ def card_body(
"""
Card body container
A general container for the "main content" of a :func:`~shiny.ui.card`. This component is designed
to be provided as direct children to :func:`~shiny.ui.card`.
A general container for the "main content" of a :func:`~shiny.ui.card`. This
component is designed to be provided as direct children to :func:`~shiny.ui.card`.
Parameters
----------
Expand Down Expand Up @@ -348,7 +348,6 @@ def card_body(
(or multiple columns inside a card).
* :func:`~shiny.ui.card` for creating a card component.
* :func:`~shiny.ui.card_header` for creating a header within the card.
* :func:`~shiny.experimental.ui.card_title` for creating a title within the card body.
* :func:`~shiny.ui.card_footer` for creating a footer within the card.
"""
if isinstance(max_height_full_screen, MISSING_TYPE):
Expand All @@ -368,9 +367,10 @@ def card_body(
}
tag = tags.div(
{
"class": "card-body bslib-gap-spacing",
"class": "card-body",
"style": css(**div_style_args),
},
{"class": "bslib-gap-spacing"} if fillable else None,
*args,
class_=class_,
**kwargs,
Expand Down

0 comments on commit 7be5c87

Please sign in to comment.