From f5fcc71a6348066f12152918e2f12de7393ed5b3 Mon Sep 17 00:00:00 2001 From: DivadNojnarg Date: Sun, 14 Apr 2024 00:24:59 +0200 Subject: [PATCH] add f7MultiLayout, change toolbar position default --- NAMESPACE | 2 + NEWS.md | 7 +- R/f7Navbar.R | 4 +- R/f7Page.R | 114 +++++++++++++++++++++----------- R/f7Toolbar.R | 2 +- inst/examples/router/app.r | 43 +++++++----- man/f7DefaultOptions.Rd | 15 +++++ man/f7MultiLayout.Rd | 80 ++++++++++++++++++++++ man/f7Page.Rd | 18 +---- man/f7Toolbar.Rd | 2 +- man/navbar.Rd | 4 +- tests/testthat/test-f7Toolbar.R | 4 +- 12 files changed, 212 insertions(+), 83 deletions(-) create mode 100644 man/f7DefaultOptions.Rd create mode 100644 man/f7MultiLayout.Rd diff --git a/NAMESPACE b/NAMESPACE index b384d4b6..a15c8a9b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,6 +25,7 @@ export(f7Chip) export(f7Col) export(f7ColorPicker) export(f7DatePicker) +export(f7DefaultOptions) export(f7Dialog) export(f7DownloadButton) export(f7ExpandableCard) @@ -60,6 +61,7 @@ export(f7MenuItem) export(f7Message) export(f7MessageBar) export(f7Messages) +export(f7MultiLayout) export(f7Navbar) export(f7Next) export(f7NotFound) diff --git a/NEWS.md b/NEWS.md index 557ed9aa..d27acd6d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,7 @@ # shinyMobile 2.0.0 ## Major change - Update Framework7 from 5.7.14 to 8.3.2 -- New experimental router layout: supported by {brochure}, this allows to have beautiful transitions between pages as more native like experience. +- New experimental router layout `f7MultiLayout()`: supported by `{brochure}`, this allows to have beautiful transitions between pages to provide a more native like experience. - New `f7Form()`: gather inputs in the same form to get a nested list containing all input values. This allows to reduce the number of inputs on the server side. `updateF7Form()` makes it possible to update input in batch or only selected ones. - Whenever you have multiple inputs, we now recommend to wrap all of them within `f7List()` which allows you to benefit from new styling options such as outline, inset, strong, ... Internally, we use a function able to detect whether the input is inside a `f7List()`: if yes, you can style this list by passing parameters like `f7List(outline = TRUE, inset = TRUE, ...)`; if not, the input is internally wrapped in a list to have correct rendering (but no styling is possible). Besides, some input like `f7Text()` can have custom styling (add an icon, clear button, outline style), which is independent from the external list wrapper style. Hence, we don't recommend doing `f7List(outline = TRUE, f7Text(outline = TRUE))` since it won't render very well (only use `f7List(outline = TRUE, f7Text())`). Please have a look at the corresponding examples in the documentation. @@ -21,6 +21,7 @@ - `f7Icon()`: remove deprecated parameter `old`. - `f7SmartSelect()`: `maxlength` becomes `maxLength`. Typo from Framework7. - Remove `value` from `f7Password()` (accidental copy and paste from `f7Text()`). +- Possible breaking change: `f7Toolbar()` default position is now `bottom`. ## Soft deprecation - `f7Accordion()`: @@ -78,10 +79,10 @@ Also, `f7Radio()` inherits from `f7List()` styling parameters such as `inset`, ` - `f7SplitLayout()` has a new look and at a minimal app width (1024 px) the sidebar becomes always visible. The sidebar will be collapsed on smaller screens. - `f7Text()`, `f7TextArea()` and `f7Password()` have new parameters: `description`, `media`, `floating`, `outline` and `cleareable` for more styling options. `label` can also be NULL. - `f7Select()` has new `description`, `media` and `outline` parameters. -- `f7Link()` has new `routable` parameter which allows to use the new experimental router layout. +- `f7Link()` has new `routable` parameter which allows to use the new experimental router layout in `f7MultiLayout()`. - `f7Navbar()`: both `leftPanel` and `rightPanel` now accept shiny tag such as an icon or link. This is useful to support the new router layout. -- `f7Page()`: new `allowRouter` parameter which allows to use the new experimental router layout. +- New `f7DefaultOptions()`: can be used in `f7Page()` to pass app options. - Fix various issues in documentation. # shinyMobile 1.0.1 diff --git a/R/f7Navbar.R b/R/f7Navbar.R index 07471d38..b96173b1 100644 --- a/R/f7Navbar.R +++ b/R/f7Navbar.R @@ -18,10 +18,10 @@ #' Only works if bigger is TRUE. #' @param leftPanel Whether to enable the left panel. FALSE by default. #' You can also pass a shiny tag such as an icon or text. This is useful -#' when using the yet experimental routable API. +#' when using the yet experimental routable API with \link{f7MultiLayout}. #' @param rightPanel Whether to enable the right panel. FALSE by default. #' You can also pass a shiny tag such as an icon or text. This is useful -#' when using the yet experimental routable API. +#' when using the yet experimental routable API with \link{f7MultiLayout}. #' #' @note Currently, bigger parameters does mess with the CSS. #' diff --git a/R/f7Page.R b/R/f7Page.R index fd56ef91..c9c8b64f 100644 --- a/R/f7Page.R +++ b/R/f7Page.R @@ -5,7 +5,8 @@ #' @param ... Slot for shinyMobile skeleton elements: \link{f7SingleLayout}, #' \link{f7TabLayout}, \link{f7SplitLayout}. #' @param title Page title. -#' @param options shinyMobile configuration. See \url{https://framework7.io/docs/app.html}. Below are the most +#' @param options shinyMobile configuration. See \link{f7DefaultOptions} and +#' \url{https://framework7.io/docs/app.html}. Below are the most #' notable options. General options: #' \itemize{ #' \item \code{theme}: App skin: "ios", "md", or "auto". @@ -51,7 +52,6 @@ #' In any case, you must follow the same structure as provided in the function arguments. #' #' @param allowPWA Whether to include PWA dependencies. Default to FALSE. -#' @param allowRouter Experimental router support. See vignette. #' #' @author David Granjon, \email{dgranjon@@ymail.com} #' @@ -60,33 +60,8 @@ f7Page <- function( ..., title = NULL, # default options - options = list( - theme = c("auto", "ios", "md"), - dark = "auto", - skeletonsOnLoad = FALSE, - preloader = FALSE, - filled = FALSE, - color = "#007aff", - touch = list( - touchClicksDistanceThreshold = 5, - tapHold = TRUE, - tapHoldDelay = 750, - tapHoldPreventClicks = TRUE, - iosTouchRipple = FALSE, - mdTouchRipple = TRUE - ), - iosTranslucentBars = FALSE, - navbar = list( - iosCenterTitle = TRUE, - hideOnPageScroll = TRUE - ), - toolbar = list( - hideOnPageScroll = FALSE - ), - pullToRefresh = FALSE - ), - allowPWA = FALSE, - allowRouter = FALSE) { + options = f7DefaultOptions(), + allowPWA = FALSE) { # Color must be converted to HEX before going to JavaScript if (!is.null(options$color)) { # If color is a name @@ -145,16 +120,6 @@ f7Page <- function( } })) - if (allowRouter) { - items <- tags$div( - class = "view view-main view-init", - `data-url` = "/", - # Important: to be able to have updated url - `data-browser-history` = "true", - items - ) - } - bodyTag <- shiny::tags$body( `data-pwa` = tolower(allowPWA), `data-ptr` = dataPTR, @@ -200,6 +165,77 @@ f7Page <- function( ) } +#' shinyMobile app default options +#' +#' List of default custom options. +#' +#' @export +#' @return A list of options to pass in +#' \link{f7Page}. +f7DefaultOptions <- function() { + list( + theme = c("auto", "ios", "md"), + dark = "auto", + skeletonsOnLoad = FALSE, + preloader = FALSE, + filled = FALSE, + color = "#007aff", + touch = list( + touchClicksDistanceThreshold = 5, + tapHold = TRUE, + tapHoldDelay = 750, + tapHoldPreventClicks = TRUE, + iosTouchRipple = FALSE, + mdTouchRipple = TRUE + ), + iosTranslucentBars = FALSE, + navbar = list( + iosCenterTitle = TRUE, + hideOnPageScroll = TRUE + ), + toolbar = list( + hideOnPageScroll = FALSE + ), + pullToRefresh = FALSE + ) +} + +#' Framework7 multi pages layout +#' +#' r lifecycle::badge("experimental")` +#' Experimental multi pages layout. This has to be used +#' with the brochure R package. See the corresponding vignette at +#' \code{vignette("multipages", package = "shinyMobile")}. +#' +#' @param ... Pages. Must be an element like +#' \code{shiny::tags$div(class = "page", ...)} +#' @param toolbar Contrary to \link{f7SingleLayout} or any other layout, +#' the multi page layout can have a common toolbar for all pages. +#' See more at \url{https://framework7.io/docs/toolbar-tabbar#common-toolbar}. +#' You can pass \link{f7Toolbar} in this slot or \link{f7Tabs} but if you +#' do so, don't pass any toolbar in the different pages elements. +#' @inheritParams f7Page +#' +#' @export +f7MultiLayout <- function( + ..., + toolbar = NULL, + title = NULL, + options = f7DefaultOptions(), + allowPWA = FALSE) { + items <- shiny::tags$div( + class = "view view-main view-init", + `data-url` = "/", + # Important: to be able to have updated url + `data-browser-history` = "true", + # Optional common toolbar + toolbar, + ... + ) + + f7Page(items, title = title, options = options, allowPWA = allowPWA) +} + #' Framework7 single layout #' #' \code{f7SingleLayout} provides a simple page layout. diff --git a/R/f7Toolbar.R b/R/f7Toolbar.R index 682afc4a..43f5be99 100644 --- a/R/f7Toolbar.R +++ b/R/f7Toolbar.R @@ -19,7 +19,7 @@ #' @author David Granjon, \email{dgranjon@@ymail.com} #' #' @export -f7Toolbar <- function(..., position = c("top", "bottom"), hairline = deprecated(), shadow = deprecated(), +f7Toolbar <- function(..., position = c("bottom", "top"), hairline = deprecated(), shadow = deprecated(), icons = FALSE, scrollable = FALSE) { if (lifecycle::is_present(hairline)) { lifecycle::deprecate_warn( diff --git a/inst/examples/router/app.r b/inst/examples/router/app.r index 11da3947..9380badb 100644 --- a/inst/examples/router/app.r +++ b/inst/examples/router/app.r @@ -89,14 +89,16 @@ page_2 <- function() { ) ) ), - f7Toolbar( - position = "bottom", - tags$a( - href = "/", - "Main page", - class = "link" - ) - ), + # NOTE: when the main toolbar is enabled in + # f7MultiLayout, we can't use individual page toolbars. + # f7Toolbar( + # position = "bottom", + # tags$a( + # href = "/", + # "Main page", + # class = "link" + # ) + # ), shiny::tags$div( class = "page-content", f7Block( strong = TRUE, @@ -150,14 +152,16 @@ page_3 <- function() { ) ) ), - f7Toolbar( - position = "bottom", - tags$a( - href = "/2", - "Second page", - class = "link" - ) - ), + # NOTE: when the main toolbar is enabled in + # f7MultiLayout, we can't use individual page toolbars. + # f7Toolbar( + # position = "bottom", + # tags$a( + # href = "/2", + # "Second page", + # class = "link" + # ) + # ), shiny::tags$div( class = "page-content", f7Block("Nothing to show yet ...") @@ -172,9 +176,12 @@ brochureApp( page_1(), page_2(), page_3(), - wrapped = f7Page, + wrapped = f7MultiLayout, wrapped_options = list( - allowRouter = TRUE, + # Common toolbar + toolbar = f7Toolbar( + f7Link(icon = f7Icon("house"), href = "/", routable = TRUE) + ), options = list( dark = TRUE, # Note: ios seems to have issue diff --git a/man/f7DefaultOptions.Rd b/man/f7DefaultOptions.Rd new file mode 100644 index 00000000..282ad314 --- /dev/null +++ b/man/f7DefaultOptions.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/f7Page.R +\name{f7DefaultOptions} +\alias{f7DefaultOptions} +\title{shinyMobile app default options} +\usage{ +f7DefaultOptions() +} +\value{ +A list of options to pass in +\link{f7Page}. +} +\description{ +List of default custom options. +} diff --git a/man/f7MultiLayout.Rd b/man/f7MultiLayout.Rd new file mode 100644 index 00000000..f4bdc7e7 --- /dev/null +++ b/man/f7MultiLayout.Rd @@ -0,0 +1,80 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/f7Page.R +\name{f7MultiLayout} +\alias{f7MultiLayout} +\title{Framework7 multi pages layout} +\usage{ +f7MultiLayout( + ..., + toolbar = NULL, + title = NULL, + options = f7DefaultOptions(), + allowPWA = FALSE +) +} +\arguments{ +\item{...}{Pages. Must be an element like +\code{shiny::tags$div(class = "page", ...)}} + +\item{toolbar}{Contrary to \link{f7SingleLayout} or any other layout, +the multi page layout can have a common toolbar for all pages. +See more at \url{https://framework7.io/docs/toolbar-tabbar#common-toolbar}. +You can pass \link{f7Toolbar} in this slot or \link{f7Tabs} but if you +do so, don't pass any toolbar in the different pages elements.} + +\item{title}{Page title.} + +\item{options}{shinyMobile configuration. See \link{f7DefaultOptions} and +\url{https://framework7.io/docs/app.html}. Below are the most +notable options. General options: +\itemize{ +\item \code{theme}: App skin: "ios", "md", or "auto". +\item \code{dark}: Dark layout. TRUE, FALSE, or "auto". The default is "auto". +If set to "auto" automatically enables dark theme based on user system color scheme preference. +\item \code{skeletonsOnLoad}: Whether to display skeletons on load. +This is a preloading effect. Not compatible with preloader. +\item \code{preloader}: Loading spinner. Not compatible with skeletonsOnLoad. +\item \code{filled}: Whether to fill the \link{f7Navbar} and \link{f7Toolbar} with +the current selected color. FALSE by default. +\item \code{color}: Color theme: See \url{https://framework7.io/docs/color-themes.html}. +Expect a name like blue, red or hex code like \verb{#FF0000}. If NULL, use the default color. +If a name is specified it must be accepted either by \link[gplots]{col2hex} or +\link{getF7Colors} (valid Framework 7 color names). +\item \code{pullToRefresh}: Whether to active the pull to refresh feature. Default to FALSE. +See \url{https://framework7.io/docs/pull-to-refresh#examples}. +\item \code{iosTranslucentBars}: Enable translucent effect (blur background) on navigation bars for iOS theme (on iOS devices). +FALSE by default. +} +Touch module options \url{https://framework7.io/docs/app#param-touch}: +\itemize{ +\item \code{touchClicksDistanceThreshold}: Distance threshold (in px) to prevent short swipes. +So if tap/move distance is larger than this value then "click" will not be triggered. +\item \code{tapHold}: It triggers (if enabled) after a sustained, complete touch event. +By default it is enabled. See \link{f7TapHold} for usage. +\item \code{tapHoldDelay}: Determines how long (in ms) the user must hold their tap before the taphold event is fired on the target element. +Default to 750 ms. +\item \code{tapHoldPreventClicks}: When enabled (by default), then click event will not be fired after tap hold event. +\item \code{iosTouchRipple}: Default to FALSE. Enables touch ripple effect for iOS theme. +\item \code{mdTouchRipple}: Default to TRUE. Enables touch ripple effect for MD theme. +} +Navbar options \url{https://framework7.io/docs/navbar#navbar-app-parameters}: +\itemize{ +\item \code{iosCenterTitle}: Default to TRUE. When enabled then it will try to position +title at the center in iOS theme. Sometime (with some custom design) it may not needed. +\item \code{hideOnPageScroll}: Default to FALSE. Will hide Navbars on page scroll. +} +Toolbar options \url{https://framework7.io/docs/toolbar-tabbar#toolbar-app-parameters}: +\itemize{ +\item \code{hideOnPageScroll}: Default to FALSE. Will hide tabs on page scroll. +} + +In any case, you must follow the same structure as provided in the function arguments.} + +\item{allowPWA}{Whether to include PWA dependencies. Default to FALSE.} +} +\description{ +r lifecycle::badge("experimental")` +Experimental multi pages layout. This has to be used +with the brochure R package. See the corresponding vignette at +\code{vignette("multipages", package = "shinyMobile")}. +} diff --git a/man/f7Page.Rd b/man/f7Page.Rd index 1b040aee..b32beef0 100644 --- a/man/f7Page.Rd +++ b/man/f7Page.Rd @@ -4,18 +4,7 @@ \alias{f7Page} \title{Framework7 page container} \usage{ -f7Page( - ..., - title = NULL, - options = list(theme = c("auto", "ios", "md"), dark = "auto", skeletonsOnLoad = FALSE, - preloader = FALSE, filled = FALSE, color = "#007aff", touch = - list(touchClicksDistanceThreshold = 5, tapHold = TRUE, tapHoldDelay = 750, - tapHoldPreventClicks = TRUE, iosTouchRipple = FALSE, mdTouchRipple = TRUE), - iosTranslucentBars = FALSE, navbar = list(iosCenterTitle = TRUE, hideOnPageScroll = - TRUE), toolbar = list(hideOnPageScroll = FALSE), pullToRefresh = FALSE), - allowPWA = FALSE, - allowRouter = FALSE -) +f7Page(..., title = NULL, options = f7DefaultOptions(), allowPWA = FALSE) } \arguments{ \item{...}{Slot for shinyMobile skeleton elements: \link{f7SingleLayout}, @@ -23,7 +12,8 @@ f7Page( \item{title}{Page title.} -\item{options}{shinyMobile configuration. See \url{https://framework7.io/docs/app.html}. Below are the most +\item{options}{shinyMobile configuration. See \link{f7DefaultOptions} and +\url{https://framework7.io/docs/app.html}. Below are the most notable options. General options: \itemize{ \item \code{theme}: App skin: "ios", "md", or "auto". @@ -69,8 +59,6 @@ Toolbar options \url{https://framework7.io/docs/toolbar-tabbar#toolbar-app-param In any case, you must follow the same structure as provided in the function arguments.} \item{allowPWA}{Whether to include PWA dependencies. Default to FALSE.} - -\item{allowRouter}{Experimental router support. See vignette.} } \description{ \code{f7Page} is the main app container. diff --git a/man/f7Toolbar.Rd b/man/f7Toolbar.Rd index 2eacd471..ec021386 100644 --- a/man/f7Toolbar.Rd +++ b/man/f7Toolbar.Rd @@ -6,7 +6,7 @@ \usage{ f7Toolbar( ..., - position = c("top", "bottom"), + position = c("bottom", "top"), hairline = deprecated(), shadow = deprecated(), icons = FALSE, diff --git a/man/navbar.Rd b/man/navbar.Rd index d81b929a..12a30adb 100644 --- a/man/navbar.Rd +++ b/man/navbar.Rd @@ -48,11 +48,11 @@ Only works if bigger is TRUE.} \item{leftPanel}{Whether to enable the left panel. FALSE by default. You can also pass a shiny tag such as an icon or text. This is useful -when using the yet experimental routable API.} +when using the yet experimental routable API with \link{f7MultiLayout}.} \item{rightPanel}{Whether to enable the right panel. FALSE by default. You can also pass a shiny tag such as an icon or text. This is useful -when using the yet experimental routable API.} +when using the yet experimental routable API with \link{f7MultiLayout}.} \item{animate}{Whether it should be hidden with animation or not. By default is TRUE.} diff --git a/tests/testthat/test-f7Toolbar.R b/tests/testthat/test-f7Toolbar.R index f1aaa717..ca952c07 100644 --- a/tests/testthat/test-f7Toolbar.R +++ b/tests/testthat/test-f7Toolbar.R @@ -1,5 +1,5 @@ test_that("toolbar works", { - expect_s3_class(f7Toolbar(position = "top"), "shiny.tag") + expect_s3_class(f7Toolbar(), "shiny.tag") expect_identical(f7Toolbar(position = "top")$attribs$class, "toolbar toolbar-top") - expect_identical(f7Toolbar(icons = TRUE, position = "top")$attribs$class, "toolbar tabbar tabbar-icons toolbar-top") + expect_identical(f7Toolbar(icons = TRUE)$attribs$class, "toolbar tabbar tabbar-icons toolbar-bottom") })