diff --git a/R/draggable_buckets.R b/R/draggable_buckets.R index 9b996cc3..7753257f 100644 --- a/R/draggable_buckets.R +++ b/R/draggable_buckets.R @@ -1,3 +1,16 @@ +#' @keywords internal +#' @noRd +draggable_buckets_deps <- function() { + htmltools::htmlDependency( + name = "teal-widgets-draggable-buckets", + version = utils::packageVersion("teal.widgets"), + package = "teal.widgets", + src = "draggable-buckets", + script = "draggable-buckets.js", + stylesheet = "draggable-buckets.css" + ) +} + #' @title Draggable Buckets #' @description `r lifecycle::badge("experimental")` #' A custom widget with draggable elements that can be put into buckets. @@ -67,10 +80,7 @@ draggable_buckets <- function(input_id, label, elements = character(), buckets) elements_iterator$it <- 0 shiny::tagList( - shiny::singleton(tags$head( - shiny::includeScript(system.file("widgets/draggable_buckets.js", package = "teal.widgets")) - )), - include_css_files("draggable_buckets.css"), + draggable_buckets_deps(), shiny::div( tags$span(label), render_unbucketed_elements(elements = elements, elements_iterator = elements_iterator, widget_id = input_id), diff --git a/R/include_css_js.R b/R/include_css_js.R deleted file mode 100644 index d59a5636..00000000 --- a/R/include_css_js.R +++ /dev/null @@ -1,20 +0,0 @@ -#' Include `CSS` files from `/inst/css/` package directory to application header -#' -#' `system.file` should not be used to access files in other packages, it does -#' not work with `devtools`. Therefore, we redefine this method in each package -#' as needed. Thus, we do not export this method -#' -#' @param pattern (`character`) pattern of files to be included -#' -#' @return HTML code that includes `CSS` files -#' @keywords internal -include_css_files <- function(pattern = "*") { - css_files <- list.files( - system.file("css", package = "teal.widgets", mustWork = TRUE), - pattern = pattern, full.names = TRUE - ) - if (length(css_files) == 0) { - return(NULL) - } - return(shiny::singleton(tags$head(lapply(css_files, shiny::includeCSS)))) -} diff --git a/R/optionalInput.R b/R/optionalInput.R index 3403862c..39abc890 100644 --- a/R/optionalInput.R +++ b/R/optionalInput.R @@ -1,3 +1,15 @@ +#' @keywords internal +#' @noRd +optional_select_input_deps <- function() { + htmltools::htmlDependency( + name = "teal-widgets-optional-select-input", + version = utils::packageVersion("teal.widgets"), + package = "teal.widgets", + src = "optional-select-input", + stylesheet = "optional-select-input.css" + ) +} + #' Wrapper for `pickerInput` #' #' @description `r lifecycle::badge("stable")` @@ -244,7 +256,7 @@ optionalSelectInput <- function(inputId, # nolint ) tags$div( - include_css_files(pattern = "picker_input"), + optional_select_input_deps(), # when selected values in ui_picker change # then update ui_fixed - specifically, update '{id}_selected_text' element diff --git a/R/panel_group.R b/R/panel_group.R index ef81dad7..a4043ee8 100644 --- a/R/panel_group.R +++ b/R/panel_group.R @@ -72,6 +72,19 @@ panel_group <- function(..., id = NULL) { ) } +#' @keywords internal +#' @noRd +panel_item_deps <- function() { + htmltools::htmlDependency( + name = "teal-widgets-panel-item", + version = utils::packageVersion("teal.widgets"), + package = "teal.widgets", + src = "panel-item", + script = "panel-item.js", + stylesheet = "panel-item.css" + ) +} + #' Panel item widget #' #' @description `r lifecycle::badge("experimental")`\cr @@ -183,8 +196,7 @@ panel_item <- function(title, ..., collapsed = TRUE, input_id = NULL) { tagList( - include_css_files(pattern = "panel.css"), - tags$head(shiny::includeScript(system.file("js/panel_group.js", package = "teal.widgets"))), + panel_item_deps(), res_tag ) }) diff --git a/R/plot_with_settings.R b/R/plot_with_settings.R index 482fdd59..714e0d34 100644 --- a/R/plot_with_settings.R +++ b/R/plot_with_settings.R @@ -1,3 +1,16 @@ +#' @keywords internal +#' @noRd +plot_with_settings_deps <- function() { + htmltools::htmlDependency( + name = "teal-widgets-plot-with-settings", + version = utils::packageVersion("teal.widgets"), + package = "teal.widgets", + src = "plot-with-settings", + script = "plot-with-settings.js", + stylesheet = "plot-with-settings.css" + ) +} + #' @name plot_with_settings #' @rdname plot_with_settings #' @export @@ -7,8 +20,8 @@ plot_with_settings_ui <- function(id) { ns <- NS(id) tagList( + plot_with_settings_deps(), shiny::singleton(tags$head( - shiny::includeScript(system.file("js", "resize_plot.js", package = "teal.widgets")), tags$script( sprintf( 'establishPlotResizing("%s", "%s", "%s");', @@ -18,7 +31,6 @@ plot_with_settings_ui <- function(id) { ) ) )), - include_css_files("plot_with_settings"), tags$div( id = ns("plot-with-settings"), tags$div( diff --git a/R/table_with_settings.R b/R/table_with_settings.R index b85e435b..44acec2f 100644 --- a/R/table_with_settings.R +++ b/R/table_with_settings.R @@ -1,3 +1,15 @@ +#' @keywords internal +#' @noRd +table_with_settings_deps <- function() { + htmltools::htmlDependency( + name = "teal-widgets-table-with-settings", + version = utils::packageVersion("teal.widgets"), + package = "teal.widgets", + src = "table-with-settings", + stylesheet = "table-with-settings.css" + ) +} + #' @name table_with_settings #' #' @title `table_with_settings` module @@ -17,7 +29,7 @@ table_with_settings_ui <- function(id, ...) { ns <- NS(id) tagList( - include_css_files("table_with_settings"), + table_with_settings_deps(), tags$div( id = ns("table-with-settings"), tags$div( diff --git a/R/verbatim_popup.R b/R/verbatim_popup.R index c4cf7dc2..1f9a30e7 100644 --- a/R/verbatim_popup.R +++ b/R/verbatim_popup.R @@ -1,3 +1,15 @@ +#' @keywords internal +#' @noRd +verbatim_popup_deps <- function() { + htmltools::htmlDependency( + name = "teal-widgets-verbatim-popup", + version = utils::packageVersion("teal.widgets"), + package = "teal.widgets", + src = "verbatim-popup", + script = "verbatim-popup.js" + ) +} + #' A `shiny` module that pops up verbatim text. #' @name verbatim_popup #' @description `r lifecycle::badge("experimental")` @@ -42,9 +54,7 @@ verbatim_popup_ui <- function(id, button_label, type = c("button", "link"), ...) ) shiny::tagList( - shiny::singleton( - tags$head(shiny::includeScript(system.file("js/verbatim_popup.js", package = "teal.widgets"))) - ), + verbatim_popup_deps(), shinyjs::useShinyjs(), do.call(ui_function, c(ui_args, list(...))) ) @@ -118,9 +128,9 @@ button_click_observer <- function(click_event, shiny::showModal( shiny::modalDialog( shiny::tagList( - include_css_files(pattern = "verbatim_popup"), tags$div( class = "mb-4", + style = "margin-bottom: 1rem;", shiny::actionButton( paste0(copy_button_id, 1), "Copy to Clipboard", diff --git a/R/white_small_well.R b/R/white_small_well.R index 5e5cdd5d..2bc29044 100644 --- a/R/white_small_well.R +++ b/R/white_small_well.R @@ -17,9 +17,9 @@ #' white_small_well(shiny::htmlOutput("summary")) white_small_well <- function(...) { shiny::tagList( - include_css_files(pattern = "custom"), tags$div( - class = "well well-sm bg-white", + class = "well well-sm", + style = "background-color: white;", ... ) ) diff --git a/inst/css/custom.css b/inst/css/custom.css deleted file mode 100644 index 89143aa7..00000000 --- a/inst/css/custom.css +++ /dev/null @@ -1,5 +0,0 @@ -/* teal.widgets custom css */ - -.bg-white { - background-color: white; -} diff --git a/inst/css/verbatim_popup.css b/inst/css/verbatim_popup.css deleted file mode 100644 index 839f3857..00000000 --- a/inst/css/verbatim_popup.css +++ /dev/null @@ -1,5 +0,0 @@ -/* teal.widgets verbatim_popup css */ - -.mb-4 { - margin-bottom: 1rem; -} diff --git a/inst/css/draggable_buckets.css b/inst/draggable-buckets/draggable-buckets.css similarity index 94% rename from inst/css/draggable_buckets.css rename to inst/draggable-buckets/draggable-buckets.css index c8fb77b0..25150d6d 100644 --- a/inst/css/draggable_buckets.css +++ b/inst/draggable-buckets/draggable-buckets.css @@ -1,6 +1,5 @@ -/* teal.widgets draggable css */ - .draggableBuckets { + background: red !important; display: block; gap: 1rem; margin: 2px; @@ -18,7 +17,7 @@ } .element { - display:flex; + display: flex; justify-content: center; min-width: 1.5rem; background-color: hsl(0, 0%, 95%); @@ -51,4 +50,3 @@ position: absolute; margin-top: 8px; } - diff --git a/inst/widgets/draggable_buckets.js b/inst/draggable-buckets/draggable-buckets.js similarity index 97% rename from inst/widgets/draggable_buckets.js rename to inst/draggable-buckets/draggable-buckets.js index 9040a810..66926a95 100644 --- a/inst/widgets/draggable_buckets.js +++ b/inst/draggable-buckets/draggable-buckets.js @@ -78,11 +78,11 @@ $.extend(draggableBuckets, { // The following two methods, setInvalid and clearInvalid, will be called // whenever this input fails or passes (respectively) validation. - setInvalid: function(el, data) { + setInvalid: function (el, data) { el.setAttribute("data-error-message", data.message); el.classList.add("draggableBuckets-invalid"); }, - clearInvalid: function(el) { + clearInvalid: function (el) { el.removeAttribute("data-error-message"); el.classList.remove("draggableBuckets-invalid"); }, diff --git a/inst/js/panel_group.js b/inst/js/panel_group.js deleted file mode 100644 index 7bbeffb1..00000000 --- a/inst/js/panel_group.js +++ /dev/null @@ -1,13 +0,0 @@ -$(document).ready(function() { - $(document).on('click', '.panel-heading, .card-heading', function() { - var $icon = $(this).find('.dropdown-icon'); - - if ($(this).hasClass('collapsed')) { - $icon.removeClass('fa-angle-down').addClass('fa-angle-right'); - $(this).attr('aria-expanded', 'true'); - } else { - $icon.removeClass('fa-angle-right').addClass('fa-angle-down'); - $(this).attr('aria-expanded', 'false'); - } - }); -}); diff --git a/inst/css/picker_input.css b/inst/optional-select-input/optional-select-input.css similarity index 93% rename from inst/css/picker_input.css rename to inst/optional-select-input/optional-select-input.css index a27d6183..4856d1a9 100644 --- a/inst/css/picker_input.css +++ b/inst/optional-select-input/optional-select-input.css @@ -1,5 +1,3 @@ -/* teal.widgets picker_input css */ - /* to set the alignment of pickerInput dropdowns */ /* boostrap 3 */ .dropdown-menu.open { diff --git a/inst/css/panel.css b/inst/panel-item/panel-item.css old mode 100755 new mode 100644 similarity index 75% rename from inst/css/panel.css rename to inst/panel-item/panel-item.css index 0bd5c772..1904ea06 --- a/inst/css/panel.css +++ b/inst/panel-item/panel-item.css @@ -1,5 +1,3 @@ -/* teal.widgets panel css */ - .inline { display: inline; } diff --git a/inst/panel-item/panel-item.js b/inst/panel-item/panel-item.js new file mode 100644 index 00000000..d5d39644 --- /dev/null +++ b/inst/panel-item/panel-item.js @@ -0,0 +1,13 @@ +$(document).ready(function () { + $(document).on("click", ".panel-heading, .card-heading", function () { + var $icon = $(this).find(".dropdown-icon"); + + if ($(this).hasClass("collapsed")) { + $icon.removeClass("fa-angle-down").addClass("fa-angle-right"); + $(this).attr("aria-expanded", "true"); + } else { + $icon.removeClass("fa-angle-right").addClass("fa-angle-down"); + $(this).attr("aria-expanded", "false"); + } + }); +}); diff --git a/inst/css/plot_with_settings.css b/inst/plot-with-settings/plot-with-settings.css old mode 100755 new mode 100644 similarity index 70% rename from inst/css/plot_with_settings.css rename to inst/plot-with-settings/plot-with-settings.css index 15243d52..fa645010 --- a/inst/css/plot_with_settings.css +++ b/inst/plot-with-settings/plot-with-settings.css @@ -1,5 +1,3 @@ -/* teal.widgets plot_with_settings css */ - .well .output { position: relative; } @@ -36,16 +34,33 @@ overflow-x: auto; } -.plot-modal .modal .modal-dialog .modal-content .modal-body .plot-modal-sliders { +.plot-modal + .modal + .modal-dialog + .modal-content + .modal-body + .plot-modal-sliders { overflow: hidden; } -.plot-modal .modal .modal-dialog .modal-content .modal-body .plot-modal-sliders div:nth-child(1) { +.plot-modal + .modal + .modal-dialog + .modal-content + .modal-body + .plot-modal-sliders + div:nth-child(1) { float: left; width: 40%; } -.plot-modal .modal .modal-dialog .modal-content .modal-body .plot-modal-sliders div:nth-child(2) { +.plot-modal + .modal + .modal-dialog + .modal-content + .modal-body + .plot-modal-sliders + div:nth-child(2) { float: right; width: 40%; } diff --git a/inst/js/resize_plot.js b/inst/plot-with-settings/plot_with_settings.js similarity index 76% rename from inst/js/resize_plot.js rename to inst/plot-with-settings/plot_with_settings.js index 00014e42..bae2700e 100644 --- a/inst/js/resize_plot.js +++ b/inst/plot-with-settings/plot_with_settings.js @@ -1,13 +1,12 @@ // Function that registers resize observer for particular parent elements. // Arguments are namespaced ids of DOM elements. -var establishPlotResizing = function ( - plot_out, - flex_width, - plot_modal_width) { - +var establishPlotResizing = function (plot_out, flex_width, plot_modal_width) { // Create resize observer to trigger shiny actions when plot container is resized. var plotObserver = new ResizeObserver(function () { - Shiny.onInputChange(flex_width, document.getElementById(plot_out).clientWidth); + Shiny.onInputChange( + flex_width, + document.getElementById(plot_out).clientWidth + ); Shiny.onInputChange(plot_modal_width, 0.87 * window.innerWidth); //based on modal CSS property, also accounting for margins }); @@ -17,7 +16,7 @@ var establishPlotResizing = function ( var plotNoticer = new MutationObserver(function () { const plotContainer = document.getElementById(plot_out); if (plotContainer === null) return; - plotObserver.observe(plotContainer, { box: "border-box" } ); + plotObserver.observe(plotContainer, { box: "border-box" }); }); plotNoticer.observe(document, { subtree: true, childList: true }); diff --git a/inst/css/table_with_settings.css b/inst/table-with-settings/table-with-settings.css similarity index 74% rename from inst/css/table_with_settings.css rename to inst/table-with-settings/table-with-settings.css index fafe0ff8..8fb67918 100644 --- a/inst/css/table_with_settings.css +++ b/inst/table-with-settings/table-with-settings.css @@ -1,5 +1,3 @@ -/* teal.widgets table_with_settings css */ - .table-settings-buttons { display: flex; flex-direction: row; @@ -30,16 +28,33 @@ margin-top: 30px; } /* margin for the buttons */ -.table-modal .modal .modal-dialog .modal-content .modal-body .table-modal-sliders { +.table-modal + .modal + .modal-dialog + .modal-content + .modal-body + .table-modal-sliders { overflow: hidden; } -.table-modal .modal .modal-dialog .modal-content .modal-body .table-modal-sliders div:nth-child(1) { +.table-modal + .modal + .modal-dialog + .modal-content + .modal-body + .table-modal-sliders + div:nth-child(1) { float: left; width: 40%; } -.table-modal .modal .modal-dialog .modal-content .modal-body .table-modal-sliders div:nth-child(2) { +.table-modal + .modal + .modal-dialog + .modal-content + .modal-body + .table-modal-sliders + div:nth-child(2) { float: right; width: 40%; } diff --git a/inst/js/verbatim_popup.js b/inst/verbatim-popup/verbatim-popup.js similarity index 94% rename from inst/js/verbatim_popup.js rename to inst/verbatim-popup/verbatim-popup.js index 4ffc33bb..525967d6 100644 --- a/inst/js/verbatim_popup.js +++ b/inst/verbatim-popup/verbatim-popup.js @@ -1,8 +1,5 @@ // this code alows the show R code "copy to clipbaord" button to work -const copyToClipboard = ( - elementIdToCopy, - onFailure = () => null -) => { +const copyToClipboard = (elementIdToCopy, onFailure = () => null) => { const copiedContent = document.getElementById(elementIdToCopy).innerText; if (navigator.clipboard) { navigator.clipboard.writeText(copiedContent).then(() => { diff --git a/man/include_css_files.Rd b/man/include_css_files.Rd deleted file mode 100644 index 76ac430d..00000000 --- a/man/include_css_files.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/include_css_js.R -\name{include_css_files} -\alias{include_css_files} -\title{Include \code{CSS} files from \verb{/inst/css/} package directory to application header} -\usage{ -include_css_files(pattern = "*") -} -\arguments{ -\item{pattern}{(\code{character}) pattern of files to be included} -} -\value{ -HTML code that includes \code{CSS} files -} -\description{ -\code{system.file} should not be used to access files in other packages, it does -not work with \code{devtools}. Therefore, we redefine this method in each package -as needed. Thus, we do not export this method -} -\keyword{internal}