├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── inst ├── WORDLIST └── assets │ └── screenfull │ └── screenfull.min.js ├── LICENSE ├── echarts-bgcolor.gif ├── fullscreen-those2.gif ├── tests ├── testthat.R ├── spelling.R └── testthat │ ├── _snaps │ ├── fullscreen_all.md │ ├── fullscreen_those.md │ └── fullscreen_this.md │ ├── test-fullscreen_all.R │ ├── test-fullscreen_this.R │ └── test-fullscreen_those.R ├── .gitignore ├── NAMESPACE ├── R ├── utils.R ├── fullscreen_all.R ├── fullscreen_button.R ├── fullscreen_those.R └── fullscreen_this.R ├── cran-comments.md ├── .Rbuildignore ├── shinyfullscreen.Rproj ├── NEWS.md ├── DESCRIPTION ├── LICENSE.md ├── man ├── fullscreen_all.Rd ├── fullscreen_button.Rd ├── fullscreen_those.Rd └── fullscreen_this.Rd ├── README.md └── CODE_OF_CONDUCT.md /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | RStudio 2 | UI 3 | fullscreen 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2020 2 | COPYRIGHT HOLDER: Etienne Bacher 3 | -------------------------------------------------------------------------------- /echarts-bgcolor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etiennebacher/shinyfullscreen/HEAD/echarts-bgcolor.gif -------------------------------------------------------------------------------- /fullscreen-those2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etiennebacher/shinyfullscreen/HEAD/fullscreen-those2.gif -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(shinyfullscreen) 3 | 4 | test_check("shinyfullscreen") 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | echarts_bgcolor.mp4 5 | fullscreen_those2.mp4 6 | test.R 7 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(fullscreen_all) 4 | export(fullscreen_button) 5 | export(fullscreen_this) 6 | export(fullscreen_those) 7 | -------------------------------------------------------------------------------- /tests/spelling.R: -------------------------------------------------------------------------------- 1 | if(requireNamespace('spelling', quietly = TRUE)) 2 | spelling::spell_check_test(vignettes = TRUE, error = FALSE, 3 | skip_on_cran = TRUE) 4 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | .onLoad <- function(libname, pkgname) { 2 | shiny::addResourcePath( 3 | prefix = "shinyfullscreen-assets", 4 | directoryPath = system.file("assets", package = "shinyfullscreen")) 5 | } 6 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local R installation, R 4.0.3 3 | * ubuntu 16.04 (on travis-ci), R 4.0.3 4 | * win-builder (devel) 5 | 6 | ## R CMD check results 7 | 8 | 0 errors | 0 warnings | 1 note 9 | 10 | * This is a new release. 11 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^shinyfullscreen\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^CODE_OF_CONDUCT\.md$ 5 | ^echarts-bgcolor\.gif$ 6 | ^echarts_bgcolor\.mp4$ 7 | ^fullscreen-those2\.gif$ 8 | ^fullscreen_those2\.mp4$ 9 | ^\.github$ 10 | ^cran-comments\.md$ 11 | ^CRAN-RELEASE$ 12 | ^test\.R$ 13 | -------------------------------------------------------------------------------- /shinyfullscreen.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 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 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # shinyfullscreen (devel) 2 | 3 | * Add argument `cursor` to `fullscreen_this()` and `fullscreen_those()` to either 4 | show or hide the "zoom-in" cursor when hovering the element (thanks to 5 | @arnaudmilet for the suggestion and the code, #4). 6 | 7 | * Add function `fullscreen_button()` to toggle a specific element or the whole 8 | page to full screen (#5). 9 | 10 | # shinyfullscreen 1.1.0 11 | 12 | * use testthat's new snapshot based testing (#3, thanks @cpsievert) 13 | 14 | * modify mouse icon when hovering elements 15 | 16 | # shinyfullscreen 1.0.0 17 | 18 | * First release of the package. 19 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/fullscreen_all.md: -------------------------------------------------------------------------------- 1 | # fullscreen_all produces the right JS 2 | 3 | [1] "" 4 | 5 | # argument bg_color works 6 | 7 | [1] "" 8 | 9 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/fullscreen_those.md: -------------------------------------------------------------------------------- 1 | # fullscreen_those works with 1 item 2 | 3 | Code 4 | x 5 | Output 6 | [1] "" 7 | 8 | # fullscreen_those works with several items 9 | 10 | Code 11 | x 12 | Output 13 | [1] "" 14 | 15 | -------------------------------------------------------------------------------- /tests/testthat/test-fullscreen_all.R: -------------------------------------------------------------------------------- 1 | test_that("fullscreen_all needs a click_id argument", { 2 | expect_error(fullscreen_all()) 3 | }) 4 | 5 | test_that("fullscreen_all produces the right JS", { 6 | shiny::actionButton("click", "Click") %>% 7 | fullscreen_all() %>% 8 | paste() %>% 9 | gsub("\\t", "", .) %>% 10 | gsub("\\n", "", .) %>% 11 | # remove additional spaces 12 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) %>% 13 | expect_snapshot_output() 14 | }) 15 | 16 | test_that("argument bg_color works", { 17 | 18 | shiny::actionButton("click", "Click") %>% 19 | fullscreen_all(bg_color = "pink") %>% 20 | paste() %>% 21 | gsub("\\t", "", .) %>% 22 | gsub("\\n", "", .) %>% 23 | # remove additional spaces 24 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) %>% 25 | expect_snapshot_output() 26 | }) 27 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: shinyfullscreen 2 | Title: Display 'HTML' Elements on Full Screen in 'Shiny' Apps 3 | Version: 1.1.0.9000 4 | Authors@R: 5 | person(given = "Etienne", 6 | family = "Bacher", 7 | role = c("aut", "cre", "cph"), 8 | email = "etienne.bacher@protonmail.com") 9 | Description: In 'Shiny' apps, it is sometimes useful to see a plot or a 10 | table in full screen. Using 'Shinyfullscreen', you can easily designate 11 | the 'HTML' elements that can be displayed on fullscreen and use buttons to 12 | trigger the fullscreen view. 13 | License: MIT + file LICENSE 14 | Encoding: UTF-8 15 | LazyData: true 16 | Roxygen: list(markdown = TRUE) 17 | RoxygenNote: 7.2.3.9000 18 | Config/testthat/edition: 3 19 | Imports: 20 | shiny, 21 | jsonlite 22 | URL: https://github.com/etiennebacher/shinyfullscreen 23 | BugReports: https://github.com/etiennebacher/shinyfullscreen/issues 24 | Suggests: 25 | testthat, 26 | spelling 27 | Language: en-US 28 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2020 Etienne Bacher 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/testthat/test-fullscreen_this.R: -------------------------------------------------------------------------------- 1 | test_that("fullscreen_this throws an error if no ui_element", { 2 | expect_error(fullscreen_this()) 3 | }) 4 | 5 | 6 | test_that("fullscreen_this produces the right JS", { 7 | x <- shiny::plotOutput("plot") %>% 8 | fullscreen_this() %>% 9 | paste() %>% 10 | gsub("\\t", "", .) %>% 11 | gsub("\\n", "", .) %>% 12 | # remove additional spaces 13 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) 14 | expect_snapshot(x) 15 | }) 16 | 17 | test_that("argument click_id works", { 18 | x <- shiny::plotOutput("plot") %>% 19 | fullscreen_this(click_id = "other_id") %>% 20 | paste() %>% 21 | gsub("\\t", "", .) %>% 22 | gsub("\\n", "", .) %>% 23 | # remove additional spaces 24 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) 25 | expect_snapshot(x) 26 | }) 27 | 28 | test_that("argument bg_color works", { 29 | x <- shiny::plotOutput("plot") %>% 30 | fullscreen_this(bg_color = "pink") %>% 31 | paste() %>% 32 | gsub("\\t", "", .) %>% 33 | gsub("\\n", "", .) %>% 34 | # remove additional spaces 35 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) 36 | expect_snapshot(x) 37 | }) 38 | -------------------------------------------------------------------------------- /tests/testthat/test-fullscreen_those.R: -------------------------------------------------------------------------------- 1 | test_that("fullscreen_those creates nothing if no item", { 2 | 3 | x <- fullscreen_those(items = list()) %>% 4 | paste() %>% 5 | gsub("\\t", "", .) %>% 6 | gsub("\\n", "", .) %>% 7 | # remove additional spaces 8 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) 9 | 10 | expect_equal(length(x), 0) 11 | 12 | }) 13 | 14 | test_that("fullscreen_those works with 1 item", { 15 | 16 | plot1 <- shiny::plotOutput("plot") 17 | 18 | x <- fullscreen_those(items = list("plot")) %>% 19 | paste() %>% 20 | gsub("\\t", "", .) %>% 21 | gsub("\\n", "", .) %>% 22 | # remove additional spaces 23 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) 24 | 25 | expect_snapshot(x) 26 | 27 | }) 28 | 29 | test_that("fullscreen_those works with several items", { 30 | 31 | plot1 <- shiny::plotOutput("plot") 32 | plot2 <- shiny::plotOutput("plot2") 33 | 34 | x <- fullscreen_those(items = list("plot", "plot2")) %>% 35 | paste() %>% 36 | gsub("\\t", "", .) %>% 37 | gsub("\\n", "", .) %>% 38 | # remove additional spaces 39 | gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", ., perl = TRUE) 40 | 41 | expect_snapshot(x) 42 | 43 | }) 44 | -------------------------------------------------------------------------------- /man/fullscreen_all.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fullscreen_all.R 3 | \name{fullscreen_all} 4 | \alias{fullscreen_all} 5 | \title{Enable fullscreen for the whole page} 6 | \usage{ 7 | fullscreen_all(click_id = NULL, bg_color = "#fff") 8 | } 9 | \arguments{ 10 | \item{click_id}{Id of the item that triggers the fullscreen view. This is a mandatory argument. You can specify the id of a button for instance, so that clicking on this button triggers the fullscreen view for the whole page.} 11 | 12 | \item{bg_color}{Background color when item is displayed fullscreen. Default is white.} 13 | } 14 | \value{ 15 | Enables the whole page to be displayed in fullscreen mode. 16 | } 17 | \description{ 18 | Enable fullscreen for the whole page 19 | } 20 | \examples{ 21 | if (interactive()) { 22 | ### Only works in browser 23 | 24 | library(shiny) 25 | 26 | ui <- fluidPage( 27 | actionButton("test", "test"), 28 | plotOutput("plot"), 29 | fullscreen_all(click_id = "test") 30 | ) 31 | 32 | server <- function(input, output, session) { 33 | 34 | output$plot <- renderPlot(plot(mtcars)) 35 | 36 | } 37 | 38 | shinyApp(ui, server, options = list(launch.browser = TRUE)) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /man/fullscreen_button.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fullscreen_button.R 3 | \name{fullscreen_button} 4 | \alias{fullscreen_button} 5 | \title{Button that toggles fullscreen} 6 | \usage{ 7 | fullscreen_button( 8 | id, 9 | label, 10 | class = NULL, 11 | type = "default", 12 | target = NULL, 13 | icon = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{id}{Id of the button} 18 | 19 | \item{label}{Label of the button} 20 | 21 | \item{class}{Additional classes to give to the button} 22 | 23 | \item{type}{Type of the button ("info", "danger", etc.)} 24 | 25 | \item{target}{Id of the element to put on fullscreen. If \code{NULL}, the whole 26 | page is put on fullscreen.} 27 | 28 | \item{icon}{Icon to add before the label on the button} 29 | } 30 | \value{ 31 | Put an element or the whole page on fullscreen 32 | } 33 | \description{ 34 | Button that toggles fullscreen 35 | } 36 | \examples{ 37 | if (interactive()) { 38 | ### Only works in browser 39 | library(shiny) 40 | 41 | ui <- fluidPage( 42 | fullscreen_button(id = "toggle_fs", "Enter/Quit fullscreen", target = "plot"), 43 | plotOutput("plot") 44 | ) 45 | 46 | server <- function(input, output){ 47 | 48 | output$plot <- renderPlot(plot(mtcars)) 49 | 50 | } 51 | 52 | shinyApp(ui, server) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /man/fullscreen_those.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fullscreen_those.R 3 | \name{fullscreen_those} 4 | \alias{fullscreen_those} 5 | \title{Enable fullscreen for a list of items} 6 | \usage{ 7 | fullscreen_those(items = list(), bg_color = "#fff", cursor = TRUE) 8 | } 9 | \arguments{ 10 | \item{items}{A list containing the ids of the items for which fullscreen is enabled.} 11 | 12 | \item{bg_color}{Background color when item is displayed full screen. Default is white.} 13 | 14 | \item{cursor}{Display a special "zoom-in" cursor when hovering the element? 15 | Default is \code{TRUE}.} 16 | } 17 | \value{ 18 | Enables the selected elements to be displayed in fullscreen mode. 19 | } 20 | \description{ 21 | Enable fullscreen for a list of items 22 | } 23 | \details{ 24 | This function has to be placed AFTER the call of inputs. See Examples. 25 | } 26 | \examples{ 27 | if (interactive()) { 28 | ### Only works in browser 29 | 30 | library(shiny) 31 | library(shinyfullscreen) 32 | 33 | ui <- fluidPage( 34 | plotOutput("plot"), 35 | plotOutput("plot2"), 36 | 37 | # Has to be placed after plot and plot2 38 | fullscreen_those(items = list("plot", "plot2")) 39 | ) 40 | 41 | server <- function(input, output, session) { 42 | 43 | output$plot <- renderPlot(plot(mtcars)) 44 | output$plot2 <- renderPlot(plot(AirPassengers)) 45 | 46 | } 47 | 48 | shinyApp(ui, server, options = list(launch.browser = TRUE)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/fullscreen_this.md: -------------------------------------------------------------------------------- 1 | # fullscreen_this produces the right JS 2 | 3 | Code 4 | x 5 | Output 6 | [1] "
" 7 | 8 | # argument click_id works 9 | 10 | Code 11 | x 12 | Output 13 | [1] "
" 14 | 15 | # argument bg_color works 16 | 17 | Code 18 | x 19 | Output 20 | [1] "
" 21 | 22 | -------------------------------------------------------------------------------- /man/fullscreen_this.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fullscreen_this.R 3 | \name{fullscreen_this} 4 | \alias{fullscreen_this} 5 | \title{Enable fullscreen for a specific item} 6 | \usage{ 7 | fullscreen_this(ui_element, click_id = NULL, bg_color = "#fff", cursor = TRUE) 8 | } 9 | \arguments{ 10 | \item{ui_element}{A UI element that should be displayed fullscreen.} 11 | 12 | \item{click_id}{Id of the item that triggers the fullscreen view. By default, it is the id of \code{ui_element}, i.e clicking on the element shows it on fullscreen. You can specify the id of a button for instance, so that clicking on this button triggers the fullscreen view of \code{ui_element}.} 13 | 14 | \item{bg_color}{Background color when item is displayed fullscreen. Default is white.} 15 | 16 | \item{cursor}{Display a special "zoom-in" cursor when hovering the element? 17 | Default is \code{TRUE}.} 18 | } 19 | \value{ 20 | Enables the selected element to be displayed in fullscreen mode. 21 | } 22 | \description{ 23 | Enable fullscreen for a specific item 24 | } 25 | \examples{ 26 | if (interactive()) { 27 | ### Only works in browser 28 | 29 | library(shiny) 30 | 31 | ui <- fluidPage( 32 | actionButton("test", "test"), 33 | fullscreen_this(plotOutput("plot")) 34 | ) 35 | 36 | server <- function(input, output, session) { 37 | 38 | output$plot <- renderPlot(plot(mtcars)) 39 | 40 | } 41 | 42 | shinyApp(ui, server, options = list(launch.browser = TRUE)) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: any::rcmdcheck 45 | needs: check 46 | 47 | - uses: r-lib/actions/check-r-package@v2 48 | with: 49 | upload-snapshots: true 50 | -------------------------------------------------------------------------------- /R/fullscreen_all.R: -------------------------------------------------------------------------------- 1 | #' Enable fullscreen for the whole page 2 | #' 3 | #' @param click_id Id of the item that triggers the fullscreen view. This is a mandatory argument. You can specify the id of a button for instance, so that clicking on this button triggers the fullscreen view for the whole page. 4 | #' @param bg_color Background color when item is displayed fullscreen. Default is white. 5 | #' 6 | #' @return Enables the whole page to be displayed in fullscreen mode. 7 | #' @export 8 | #' 9 | #' @examples 10 | #' if (interactive()) { 11 | #' ### Only works in browser 12 | #' 13 | #' library(shiny) 14 | #' 15 | #' ui <- fluidPage( 16 | #' actionButton("test", "test"), 17 | #' plotOutput("plot"), 18 | #' fullscreen_all(click_id = "test") 19 | #' ) 20 | #' 21 | #' server <- function(input, output, session) { 22 | #' 23 | #' output$plot <- renderPlot(plot(mtcars)) 24 | #' 25 | #' } 26 | #' 27 | #' shinyApp(ui, server, options = list(launch.browser = TRUE)) 28 | #' } 29 | 30 | fullscreen_all <- function(click_id = NULL, bg_color = "#fff") { 31 | 32 | if (missing(click_id)) { 33 | stop("Must specify a click_id to put the whole page on fullscreen") 34 | } 35 | 36 | shiny::tagList( 37 | shiny::singleton( 38 | shiny::tags$head( 39 | shiny::tags$script( 40 | src="shinyfullscreen-assets/screenfull/screenfull.min.js" 41 | ), 42 | shiny::tags$style( 43 | shiny::HTML( 44 | ":fullscreen, ::backdrop { 45 | background-color: transparent; 46 | }" 47 | ) 48 | ) 49 | ) 50 | ), 51 | shiny::tags$script( 52 | paste0( 53 | " 54 | $(function () { 55 | if (!screenfull.isEnabled) { 56 | return false; 57 | } 58 | 59 | $('#", click_id,"').click(function () { 60 | screenfull.request(); 61 | }); 62 | });" 63 | ) 64 | ), 65 | shiny::tags$style( 66 | paste0( 67 | "::backdrop { 68 | background-color:", bg_color, "; 69 | }" 70 | ) 71 | ) 72 | ) 73 | 74 | } 75 | -------------------------------------------------------------------------------- /R/fullscreen_button.R: -------------------------------------------------------------------------------- 1 | #' Button that toggles fullscreen 2 | #' 3 | #' @param id Id of the button 4 | #' @param label Label of the button 5 | #' @param class Additional classes to give to the button 6 | #' @param type Type of the button ("info", "danger", etc.) 7 | #' @param target Id of the element to put on fullscreen. If `NULL`, the whole 8 | #' page is put on fullscreen. 9 | #' @param icon Icon to add before the label on the button 10 | #' 11 | #' @return Put an element or the whole page on fullscreen 12 | #' @export 13 | #' 14 | #' @examples 15 | #' if (interactive()) { 16 | #' ### Only works in browser 17 | #' library(shiny) 18 | #' 19 | #' ui <- fluidPage( 20 | #' fullscreen_button(id = "toggle_fs", "Enter/Quit fullscreen", target = "plot"), 21 | #' plotOutput("plot") 22 | #' ) 23 | #' 24 | #' server <- function(input, output){ 25 | #' 26 | #' output$plot <- renderPlot(plot(mtcars)) 27 | #' 28 | #' } 29 | #' 30 | #' shinyApp(ui, server) 31 | #' } 32 | 33 | fullscreen_button <- function( 34 | id, 35 | label, 36 | class = NULL, 37 | type = "default", 38 | target = NULL, 39 | icon = NULL 40 | ){ 41 | 42 | target <- if (is.null(target)) "body" else paste0("#", target) 43 | 44 | # class 45 | cl <- sprintf("btn btn-%s", type) 46 | cl <- paste(cl, class) 47 | 48 | args <- list(class = cl, label = label, inputId = id, icon = icon) 49 | 50 | ui_element <- do.call(shiny::actionButton, args) 51 | 52 | shiny::tagList( 53 | shiny::singleton( 54 | shiny::tags$head( 55 | shiny::tags$script( 56 | src="shinyfullscreen-assets/screenfull/screenfull.min.js" 57 | ), 58 | shiny::tags$style( 59 | shiny::HTML( 60 | ":fullscreen, ::backdrop { 61 | background-color: transparent; 62 | }" 63 | ) 64 | ) 65 | ) 66 | ), 67 | ui_element, 68 | shiny::tags$script( 69 | paste0( 70 | " 71 | $(function () { 72 | if (screenfull.isEnabled) { 73 | $('#", id,"').click(function () { 74 | screenfull.toggle($('", target, "')[0]); 75 | }); 76 | } 77 | });" 78 | ) 79 | ) 80 | ) 81 | } 82 | -------------------------------------------------------------------------------- /inst/assets/screenfull/screenfull.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * screenfull 3 | * v5.1.0 - 2020-12-24 4 | * (c) Sindre Sorhus; MIT License 5 | */ 6 | 7 | !function(){"use strict";var c="undefined"!=typeof window&&void 0!==window.document?window.document:{},e="undefined"!=typeof module&&module.exports,s=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],l=0,r=n.length,t={};l 1) { 48 | ids_for_CSS <- paste(ids, collapse = ", ") 49 | } else { 50 | ids_for_CSS <- paste(ids) 51 | } 52 | 53 | 54 | shiny::tagList( 55 | shiny::singleton( 56 | shiny::tags$head( 57 | shiny::tags$script( 58 | src="shinyfullscreen-assets/screenfull/screenfull.min.js" 59 | ) 60 | ), 61 | shiny::tags$style( 62 | shiny::HTML( 63 | ":fullscreen, ::backdrop { 64 | background-color: transparent; 65 | }" 66 | ) 67 | ) 68 | ), 69 | shiny::tags$script( 70 | paste0( 71 | " 72 | var ids = ", ids_for_JS, "; 73 | $(ids.join(',')).click(function () { 74 | screenfull.request(this); 75 | });" 76 | ) 77 | ), 78 | if(isTRUE(cursor)){ 79 | shiny::tags$style( 80 | paste0( 81 | "#", ids_for_CSS, "{ 82 | cursor: -webkit-zoom-in; 83 | cursor: -moz-zoom-in; 84 | }" 85 | ) 86 | ) 87 | }, 88 | shiny::tags$style( 89 | '::backdrop { 90 | background-color:", bg_color, "; 91 | }' 92 | ) 93 | ) 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /R/fullscreen_this.R: -------------------------------------------------------------------------------- 1 | #' Enable fullscreen for a specific item 2 | #' 3 | #' @param ui_element A UI element that should be displayed fullscreen. 4 | #' @param bg_color Background color when item is displayed fullscreen. Default is white. 5 | #' @param click_id Id of the item that triggers the fullscreen view. By default, it is the id of `ui_element`, i.e clicking on the element shows it on fullscreen. You can specify the id of a button for instance, so that clicking on this button triggers the fullscreen view of `ui_element`. 6 | #' @param cursor Display a special "zoom-in" cursor when hovering the element? 7 | #' Default is `TRUE`. 8 | #' 9 | #' @return Enables the selected element to be displayed in fullscreen mode. 10 | #' @export 11 | #' 12 | #' @examples 13 | #' if (interactive()) { 14 | #' ### Only works in browser 15 | #' 16 | #' library(shiny) 17 | #' 18 | #' ui <- fluidPage( 19 | #' actionButton("test", "test"), 20 | #' fullscreen_this(plotOutput("plot")) 21 | #' ) 22 | #' 23 | #' server <- function(input, output, session) { 24 | #' 25 | #' output$plot <- renderPlot(plot(mtcars)) 26 | #' 27 | #' } 28 | #' 29 | #' shinyApp(ui, server, options = list(launch.browser = TRUE)) 30 | #' } 31 | 32 | fullscreen_this <- function(ui_element, click_id = NULL, bg_color = "#fff", 33 | cursor = TRUE) { 34 | 35 | ui_element <- ui_element 36 | id_element <- ui_element$attribs$id 37 | 38 | # some ui_elements can be list but their organization is a bit different 39 | # e.g echarts4rOutput("plot") 40 | if (is.null(id_element) && "list" %in% class(ui_element)) { 41 | id_element <- unlist(ui_element)["attribs.id"] 42 | } 43 | 44 | if (missing(click_id)) { 45 | click_id <- id_element 46 | } 47 | 48 | shiny::tagList( 49 | shiny::singleton( 50 | shiny::tags$head( 51 | shiny::tags$script( 52 | src="shinyfullscreen-assets/screenfull/screenfull.min.js" 53 | ), 54 | shiny::tags$style( 55 | shiny::HTML( 56 | ":fullscreen, ::backdrop { 57 | background-color: transparent; 58 | }" 59 | ) 60 | ) 61 | ) 62 | ), 63 | ui_element, 64 | shiny::tags$script( 65 | paste0( 66 | " 67 | $(function () { 68 | if (!screenfull.isEnabled) { 69 | return false; 70 | } 71 | 72 | $('#", click_id,"').click(function () { 73 | screenfull.request($('#", id_element, "')[0]); 74 | }); 75 | });" 76 | ) 77 | ), 78 | if(isTRUE(cursor)){ 79 | shiny::tags$style( 80 | paste0( 81 | "#", id_element, "{ 82 | cursor: -webkit-zoom-in; 83 | cursor: -moz-zoom-in; 84 | }" 85 | ) 86 | ) 87 | }, 88 | shiny::tags$style( 89 | '::backdrop { 90 | background-color:", bg_color, "; 91 | }' 92 | ) 93 | ) 94 | 95 | } 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # shinyfullscreen 3 | 4 | 5 | 6 | [![Codecov.io test coverage](https://codecov.io/gh/etiennebacher/shinyfullscreen/branch/master/graphs/badge.svg)](https://codecov.io/github/etiennebacher/shinyfullscreen) [![R build status](https://github.com/etiennebacher/shinyfullscreen/workflows/R-CMD-check/badge.svg)](https://github.com/etiennebacher/shinyfullscreen/actions) [![CRAN status](https://www.r-pkg.org/badges/version/shinyfullscreen)](https://CRAN.R-project.org/package=shinyfullscreen) ![](https://cranlogs.r-pkg.org/badges/shinyfullscreen) 7 | [![R-CMD-check](https://github.com/etiennebacher/shinyfullscreen/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/etiennebacher/shinyfullscreen/actions/workflows/R-CMD-check.yaml) 8 | 9 | 10 | The goal of `{shinyfullscreen}` is to enable users to put some items on fullscreen. This package is the adaptation in R of [`screenfull.js`](https://github.com/sindresorhus/screenfull.js). 11 | 12 | ## Table of contents 13 | 14 | - [Demos](#demo) 15 | - [Installation](#installation) 16 | - [How to use](#howto) 17 | - [Code of Conduct](#CoC) 18 | 19 | 20 |

Demos

21 | 22 | * Two plots can be displayed on full screen 23 | 24 | ![](fullscreen-those2.gif) 25 | 26 | * Interactive graphs and custom background color on fullscreen only 27 | 28 | ![](echarts-bgcolor.gif) 29 | 30 | 31 |

Installation

32 | 33 | Install the CRAN version with: 34 | ```r 35 | install.packages("shinyfullscreen") 36 | ``` 37 | 38 | Install the development version with: 39 | 40 | ``` r 41 | # install.packages("devtools") 42 | devtools::install_github("etiennebacher/shinyfullscreen") 43 | ``` 44 | 45 |

How to use

46 | 47 | Note that `{shinyfullscreen}` only works when the Shiny app is launched **in the browser**. It won't work in an RStudio window. 48 | 49 | This package provides three functions that are very similar: 50 | 51 | * `fullscreen_this()` is useful if you want to enable fullscreen for few elements. Simply wrap this function around the element for which you want to enable fullscreen, and then click on this element when the app runs to display it on fullscreen: 52 | 53 | ```R 54 | ### Only works in browser 55 | 56 | library(shiny) 57 | library(shinyfullscreen) 58 | 59 | ui <- fluidPage( 60 | 61 | fullscreen_this(plotOutput("plot")) 62 | 63 | # Also works with magrittr's pipe 64 | # plotOutput("plot") %>% 65 | # fullscreen_this() 66 | ) 67 | 68 | server <- function(input, output, session) { 69 | 70 | output$plot <- renderPlot(plot(mtcars)) 71 | 72 | } 73 | 74 | shinyApp(ui, server, options = list(launch.browser = TRUE)) 75 | ``` 76 | 77 | * `fullscreen_those()` is useful if you want to enable fullscreen view for several items without rewriting the same code again and again. Simply write your UI as usual, and then call this function with a list of ids corresponding to the items for which you want to enable fullscreen view. Note that this function has to be called after having created these items: 78 | 79 | ```R 80 | ### Only works in browser 81 | 82 | library(shiny) 83 | library(shinyfullscreen) 84 | 85 | ui <- fluidPage( 86 | plotOutput("plot"), 87 | plotOutput("plot2"), 88 | 89 | # Has to be placed after plot and plot2 90 | fullscreen_those(items = list("plot", "plot2")) 91 | ) 92 | 93 | server <- function(input, output, session) { 94 | 95 | output$plot <- renderPlot(plot(mtcars)) 96 | output$plot2 <- renderPlot(plot(AirPassengers)) 97 | 98 | } 99 | 100 | shinyApp(ui, server, options = list(launch.browser = TRUE)) 101 | ``` 102 | 103 | * `fullscreen_all()` allows you to put the whole page in fullscreen mode. Note however that this requires clicking on an HTML element. 104 | 105 | ```R 106 | ### Only works in browser 107 | 108 | library(shiny) 109 | library(shinyfullscreen) 110 | 111 | ui <- fluidPage( 112 | actionButton("page_full", "Show page in fullscreen"), 113 | plotOutput("plot"), 114 | fullscreen_all(click_id = "page_full") 115 | ) 116 | 117 | server <- function(input, output, session) { 118 | 119 | output$plot <- renderPlot(plot(mtcars)) 120 | 121 | } 122 | 123 | shinyApp(ui, server, options = list(launch.browser = TRUE)) 124 | ``` 125 | 126 |

Code of Conduct

127 | 128 | Please note that the shinyfullscreen project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/0/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. 129 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards 42 | of acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies 54 | when an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail 56 | address, posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at [INSERT CONTACT 63 | METHOD]. All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series of 85 | actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or permanent 92 | ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within the 112 | community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.0, 118 | available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 119 | 120 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 121 | enforcement ladder](https://github.com/mozilla/diversity). 122 | 123 | [homepage]: https://www.contributor-covenant.org 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | https://www.contributor-covenant.org/faq. Translations are available at https:// 127 | www.contributor-covenant.org/translations. 128 | --------------------------------------------------------------------------------