├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── box.R ├── infoTooltip.R ├── infomessage.R ├── layout.R ├── modal.R ├── panels.R └── utils.R ├── README.md ├── cran-comments.md ├── inst ├── assets │ ├── css │ │ ├── line_color │ │ └── style.css │ └── js │ │ ├── box_info.js │ │ ├── iframeSizer.contentWindow.min.js │ │ └── index.js └── examples │ ├── basic-app.R │ ├── basic-panel.R │ ├── custom-css.R │ └── multiple-modal.R ├── man ├── box.Rd ├── figures │ └── shinypanels.png ├── infoTooltip.Rd ├── infomessage.Rd ├── modal.Rd ├── modalButton.Rd ├── panel.Rd ├── panelsPage.Rd └── topbar.Rd ├── shinypanels.Rproj └── tests ├── testthat.R └── testthat └── test_layout.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^pkgdown$ 2 | ^_pkgdown\.yml$ 3 | ^.github$ 4 | ^inst/pkgdown$ 5 | ^docs$ 6 | ^.*\.Rproj$ 7 | ^\.Rproj\.user$ 8 | ^README\.Rmd$ 9 | ^README 10 | ^README-.*\.png$ 11 | ^\.travis\.yml$ 12 | ^appveyor\.yml$ 13 | ^codecov\.yml$ 14 | ^cran-comments\.md$ 15 | ^CRAN-RELEASE$ 16 | ^revdep$ 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Example code in package build process 6 | *-Ex.R 7 | 8 | # RStudio files 9 | .Rproj.user/ 10 | .Rproj.user/* 11 | 12 | # RData 13 | .RData 14 | 15 | # produced vignettes 16 | vignettes/*.html 17 | vignettes/*.pdf 18 | 19 | #*.Rproj 20 | .Rproj.user 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: shinypanels 2 | Type: Package 3 | Title: Shiny Layout with Collapsible Panels 4 | Version: 0.5.1 5 | Date: 2020-01-19 6 | Authors@R: 7 | person(given = "Juan Pablo", 8 | family = "Marin Diaz", 9 | role = c("aut", "cre"), 10 | email = "jpmarindiaz@gmail.com") 11 | Maintainer: Juan Pablo Marin Diaz 12 | Description: Create 'Shiny Apps' with collapsible vertical panels. 13 | This package provides a new visual arrangement for elements on top of 'Shiny'. 14 | Use the expand and collapse capabilities to leverage web applications with 15 | many elements to focus the user attention on the panel of interest. 16 | URL: http://github.com/datasketch/shinypanels 17 | Depends: 18 | R (>= 3.1.2) 19 | Imports: 20 | htmltools, 21 | glue, 22 | shiny, 23 | shinyjs 24 | Suggests: 25 | rlang, 26 | testthat 27 | License: MIT + file LICENSE 28 | Encoding: UTF-8 29 | LazyData: true 30 | RoxygenNote: 7.2.1 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2020 2 | COPYRIGHT HOLDER: Juan Pablo Marin Diaz 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(box) 4 | export(infoTooltip) 5 | export(infomessage) 6 | export(modal) 7 | export(modalButton) 8 | export(panel) 9 | export(panelsPage) 10 | export(removeModal) 11 | export(showModal) 12 | export(showModalMultipleId) 13 | export(topbar) 14 | import(glue) 15 | import(htmltools) 16 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 2020-01-08 2 | 3 | First release 4 | 5 | -------------------------------------------------------------------------------- /R/box.R: -------------------------------------------------------------------------------- 1 | #' Box like component 2 | #' 3 | #' @param title title for the box 4 | #' @param collapsed defines initial state 5 | #' @param color color name as defined in custom css 6 | #' @param ... html list contents for the panel 7 | #' 8 | #' @return None 9 | #' 10 | #' @import htmltools 11 | #' @import glue 12 | #' @examples 13 | #' box() 14 | #' 15 | #' @export 16 | box <- function(..., title = NULL, collapsed = TRUE, color = "") { 17 | 18 | contents <- rlang::dots_list(...) 19 | state <- ifelse(collapsed, '', 'active') 20 | 21 | # shiny::div( 22 | # l, 23 | div(class="box-collapsible", 24 | tags$button(class=glue("box-collapsible-trigger {state}"), span(title), 25 | svgArrow()), 26 | div(class=glue("box-collapsible-content {state}"), 27 | div(contents) 28 | ) 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /R/infoTooltip.R: -------------------------------------------------------------------------------- 1 | #' Text with tooltip 2 | #' 3 | #' @param title Text 4 | #' @param info Message which appears when a cursor is positioned over an icon 5 | #' @param icon HTML name of icon 6 | #' @param containerStyle CSS styles for the container div 7 | #' @param iconStyle CSS styles for the icon 8 | #' @param tooltipStyle CSS styles for the tooltip 9 | #' 10 | #' @return None 11 | #' 12 | #' @examples 13 | #' infoTooltip("Information", info = "This a content of tooltip", icon = "cloud") 14 | #' 15 | #' @export 16 | infoTooltip <- function(title, info, icon = "info-circle", containerStyle = "", iconStyle = "", tooltipStyle = "") { 17 | HTML(paste0('
', 20 | title, 21 | '
', 24 | icon(icon), 25 | '
', 28 | info, 29 | '
' 30 | )) 31 | } 32 | -------------------------------------------------------------------------------- /R/infomessage.R: -------------------------------------------------------------------------------- 1 | #' Infomessage to show messages 2 | #' 3 | #' @param type one of: warning, success, error or info 4 | #' @param id id of html element 5 | #' @param class class of html element 6 | #' @param ... html list contents for the panel 7 | #' 8 | #' @return None 9 | #' 10 | #' @import htmltools 11 | #' @import glue 12 | #' @examples 13 | #' infomessage() 14 | #' 15 | #' @export 16 | infomessage <- function(..., type = "warning", id = NULL, class = NULL){ 17 | if(!type %in% c("warning","error", "info", "success")) 18 | stop('Type must be one of "warning","error", "info", "success"') 19 | div(class = paste("infomessage", type, class), id = id, 20 | rlang::dots_list(...) 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /R/layout.R: -------------------------------------------------------------------------------- 1 | #' Shiny panels layout 2 | #' 3 | #' @param header html list with custom header 4 | #' @param title Title html page attribute 5 | #' @param debug Used for debugging layout html 6 | #' @param styles custom css styles 7 | #' @param ... html list contents for the panel 8 | #' 9 | #' @return None 10 | #' 11 | #' @examples 12 | #' panelsPage() 13 | #' 14 | #' @export 15 | panelsPage <- function(..., styles = "", header = NULL, title = NULL, debug = FALSE){ 16 | deps <- list( 17 | 18 | htmlDependency("font-awesome", "4.1.0", 19 | src = c(href = "//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/"), 20 | stylesheet = "font-awesome.min.css" 21 | ), 22 | # htmlDependency("box", "0.0.1", 23 | # src = (file = system.file("assets/js", package = "shinypanels")), 24 | # script = "box_info.js" 25 | # ), 26 | htmlDependency("style", "0.0.1", 27 | src = (file = system.file("assets","css", package = "shinypanels")), 28 | stylesheet = "style.css" 29 | ) 30 | ) 31 | panels <- list(...) 32 | 33 | jsfile <- system.file("assets","js", "index.js", package = "shinypanels") 34 | indexJS <- tags$script(HTML(paste0(readLines(jsfile),collapse="\n"))) 35 | #debugJS <- tags$script(ifelse(debug,"var debug = true;","var debug = false;")) 36 | 37 | 38 | # addResourcePath( 39 | # prefix = 'box', 40 | # directoryPath = system.file('/assets/js', package='shinypanels') 41 | # ) 42 | jsbox <- system.file("assets","js", "box_info.js", package = "shinypanels") 43 | boxJS <- tags$script(HTML(paste0(readLines(jsbox),collapse="\n"))) 44 | 45 | header <- header 46 | if (!is.null(header)) { 47 | div(class = "layout-header", 48 | header) 49 | } 50 | 51 | 52 | page <- tagList( 53 | tags$head( 54 | tags$meta(name = "viewport", content = "width=device-width, initial-scale=1.0"), 55 | tags$meta(`http-equiv` = "X-UA-Compatible", content="ie=edge"), 56 | tags$title(title)#, 57 | #tags$script(src = "box/box_info.js") 58 | ), 59 | # div(class = "orientation-notice", 60 | # div(class="orientation-notice-content", 61 | # p('Gira tu dispositivo', style = "text-align: center;"), 62 | # svgRotate() 63 | # ), 64 | # ), 65 | div(class = "layout-container", 66 | header, 67 | div(class = "layout-panels", 68 | div(class="app-container", 69 | panels 70 | ) 71 | ) 72 | ), 73 | indexJS, 74 | boxJS, 75 | tags$style(styles) 76 | ) 77 | old <- attr(page, "html_dependencies", TRUE) 78 | htmlDependencies(page) <- c(old, deps) 79 | page 80 | } 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /R/modal.R: -------------------------------------------------------------------------------- 1 | #' Modal window 2 | #' 3 | #' @param title title for the modal 4 | #' @param id html attribute id for the component 5 | #' @param ... html list contents for the panel 6 | #' 7 | #' @return None 8 | #' 9 | #' @examples 10 | #' modal() 11 | #' @export 12 | modal <- function(..., title = NULL, id = NULL, fullscreen = FALSE, id_wrapper = NULL, id_title = NULL, id_content = NULL){ 13 | contents <- rlang::dots_list(...) 14 | div(class = "modal", id = id, `data-fullscreen` = fullscreen, 15 | div(class = "modal-wrapper",id = id_wrapper, 16 | div(class = "modal-title", id = id_title, 17 | tags$h3(title), 18 | tags$button(style = "background-color: inherit; border: none;", id = "close-modal", 19 | svgX())), 20 | div(class = "modal-content", id = id_content, div(contents)))) 21 | } 22 | 23 | #' Modal button to trigger a modal 24 | #' 25 | #' @param label label for the button 26 | #' @param modal_id modal id to be triggered by the button 27 | #' @param id html attribute id for the button 28 | #' 29 | #' @return None 30 | #' 31 | #' @examples 32 | #' modal() 33 | #' @export 34 | modalButton <- function(modal_id = NULL, label = NULL, id = NULL) { 35 | tags$button('data-modal' = modal_id, 36 | class="modal-trigger", 37 | id = id, 38 | tags$span(label) 39 | ) 40 | } 41 | 42 | 43 | #' @export 44 | showModal <- function(modal_id, session = getDefaultReactiveDomain()) { 45 | session$sendCustomMessage("showModalManually", modal_id) 46 | } 47 | 48 | #' @export 49 | removeModal <- function(modal_id, session = getDefaultReactiveDomain()) { 50 | session$sendCustomMessage("removeModalManually", modal_id) 51 | } 52 | 53 | #' @export 54 | showModalMultipleId <- function(modal_id, list_id, session = getDefaultReactiveDomain()) { 55 | purrr::map(list_id, ~ session$sendCustomMessage("showModalMultiple", message = list( 56 | apply_id = .x, inputId = modal_id)) 57 | ) 58 | } 59 | 60 | -------------------------------------------------------------------------------- /R/panels.R: -------------------------------------------------------------------------------- 1 | #' Panel component for shiny panels layout 2 | #' 3 | #' @param head html for the panel header 4 | #' @param body html tag list for panel body contents 5 | #' @param show_footer include footer 6 | #' @param footer footer contents 7 | #' @param color color name as defined in custom css 8 | #' @param id panel div id 9 | #' @param collapsed panel starts as collapsed 10 | #' @param width panel width in pixels 11 | #' @param title panel title 12 | #' @param ... html list contents for the panel 13 | #' 14 | #' @return None 15 | #' 16 | #' @examples 17 | #' panel(title = "My title") 18 | #' 19 | #' @export 20 | panel <- function(head = NULL, body = NULL, footer = NULL, 21 | title = NULL, header_right = NULL, color = "malibu", 22 | id = NULL, collapsed = FALSE, can_collapse = TRUE, width = NULL, 23 | hidden = FALSE, 24 | ...){ 25 | collapsed <- ifelse(collapsed, "collapsed", "") 26 | if(is.null(title)) stop("Need panel title") 27 | 28 | id_head <- paste0(id,"_head") 29 | id_body <- paste0(id,"_body") 30 | 31 | footer <- footer 32 | if (!is.null(footer)) { 33 | footer <- div(class="panel-footer", 34 | footer 35 | ) 36 | } 37 | 38 | 39 | header_right <- header_right 40 | if (!is.null(header_right)) { 41 | header_right <- div(class="panel-header_right", 42 | header_right 43 | ) 44 | } 45 | 46 | if (!color %in% c("malibu", "chardonnay", "magenta")) { 47 | class0 <- glue("panel-header-dismiss") 48 | style0 <- style2 <- glue("color: {color};") 49 | class1 <- glue("panel {collapsed}") 50 | style1 <- glue("border-top: 1.5px solid {color};") 51 | class2 <- "panel-header-title" 52 | } else { 53 | class0 <- glue("panel-header-dismiss text-{color}") 54 | class1 <- glue("panel top-{color} {collapsed}") 55 | class2 <- glue("panel-header-title text-{color}") 56 | style0 <- style1 <- style2 <- "" 57 | } 58 | if(hidden){ 59 | style1<- paste0(style1, "display:none;") 60 | } 61 | 62 | can_collapse <- can_collapse 63 | if (can_collapse) { 64 | can_collapse <- tags$button(class = class0, style = style0, svgX(color)) 65 | } else { 66 | can_collapse <- NULL 67 | } 68 | 69 | div(class = class1, 70 | style = style1, 71 | `data-width` = width, 72 | id=id, 73 | div(class="panel-header", id = id_head, 74 | p(class=class2, style = style2, title), 75 | header_right, 76 | can_collapse 77 | ), 78 | div(class="panel-body", id = id_body, 79 | div(class="panel-content", 80 | body 81 | ) 82 | ), 83 | footer 84 | 85 | ) 86 | } 87 | 88 | #' Top bar component for shiny panels layout 89 | #' 90 | #' @param title Top bar panel 91 | #' @param image Logo image 92 | #' @param background_color background color for top bar 93 | #' @param ... html list contents for the panel 94 | #' 95 | #' @return None 96 | #' 97 | #' @examples 98 | #' topbar() 99 | #' 100 | #' @export 101 | topbar <- function(..., title = NULL, image = NULL, background_color = NULL){ 102 | if(is.null(title) && is.null(image)){ 103 | contents <- list(...) 104 | } else{ 105 | contents <- "" 106 | } 107 | message(contents) 108 | div(style=glue("background-color:{background_color}"), class="topbar", 109 | img(class="topbar__img", src = image), 110 | h3(class = "topbar__title", title), 111 | contents 112 | ) 113 | } 114 | 115 | svgArrow <- function(color){ 116 | HTML(glue(' 117 | 118 | ')) 119 | } 120 | 121 | svgX <- function(color = ""){ 122 | HTML(glue(' 123 | ')) 124 | } 125 | 126 | svgRotate <- function() { 127 | HTML(' 128 | 132 | 136 | 137 | ') 140 | } 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | is.reactive <- function(obj){ 2 | all(class(obj) %in% c("reactiveExpr","reactive")) 3 | } 4 | 5 | 6 | `%||%` <- function (x, y) 7 | { 8 | if (is.empty(x)) 9 | return(y) 10 | else if (is.null(x) || is.na(x)) 11 | return(y) 12 | else if (class(x) == "character" && nchar(x) == 0) 13 | return(y) 14 | else x 15 | } 16 | 17 | is.empty <- function (x) 18 | { 19 | !as.logical(length(x)) 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # shinypanels 3 | 4 | `shinypanels` provides a new layout with collapsible horizontal panels for building shiny apps. 5 | 6 | ![shinypanels](man/figures/shinypanels.png) 7 | 8 | # Installation 9 | 10 | ``` 11 | remotes::install_github("datasketch/shinypanels") 12 | ``` 13 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Resubmission 4 2 | 3 | Update LICENSE year to 2020. 4 | 5 | ## Resubmission 3 6 | 7 | Update LICENSE year. 8 | Provided better Description of package in DESCRIPTION. 9 | 10 | Renamed package for a clearer name 11 | dsAppLayout -> shinypanels 12 | 13 | There were no ERRORs, WARNINGs or NOTES on Ubuntu. 14 | One note on CRAN Win Builder 15 | Maintainer: 'Juan Pablo Marin Diaz ' 16 | 17 | New submission 18 | 19 | 20 | ## Resubmission 2 21 | 22 | Removed ORGANIZATION from LICENSE. 23 | Fixed LICENSE according to CRAN template for MIT License. 24 | 25 | ## Test environments 26 | * local Ubuntu 18. R version 3.6.2 (2019-12-12) 27 | * Windows with devtools::check_win_* 28 | * rhub with devtools::check_rhub() 29 | 30 | ## R CMD check results 31 | There were no ERRORs, WARNINGs or NOTES on Ubuntu. 32 | One note on CRAN Win Builder 33 | Maintainer: 'Juan Pablo Marin Diaz ' 34 | 35 | New submission 36 | 37 | License components with restrictions and base license permitting such: 38 | MIT + file LICENSE 39 | File 'LICENSE': 40 | The MIT License (MIT) 41 | 42 | ## Reverse dependencies 43 | 44 | This is a new release, so there are no reverse dependencies. 45 | 46 | -------------------------------------------------------------------------------- /inst/assets/css/line_color: -------------------------------------------------------------------------------- 1 | line_color 2 | axis_title_color 3 | axis_line_color 4 | axis_ticks_color 5 | grid_color 6 | grid_x_color 7 | grid_y_color 8 | -------------------------------------------------------------------------------- /inst/assets/css/style.css: -------------------------------------------------------------------------------- 1 | /*@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;700&display=swap');*/ 2 | 3 | @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;500;700&family=Ubuntu:wght@300;700&display=swap'); 4 | 5 | *, 6 | *:before, 7 | *:after { 8 | box-sizing: inherit; 9 | margin: 0; 10 | } 11 | 12 | html, 13 | body { 14 | background-color: #fbfdfe; 15 | box-sizing: border-box; 16 | color: #435b69; 17 | font-family: 'IBM Plex Sans', sans-serif; 18 | font-weight: 300; 19 | height: 100%; 20 | } 21 | 22 | hr { 23 | border-top: 1px solid #eef3f5; 24 | color: #eef3f5; 25 | margin: 10px 0 20px 0; 26 | } 27 | 28 | /* STYLES PANELS*/ 29 | 30 | .layout-container { 31 | display: flex; 32 | flex-direction: column; 33 | height: 100%; 34 | } 35 | 36 | .layout-header { 37 | background-color: teal; 38 | color: #fafafa; 39 | padding: 1rem; 40 | } 41 | 42 | .layout-panels { 43 | background-color: #fbfdfe; 44 | flex-grow: 1; 45 | flex-shrink: 1; 46 | overflow-x: auto; 47 | padding: 1rem; 48 | } 49 | 50 | .app-container:after { 51 | content: ''; 52 | flex: 0 0 1rem; 53 | } 54 | 55 | .app-container { 56 | display: flex; 57 | height: 100%; 58 | } 59 | 60 | .panel { 61 | background: #ffffff; 62 | border-top: 1.5px solid #feca84; 63 | box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1); 64 | display: flex; 65 | flex-direction: column; 66 | flex-shrink: 0; 67 | font-size: 0.875rem; 68 | margin-right: 1.3rem; 69 | overflow-y: auto; 70 | /* padding: 0 0 1.5rem 0; */ 71 | padding: 0; 72 | } 73 | 74 | .panel::-webkit-scrollbar-thumb { 75 | background-color: #ffffff; 76 | } 77 | 78 | .panel:last-child { 79 | margin-right: 0; 80 | } 81 | 82 | .panel-header { 83 | align-items: center; 84 | background: #ffffff; 85 | display: flex; 86 | justify-content: space-between; 87 | padding: 1rem 1.5rem 1rem 2rem; 88 | position: sticky; 89 | top: 0; 90 | z-index: 10; 91 | } 92 | 93 | .panel-header-title { 94 | font-family: 'Ubuntu', sans-serif; 95 | font-size: 0.875rem; 96 | font-weight: 700; 97 | letter-spacing: 0.055em; 98 | text-transform: uppercase; 99 | } 100 | 101 | .panel-header-dismiss { 102 | background-color: transparent; 103 | border: none; 104 | cursor: pointer; 105 | line-height: 0; 106 | margin: 0; 107 | padding: 0; 108 | } 109 | 110 | .panel-header-dismiss:focus { 111 | outline: none; 112 | } 113 | 114 | .panel-body { 115 | flex-grow: 1; 116 | margin-top: 1rem; 117 | padding: 0 2rem; 118 | } 119 | 120 | .panel-body.footerless { 121 | padding-bottom: 1.5rem; 122 | } 123 | 124 | #edit_viz_body { 125 | overflow-y: auto; 126 | } 127 | 128 | .panel-content { 129 | height: 100%; 130 | /* position: relative; */ 131 | } 132 | 133 | .panel-footer { 134 | background-color: #ffffff; 135 | bottom: 0; 136 | /* padding: 0.5rem 2rem 2rem 3rem; */ 137 | padding: 1rem 2rem; 138 | position: sticky; 139 | z-index: 10; 140 | } 141 | 142 | .panel.collapsed { 143 | display: block; 144 | overflow: hidden; 145 | padding: 1rem; 146 | width: auto; 147 | writing-mode: vertical-lr; 148 | } 149 | 150 | .panel.collapsed .panel-header { 151 | padding: 0rem; 152 | transform: rotateZ(180deg); 153 | } 154 | 155 | .panel.collapsed { 156 | cursor: pointer; 157 | } 158 | 159 | .panel.collapsed .panel-header-title { 160 | flex-grow: 1; 161 | text-align: right; 162 | } 163 | 164 | .panel.collapsed .panel-header-dismiss { 165 | margin: 1rem 0 0; 166 | transform: rotate(45deg); 167 | } 168 | 169 | .panel #download { 170 | display: block; 171 | } 172 | 173 | .panel.collapsed #download { 174 | display: none; 175 | } 176 | 177 | .panel.collapsed .panel-body, 178 | .panel.collapsed .panel-footer { 179 | opacity: 0; 180 | padding: 0; 181 | } 182 | 183 | .panel.collapsed .panel-content, 184 | .panel.collapsed .panel-footer { 185 | overflow: hidden; 186 | width: 0; 187 | } 188 | 189 | /* END STYLES PANELS*/ 190 | 191 | img { 192 | height: auto !important; 193 | max-width: 100% !important; 194 | } 195 | 196 | h4 { 197 | color: #b70f7f; 198 | font-size: 13px; 199 | font-weight: 700; 200 | letter-spacing: 0.7px; 201 | opacity: 1; 202 | text-transform: uppercase; 203 | } 204 | 205 | .orientation-notice { 206 | background-color: #000000; 207 | color: white; 208 | display: flex; 209 | height: 100%; 210 | left: 0; 211 | position: absolute; 212 | top: 0; 213 | width: 100%; 214 | z-index: 9999; 215 | } 216 | 217 | .orientation-notice-content { 218 | margin: auto; 219 | width: 90%; 220 | } 221 | 222 | .orientation-notice svg { 223 | fill: currentColor; 224 | } 225 | 226 | .viz-types { 227 | background-color: #ffffff; 228 | display: grid; 229 | grid-gap: 20px; 230 | grid-template-columns: repeat(auto-fill, 40px); 231 | padding: 1rem 0; 232 | } 233 | 234 | .viz-types button { 235 | align-items: center; 236 | background-color: transparent; 237 | border: none; 238 | box-shadow: none; 239 | cursor: pointer; 240 | display: flex; 241 | height: 40px; 242 | justify-content: center; 243 | outline: 0; 244 | position: relative; 245 | text-align: center; 246 | width: 40px; 247 | } 248 | 249 | .viz-types button:before { 250 | background: url(/images/check.svg) no-repeat center; 251 | background-color: #b70f7f; 252 | background-size: cover; 253 | border-radius: 50%; 254 | content: ''; 255 | height: 10px; 256 | position: absolute; 257 | right: 0; 258 | top: 0; 259 | transform: scale(0); 260 | transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); 261 | width: 10px; 262 | } 263 | 264 | .viz-types button.active:before { 265 | transform: scale(1); 266 | } 267 | 268 | .viz-types button img { 269 | filter: brightness(0) invert(0.7); 270 | height: 35px; 271 | transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); 272 | width: 35px; 273 | } 274 | 275 | .viz-types button.active img { 276 | filter: brightness(1) invert(0) !important; 277 | } 278 | 279 | .top-malibu { 280 | border-top: 1.5px solid #3295f5; 281 | } 282 | 283 | .top-chardonnay { 284 | border-top: 1.5px solid #fbc140; 285 | } 286 | 287 | .top-magenta { 288 | border-top: 1.5px solid #da1c95; 289 | } 290 | 291 | .text-malibu { 292 | color: #3295f5; 293 | } 294 | 295 | .text-chardonnay { 296 | color: #fbc140; 297 | } 298 | 299 | .text-magenta { 300 | color: #da1c95; 301 | } 302 | 303 | /* Loader GIF -- rewriting shinycostumloader package styles */ 304 | .load-container { 305 | transform: translateY(37%) !important; 306 | } 307 | 308 | .loader-img { 309 | width: 20% !important; 310 | } 311 | 312 | /* ESTILOS BOX */ 313 | .box-collapsible { 314 | background-color: #ffffff; 315 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); 316 | } 317 | 318 | .box-collapsible-trigger { 319 | background-color: transparent; 320 | border: none; 321 | color: #444; 322 | cursor: pointer; 323 | display: flex; 324 | font-size: 15px; 325 | font-weight: 700; 326 | justify-content: space-between; 327 | outline: none; 328 | outline: none; 329 | padding: 1rem 1.25rem; 330 | text-align: left; 331 | text-transform: uppercase; 332 | width: 100%; 333 | } 334 | 335 | .box-collapsible-trigger.active .box-collapsible-icon { 336 | transform: rotate(0); 337 | } 338 | 339 | .box-collapsible-icon { 340 | height: 1.25rem; 341 | transform: rotate(180deg); 342 | width: 1.25rem; 343 | } 344 | 345 | .box-collapsible-trigger:hover { 346 | background-color: #f7fafc; 347 | } 348 | 349 | .box-collapsible-content { 350 | background-color: transparent; 351 | max-height: 0; 352 | overflow: hidden; 353 | padding: 0 1.25rem; 354 | transition: max-height 0.2s ease-out; 355 | } 356 | 357 | /* MODAL */ 358 | .modal { 359 | background-color: rgba(0, 0, 0, 0.7); 360 | height: 100%; 361 | left: 0; 362 | opacity: 0; 363 | position: absolute; 364 | top: 0; 365 | transition-delay: 0.25s; 366 | transition: opacity 0.5s ease-in; 367 | width: 100%; 368 | z-index: -1; 369 | } 370 | 371 | .modal-wrapper { 372 | background-color: #ffffff; 373 | border-radius: 3px; 374 | box-shadow: 5px 5px 5px 0 rgba(0, 0, 0, 0.2); 375 | left: 50%; 376 | max-width: 80%; 377 | opacity: 0; 378 | overflow-y: scroll; 379 | position: absolute; 380 | top: -100%; 381 | transform: translate(-50%, -50%); 382 | transition-delay: 0.25s; 383 | transition: all 0.5s ease-in; 384 | /* Para diseño */ 385 | max-height: 90%; 386 | } 387 | 388 | .modal-content { 389 | opacity: 0; 390 | padding: 1rem; 391 | transition-delay: 0s; 392 | transition: opacity 0.25s ease-in; 393 | } 394 | 395 | .modal.is-visible { 396 | opacity: 1; 397 | transition-delay: 0s; 398 | z-index: 9999; 399 | } 400 | 401 | .modal.is-visible .modal-wrapper { 402 | opacity: 1; 403 | top: 46%; 404 | transition-delay: 0s; 405 | } 406 | 407 | .modal.is-visible .modal-content { 408 | opacity: 1; 409 | transition-delay: 0.5s; 410 | } 411 | 412 | .modal-title { 413 | align-items: center; 414 | border-bottom: 1px solid #eee; 415 | display: flex; 416 | justify-content: space-between; 417 | padding: 1rem; 418 | } 419 | 420 | .modal-title h3 { 421 | margin: 0; 422 | } 423 | 424 | /* Topbar */ 425 | .topbar { 426 | align-items: center; 427 | display: flex; 428 | padding: 0 30px; 429 | width: 100%; 430 | } 431 | 432 | .topbar__img { 433 | width: 80px; 434 | } 435 | 436 | .topbar__title { 437 | margin-left: 1rem; 438 | } 439 | 440 | /* 441 | TOOLTIP 442 | */ 443 | 444 | .tooltip { 445 | align-items: center; 446 | display: flex; 447 | } 448 | 449 | .tooltip-slot { 450 | margin-left: 4px; 451 | } 452 | 453 | .tooltip-icon { 454 | color: #8097a4; 455 | cursor: pointer; 456 | } 457 | 458 | .tooltip-content { 459 | background-color: #ffffff; 460 | border: 1px solid #e6eaed; 461 | box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1); 462 | color: #435b69; 463 | display: none; 464 | font-family: Arial; 465 | font-size: 0.75rem; 466 | max-width: 250px; 467 | min-width: 180px; 468 | padding: 1rem; 469 | position: absolute; 470 | } 471 | 472 | .tooltip-slot:hover .tooltip-content { 473 | display: block; 474 | z-index: 10; 475 | } 476 | 477 | /* 478 | BUTTONS STYLE 479 | */ 480 | 481 | .input-group { 482 | align-items: baseline; 483 | border-collapse: separate; 484 | display: inline-flex; 485 | flex-direction: column; 486 | position: relative; 487 | } 488 | 489 | .form-control[disabled], 490 | .form-control[readonly], 491 | fieldset[disabled] .form-control { 492 | background-color: #eef3f5; 493 | border-radius: 2px; 494 | opacity: 1; 495 | width: 100%; 496 | } 497 | 498 | .btn, 499 | .modal-trigger { 500 | background: #da1c95; 501 | border-radius: 5px; 502 | border: 0px; 503 | color: #ffffff; 504 | cursor: pointer; 505 | font-family: 'Ubuntu', sans-serif; 506 | font-size: 0.75rem; 507 | font-weight: 700; 508 | letter-spacing: 0.055em; 509 | padding: 10px 15px; 510 | text-decoration: none; 511 | text-transform: uppercase; 512 | transition: background 0.3s linear; 513 | } 514 | 515 | .btn-default { 516 | border-radius: 0.35rem; 517 | display: block; 518 | text-align: center; 519 | margin-right: auto; 520 | margin-left: auto; 521 | } 522 | 523 | .btn:hover { 524 | background: #b70f7f; 525 | } 526 | 527 | .progress.shiny-file-input-progress { 528 | visibility: hidden; 529 | } 530 | 531 | .progress { 532 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 533 | background-color: #f5f5f5; 534 | border-radius: 4px; 535 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); 536 | height: 20px; 537 | margin-top: 10px; 538 | overflow: hidden; 539 | } 540 | 541 | .progress-bar.active, 542 | .progress.active .progress-bar { 543 | -o-animation: progress-bar-stripes 2s linear infinite; 544 | -webkit-animation: progress-bar-stripes 2s linear infinite; 545 | animation: progress-bar-stripes 2s linear infinite; 546 | } 547 | 548 | .progress-bar-striped, 549 | .progress-striped .progress-bar { 550 | background-image: -webkit-linear-gradient( 551 | 45deg, 552 | rgba(255, 255, 255, 0.15) 25%, 553 | transparent 25%, 554 | transparent 50%, 555 | rgba(255, 255, 255, 0.15) 50%, 556 | rgba(255, 255, 255, 0.15) 75%, 557 | transparent 75%, 558 | transparent 559 | ); 560 | background-image: -o-linear-gradient( 561 | 45deg, 562 | rgba(255, 255, 255, 0.15) 25%, 563 | transparent 25%, 564 | transparent 50%, 565 | rgba(255, 255, 255, 0.15) 50%, 566 | rgba(255, 255, 255, 0.15) 75%, 567 | transparent 75%, 568 | transparent 569 | ); 570 | background-image: linear-gradient( 571 | 45deg, 572 | rgba(255, 255, 255, 0.15) 25%, 573 | transparent 25%, 574 | transparent 50%, 575 | rgba(255, 255, 255, 0.15) 50%, 576 | rgba(255, 255, 255, 0.15) 75%, 577 | transparent 75%, 578 | transparent 579 | ); 580 | -webkit-background-size: 40px 40px; 581 | background-size: 40px 40px; 582 | } 583 | 584 | .progress-bar { 585 | -o-transition: width 0.6s ease; 586 | -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); 587 | -webkit-transition: width 0.6s ease; 588 | background-color: #b70f7f; 589 | box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); 590 | color: #fff; 591 | float: left; 592 | font-size: 12px; 593 | height: 100%; 594 | line-height: 20px; 595 | text-align: center; 596 | transition: width 0.6s ease; 597 | width: 0%; 598 | } 599 | 600 | .control-label { 601 | display: inline-block; 602 | font-weight: 500; 603 | } 604 | 605 | #initial_data-tableInputControls .control-label { 606 | margin-bottom: 5px; 607 | } 608 | 609 | /* 610 | TEXTAREA STYLE 611 | */ 612 | 613 | textarea.form-control { 614 | border-radius: 8px; 615 | padding: 10px; 616 | } 617 | 618 | /* 619 | CHECKBOX STYLE (Not working) 620 | */ 621 | 622 | /*.checkbox label { 623 | display: block; 624 | position: relative; 625 | padding-left: 35px; 626 | margin-bottom: 12px; 627 | cursor: pointer; 628 | font-size: 22px; 629 | -webkit-user-select: none; 630 | -moz-user-select: none; 631 | -ms-user-select: none; 632 | user-select: none; 633 | } 634 | 635 | .checkbox label input[type="checkbox"] { 636 | position: absolute; 637 | opacity: 0; 638 | cursor: pointer; 639 | height: 0; 640 | width: 0; 641 | } 642 | 643 | .checkbox label span { 644 | position: absolute; 645 | top: 0; 646 | left: 0; 647 | height: 25px; 648 | width: 25px; 649 | background-color: #eee; 650 | } 651 | 652 | .checkbox label:hover input[type="checkbox"] ~ .checkbox label span { 653 | background-color: #ccc; 654 | } 655 | 656 | .checkbox label input[type="checkbox"]:checked ~ .checkbox label span { 657 | background-color: #2196F3; 658 | } 659 | 660 | .checkbox label span:after { 661 | content: ""; 662 | position: absolute; 663 | display: none; 664 | } 665 | 666 | .checkbox label input[type="checkbox"]:checked ~ .checkbox label span:after { 667 | display: block; 668 | } 669 | 670 | .checkbox label .checkbox label span:after { 671 | left: 9px; 672 | top: 5px; 673 | width: 5px; 674 | height: 10px; 675 | border: solid white; 676 | border-width: 0 3px 3px 0; 677 | -webkit-transform: rotate(45deg); 678 | -ms-transform: rotate(45deg); 679 | transform: rotate(45deg); 680 | }*/ 681 | 682 | /* Selectores */ 683 | 684 | .shiny-input-checkboxgroup label ~ .shiny-options-group, 685 | .shiny-input-radiogroup label ~ .shiny-options-group { 686 | margin-top: 0px; 687 | } 688 | 689 | .shiny-input-container:not(.shiny-input-container-inline) { 690 | width: 100% !important; 691 | } 692 | 693 | .form-group { 694 | display: flex; 695 | flex-direction: column; 696 | margin-bottom: 13px; 697 | } 698 | 699 | #initial_data-tableInputControls .form-group { 700 | margin-bottom: 20px; 701 | } 702 | 703 | /*#initial_data-tableInputControls .input-group { 704 | margin-top: 10px; 705 | }*/ 706 | 707 | #initial_data-tableInput.form-group { 708 | margin-bottom: 25px; 709 | } 710 | 711 | .selectize-input { 712 | border: 1px solid #e6eaed !important; 713 | border-radius: 5px !important; 714 | } 715 | 716 | .selectize-input.focus { 717 | box-shadow: none !important; 718 | } 719 | 720 | .selectize-dropdown, 721 | .selectize-input, 722 | .selectize-input input { 723 | color: #435b69 !important; 724 | } 725 | 726 | .selectize-dropdown .active { 727 | color: #435b69 !important; 728 | } 729 | 730 | .selectize-dropdown, 731 | .selectize-dropdown.form-control { 732 | border: 1px solid #e6eaed !important; 733 | } 734 | 735 | .selectize-control.single .selectize-input::after { 736 | border-color: #cad5dd transparent transparent transparent !important; 737 | } 738 | 739 | .selectize-control.multi .selectize-input.has-items { 740 | padding: 5px 5px 2px 5px !important; 741 | } 742 | 743 | .selectize-control.multi .selectize-input > div { 744 | background-color: #eef3f5 !important; 745 | color: #435b69 !important; 746 | margin: 0 4px 4px 0 !important; 747 | } 748 | 749 | .selectize-control.plugin-remove_button [data-value] .remove { 750 | width: 20px !important; 751 | } 752 | 753 | label { 754 | margin-bottom: 5px; 755 | } 756 | 757 | .form-control { 758 | background: #eef3f5; 759 | border: 0px; 760 | border-radius: 0px; 761 | padding: 5px; 762 | color: #435b69; 763 | font-family: 'IBM Plex Sans'; 764 | font-size: 0.8rem; 765 | font-weight: 300; 766 | outline: none; 767 | width: 100% !important; 768 | } 769 | 770 | .form-control.selectize-control, 771 | .form-control .selectize-dropdown-content { 772 | font-size: 0.875rem; 773 | font-weight: 300; 774 | } 775 | 776 | /* 777 | SLIDER STYLES 778 | */ 779 | 780 | .irs-bar-edge { 781 | border: 0px !important; 782 | border-right: 0 !important; 783 | background: #da1c95 !important; 784 | } 785 | 786 | .irs-bar { 787 | border-top: 1px solid #da1c95 !important; 788 | border-bottom: 1px solid #da1c95 !important; 789 | background: #da1c95 !important; 790 | } 791 | 792 | .irs-slider { 793 | top: 18px !important; 794 | width: 19px !important; 795 | height: 19px !important; 796 | border: none !important; 797 | box-shadow: none !important; 798 | background: #da1c95 !important; 799 | border-radius: 50% !important; 800 | } 801 | 802 | .irs-slider:hover { 803 | background-color: #b70f7f !important; 804 | } 805 | 806 | .irs-line { 807 | height: 8px !important; 808 | top: 25px !important; 809 | background: #eef3f5 !important; 810 | border: 0px !important; 811 | } 812 | 813 | .irs-from, 814 | .irs-to, 815 | .irs-single { 816 | color: #da1c95 !important; 817 | background: transparent !important; 818 | font-weight: 700 !important; 819 | } 820 | 821 | .irs-min, 822 | .irs-max { 823 | display: none !important; 824 | } 825 | 826 | .irs-grid-pol { 827 | background: #c7cfd1 !important; 828 | height: 4px !important; 829 | width: 2px !important; 830 | } 831 | 832 | .irs-grid-pol.small { 833 | background: none !important; 834 | height: 0px !important; 835 | width: 0px !important; 836 | } 837 | 838 | .irs-grid-text { 839 | color: #435b69 !important; 840 | } 841 | 842 | /*RADIOBUTTONS STYLE*/ 843 | 844 | input[type='radio'] { 845 | cursor: pointer; 846 | margin: 0px; 847 | outline: none; 848 | padding: 3px; 849 | position: relative; 850 | transition: all 0.25s; 851 | } 852 | 853 | /* 854 | scroll STYLES 855 | */ 856 | ::-webkit-scrollbar { 857 | width: 7px; 858 | height: 7px; 859 | } 860 | 861 | ::-webkit-scrollbar-track { 862 | background: #e2eaed; 863 | } 864 | 865 | ::-webkit-scrollbar-thumb { 866 | background: #cccccc; 867 | } 868 | 869 | ::-webkit-scrollbar:focus { 870 | overflow: scroll; 871 | display: block; 872 | background: #cccccc; 873 | } 874 | 875 | .infomessage { 876 | color: #666; 877 | padding: 10px; 878 | margin: 10px auto; 879 | } 880 | 881 | .infomessage.warning { 882 | background-color: #fff7e8; 883 | border: orange solid 1px; 884 | } 885 | 886 | .infomessage.success { 887 | background-color: #e8fff5; 888 | border: green solid 1px; 889 | } 890 | 891 | .infomessage.info { 892 | background-color: #e8f6ff; 893 | border: #6898ca solid 1px; 894 | } 895 | 896 | .infomessage.error { 897 | background-color: #fbeaea; 898 | border: #f28484 solid 1px; 899 | } 900 | 901 | /*TITLES STYLES*/ 902 | 903 | .section_0 { 904 | margin-bottom: 1.5rem; 905 | } 906 | 907 | .style_section { 908 | color: #da1c95; 909 | text-transform: uppercase; 910 | font-family: 'Ubuntu', sans-serif; 911 | font-size: 0.875rem !important; 912 | font-weight: 700 !important; 913 | letter-spacing: 0.055em; 914 | margin-bottom: 1rem; 915 | padding-top: 0.5rem; 916 | } 917 | 918 | .style_section:first-of-type { 919 | margin-top: 0rem; 920 | } 921 | 922 | .title-data-select { 923 | color: #da1c95 !important; 924 | font-family: 'Ubuntu', sans-serif; 925 | font-size: 0.875rem; 926 | font-weight: 700; 927 | letter-spacing: 0.055em; 928 | text-transform: uppercase; 929 | } 930 | 931 | @media screen and (min-width: 0px) and (orientation: landscape) { 932 | .orientation-notice { 933 | display: none; 934 | } 935 | } 936 | 937 | @media screen and (min-width: 768px) { 938 | .orientation-notice { 939 | display: none; 940 | } 941 | } 942 | 943 | /*PRE*/ 944 | 945 | pre { 946 | word-wrap: normal; 947 | display: block; 948 | padding: 9.5px; 949 | margin: 0 0 10px; 950 | font-size: 13px; 951 | line-height: 1.42857143; 952 | color: #333; 953 | word-break: break-all; 954 | word-wrap: break-word; 955 | background-color: #f5f5f5; 956 | border: 1px solid #ccc; 957 | border-radius: 4px; 958 | overflow: auto; 959 | } 960 | 961 | 962 | /* end session style */ 963 | 964 | #ss-connect-dialog { 965 | font-family: 'IBM Plex Sans' !important; 966 | } 967 | 968 | 969 | #ss-connect-dialog a{ 970 | text-decoration: none !important; 971 | } 972 | 973 | #ss-connect-dialog a::before { 974 | font-size: 0.875rem; 975 | border-radius: 0.35rem !important; 976 | background: #b707f7 !important; 977 | padding: 10px !important; 978 | font-family: 'Ubuntu' !important; 979 | } 980 | -------------------------------------------------------------------------------- /inst/assets/js/box_info.js: -------------------------------------------------------------------------------- 1 | const collapsibles = Array.prototype.map.call( 2 | document.getElementsByClassName("box-collapsible-trigger"), 3 | function (el) { return el } 4 | ); 5 | 6 | 7 | collapsibles.forEach(function (collapsible) { 8 | console.log("hola"); 9 | console.log(collapsible); 10 | const content = collapsible.nextElementSibling; 11 | if (content.classList.contains('active')) { 12 | content.style.maxHeight = content.scrollHeight + "px"; 13 | } 14 | 15 | collapsible.addEventListener('click', function () { 16 | this.classList.toggle('active'); 17 | content.classList.toggle('active'); 18 | if (content.style.maxHeight) { 19 | content.style.maxHeight = null; 20 | } else { 21 | content.style.maxHeight = content.scrollHeight + "px"; 22 | } 23 | }); 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /inst/assets/js/iframeSizer.contentWindow.min.js: -------------------------------------------------------------------------------- 1 | /*! iFrame Resizer (iframeSizer.contentWindow.min.js) - v3.5.14 - 2017-03-30 2 | * Desc: Include this file in any page being loaded into an iframe 3 | * to force the iframe to resize to the content size. 4 | * Requires: iframeResizer.min.js on host page. 5 | * Copyright: (c) 2017 David J. Bradshaw - dave@bradshaw.net 6 | * License: MIT 7 | */ 8 | 9 | !function(a){"use strict";function b(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function c(a,b,c){"removeEventListener"in window?a.removeEventListener(b,c,!1):"detachEvent"in window&&a.detachEvent("on"+b,c)}function d(a){return a.charAt(0).toUpperCase()+a.slice(1)}function e(a){var b,c,d,e=null,f=0,g=function(){f=Ha(),e=null,d=a.apply(b,c),e||(b=c=null)};return function(){var h=Ha();f||(f=h);var i=xa-(h-f);return b=this,c=arguments,0>=i||i>xa?(e&&(clearTimeout(e),e=null),f=h,d=a.apply(b,c),e||(b=c=null)):e||(e=setTimeout(g,i)),d}}function f(a){return ma+"["+oa+"] "+a}function g(a){la&&"object"==typeof window.console&&console.log(f(a))}function h(a){"object"==typeof window.console&&console.warn(f(a))}function i(){j(),g("Initialising iFrame ("+location.href+")"),k(),n(),m("background",W),m("padding",$),A(),s(),t(),o(),C(),u(),ia=B(),N("init","Init message from host page"),Da()}function j(){function b(a){return"true"===a?!0:!1}var c=ha.substr(na).split(":");oa=c[0],X=a!==c[1]?Number(c[1]):X,_=a!==c[2]?b(c[2]):_,la=a!==c[3]?b(c[3]):la,ja=a!==c[4]?Number(c[4]):ja,U=a!==c[6]?b(c[6]):U,Y=c[7],fa=a!==c[8]?c[8]:fa,W=c[9],$=c[10],ua=a!==c[11]?Number(c[11]):ua,ia.enable=a!==c[12]?b(c[12]):!1,qa=a!==c[13]?c[13]:qa,Aa=a!==c[14]?c[14]:Aa}function k(){function a(){var a=window.iFrameResizer;g("Reading data from page: "+JSON.stringify(a)),Ca="messageCallback"in a?a.messageCallback:Ca,Da="readyCallback"in a?a.readyCallback:Da,ta="targetOrigin"in a?a.targetOrigin:ta,fa="heightCalculationMethod"in a?a.heightCalculationMethod:fa,Aa="widthCalculationMethod"in a?a.widthCalculationMethod:Aa}function b(a,b){return"function"==typeof a&&(g("Setup custom "+b+"CalcMethod"),Fa[b]=a,a="custom"),a}"iFrameResizer"in window&&Object===window.iFrameResizer.constructor&&(a(),fa=b(fa,"height"),Aa=b(Aa,"width")),g("TargetOrigin for parent set to: "+ta)}function l(a,b){return-1!==b.indexOf("-")&&(h("Negative CSS value ignored for "+a),b=""),b}function m(b,c){a!==c&&""!==c&&"null"!==c&&(document.body.style[b]=c,g("Body "+b+' set to "'+c+'"'))}function n(){a===Y&&(Y=X+"px"),m("margin",l("margin",Y))}function o(){document.documentElement.style.height="",document.body.style.height="",g('HTML & body height set to "auto"')}function p(a){var e={add:function(c){function d(){N(a.eventName,a.eventType)}Ga[c]=d,b(window,c,d)},remove:function(a){var b=Ga[a];delete Ga[a],c(window,a,b)}};a.eventNames&&Array.prototype.map?(a.eventName=a.eventNames[0],a.eventNames.map(e[a.method])):e[a.method](a.eventName),g(d(a.method)+" event listener: "+a.eventType)}function q(a){p({method:a,eventType:"Animation Start",eventNames:["animationstart","webkitAnimationStart"]}),p({method:a,eventType:"Animation Iteration",eventNames:["animationiteration","webkitAnimationIteration"]}),p({method:a,eventType:"Animation End",eventNames:["animationend","webkitAnimationEnd"]}),p({method:a,eventType:"Input",eventName:"input"}),p({method:a,eventType:"Mouse Up",eventName:"mouseup"}),p({method:a,eventType:"Mouse Down",eventName:"mousedown"}),p({method:a,eventType:"Orientation Change",eventName:"orientationchange"}),p({method:a,eventType:"Print",eventName:["afterprint","beforeprint"]}),p({method:a,eventType:"Ready State Change",eventName:"readystatechange"}),p({method:a,eventType:"Touch Start",eventName:"touchstart"}),p({method:a,eventType:"Touch End",eventName:"touchend"}),p({method:a,eventType:"Touch Cancel",eventName:"touchcancel"}),p({method:a,eventType:"Transition Start",eventNames:["transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart"]}),p({method:a,eventType:"Transition Iteration",eventNames:["transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration"]}),p({method:a,eventType:"Transition End",eventNames:["transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend"]}),"child"===qa&&p({method:a,eventType:"IFrame Resized",eventName:"resize"})}function r(a,b,c,d){return b!==a&&(a in c||(h(a+" is not a valid option for "+d+"CalculationMethod."),a=b),g(d+' calculation method set to "'+a+'"')),a}function s(){fa=r(fa,ea,Ia,"height")}function t(){Aa=r(Aa,za,Ja,"width")}function u(){!0===U?(q("add"),F()):g("Auto Resize disabled")}function v(){g("Disable outgoing messages"),ra=!1}function w(){g("Remove event listener: Message"),c(window,"message",S)}function x(){null!==Z&&Z.disconnect()}function y(){q("remove"),x(),clearInterval(ka)}function z(){v(),w(),!0===U&&y()}function A(){var a=document.createElement("div");a.style.clear="both",a.style.display="block",document.body.appendChild(a)}function B(){function c(){return{x:window.pageXOffset!==a?window.pageXOffset:document.documentElement.scrollLeft,y:window.pageYOffset!==a?window.pageYOffset:document.documentElement.scrollTop}}function d(a){var b=a.getBoundingClientRect(),d=c();return{x:parseInt(b.left,10)+parseInt(d.x,10),y:parseInt(b.top,10)+parseInt(d.y,10)}}function e(b){function c(a){var b=d(a);g("Moving to in page link (#"+e+") at x: "+b.x+" y: "+b.y),R(b.y,b.x,"scrollToOffset")}var e=b.split("#")[1]||b,f=decodeURIComponent(e),h=document.getElementById(f)||document.getElementsByName(f)[0];a!==h?c(h):(g("In page link (#"+e+") not found in iFrame, so sending to parent"),R(0,0,"inPageLink","#"+e))}function f(){""!==location.hash&&"#"!==location.hash&&e(location.href)}function i(){function a(a){function c(a){a.preventDefault(),e(this.getAttribute("href"))}"#"!==a.getAttribute("href")&&b(a,"click",c)}Array.prototype.forEach.call(document.querySelectorAll('a[href^="#"]'),a)}function j(){b(window,"hashchange",f)}function k(){setTimeout(f,ba)}function l(){Array.prototype.forEach&&document.querySelectorAll?(g("Setting up location.hash handlers"),i(),j(),k()):h("In page linking not fully supported in this browser! (See README.md for IE8 workaround)")}return ia.enable?l():g("In page linking not enabled"),{findTarget:e}}function C(){g("Enable public methods"),Ba.parentIFrame={autoResize:function(a){return!0===a&&!1===U?(U=!0,u()):!1===a&&!0===U&&(U=!1,y()),U},close:function(){R(0,0,"close"),z()},getId:function(){return oa},getPageInfo:function(a){"function"==typeof a?(Ea=a,R(0,0,"pageInfo")):(Ea=function(){},R(0,0,"pageInfoStop"))},moveToAnchor:function(a){ia.findTarget(a)},reset:function(){Q("parentIFrame.reset")},scrollTo:function(a,b){R(b,a,"scrollTo")},scrollToOffset:function(a,b){R(b,a,"scrollToOffset")},sendMessage:function(a,b){R(0,0,"message",JSON.stringify(a),b)},setHeightCalculationMethod:function(a){fa=a,s()},setWidthCalculationMethod:function(a){Aa=a,t()},setTargetOrigin:function(a){g("Set targetOrigin: "+a),ta=a},size:function(a,b){var c=""+(a?a:"")+(b?","+b:"");N("size","parentIFrame.size("+c+")",a,b)}}}function D(){0!==ja&&(g("setInterval: "+ja+"ms"),ka=setInterval(function(){N("interval","setInterval: "+ja)},Math.abs(ja)))}function E(){function b(a){function b(a){!1===a.complete&&(g("Attach listeners to "+a.src),a.addEventListener("load",f,!1),a.addEventListener("error",h,!1),k.push(a))}"attributes"===a.type&&"src"===a.attributeName?b(a.target):"childList"===a.type&&Array.prototype.forEach.call(a.target.querySelectorAll("img"),b)}function c(a){k.splice(k.indexOf(a),1)}function d(a){g("Remove listeners from "+a.src),a.removeEventListener("load",f,!1),a.removeEventListener("error",h,!1),c(a)}function e(b,c,e){d(b.target),N(c,e+": "+b.target.src,a,a)}function f(a){e(a,"imageLoad","Image loaded")}function h(a){e(a,"imageLoadFailed","Image load failed")}function i(a){N("mutationObserver","mutationObserver: "+a[0].target+" "+a[0].type),a.forEach(b)}function j(){var a=document.querySelector("body"),b={attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0};return m=new l(i),g("Create body MutationObserver"),m.observe(a,b),m}var k=[],l=window.MutationObserver||window.WebKitMutationObserver,m=j();return{disconnect:function(){"disconnect"in m&&(g("Disconnect body MutationObserver"),m.disconnect(),k.forEach(d))}}}function F(){var a=0>ja;window.MutationObserver||window.WebKitMutationObserver?a?D():Z=E():(g("MutationObserver not supported in this browser!"),D())}function G(a,b){function c(a){var c=/^\d+(px)?$/i;if(c.test(a))return parseInt(a,V);var d=b.style.left,e=b.runtimeStyle.left;return b.runtimeStyle.left=b.currentStyle.left,b.style.left=a||0,a=b.style.pixelLeft,b.style.left=d,b.runtimeStyle.left=e,a}var d=0;return b=b||document.body,"defaultView"in document&&"getComputedStyle"in document.defaultView?(d=document.defaultView.getComputedStyle(b,null),d=null!==d?d[a]:0):d=c(b.currentStyle[a]),parseInt(d,V)}function H(a){a>xa/2&&(xa=2*a,g("Event throttle increased to "+xa+"ms"))}function I(a,b){for(var c=b.length,e=0,f=0,h=d(a),i=Ha(),j=0;c>j;j++)e=b[j].getBoundingClientRect()[a]+G("margin"+h,b[j]),e>f&&(f=e);return i=Ha()-i,g("Parsed "+c+" HTML elements"),g("Element position calculated in "+i+"ms"),H(i),f}function J(a){return[a.bodyOffset(),a.bodyScroll(),a.documentElementOffset(),a.documentElementScroll()]}function K(a,b){function c(){return h("No tagged elements ("+b+") found on page"),document.querySelectorAll("body *")}var d=document.querySelectorAll("["+b+"]");return 0===d.length&&c(),I(a,d)}function L(){return document.querySelectorAll("body *")}function M(b,c,d,e){function f(){da=m,ya=n,R(da,ya,b)}function h(){function b(a,b){var c=Math.abs(a-b)<=ua;return!c}return m=a!==d?d:Ia[fa](),n=a!==e?e:Ja[Aa](),b(da,m)||_&&b(ya,n)}function i(){return!(b in{init:1,interval:1,size:1})}function j(){return fa in pa||_&&Aa in pa}function k(){g("No change in size detected")}function l(){i()&&j()?Q(c):b in{interval:1}||k()}var m,n;h()||"init"===b?(O(),f()):l()}function N(a,b,c,d){function e(){a in{reset:1,resetPage:1,init:1}||g("Trigger event: "+b)}function f(){return va&&a in aa}f()?g("Trigger event cancelled: "+a):(e(),Ka(a,b,c,d))}function O(){va||(va=!0,g("Trigger event lock on")),clearTimeout(wa),wa=setTimeout(function(){va=!1,g("Trigger event lock off"),g("--")},ba)}function P(a){da=Ia[fa](),ya=Ja[Aa](),R(da,ya,a)}function Q(a){var b=fa;fa=ea,g("Reset trigger event: "+a),O(),P("reset"),fa=b}function R(b,c,d,e,f){function h(){a===f?f=ta:g("Message targetOrigin: "+f)}function i(){var h=b+":"+c,i=oa+":"+h+":"+d+(a!==e?":"+e:"");g("Sending message to host page ("+i+")"),sa.postMessage(ma+i,f)}!0===ra&&(h(),i())}function S(a){function c(){return ma===(""+a.data).substr(0,na)}function d(){return a.data.split("]")[1].split(":")[0]}function e(){return a.data.substr(a.data.indexOf(":")+1)}function f(){return!("undefined"!=typeof module&&module.exports)&&"iFrameResize"in window}function j(){return a.data.split(":")[2]in{"true":1,"false":1}}function k(){var b=d();b in m?m[b]():f()||j()||h("Unexpected message ("+a.data+")")}function l(){!1===ca?k():j()?m.init():g('Ignored message of type "'+d()+'". Received before initialization.')}var m={init:function(){function c(){ha=a.data,sa=a.source,i(),ca=!1,setTimeout(function(){ga=!1},ba)}document.body?c():(g("Waiting for page ready"),b(window,"readystatechange",m.initFromParent))},reset:function(){ga?g("Page reset ignored by init"):(g("Page size reset by host page"),P("resetPage"))},resize:function(){N("resizeParent","Parent window requested size check")},moveToAnchor:function(){ia.findTarget(e())},inPageLink:function(){this.moveToAnchor()},pageInfo:function(){var a=e();g("PageInfoFromParent called from parent: "+a),Ea(JSON.parse(a)),g(" --")},message:function(){var a=e();g("MessageCallback called from parent: "+a),Ca(JSON.parse(a)),g(" --")}};c()&&l()}function T(){"loading"!==document.readyState&&window.parent.postMessage("[iFrameResizerChild]Ready","*")}if("undefined"!=typeof window){var U=!0,V=10,W="",X=0,Y="",Z=null,$="",_=!1,aa={resize:1,click:1},ba=128,ca=!0,da=1,ea="bodyOffset",fa=ea,ga=!0,ha="",ia={},ja=32,ka=null,la=!1,ma="[iFrameSizer]",na=ma.length,oa="",pa={max:1,min:1,bodyScroll:1,documentElementScroll:1},qa="child",ra=!0,sa=window.parent,ta="*",ua=0,va=!1,wa=null,xa=16,ya=1,za="scroll",Aa=za,Ba=window,Ca=function(){h("MessageCallback function not defined")},Da=function(){},Ea=function(){},Fa={height:function(){return h("Custom height calculation function not defined"),document.documentElement.offsetHeight},width:function(){return h("Custom width calculation function not defined"),document.body.scrollWidth}},Ga={},Ha=Date.now||function(){return(new Date).getTime()},Ia={bodyOffset:function(){return document.body.offsetHeight+G("marginTop")+G("marginBottom")},offset:function(){return Ia.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},custom:function(){return Fa.height()},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,J(Ia))},min:function(){return Math.min.apply(null,J(Ia))},grow:function(){return Ia.max()},lowestElement:function(){return Math.max(Ia.bodyOffset(),I("bottom",L()))},taggedElement:function(){return K("bottom","data-iframe-height")}},Ja={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},custom:function(){return Fa.width()},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max(Ja.bodyScroll(),Ja.documentElementScroll())},max:function(){return Math.max.apply(null,J(Ja))},min:function(){return Math.min.apply(null,J(Ja))},rightMostElement:function(){return I("right",L())},taggedElement:function(){return K("right","data-iframe-width")}},Ka=e(M);b(window,"message",S),T()}}(); 10 | //# sourceMappingURL=iframeResizer.contentWindow.map -------------------------------------------------------------------------------- /inst/assets/js/index.js: -------------------------------------------------------------------------------- 1 | const layoutSettings = { 2 | minWidth: '600px', 3 | panelClass: 'panel', 4 | panelCollapsedClass: 'collapsed', 5 | panelHeaderClass: 'panel', 6 | panelHeaderTitleClass: 'panel-header-title', 7 | panelDismissClass: 'panel-header-dismiss', 8 | panelBodyClass: 'panel-body' 9 | } 10 | const panels = Array.from( 11 | document.querySelectorAll(`.${layoutSettings.panelClass}`) 12 | ) 13 | const dismiss = Array.from( 14 | document.querySelectorAll(`.${layoutSettings.panelDismissClass}`) 15 | ) 16 | 17 | function setPanelWidth (panel, reset) { 18 | if (!reset) { 19 | if (panel.dataset.width) { 20 | panel.style.width = `${panel.dataset.width}px` 21 | } else { 22 | panel.style['flex-grow'] = '1' 23 | panel.style['min-width'] = layoutSettings.minWidth 24 | } 25 | } else { 26 | if (!panel.dataset.width) { 27 | panel.style['flex-grow'] = '0' 28 | panel.style['min-width'] = '0' 29 | } 30 | panel.style.width = 'auto' 31 | } 32 | } 33 | 34 | function showModalJs (modalID) { 35 | const modal = document.getElementById(modalID) 36 | modal.classList.add('is-visible') 37 | modal.addEventListener('click', (event) => { 38 | if ( 39 | event.target.matches('.modal-title button') || 40 | event.target.matches('.modal') || 41 | event.target.matches('.modal-title svg') || 42 | event.target.matches('.modal-title path') 43 | ) { 44 | modal.classList.remove('is-visible') 45 | } 46 | }) 47 | } 48 | 49 | for (const panel of panels) { 50 | setPanelWidth(panel, panel.classList.contains('collapsed')) 51 | panel.addEventListener('click', function onPanelClick () { 52 | const isCollapsed = this.classList.contains(layoutSettings.panelCollapsedClass) 53 | if (isCollapsed) { 54 | setPanelWidth(this) 55 | this.classList.toggle(layoutSettings.panelCollapsedClass) 56 | } 57 | }) 58 | } 59 | 60 | for (const button of dismiss) { 61 | button.addEventListener('click', function onDismissBtnClick (event) { 62 | const panel = this.parentNode.parentNode 63 | const isCollapsed = panel.classList.contains(layoutSettings.panelCollapsedClass) 64 | setPanelWidth(panel, !isCollapsed) 65 | panel.classList.toggle(layoutSettings.panelCollapsedClass) 66 | event.stopPropagation() 67 | }) 68 | } 69 | 70 | $(document).ready(() => { 71 | Shiny.addCustomMessageHandler('showModalManually', (modalID) => { 72 | showModalJs(modalID) 73 | }) 74 | }) 75 | 76 | $(document).ready(() => { 77 | Shiny.addCustomMessageHandler('removeModalManually', (modalID) => { 78 | const modal = document.getElementById(modalID) 79 | modal.classList.remove('is-visible') 80 | }) 81 | }) 82 | 83 | $(document).on('shiny:value', (event) => { 84 | const modalTriggers = Array.prototype.map.call( 85 | document.querySelectorAll('.modal-trigger'), 86 | (e) => e 87 | ) 88 | const modals = Array.prototype.map.call( 89 | document.querySelectorAll('.modal'), 90 | (e) => e 91 | ) 92 | if (modals) { 93 | const refNode = document.querySelector('.layout-container') 94 | modals.forEach((modal) => { 95 | if ( 96 | modal.dataset.fullscreen && 97 | modal.dataset.fullscreen.match(/T|TRUE/) 98 | ) { 99 | refNode.parentNode.insertBefore(modal, refNode) 100 | } 101 | }) 102 | } 103 | if (modalTriggers) { 104 | // Add listener to triggers 105 | modalTriggers.forEach((modalTrigger) => { 106 | function handleModalTrigger (event) { 107 | const modal = document.getElementById(this.dataset.modal) 108 | modal.classList.add('is-visible') 109 | modal.addEventListener('click', (event) => { 110 | if ( 111 | event.target.matches('.modal-title button') || 112 | event.target.matches('.modal') || 113 | event.target.matches('.modal-title svg') || 114 | event.target.matches('.modal-title path') 115 | ) { 116 | modal.classList.remove('is-visible') 117 | } 118 | }) 119 | } 120 | modalTrigger.addEventListener('click', handleModalTrigger) 121 | }) 122 | } 123 | }) 124 | 125 | $('#ss-reload-link').attr('style', 'margin-top: 31px !important;') 126 | 127 | $(document).ready(() => { 128 | Shiny.addCustomMessageHandler('showModalMultiple', (e) => { 129 | const modalId = e.inputId 130 | const triggerEl = document.getElementById(e.apply_id) 131 | const container = document.createElement('div') 132 | const mask = document.createElement('div') 133 | 134 | // Add attrs 135 | container.style.position = 'relative' 136 | mask.setAttribute('style', 'height: 100%; left: 0; top: 0; width: 100%; z-index: 1; position: absolute;') 137 | 138 | // Append 139 | triggerEl.insertAdjacentElement('beforebegin', container) 140 | container.appendChild(mask) 141 | container.appendChild(triggerEl) 142 | 143 | container.addEventListener('click', () => { 144 | showModalJs(modalId) 145 | }) 146 | }) 147 | }) 148 | -------------------------------------------------------------------------------- /inst/examples/basic-app.R: -------------------------------------------------------------------------------- 1 | library(shinypanels) 2 | 3 | ui <- panelsPage( 4 | panel(title = "Panel Hidden", 5 | width = 300, 6 | hidden = TRUE, 7 | body = h1("Nothing here") 8 | ), 9 | panel( 10 | title = "Panel 1", 11 | width = 300, 12 | color = "magenta", 13 | hidden = FALSE, 14 | body = div( 15 | h3("Here is some info"), 16 | hr(), 17 | verbatimTextOutput("debug"), 18 | hr(), 19 | p("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 20 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 21 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 22 | consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 23 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 24 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") 25 | ), 26 | hr(), 27 | h2("More info") 28 | ), 29 | panel( 30 | title = "Panel 3", 31 | width = 350, 32 | collapsed = TRUE, 33 | body = div( 34 | plotOutput("plot") 35 | ) 36 | ), 37 | panel( 38 | title = "Panel 4", 39 | can_collapse = FALSE, 40 | body = div( 41 | ), 42 | footer = HTML("Footer") 43 | ) 44 | ) 45 | 46 | 47 | 48 | server <- function(input, output, session) { 49 | 50 | output$debug <- renderPrint({ 51 | cat(paste(c("La", "casa", "en", "el", "árbol"), collapse = "\n")) 52 | }) 53 | output$plot <- renderPlot( 54 | plot(cars) 55 | ) 56 | 57 | } 58 | 59 | shinyApp(ui, server) 60 | 61 | -------------------------------------------------------------------------------- /inst/examples/basic-panel.R: -------------------------------------------------------------------------------- 1 | library(shinypanels) 2 | 3 | styles <- " 4 | .topbar { 5 | padding: 20px 55px; 6 | background-color: #2e4856; 7 | font-size: 14px; 8 | color: #fff; 9 | overflow: hidden; 10 | } 11 | 12 | .top_title { 13 | margin-left: 24px; 14 | display: flex; 15 | } 16 | 17 | .topbar__img { 18 | height: auto; 19 | width: 72px; 20 | } 21 | 22 | .top_line { 23 | border-left: 1px solid #ffffff; 24 | margin-left: 10px; 25 | font-weight: 700; 26 | } 27 | 28 | 29 | .topbar-modal, .tex_sub { 30 | font-size: 14px; 31 | color: #fff; 32 | } 33 | 34 | @media only screen and (min-width: 768px) { 35 | .topbar, .tex_sub { 36 | font-size: 20px; 37 | } 38 | } 39 | 40 | @media only screen and (min-width: 1024px) { 41 | .topbar, .tex_sub { 42 | font-size: 32px; 43 | } 44 | } 45 | 46 | 47 | } 48 | 49 | " 50 | 51 | ui <- panelsPage( 52 | styles = styles, 53 | # header = topbar(title = 'Herramienta | CO2', 54 | # image = 'https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F0%2F0b%2FQt_logo_2016.svg%2F1200px-Qt_logo_2016.svg.png&f=1&nofb=1', 55 | # background_color = 'steelblue'), 56 | header = div(style="", class="topbar", 57 | img(class="topbar__img", src = "https://datasketch.github.io/landing-gcs/images/logo.webp"), 58 | HTML("
HERRAMIENTA
ESTIMACIÓN DE BIODIVERSIDAD Y CAPTURA DE CO2
"), 59 | uiOutput("for_modal"), 60 | ), 61 | modal(id = 'test', title = uiOutput("title_modal"), p('Modal ipsum')), 62 | panel(title = "First Panel", title_complent = "HOLAAAA", color = "#04bb7a", collapsed = FALSE, width = 400, 63 | head = h2("Head"), 64 | body = div( 65 | h2("Body"), 66 | infomessage(type = "warning", p("Hello, this is a warning")), 67 | infomessage(type = "info", p("Oh yes, this is some information")), 68 | infomessage(type = "success", p("You did it!")), 69 | infomessage(type = "error", p("Ups!, try again")), 70 | selectizeInput("selector", "Select One", choices = c("First", "Second"), selected = "Fist"), 71 | textInput("text", "Text input"), 72 | radioButtons("radioButtons1", "Radio Buttons", choices = c("First", "Second"), inline = TRUE), 73 | radioButtons("radioButtons2", "Radio Buttons", choices = c("First", "Second"), inline = FALSE), 74 | img(src="https://placeimg.com/640/180/any"), 75 | shinypanels::modal(id = "modal_action", title = " ", "hola"), 76 | actionButton(inputId = "ss",label = "test modal") 77 | #shinypanels::modalButton(id = "ss", modal_id = 'test', label = 'Test modal BLAL') 78 | ), 79 | footer = NULL 80 | ), 81 | panel(title = "Second Panel", color = "chardonnay", collapsed = FALSE, width = 400, 82 | head = h2("Head"), 83 | body = div( 84 | h2("Body"), 85 | selectizeInput("selector", "Select One", choices = c("First", "Second"), selected = "Fist"), 86 | textInput("text", "Text input"), 87 | radioButtons("radioButtons1", "Radio Buttons", choices = c("First", "Second"), inline = TRUE), 88 | radioButtons("radioButtons2", "Radio Buttons", choices = c("First", "Second"), inline = FALSE), 89 | img(src="https://placeimg.com/640/180/any"), 90 | shinypanels::modalButton(id = "aa", modal_id = 'test', label = 'Test modal') 91 | ), 92 | footer = NULL 93 | ), 94 | panel(title = "Visualize", color = "magenta", collapsed = FALSE, 95 | head = h2("Head 2"), 96 | body = list( 97 | # box(title = "New box", 98 | # collapsed = FALSE, 99 | # p("Lorem ipsum 3"), 100 | # selectInput("selector2", "Select", choices = 1980:2019) 101 | # ), 102 | uiOutput("box_test"), 103 | h2(textOutput("selected")), 104 | img(src="https://placeimg.com/640/180/nature"), 105 | actionButton("show", label = "Test modal 2") 106 | ), 107 | footer = list( 108 | div(class="panel-title", "Tipos de visualización"), 109 | h3("This is a footer") 110 | ) 111 | ) 112 | ) 113 | 114 | server <- function(input, output, session) { 115 | 116 | 117 | output$title_modal <- renderUI({ 118 | HTML( 119 | ' 120 |
121 | 122 |
123 | 124 | 125 | 126 |
127 | ' 128 | ) 129 | }) 130 | 131 | # modal button rendered within server 132 | output$for_modal <- renderUI({ 133 | shinypanels::modalButton(id = 'id-but-mod', modal_id = 'test', label = HTML('')) 134 | }) 135 | 136 | output$selected <- renderText({ 137 | input$selector 138 | }) 139 | 140 | output$box_test <- renderUI({ 141 | box(title = "New box", 142 | collapsed = FALSE, 143 | p("Lorem ipsum 3"), 144 | selectInput("selector2", "Select", choices = 1980:2019) 145 | ) 146 | }) 147 | 148 | observeEvent(input$show, { 149 | showModal('test') 150 | }) 151 | 152 | observeEvent(input$ss, { 153 | showModal("modal_action") 154 | }) 155 | 156 | } 157 | shinyApp(ui, server) 158 | 159 | -------------------------------------------------------------------------------- /inst/examples/custom-css.R: -------------------------------------------------------------------------------- 1 | library(shinypanels) 2 | 3 | styles <- " 4 | 5 | app-container { 6 | background-color: #F2F7F9; 7 | } 8 | 9 | .top-olive { 10 | border-top: 2px solid #b0d361; 11 | } 12 | .text-olive { 13 | color: #b0d361; 14 | } 15 | .icon-close--olive line { 16 | stroke: #b0d361; 17 | } 18 | 19 | 20 | " 21 | 22 | 23 | ui <- panelsPage( styles = styles, 24 | header = p("THIS IS A CUSTOM TITLE"), 25 | panel(title = infoTooltip("First Panel", "info panel"), color = "olive", collapsed = FALSE, width = 400, 26 | #head = h2("Head"), 27 | body = div( 28 | infoTooltip("Body", "Duis metus leo, sollicitudin sit amet bibendum sit amet, elementum a risus. Maecenas in bibendum felis. Etiam lobortis fringilla purus at dignissim. Etiam in leo ac lorem venenatis placerat. Proin sodales sagittis ipsum ac molestie. Quisque vitae egestas metus. Pellentesque molestie eget arcu a pellentesque. Nunc vel convallis quam. Nam vehicula, massa vel bibendum accumsan, ante nunc rutrum ante, eu mattis mi arcu eu dolor.", icon = "cloud" 29 | ), 30 | box(title = "test-box", 31 | collapsed = FALSE, 32 | "esto es una caja" 33 | ), 34 | br(), 35 | br(), 36 | selectizeInput("selector", "Select One", choices = c("First", "Second"), selected = "Fist"), 37 | img(src="https://placeimg.com/640/480/any") 38 | ), 39 | footer = h3("This is a footer") 40 | ), 41 | panel(title = "Visualize", color = "olive", 42 | head = h2("Head 2"), 43 | body = div( 44 | uiOutput("test"), 45 | h2(textOutput("selected")), 46 | img(src="https://placeimg.com/640/480/nature") 47 | 48 | ), 49 | footer = list( 50 | div(class="panel-title", "Tipos de visualización"), 51 | h3("This is a footer") 52 | ) 53 | ) 54 | ) 55 | 56 | server <- function(input, output, session) { 57 | 58 | output$selected <- renderText({ 59 | input$selector 60 | }) 61 | 62 | output$test <- renderUI({ 63 | box(title = "test-box-b", 64 | collapsed = T, 65 | #div(class = 'test-content', 66 | "Negro chuchón" 67 | #) 68 | ) 69 | }) 70 | 71 | } 72 | shinyApp(ui, server) 73 | 74 | -------------------------------------------------------------------------------- /inst/examples/multiple-modal.R: -------------------------------------------------------------------------------- 1 | library(shinypanels) 2 | library(shinyinvoer) 3 | styles <- " 4 | 5 | .modal-wrapper { 6 | width: 60%; 7 | height: 100%; 8 | } 9 | " 10 | 11 | ui <- panelsPage( 12 | shinypanels::modal(id = 'mytest', title = 'Important message', p('This is an important message!')), 13 | panel(title = "Panel", 14 | color = "chardonnay", 15 | collapsed = FALSE, 16 | body = div( 17 | uiOutput("select_countries"), 18 | uiOutput("select_colors"), 19 | uiOutput("select_number") 20 | ), 21 | footer = NULL 22 | ) 23 | ) 24 | 25 | server <- function(input, output, session) { 26 | 27 | 28 | output$select_countries <- renderUI({ 29 | selectizeInput(inputId = "countries", "Countries", c("Colombia", "Argentina", "Brazil", "Mexico")) 30 | }) 31 | 32 | output$select_colors <- renderUI({ 33 | shinyinvoer::colorPaletteInput("id_colors", "Colores", colors = c("#FEAFEA", "#AFCA31")) 34 | }) 35 | 36 | output$select_number <- renderUI({ 37 | radioButtons("id_num", "Numbers", c("One", "Two", "Three")) 38 | }) 39 | 40 | observe({ 41 | showModalMultipleId("mytest", list_id = c("select_countries", "select_colors")) 42 | }) 43 | 44 | 45 | } 46 | shinyApp(ui, server) 47 | 48 | -------------------------------------------------------------------------------- /man/box.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/box.R 3 | \name{box} 4 | \alias{box} 5 | \title{Box like component} 6 | \usage{ 7 | box(..., title = NULL, collapsed = TRUE, color = "") 8 | } 9 | \arguments{ 10 | \item{...}{html list contents for the panel} 11 | 12 | \item{title}{title for the box} 13 | 14 | \item{collapsed}{defines initial state} 15 | 16 | \item{color}{color name as defined in custom css} 17 | } 18 | \value{ 19 | None 20 | } 21 | \description{ 22 | Box like component 23 | } 24 | \examples{ 25 | box() 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/figures/shinypanels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datasketch/shinypanels/0770ba920f748babb99137eb2da1c3a27d6312a5/man/figures/shinypanels.png -------------------------------------------------------------------------------- /man/infoTooltip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infoTooltip.R 3 | \name{infoTooltip} 4 | \alias{infoTooltip} 5 | \title{Text with tooltip} 6 | \usage{ 7 | infoTooltip( 8 | title, 9 | info, 10 | icon = "info-circle", 11 | containerStyle = "", 12 | iconStyle = "", 13 | tooltipStyle = "" 14 | ) 15 | } 16 | \arguments{ 17 | \item{title}{Text} 18 | 19 | \item{info}{Message which appears when a cursor is positioned over an icon} 20 | 21 | \item{icon}{HTML name of icon} 22 | 23 | \item{containerStyle}{CSS styles for the container div} 24 | 25 | \item{iconStyle}{CSS styles for the icon} 26 | 27 | \item{tooltipStyle}{CSS styles for the tooltip} 28 | } 29 | \value{ 30 | None 31 | } 32 | \description{ 33 | Text with tooltip 34 | } 35 | \examples{ 36 | infoTooltip("Information", info = "This a content of tooltip", icon = "cloud") 37 | 38 | } 39 | -------------------------------------------------------------------------------- /man/infomessage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/infomessage.R 3 | \name{infomessage} 4 | \alias{infomessage} 5 | \title{Infomessage to show messages} 6 | \usage{ 7 | infomessage(..., type = "warning", id = NULL, class = NULL) 8 | } 9 | \arguments{ 10 | \item{...}{html list contents for the panel} 11 | 12 | \item{type}{one of: warning, success, error or info} 13 | 14 | \item{id}{id of html element} 15 | 16 | \item{class}{class of html element} 17 | } 18 | \value{ 19 | None 20 | } 21 | \description{ 22 | Infomessage to show messages 23 | } 24 | \examples{ 25 | infomessage() 26 | 27 | } 28 | -------------------------------------------------------------------------------- /man/modal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/modal.R 3 | \name{modal} 4 | \alias{modal} 5 | \title{Modal window} 6 | \usage{ 7 | modal( 8 | ..., 9 | title = NULL, 10 | id = NULL, 11 | fullscreen = FALSE, 12 | id_wrapper = NULL, 13 | id_title = NULL, 14 | id_content = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{...}{html list contents for the panel} 19 | 20 | \item{title}{title for the modal} 21 | 22 | \item{id}{html attribute id for the component} 23 | } 24 | \value{ 25 | None 26 | } 27 | \description{ 28 | Modal window 29 | } 30 | \examples{ 31 | modal() 32 | } 33 | -------------------------------------------------------------------------------- /man/modalButton.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/modal.R 3 | \name{modalButton} 4 | \alias{modalButton} 5 | \title{Modal button to trigger a modal} 6 | \usage{ 7 | modalButton(modal_id = NULL, label = NULL, id = NULL) 8 | } 9 | \arguments{ 10 | \item{modal_id}{modal id to be triggered by the button} 11 | 12 | \item{label}{label for the button} 13 | 14 | \item{id}{html attribute id for the button} 15 | } 16 | \value{ 17 | None 18 | } 19 | \description{ 20 | Modal button to trigger a modal 21 | } 22 | \examples{ 23 | modal() 24 | } 25 | -------------------------------------------------------------------------------- /man/panel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/panels.R 3 | \name{panel} 4 | \alias{panel} 5 | \title{Panel component for shiny panels layout} 6 | \usage{ 7 | panel( 8 | head = NULL, 9 | body = NULL, 10 | footer = NULL, 11 | title = NULL, 12 | header_right = NULL, 13 | color = "malibu", 14 | id = NULL, 15 | collapsed = FALSE, 16 | can_collapse = TRUE, 17 | width = NULL, 18 | hidden = FALSE, 19 | ... 20 | ) 21 | } 22 | \arguments{ 23 | \item{head}{html for the panel header} 24 | 25 | \item{body}{html tag list for panel body contents} 26 | 27 | \item{footer}{footer contents} 28 | 29 | \item{title}{panel title} 30 | 31 | \item{color}{color name as defined in custom css} 32 | 33 | \item{id}{panel div id} 34 | 35 | \item{collapsed}{panel starts as collapsed} 36 | 37 | \item{width}{panel width in pixels} 38 | 39 | \item{...}{html list contents for the panel} 40 | 41 | \item{show_footer}{include footer} 42 | } 43 | \value{ 44 | None 45 | } 46 | \description{ 47 | Panel component for shiny panels layout 48 | } 49 | \examples{ 50 | panel(title = "My title") 51 | 52 | } 53 | -------------------------------------------------------------------------------- /man/panelsPage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layout.R 3 | \name{panelsPage} 4 | \alias{panelsPage} 5 | \title{Shiny panels layout} 6 | \usage{ 7 | panelsPage(..., styles = "", header = NULL, title = NULL, debug = FALSE) 8 | } 9 | \arguments{ 10 | \item{...}{html list contents for the panel} 11 | 12 | \item{styles}{custom css styles} 13 | 14 | \item{header}{html list with custom header} 15 | 16 | \item{title}{Title html page attribute} 17 | 18 | \item{debug}{Used for debugging layout html} 19 | } 20 | \value{ 21 | None 22 | } 23 | \description{ 24 | Shiny panels layout 25 | } 26 | \examples{ 27 | panelsPage() 28 | 29 | } 30 | -------------------------------------------------------------------------------- /man/topbar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/panels.R 3 | \name{topbar} 4 | \alias{topbar} 5 | \title{Top bar component for shiny panels layout} 6 | \usage{ 7 | topbar(..., title = NULL, image = NULL, background_color = NULL) 8 | } 9 | \arguments{ 10 | \item{...}{html list contents for the panel} 11 | 12 | \item{title}{Top bar panel} 13 | 14 | \item{image}{Logo image} 15 | 16 | \item{background_color}{background color for top bar} 17 | } 18 | \value{ 19 | None 20 | } 21 | \description{ 22 | Top bar component for shiny panels layout 23 | } 24 | \examples{ 25 | topbar() 26 | 27 | } 28 | -------------------------------------------------------------------------------- /shinypanels.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | suppressMessages(library(shinypanels)) 3 | 4 | test_check("shinypanels") 5 | -------------------------------------------------------------------------------- /tests/testthat/test_layout.R: -------------------------------------------------------------------------------- 1 | context("layout") 2 | 3 | test_that("Layout",{ 4 | 5 | topbar(p("ds")) 6 | 7 | 8 | panelsPage() 9 | 10 | }) 11 | --------------------------------------------------------------------------------