# Layout ------------------------------------------------------------------
#' Bulma Level
#'
#' A multi-purpose horizontal level that can contain almost any other element.
#'
#' @param ... Items to be wrapped in a `"level-item"` `
` and included in the
#' main level container. If only one argument is provided and that argument is
#' a list, the items inside the list will be treated as individual level items.
#' @param left A list of items to be placed in the left side of the level in a
#' `"level-left"` container.
#' @param right A list of items to be placed in the right side of the level in a
#' `"level-right"` container.
#' @param type One of `"item"` or `"header"`. The default (`"item"`) places level
#' items in the standard `"level-item"` container. Use `"header"` to use the
#' names of the arguments in `...` as headers over their elements to create a
#' large single-row pseudo-table. See examples for more details.
#' @param container_tag Which tag should be used for the main `"level"` container?
#' One of `"div"` or `"nav"`.
#' @param class Additional classes applied to level container
#' @param style Additional style parameters applied to level container
#' @param level_class Additional classes applied to all level item containers (except
#' for manually created level items).
#' @param level_style Additional style arguments applied to all level item containers
#' (except for manually create level items).
#' @examples
#' bulma_level("Home", "Menu", "Bulma", "Reservations", "Contact")
#' bulma_level("Tweets" = 3456, Following = 123, Followers = "456K", Likes = 789, type = "header")
#'
#' iris_vals <- lapply(iris, function(x) length(unique(x)))
#' bulma_level(iris_vals, type = "header")
#'
#' @references
#' @family Bulma layouts
#' @export
bulma_level <- function(
...,
left = NULL,
right = NULL,
is_mobile = TRUE,
type = c("item", "header"),
container_tag = c("div", "nav"),
class = NULL,
style = NULL,
level_class = NULL,
level_style = NULL
) {
type <- match.arg(type)
tag_f <- tag_function(match.arg(container_tag))
x <- tag_f(
class = c_str("level", if (is_mobile) "is-mobile", class),
style = style,
level_side(left, "left"),
if (type == "item")
tagList(lapply(dots2list(...), bulma_level_item, class = level_class, style = level_style)),
if (type == "header") bulma_level_items_header(..., class = level_class, style = level_style),
level_side(right, "right")
)
x
}
#' Bulma Level Item
#'
#' Constructs an individual level item.
#'
#' @param ... Elements to be included in the level item
#' @param class Additional classes to be applied to the level item container
#' @param style Additional CSS style directives to be applied to the level item container
#' @family Bulma layouts
#' @export
bulma_level_item <- function(..., class = NULL, style = NULL) {
item <- dots2list(...)
if (is_level_item(item)) return(item)
as_level_item(
tag_div(class = c_str("level-item", class),
style = style,
item)
)
}
as_level_item <- function(x) {
if (inherits(x, "level_item")) return(x)
class(x) <- c("level_item", class(x))
x
}
is_level_item <- function(x) inherits(x, "level_item")
level_side <- function(x, side = "left") {
if (is.null(x)) return(NULL)
match.arg(side, c("left", "right"))
items <- lapply(x, bulma_level_item)
tag_div(class = c_prefix(side, "level-"), items)
}
#' Bulma Level Items with Headers
#'
#' Takes named arguments and converts them to
#' (level items with headers)[bulma_level_item_header].
#'
#' @inheritParams bulma_level_item
#' @param header_class Additional classes to be applied to the header (upper)
#' container in addition to `"heading"`
#' @param body_class Additional classes to be applied to the title (lower)
#' container in addition to `"title"`
#' @family Bulma layouts
#' @export
bulma_level_items_header <- function(..., class = NULL, style = NULL, header_class = NULL, body_class = NULL) {
items <- dots2list(...)
x <- map_arg(
.f = bulma_level_item_header,
names(items),
items,
.args = list(class = if (is.null(class)) "has-text-centered" else class,
style = style,
header_class = header_class,
body_class = body_class)
)
tagList(x)
}
#' Bulma Level Item with Header
#'
#' Constructs an individual level item with a header (upper) and a title (lower).
#'
#' @param item_name The header (or name) of the item
#' @param item_body The body of the item
#' @inheritParams bulma_level_items_header
#' @family Bulma layouts
#' @export
bulma_level_item_header <- function(item_header, item_body, class = NULL, style = NULL, header_class = NULL, body_class = NULL) {
bulma_level_item(
class = class,
style = style,
tag_div(
tag_p(class = c_str("heading", header_class), item_header),
tag_p(class = c_str("title", body_class), item_body)
))
}