From f971f3fd11efdc8749c7e2d74c28fdd4fbdae2c3 Mon Sep 17 00:00:00 2001 From: Stephen Holsenbeck Date: Wed, 8 Sep 2021 10:49:35 -0400 Subject: [PATCH 01/43] Use `span` instead of `p` tags in `menuSidebarItems` such that word wrapping happens appropriately --- R/dashboardSidebar.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/dashboardSidebar.R b/R/dashboardSidebar.R index 648f9aed..b6e4ce7b 100644 --- a/R/dashboardSidebar.R +++ b/R/dashboardSidebar.R @@ -409,7 +409,7 @@ bs4SidebarMenuItem <- function(text, ..., icon = NULL, badgeLabel = NULL, badgeC # needed by leftSidebar.js `data-start-selected` = if (isTRUE(selected)) 1 else NULL, icon, - shiny::tags$p(text, badgeTag) + shiny::tags$span(text, badgeTag) ) ) ) @@ -449,7 +449,7 @@ bs4SidebarMenuItem <- function(text, ..., icon = NULL, badgeLabel = NULL, badgeC class = "nav-link", `data-start-selected` = if (isTRUE(selected)) 1 else NULL, icon, - shiny::tags$p( + shiny::tags$span( text, shiny::tags$i(class = "right fas fa-angle-left") ) @@ -512,7 +512,7 @@ bs4SidebarMenuSubItem <- function(text, tabName = NULL, href = NULL, # below this is needed by leftSidebar.js `data-start-selected` = if (isTRUE(selected)) 1 else NULL, icon, - shiny::tags$p(text) + shiny::tags$span(text) ) ) } From 8279d5208f201f28b37806a810606f7d6942f3ea Mon Sep 17 00:00:00 2001 From: Stephen Holsenbeck Date: Mon, 13 Sep 2021 15:43:06 -0400 Subject: [PATCH 02/43] Add auto-reload when maximized to hopefully fix resize issues on Mac Safari --- R/cards.R | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/R/cards.R b/R/cards.R index 47960e91..cfeea5c5 100644 --- a/R/cards.R +++ b/R/cards.R @@ -279,7 +279,24 @@ bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, auto_unbox = TRUE, json_verbatim = TRUE ) - ) + ), + if (maximizable) + shiny::tags$script( + type = "text/javascript", + paste0(" + $(document).ready(function() { + $('[data-card-widget=\"maximize\"]').on('click', function() { + setTimeout(function() { + var isMaximized = $('html').hasClass('maximized-card'); + if (isMaximized) { + window.location.reload() + } + }, 300); + $('#",ifelse(is.null(id), "", paste0("#",id)),"').trigger('resize'); + }); + } + ") + ) ) } From 1952f9eaa378a0a7b3a90ff645a0b905ae0b1548 Mon Sep 17 00:00:00 2001 From: Stephen Holsenbeck Date: Mon, 13 Sep 2021 19:27:32 -0400 Subject: [PATCH 03/43] Add `tip_icon` argument to `bs4Card`, add `tippy` to suggests --- DESCRIPTION | 1 + R/cards.R | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index cb39d2ac..a7638ea9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,6 +33,7 @@ Suggests: golem, DT, thematic (>= 0.1.2), + tippy, echarts4r Encoding: UTF-8 RoxygenNote: 7.1.1.9000 diff --git a/R/cards.R b/R/cards.R index cfeea5c5..0b01bd23 100644 --- a/R/cards.R +++ b/R/cards.R @@ -69,6 +69,7 @@ #' @param closable If TRUE, display a button in the upper right that allows the user to close the box. #' @param maximizable If TRUE, the card can be displayed in full screen mode. #' @param icon Header icon. Displayed before title. Expect \code{\link[shiny]{icon}}. +#' @param tip_icon Tip icon. Tooltip Icon displayed after title. Expect \code{\link[tippy]{tippy}}. #' @param gradient Whether to allow gradient effect for the background color. Default to FALSE. #' @param boxToolSize Size of the toolbox: choose among "xs", "sm", "md", "lg". #' @param elevation Card elevation. @@ -137,7 +138,7 @@ #' @export bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, solidHeader = FALSE, background = NULL, width = 6, height = NULL, - collapsible = TRUE, collapsed = FALSE, closable = FALSE, maximizable = FALSE, icon = NULL, + collapsible = TRUE, collapsed = FALSE, closable = FALSE, maximizable = FALSE, icon = NULL, tip_icon = NULL, gradient = FALSE, boxToolSize = "sm", elevation = NULL, headerBorder = TRUE, label = NULL, dropdownMenu = NULL, sidebar = NULL, id = NULL) { @@ -242,7 +243,7 @@ bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, headerTag <- shiny::tags$div( class = if (headerBorder) "card-header" else "card-header border-0", - shiny::tags$h3(class = "card-title", icon, title) + shiny::tags$h3(class = "card-title", icon, title, tip_icon) ) headerTag <- shiny::tagAppendChild(headerTag, cardToolTag) @@ -283,6 +284,36 @@ bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, if (maximizable) shiny::tags$script( type = "text/javascript", + # paste0(" + # $(document).ready(function() { + # var ids = $('div",ifelse(is.null(id), "", paste0("#",id))," div.card-body div').map(function(){ + # return $(this).attr('id'); + # }).get(); + # function resizeBoxContent(trigger, target) { + # var target = '#' + target + # $(trigger).on('click', function() { + # setTimeout(function() { + # var isMaximized = $('html').hasClass('maximized-card'); + # if (isMaximized) { + # $(target).css('height', '100%'); + # $(target).css('width', 'auto'); + # } else { + # $(target).css('height', '400px'); + # $(target).css('width', 'auto'); + # } + # console.log('resizing '+ target) + # }, 300); + # $(target).trigger('resize'); + # }); + # }; + # setTimeout(function() { + # ids.map(function(x){ + # resizeBoxContent('div.card button[data-card-widget=\"maximize\"]', x); + # }) + # + # }, 500); + # console.log(ids); + # });"), paste0(" $(document).ready(function() { $('[data-card-widget=\"maximize\"]').on('click', function() { @@ -297,6 +328,7 @@ bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, } ") ) + ) } From 34aaceeee7805e3aa95db85864d93a78e06de1a6 Mon Sep 17 00:00:00 2001 From: Stephen Holsenbeck Date: Fri, 17 Sep 2021 07:56:47 -0400 Subject: [PATCH 04/43] Apply style to card, not card-body --- R/cards.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/cards.R b/R/cards.R index 0b01bd23..65d7bfa1 100644 --- a/R/cards.R +++ b/R/cards.R @@ -251,7 +251,6 @@ bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, # body bodyTag <- shiny::tags$div( class = "card-body", - style = style, ..., sidebar[[2]] ) @@ -264,7 +263,7 @@ bs4Card <- function(..., title = NULL, footer = NULL, status = NULL, ) } - cardTag <- shiny::tags$div(class = cardCl, id = id) + cardTag <- shiny::tags$div(class = cardCl, id = id, style = style) cardTag <- shiny::tagAppendChildren(cardTag, headerTag, bodyTag, footerTag) # wrapper From 8d4db645f857aa1395b5c0af82ea89741e929eb1 Mon Sep 17 00:00:00 2001 From: Stephen Holsenbeck Date: Mon, 27 Sep 2021 19:51:39 -0400 Subject: [PATCH 05/43] Fix collapse on app start --- inst/bs4Dash-2.0.2/bs4Dash-old.min.js | 2 ++ inst/bs4Dash-2.0.2/bs4Dash.js | 14 +++++++++----- inst/bs4Dash-2.0.2/bs4Dash.min.js | 3 +-- 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 inst/bs4Dash-2.0.2/bs4Dash-old.min.js diff --git a/inst/bs4Dash-2.0.2/bs4Dash-old.min.js b/inst/bs4Dash-2.0.2/bs4Dash-old.min.js new file mode 100644 index 00000000..9f0aca32 --- /dev/null +++ b/inst/bs4Dash-2.0.2/bs4Dash-old.min.js @@ -0,0 +1,2 @@ +var accordionBinding=new Shiny.InputBinding;$.extend(accordionBinding,{find:function(a){return $(a).find(".accordion")},getValue:function(a){var t=$(a).find(".active").index()+1;if(0!==t)return t},setValue:function(a,t){$(a).find(".active").removeClass("active"),$(a).children().eq(t-1).addClass("active"),$(a).children().eq(t-1).find('[data-toggle="collapse"]').click(),$(a).trigger("change")},receiveMessage:function(a,t){this.setValue(a,t)},subscribe:function(a,t){$(a).on("change",(function(a){t()})),$(a).find('[data-toggle="collapse"]').on("click",(function(e){$(this).closest(".card").hasClass("active")||$(a).find(".active").removeClass("active"),$(this).closest(".card").addClass("active"),t()}))},unsubscribe:function(a){$(a).off(".accordionBinding")}}),Shiny.inputBindings.register(accordionBinding,"accordion-input");const validStatuses=["primary","secondary","success","info","warning","danger"],validStatusesPlus=["dark","white","lightblue","navy","orange","fuchsia","purple","indigo","gray","gray-dark","pink","maroon","teal","lime","olive","green","yellow","red","blue"];var cardBinding=new Shiny.InputBinding;$.extend(cardBinding,{find:function(a){return $(a).find(".card")},getValue:function(a){var t=$(a).parent().find("script[data-for='"+a.id+"']");t=JSON.parse(t.html());var e,i=$(a).hasClass("collapsed-card"),n=$(a).css("display"),s=$(a).hasClass("maximized-card");return e="none"!==n,s?$(a).find("[data-card-widget = 'collapse']").hide():$(a).find("[data-card-widget = 'collapse']").show(),{collapsible:t.collapsible,collapsed:i,closable:t.closable,visible:e,maximizable:t.maximizable,maximized:s,status:t.status,solidHeader:t.solidHeader,background:t.background,width:t.width,height:t.height}},_updateWidth:function(a,t,e){$(a).parent().toggleClass("col-sm-"+t),$(a).parent().addClass("col-sm-"+e),$(a).trigger("resize")},setValue:function(a,t){var e=$(a).parent().find("script[data-for='"+a.id+"']");if(e=JSON.parse(e.html()),"update"===t.action){var i=$(a).hasClass("user-card"),n=$(a).hasClass("social-card");if(t.options.hasOwnProperty("title")&&t.options.title!==e.title){var s;s="string"!=typeof t.options.title?$.parseHTML(t.options.title[0]):$.parseHTML(t.options.title);var r=$(a).find(".card-tools");n?$(a).find(".user-block").replaceWith($(s)):i?("string"==typeof t.options.title?(s=[s[0],s[2]],$(a).removeClass("widget-user-2").addClass("widget-user"),$(a).find(".widget-user-header").replaceWith($(s[0])),$(s[1]).insertAfter($(a).find(".widget-user-header"))):($(a).removeClass("widget-user").addClass("widget-user-2"),$(a).find(".widget-user-image").remove(),$(a).find(".widget-user-header").replaceWith($(s)),null!==t.options.status&&(t.options.gradient?$(a).find(".widget-user-header").addClass("bg-gradient-",c):$(a).find(".widget-user-header").addClass("bg-",c))),$(a).find(".widget-user-header").prepend($(r))):($(s).hasClass("card-title")||$(s).addClass("card-title"),$(a).find(".card-title").replaceWith($(s))),e.title=t.options.title}if(t.options.hasOwnProperty("collapsible")&&t.options.collapsible!==e.collapsible&&(t.options.collapsible?0===$(a).find('[data-card-widget = "collapse"]').length&&($(a).find(".card-tools.float-right").prepend($('')),e.collapsible=!0):($(a).find('[data-card-widget = "collapse"]').remove(),e.collapsible=!1)),t.options.hasOwnProperty("closable")&&t.options.closable!==e.closable&&(t.options.closable?0===$(a).find('[data-card-widget = "remove"]').length&&(0===$(a).find('[data-card-widget = "maximize"]').length?$(a).find(".card-tools.float-right").append($('')):$('').insertBefore($(a).find('[data-card-widget = "maximize"]')),e.closable=!0):($(a).find('[data-card-widget = "remove"]').remove(),e.closable=!1)),t.options.hasOwnProperty("maximizable")&&t.options.maximizable!==e.maximizable&&(t.options.maximizable?0===$(a).find('[data-card-widget = "maximize"]').length&&($(a).find(".card-tools.float-right").append($('')),e.maximizable=!0):($(a).find('[data-card-widget = "maximize"]').remove(),e.maximizable=!1)),t.options.hasOwnProperty("solidHeader")&&!n&&!i)if(t.options.solidHeader!==e.solidHeader&&$(a).hasClass("card-outline"))$(a).removeClass("card-outline"),e.solidHeader=!0;else if($(a).hasClass("card-outline")||t.options.solidHeader){if($(a).hasClass("card-outline")){o=e.status||t.options.status;t.options.background&&o?($(a).removeClass("card-outline"),e.solidHeader=!0):e.background&&o&&($(a).removeClass("card-outline"),e.solidHeader=!1)}}else{var o=e.status||t.options.status;t.options.background&&o&&(null!==t.options.background||e.background&&o)||($(a).addClass("card-outline"),e.solidHeader=!1)}if(t.options.hasOwnProperty("status")&&!n&&t.options.status!==e.status){var d,l,c;if(null===t.options.status&&null!==e.status){if(i||$(a).removeClass("card-"+e.status),$(a).hasClass("card-outline")&&!i&&$(a).addClass("card-outline"),t.options.background){var u=t.options.background;validStatusesPlus.indexOf(u)>-1?$(a).find(".btn-tool").addClass("bg-"+u):validStatuses.indexOf(u)>-1&&$(a).find(".btn-tool").addClass("btn-"+u)}}else t.options.status&&(i?(l="bg-",t.options.gradient&&(l+="gradient-"),l+=t.options.status,$(a).find(".widget-user-header").addClass(l)):(l="card-"+t.options.status,$(a).addClass(l)),e.status&&(i?(d="bg-",e.gradient&&(d+="gradient-"),d+=e.status,$(a).find(".widget-user-header").removeClass(d)):(d="card-"+e.status,$(a).removeClass(d))),$(a).hasClass("card-outline")&&!i||(validStatusesPlus.indexOf(t.options.status)>-1?$(a).find(".btn-tool").addClass("bg-"+t.options.status):validStatuses.indexOf(t.options.status)>-1&&$(a).find(".btn-tool").addClass("btn-"+t.options.status)));(e.status||e.background)&&(e.status?c=e.status:e.background&&(c=e.background),validStatusesPlus.indexOf(c)>-1?$(a).find(".btn-tool").removeClass("bg-"+c):validStatuses.indexOf(c)>-1&&$(a).find(".btn-tool").removeClass("btn-"+c)),e.status=t.options.status}if(t.options.hasOwnProperty("background")&&t.options.background!==e.background){var b="bg-";if(newBgClass=b,e.background){if(e.gradient&&(b+="gradient-"),b+=e.background,i&&!e.status&&!t.options.status){var h=$(a).find(".widget-user-header");$(h).removeClass(b)}$(a).removeClass(b)}if(t.options.background){if((e.gradient||t.options.gradient)&&(newBgClass+="gradient-"),newBgClass+=t.options.background,i&&!e.status&&!t.options.status){h=$(a).find(".widget-user-header");$(h).addClass(newBgClass)}$(a).addClass(newBgClass)}e.gradient!==t.options.gradient&&void 0!==t.options.gradient&&(e.gradient=t.options.gradient),e.background=t.options.background}t.options.hasOwnProperty("width")&&t.options.width!==e.width&&(this._updateWidth(a,e.width,t.options.width),e.width=t.options.width),t.options.hasOwnProperty("height")&&t.options.height!==e.height&&(null===t.options.height?$(a).find(".card-body").css("height",""):$(a).find(".card-body").css("height",t.options.height),e.height=t.options.height),$(a).parent().find("script[data-for='"+a.id+"']").replaceWith('