Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Export ui.card_body() #1506

Merged
merged 6 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,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
Loading