diff --git a/NEWS.md b/NEWS.md index e6552030..e635cf69 100644 --- a/NEWS.md +++ b/NEWS.md @@ -62,7 +62,7 @@ the check icon position. Default to left. - `f7Panel()` has new "floating"/"push" effects as well as a new `options` parameter to pass in extra configuration. See https://framework7.io/docs/panel#panel-parameters. - `f7VirtualList()` has new `outline`, `dividers` and `strong` styles. Additionally, `mode` was added with the following possible values: `simple`, `links`, `media` or `contacts`. -- `f7Popup()` has a new `push` effect (pushing the main view behind on opening). +- `f7Popup()` has a new `push` effect (pushing the main view behind on opening). There's also a new argument called `page` that can control whether or not the popup behaves as a page and can scroll- handy for popups with more content. - `f7Radio()` has a new `position` parameter to control the check icon position. Default to left (like `f7CheckboxGroup()`). Also, `f7Radio()` inherits from `f7List()` styling parameters such as `inset`, `outline`,`dividers`, `strong` for more styling option. @@ -94,6 +94,7 @@ the new router layout. Items must be wrapped in a `shiny::tagList()`. - `updateF7App` can now also handle changes in app theme (ios or md), dark mode, and color. - `f7Fabs()` has a new argument `global` that can be used to make FABs persistent across different tabs in `f7TabLayout()`. - `f7ExpandableCard()` has a new argument `buttonColor` that can be used to control the color of the close button. +- `f7Login()` has a new argument `module` that can, optionally, be set to `FALSE` for more flexibility. For example, this allows you to use `f7Login()` inside your own modules, or without the provided `f7LoginServer()` module. - Fix various issues in documentation. - Include new vignettes. diff --git a/R/f7Login.R b/R/f7Login.R index b4e96e82..9f6c2d46 100644 --- a/R/f7Login.R +++ b/R/f7Login.R @@ -20,13 +20,18 @@ #' @param startOpen Whether to open the login page at start. Default to TRUE. There #' are some cases where it is interesting to set up to FALSE, for instance when you want #' to have authentication only in a specific tab of your app (See example 2). +#' @param module Whether or not to use in combination with \link{f7LoginServer}. Can be +#' set to FALSE if you want to develop your own server functionality, or if you want to +#' use \code{f7Login} inside a module yourself. Note that inputs, like user, password and submit, +#' will need to be accessed with the id of \code{f7Login} with -user, -password or -submit appended. #' #' @export #' @rdname authentication #' @importFrom jsonlite toJSON #' @example inst/examples/login/app.R f7Login <- function(..., id, title, label = "Sign In", footer = NULL, - startOpen = TRUE) { + startOpen = TRUE, module = TRUE) { + ns <- shiny::NS(id) submitBttn <- f7Button(inputId = ns("submit"), label = label) diff --git a/R/f7Popup.R b/R/f7Popup.R index 8d46ad37..d681ac63 100644 --- a/R/f7Popup.R +++ b/R/f7Popup.R @@ -22,6 +22,7 @@ #' @param closeButton Add or not a button to easily close the popup. #' Default to \code{TRUE}. #' @param push Push effect. Default to TRUE. +#' @param page Allow content to be scrollable, as a page. Default to FALSE. #' @param session Shiny session object. #' #' @export @@ -36,6 +37,7 @@ f7Popup <- function(..., id, title = NULL, fullsize = FALSE, closeButton = TRUE, push = TRUE, + page = FALSE, session = shiny::getDefaultReactiveDomain()) { message <- dropNulls( list( @@ -49,18 +51,32 @@ f7Popup <- function(..., id, title = NULL, ) ) - content <- shiny::tags$div( - class = "block", - if (!is.null(title)) shiny::tags$div(class = "block-title", title), - ... - ) + if (page) { + content <- shiny::tags$div( + class = "page", + shiny::tags$div( + class = "page-content", + shiny::tags$div( + class = "block", + if (!is.null(title)) shiny::tags$div(class = "block-title", title), + ... + ) + ) + ) + } else { + content <- shiny::tags$div( + class = "block", + if (!is.null(title)) shiny::tags$div(class = "block-title", title), + ... + ) + } if (closeButton) { content <- htmltools::tagAppendChild( content, shiny::tags$a( class = "link popup-close", - style = "position: absolute; top: -15px; right: 10px;", + style = sprintf("position: absolute; top: %s; right: 10px;", ifelse(page, "15px", "-15px")), href = "#", f7Icon("multiply") ) diff --git a/inst/examples/popup/app.R b/inst/examples/popup/app.R index 3f64caf1..61d20715 100644 --- a/inst/examples/popup/app.R +++ b/inst/examples/popup/app.R @@ -8,21 +8,75 @@ app <- shinyApp( navbar = f7Navbar( title = "f7Popup" ), - f7Block(f7Button("toggle", "Toggle Popup")) + f7Block(f7Button("toggle1", "Toggle Popup")), + br(), + f7Block(f7Button("toggle2", "Toggle Page Popup")) ) ), server = function(input, output, session) { - output$res <- renderPrint(input$text) - observeEvent(input$toggle, { + output$res1 <- renderPrint(input$text) + output$res2 <- renderPrint(input$text2) + + observeEvent(input$toggle1, { f7Popup( - id = "popup", + id = "popup1", title = "My first popup", f7Text( - "text", "Popup content", + "text1", "Popup content", "This is my first popup ever, I swear!" ), - verbatimTextOutput("res") + verbatimTextOutput("res1") + ) + }) + + observeEvent(input$toggle2, { + f7Popup( + id = "popup2", + title = "My first popup", + page = TRUE, + f7Text( + "text2", "Popup content", + "Look at me, I can scroll!" + ), + verbatimTextOutput("res2"), + p("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse + hendrerit magna non sem iaculis, ac rhoncus est pulvinar. Interdum et + malesuada fames ac ante ipsum primis in faucibus. In sagittis vel lacus + ac bibendum. Maecenas mollis, diam nec fermentum sollicitudin, massa + lectus ullamcorper orci, in laoreet lectus quam nec lacus. + Nulla sollicitudin imperdiet metus, quis mollis justo finibus varius. + In mattis malesuada enim in tincidunt. Nulla vehicula dui lacus, + iaculis condimentum dui dapibus ac. Cras elit nunc, auctor vestibulum + odio id, iaculis posuere arcu. Mauris dignissim id lectus sit amet + vestibulum. Nam rutrum sit amet augue vel interdum. Donec sed orci vitae + eros eleifend posuere vitae id nibh. Donec faucibus erat in placerat + feugiat. Sed sodales facilisis eros, porta viverra purus pretium eu. + Morbi vehicula metus lacus, id commodo mauris posuere nec. Vivamus + ornare et lacus et lobortis. Etiam tristique elit id eros ornare, + vel faucibus mauris hendrerit. Nulla elit nulla, consequat sit amet + neque et, ultrices elementum diam. Etiam dignissim elit a arcu pulvinar, + ut dapibus elit maximus. Mauris ultricies nulla in mauris laoreet, at + lacinia lorem maximus. Nulla sed enim diam. In ac felis dignissim, + euismod augue nec, tempus augue. Maecenas eget aliquam mi. + In tincidunt massa a velit suscipit, ac dapibus mi laoreet. Vestibulum + lacinia nulla lorem, nec blandit quam sollicitudin at. Pellentesque + in vehicula lacus. Etiam vitae lectus malesuada, hendrerit mauris eu, + placerat elit. Mauris vehicula dictum pharetra. Etiam interdum vehicula + urna, ac blandit lectus posuere id. Nullam facilisis tincidunt sem et + pretium. Praesent pulvinar feugiat augue, quis pretium nunc vestibulum a. + Morbi id eros eget lectus placerat placerat. Morbi dapibus viverra + orci nec pellentesque. Vestibulum mollis gravida sem, quis tincidunt + sem maximus gravida. Nam id egestas augue, sit amet egestas orci. Duis + porttitor lectus sit amet efficitur auctor. Quisque dui ante, eleifend + eget nibh a, tincidunt interdum nisi. Integer varius tempor erat, in + commodo neque elementum ut. Maecenas eu lorem ultrices, posuere neque ac, + aliquam ante. Maecenas eu volutpat arcu. Morbi hendrerit sem sed vehicula + sodales. Quisque ultrices massa erat, vel accumsan risus vehicula eu. + Donec laoreet aliquet est, a consequat odio viverra lacinia. Suspendisse + id iaculis risus. Vestibulum posuere dignissim lacus quis ornare. Nam + dapibus efficitur neque sed tristique." + ) ) }) @@ -31,7 +85,7 @@ app <- shinyApp( f7Toast( position = "top", - text = paste("Popup is", popupStatus) + text = paste("Popup1 is", popupStatus) ) }) } diff --git a/man/authentication.Rd b/man/authentication.Rd index dfc71a31..f9cd2e97 100644 --- a/man/authentication.Rd +++ b/man/authentication.Rd @@ -6,7 +6,15 @@ \alias{updateF7Login} \title{Framework7 login screen} \usage{ -f7Login(..., id, title, label = "Sign In", footer = NULL, startOpen = TRUE) +f7Login( + ..., + id, + title, + label = "Sign In", + footer = NULL, + startOpen = TRUE, + module = TRUE +) f7LoginServer(id, ignoreInit = FALSE, trigger = NULL) @@ -33,6 +41,12 @@ either opened or closed).} are some cases where it is interesting to set up to FALSE, for instance when you want to have authentication only in a specific tab of your app (See example 2).} +\item{module}{Whether or not to use in combination with \link{f7LoginServer}. Can be +set to FALSE if you want to develop your own server functionality, or if you want to +use \code{f7Login} inside a module yourself. Note that inputs, like user, password and submit, +will need to be accessed with the id of \code{f7Login} with -user, -password or -submit appended. +For example: "input$\code{login-user}".} + \item{ignoreInit}{If TRUE, then, when this observeEvent is first created/initialized, ignore the handlerExpr (the second argument), whether it is otherwise supposed to run or not. The default is FALSE.} diff --git a/man/f7Popup.Rd b/man/f7Popup.Rd index f71d29cf..d3e8cd4e 100644 --- a/man/f7Popup.Rd +++ b/man/f7Popup.Rd @@ -16,6 +16,7 @@ f7Popup( fullsize = FALSE, closeButton = TRUE, push = TRUE, + page = FALSE, session = shiny::getDefaultReactiveDomain() ) } @@ -50,6 +51,8 @@ Default to \code{TRUE}.} \item{push}{Push effect. Default to TRUE.} +\item{page}{Allow content to be scrollable, as a page. Default to FALSE.} + \item{session}{Shiny session object.} } \description{ @@ -67,21 +70,75 @@ app <- shinyApp( navbar = f7Navbar( title = "f7Popup" ), - f7Block(f7Button("toggle", "Toggle Popup")) + f7Block(f7Button("toggle1", "Toggle Popup")), + br(), + f7Block(f7Button("toggle2", "Toggle Page Popup")) ) ), server = function(input, output, session) { - output$res <- renderPrint(input$text) - observeEvent(input$toggle, { + output$res1 <- renderPrint(input$text) + output$res2 <- renderPrint(input$text2) + + observeEvent(input$toggle1, { f7Popup( - id = "popup", + id = "popup1", title = "My first popup", f7Text( - "text", "Popup content", + "text1", "Popup content", "This is my first popup ever, I swear!" ), - verbatimTextOutput("res") + verbatimTextOutput("res1") + ) + }) + + observeEvent(input$toggle2, { + f7Popup( + id = "popup2", + title = "My first popup", + page = TRUE, + f7Text( + "text2", "Popup content", + "Look at me, I can scroll!" + ), + verbatimTextOutput("res2"), + p("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse + hendrerit magna non sem iaculis, ac rhoncus est pulvinar. Interdum et + malesuada fames ac ante ipsum primis in faucibus. In sagittis vel lacus + ac bibendum. Maecenas mollis, diam nec fermentum sollicitudin, massa + lectus ullamcorper orci, in laoreet lectus quam nec lacus. + Nulla sollicitudin imperdiet metus, quis mollis justo finibus varius. + In mattis malesuada enim in tincidunt. Nulla vehicula dui lacus, + iaculis condimentum dui dapibus ac. Cras elit nunc, auctor vestibulum + odio id, iaculis posuere arcu. Mauris dignissim id lectus sit amet + vestibulum. Nam rutrum sit amet augue vel interdum. Donec sed orci vitae + eros eleifend posuere vitae id nibh. Donec faucibus erat in placerat + feugiat. Sed sodales facilisis eros, porta viverra purus pretium eu. + Morbi vehicula metus lacus, id commodo mauris posuere nec. Vivamus + ornare et lacus et lobortis. Etiam tristique elit id eros ornare, + vel faucibus mauris hendrerit. Nulla elit nulla, consequat sit amet + neque et, ultrices elementum diam. Etiam dignissim elit a arcu pulvinar, + ut dapibus elit maximus. Mauris ultricies nulla in mauris laoreet, at + lacinia lorem maximus. Nulla sed enim diam. In ac felis dignissim, + euismod augue nec, tempus augue. Maecenas eget aliquam mi. + In tincidunt massa a velit suscipit, ac dapibus mi laoreet. Vestibulum + lacinia nulla lorem, nec blandit quam sollicitudin at. Pellentesque + in vehicula lacus. Etiam vitae lectus malesuada, hendrerit mauris eu, + placerat elit. Mauris vehicula dictum pharetra. Etiam interdum vehicula + urna, ac blandit lectus posuere id. Nullam facilisis tincidunt sem et + pretium. Praesent pulvinar feugiat augue, quis pretium nunc vestibulum a. + Morbi id eros eget lectus placerat placerat. Morbi dapibus viverra + orci nec pellentesque. Vestibulum mollis gravida sem, quis tincidunt + sem maximus gravida. Nam id egestas augue, sit amet egestas orci. Duis + porttitor lectus sit amet efficitur auctor. Quisque dui ante, eleifend + eget nibh a, tincidunt interdum nisi. Integer varius tempor erat, in + commodo neque elementum ut. Maecenas eu lorem ultrices, posuere neque ac, + aliquam ante. Maecenas eu volutpat arcu. Morbi hendrerit sem sed vehicula + sodales. Quisque ultrices massa erat, vel accumsan risus vehicula eu. + Donec laoreet aliquet est, a consequat odio viverra lacinia. Suspendisse + id iaculis risus. Vestibulum posuere dignissim lacus quis ornare. Nam + dapibus efficitur neque sed tristique." + ) ) }) @@ -90,7 +147,7 @@ app <- shinyApp( f7Toast( position = "top", - text = paste("Popup is", popupStatus) + text = paste("Popup1 is", popupStatus) ) }) } diff --git a/tests/testthat/_snaps/f7Popup/popup-app-001.json b/tests/testthat/_snaps/f7Popup/popup-app-001.json index a54a273d..557c7140 100644 --- a/tests/testthat/_snaps/f7Popup/popup-app-001.json +++ b/tests/testthat/_snaps/f7Popup/popup-app-001.json @@ -1,5 +1,5 @@ { "input": { - "popup": true + "popup1": true } } diff --git a/tests/testthat/_snaps/f7Popup/popup-app-001_.png b/tests/testthat/_snaps/f7Popup/popup-app-001_.png index d13628a7..9e88493b 100644 Binary files a/tests/testthat/_snaps/f7Popup/popup-app-001_.png and b/tests/testthat/_snaps/f7Popup/popup-app-001_.png differ diff --git a/tests/testthat/_snaps/f7Popup/popup-app-002.json b/tests/testthat/_snaps/f7Popup/popup-app-002.json index b9e943b6..e8b8df5c 100644 --- a/tests/testthat/_snaps/f7Popup/popup-app-002.json +++ b/tests/testthat/_snaps/f7Popup/popup-app-002.json @@ -1,9 +1,9 @@ { "input": { - "popup": true, - "text": "balbla" + "popup1": true, + "text1": "balbla" }, "output": { - "res": "[1] \"balbla\"" + "res1": "NULL" } } diff --git a/tests/testthat/_snaps/f7Popup/popup-app-002_.png b/tests/testthat/_snaps/f7Popup/popup-app-002_.png index b4b437aa..23bc1b70 100644 Binary files a/tests/testthat/_snaps/f7Popup/popup-app-002_.png and b/tests/testthat/_snaps/f7Popup/popup-app-002_.png differ diff --git a/tests/testthat/_snaps/f7Popup/popup-app-003.json b/tests/testthat/_snaps/f7Popup/popup-app-003.json index 5c583291..758f1dbe 100644 --- a/tests/testthat/_snaps/f7Popup/popup-app-003.json +++ b/tests/testthat/_snaps/f7Popup/popup-app-003.json @@ -1,5 +1,5 @@ { "input": { - "popup": false + "popup1": false } } diff --git a/tests/testthat/_snaps/f7Popup/popup-app-003_.png b/tests/testthat/_snaps/f7Popup/popup-app-003_.png index 785c48c9..8ce553e3 100644 Binary files a/tests/testthat/_snaps/f7Popup/popup-app-003_.png and b/tests/testthat/_snaps/f7Popup/popup-app-003_.png differ diff --git a/tests/testthat/_snaps/f7Popup/popup-app-004.json b/tests/testthat/_snaps/f7Popup/popup-app-004.json new file mode 100644 index 00000000..f328540c --- /dev/null +++ b/tests/testthat/_snaps/f7Popup/popup-app-004.json @@ -0,0 +1,5 @@ +{ + "input": { + "popup2": true + } +} diff --git a/tests/testthat/_snaps/f7Popup/popup-app-004_.png b/tests/testthat/_snaps/f7Popup/popup-app-004_.png new file mode 100644 index 00000000..ec2a9190 Binary files /dev/null and b/tests/testthat/_snaps/f7Popup/popup-app-004_.png differ diff --git a/tests/testthat/_snaps/f7Popup/popup-app-005.json b/tests/testthat/_snaps/f7Popup/popup-app-005.json new file mode 100644 index 00000000..fc58e37e --- /dev/null +++ b/tests/testthat/_snaps/f7Popup/popup-app-005.json @@ -0,0 +1,9 @@ +{ + "input": { + "popup2": true, + "text2": "balbla" + }, + "output": { + "res2": "[1] \"balbla\"" + } +} diff --git a/tests/testthat/_snaps/f7Popup/popup-app-005_.png b/tests/testthat/_snaps/f7Popup/popup-app-005_.png new file mode 100644 index 00000000..3bda6537 Binary files /dev/null and b/tests/testthat/_snaps/f7Popup/popup-app-005_.png differ diff --git a/tests/testthat/_snaps/f7Popup/popup-app-006.json b/tests/testthat/_snaps/f7Popup/popup-app-006.json new file mode 100644 index 00000000..e1df2e19 --- /dev/null +++ b/tests/testthat/_snaps/f7Popup/popup-app-006.json @@ -0,0 +1,5 @@ +{ + "input": { + "popup2": false + } +} diff --git a/tests/testthat/_snaps/f7Popup/popup-app-006_.png b/tests/testthat/_snaps/f7Popup/popup-app-006_.png new file mode 100644 index 00000000..f2238e47 Binary files /dev/null and b/tests/testthat/_snaps/f7Popup/popup-app-006_.png differ diff --git a/tests/testthat/test-f7Popup.R b/tests/testthat/test-f7Popup.R index 42ee2815..d9e87873 100644 --- a/tests/testthat/test-f7Popup.R +++ b/tests/testthat/test-f7Popup.R @@ -10,19 +10,34 @@ test_that("popup works", { ) # Open - app$click(select = "#toggle") + app$click(select = "#toggle1") app$wait_for_idle(3000) - app$expect_values(input = "popup") + app$expect_values(input = "popup1") # Inputs work in a popup - app$set_inputs("text" = "balbla") + app$set_inputs("text1" = "balbla") app$wait_for_idle(1000) - app$expect_values(input = c("popup", "text"), output = "res") + app$expect_values(input = c("popup1", "text1"), output = "res1") # Close app$click(select = ".popup-close") app$wait_for_idle(1000) - app$expect_values(input = "popup") + app$expect_values(input = "popup1") + + # Open + app$click(select = "#toggle2") + app$wait_for_idle(3000) + app$expect_values(input = "popup2") + + # Inputs work in a popup + app$set_inputs("text2" = "balbla") + app$wait_for_idle(1000) + app$expect_values(input = c("popup2", "text2"), output = "res2") + + # Close + app$click(select = ".popup-close") + app$wait_for_idle(1000) + app$expect_values(input = "popup2") }) test_that("Popup R function work", { @@ -49,4 +64,24 @@ test_that("Popup R function work", { expect_length(res, 2) expect_equal(res$type, "popup") expect_identical(res$message$id, "popup") + expect_equal(grepl("page-content", res$message$content), FALSE) + + + f7Popup( + id = "popup", + title = "My first popup", + page = TRUE, + f7Text( + "text", "Popup content", + "This is my first popup ever, I swear!" + ), + shiny::verbatimTextOutput("res"), + session = session + ) + + res <- session$lastCustomMessage + res$message <- jsonlite::fromJSON(res$message) + expect_length(res, 2) + expect_equal(grepl("page-content", res$message$content), TRUE) + })