You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 satır
3.4KB

  1. apply_tag <- function(ll, tag, class = NULL, extra_attributes = NULL) {
  2. lapply(ll, function(x) htmltools::tag(tag, c(x, class = class, extra_attributes)))
  3. }
  4. dots2list <- function(...) {
  5. # Convert dots to list, but return first element if the first element is a list
  6. # and the length of ... is 1
  7. x <- list(...)
  8. if (length(x) == 1 && is.list(x[[1]])) return(x[[1]])
  9. x
  10. }
  11. map_arg <- function(..., .f, .args = NULL) {
  12. .args <- compact(.args)
  13. if (is.null(.args)) {
  14. mapply(.f, ..., SIMPLIFY = FALSE, USE.NAMES = TRUE)
  15. } else {
  16. mapply(.f, ..., MoreArgs = compact(.args), SIMPLIFY = FALSE, USE.NAMES = TRUE)
  17. }
  18. }
  19. compact <- function(x) {
  20. x <- x[!vapply(x, is.null, logical(1))]
  21. if (length(x)) x else NULL
  22. }
  23. tag_function <- function(.tag = "div") {
  24. function(...) htmltools::tag(.tag, list(...))
  25. }
  26. tag_div <- tag_function("div")
  27. tag_p <- tag_function("p")
  28. tag_a <- tag_function("a")
  29. validate_value <- function(value = NULL, choices, several.ok = TRUE, value_name = "") {
  30. if (!is.null(value) && length(value)) {
  31. value_name <- if (nchar(value_name) > 0) glue("`{value_name}` - ") else ""
  32. warnings <- c()
  33. not_in_choices <- setdiff(value, choices)
  34. if (length(not_in_choices)) {
  35. warnings <- glue("{value_name}Ignoring invalid choices: ",
  36. "\"{paste(not_in_choices, collapse = '\", \"')}\"")
  37. value <- intersect(value, choices)
  38. }
  39. if (!several.ok && length(value) > 1) {
  40. warnings <- c(
  41. warnings,
  42. glue("{value_name}Using the first of {length(value)} values: {value[1]}")
  43. )
  44. value <- value[1]
  45. }
  46. if (length(value)) {
  47. if (length(warnings)) {
  48. rlang::warn(paste(warnings, collapse = "\n"))
  49. }
  50. value
  51. } else {
  52. rlang::abort(glue("{value_name}Must be one of the following valid choices: ",
  53. "\"{paste(choices, collapse = '\", \"')}\""))
  54. }
  55. } else if (!is.null(value) && !length(value)) NULL
  56. }
  57. is_html <- function(x) inherits(x, "html")
  58. is_tagList <- function(x) inherits(x, "shiny.tag.list")
  59. is_tag <- function(x) inherits(x, "shiny.tag")
  60. is_htmlish <- function(x) is_html(x) | is_tag(x) | is_tagList(x)
  61. c_is <- function(x) {
  62. if (is.null(x)) return(NULL)
  63. str_trim(paste("is-", x, sep = "", collapse = " "))
  64. }
  65. c_has <- function(x) {
  66. if (is.null(x)) return(NULL)
  67. str_trim(paste("has-", x, sep = "", collapse = " "))
  68. }
  69. c_prefix <- function(x = NULL, prefix = NULL) {
  70. if (is.null(x)) return(NULL)
  71. paste0(prefix, x)
  72. }
  73. c_str <- function(...) {
  74. str_trim(paste(..., sep = " ", collapse = " "))
  75. }
  76. str_trim <- function(x) {
  77. x <- gsub("^\\s*|\\s*$", "", x)
  78. gsub("\\s+", " ", x)
  79. }
  80. #' Font Awesome Icon
  81. #'
  82. #' Create the correct Font Awesome class.
  83. #' @param name Name of the Font Awesome icon
  84. #' @param solid Should the solid or the regular icon be used?
  85. #' @param as_html If `FALSE` (default), only the icon class is returned.
  86. #' @examples
  87. #' fa_icon("github")
  88. #' fa_icon("star")
  89. #' fa_icon("star", FALSE)
  90. #'
  91. #' @references <https://fontawesome.com/icons>
  92. #' @export
  93. fa_icon <- function(name, solid = TRUE, as_html = FALSE) {
  94. iconClass <- if (name %in% font_awesome_brands) "fab" else {
  95. if (solid) "fas" else "far"
  96. }
  97. iconClass <- paste(iconClass, paste0("fa-", name))
  98. if (!as_html) return(iconClass)
  99. icon <- tag_function("i")(class = iconClass)
  100. htmltools::htmlDependencies(icon) <- rmarkdown::html_dependency_font_awesome()
  101. icon
  102. }