diff --git a/DESCRIPTION b/DESCRIPTION index b049c806..4fa512c8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -45,6 +45,7 @@ Suggests: rmarkdown, sass, shiny.router, + shinyjs, sortable, stringi, testthat (>= 3.0.0), diff --git a/R/examples.R b/R/examples.R index f618d347..1310d3f7 100644 --- a/R/examples.R +++ b/R/examples.R @@ -14,6 +14,8 @@ NULL #' @example inst/examples/Button.R #' @example inst/examples/Button2.R +#' @example inst/examples/Button3.R +#' @example inst/examples/Button4.R #' @name Button NULL diff --git a/inst/examples/Button3.R b/inst/examples/Button3.R new file mode 100644 index 00000000..87f6a060 --- /dev/null +++ b/inst/examples/Button3.R @@ -0,0 +1,54 @@ + +# Example 3 +library(shiny) +library(shiny.fluent) +library(shinyjs) + +# This example app shows how to use a Fluent UI Button to trigger a file upload. +# File upload is not natively supported by shiny.fluent so shinyjs is used +# to trigger the file upload input. +ui <- function(id) { + ns <- NS(id) + fluentPage( + useShinyjs(), + Stack( + tokens = list( + childrenGap = 10L + ), + horizontal = TRUE, + DefaultButton.shinyInput( + inputId = ns("uploadFileButton"), + text = "Upload File", + iconProps = list(iconName = "Upload") + ), + div( + style = " + visibility: hidden; + height: 0; + width: 0; + ", + fileInput( + inputId = ns("uploadFile"), + label = NULL + ) + ) + ), + textOutput(ns("file_path")) + ) +} + +server <- function(id) { + moduleServer(id, function(input, output, session) { + observeEvent(input$uploadFileButton, { + click("uploadFile") + }) + + output$file_path <- renderText({ + input$uploadFile$name + }) + }) +} + +if (interactive()) { + shinyApp(ui("app"), function(input, output) server("app")) +} diff --git a/inst/examples/Button4.R b/inst/examples/Button4.R new file mode 100644 index 00000000..0bbead06 --- /dev/null +++ b/inst/examples/Button4.R @@ -0,0 +1,45 @@ + +# Example 4 +library(shiny) +library(shiny.fluent) +library(shinyjs) + +# This example app shows how to use a Fluent UI Button to trigger a file download. +# File download is not natively supported by shiny.fluent so shinyjs is used +# to trigger the file download. +ui <- function(id) { + ns <- NS(id) + fluentPage( + useShinyjs(), + DefaultButton.shinyInput( + inputId = ns("downloadButton"), + text = "Download", + iconProps = list(iconName = "Download") + ), + div( + style = "visibility: hidden;", + downloadButton(ns("download"), label = "") + ) + ) +} + +server <- function(id) { + moduleServer(id, function(input, output, session) { + observeEvent(input$downloadButton, { + click("download") + }) + + output$download <- downloadHandler( + filename = function() { + paste("data-", Sys.Date(), ".csv", sep="") + }, + content = function(file) { + write.csv(iris, file) + } + ) + }) +} + +if (interactive()) { + shinyApp(ui("app"), function(input, output) server("app")) +} diff --git a/man/Button.Rd b/man/Button.Rd index ca2204b7..1a318837 100644 --- a/man/Button.Rd +++ b/man/Button.Rd @@ -339,6 +339,105 @@ server <- function(id) { }) } +if (interactive()) { + shinyApp(ui("app"), function(input, output) server("app")) +} + +# Example 3 +library(shiny) +library(shiny.fluent) +library(shinyjs) + +# This example app shows how to use a Fluent UI Button to trigger a file upload. +# File upload is not natively supported by shiny.fluent so shinyjs is used +# to trigger the file upload input. +ui <- function(id) { + ns <- NS(id) + fluentPage( + useShinyjs(), + Stack( + tokens = list( + childrenGap = 10L + ), + horizontal = TRUE, + DefaultButton.shinyInput( + inputId = ns("uploadFileButton"), + text = "Upload File", + iconProps = list(iconName = "Upload") + ), + div( + style = " + visibility: hidden; + height: 0; + width: 0; + ", + fileInput( + inputId = ns("uploadFile"), + label = NULL + ) + ) + ), + textOutput(ns("file_path")) + ) +} + +server <- function(id) { + moduleServer(id, function(input, output, session) { + observeEvent(input$uploadFileButton, { + click("uploadFile") + }) + + output$file_path <- renderText({ + input$uploadFile$name + }) + }) +} + +if (interactive()) { + shinyApp(ui("app"), function(input, output) server("app")) +} + +# Example 4 +library(shiny) +library(shiny.fluent) +library(shinyjs) + +# This example app shows how to use a Fluent UI Button to trigger a file download. +# File download is not natively supported by shiny.fluent so shinyjs is used +# to trigger the file download. +ui <- function(id) { + ns <- NS(id) + fluentPage( + useShinyjs(), + DefaultButton.shinyInput( + inputId = ns("downloadButton"), + text = "Download", + iconProps = list(iconName = "Download") + ), + div( + style = "visibility: hidden;", + downloadButton(ns("download"), label = "") + ) + ) +} + +server <- function(id) { + moduleServer(id, function(input, output, session) { + observeEvent(input$downloadButton, { + click("download") + }) + + output$download <- downloadHandler( + filename = function() { + paste("data-", Sys.Date(), ".csv", sep="") + }, + content = function(file) { + write.csv(iris, file) + } + ) + }) +} + if (interactive()) { shinyApp(ui("app"), function(input, output) server("app")) } diff --git a/man/DetailsList.Rd b/man/DetailsList.Rd index 61e8a6b9..79242651 100644 --- a/man/DetailsList.Rd +++ b/man/DetailsList.Rd @@ -368,7 +368,7 @@ CustomComponents <- tags$script(HTML("(function() { const React = jsmodule['react']; const Fluent = jsmodule['@fluentui/react']; const Shiny = jsmodule['@/shiny']; - const CustomComponents = jsmodule['CustomComponents'] = {}; + const CustomComponents = jsmodule['CustomComponents'] ??= {}; function useSelection(inputId) { const selection = React.useRef(new Fluent.Selection({ diff --git a/man/Slider.Rd b/man/Slider.Rd index f3b3e490..8f4663f5 100644 --- a/man/Slider.Rd +++ b/man/Slider.Rd @@ -88,7 +88,7 @@ library(shiny.fluent) ui <- function(id) { ns <- NS(id) div( - Slider.shinyInput(ns("slider"), value = 42, min = -100, max = 100), + Slider.shinyInput(ns("slider"), value = 0, min = -100, max = 100), textOutput(ns("sliderValue")) ) } diff --git a/man/TextField.Rd b/man/TextField.Rd index 317019a9..e0937d3e 100644 --- a/man/TextField.Rd +++ b/man/TextField.Rd @@ -140,7 +140,7 @@ library(shiny.fluent) CustomComponents <- tags$script(HTML("(function() { const { InputAdapter } = jsmodule['@/shiny.react']; const { TextField } = jsmodule['@fluentui/react']; - const CustomComponents = jsmodule['CustomComponents'] = {}; + const CustomComponents = jsmodule['CustomComponents'] ??= {}; CustomComponents.UpperCaseTextField = InputAdapter(TextField, (value, setValue) => ({ value: value.toUpperCase(),