├── .Rbuildignore ├── .gitignore ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── R ├── dependencies.R ├── shiny.R └── widget.R ├── README.md ├── inst ├── examples │ ├── examples_shiny.R │ └── starter.R └── htmlwidgets │ ├── office-ui-fabric-react │ └── office-ui-fabric-react.js │ └── officeuiwidget.js ├── man ├── officeuiwidget-shiny.Rd ├── officeuiwidget.Rd └── roffice_deps.Rd └── roffice.Rproj /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^roffice\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^CODE_OF_CONDUCT\.md$ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http://contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: roffice 2 | Version: 0.0.0.9000 3 | Date: 2018-12-30 4 | Title: 'office-ui-fabric-react' Wrapped as a 'htmlwidget' 5 | Description: Demonstrates how to use the new helper functionality in 'reactR' to inject the world 6 | of office-ui-fabric-react components into the R experience. 7 | Authors@R: person("Kenton", "Russell", , "kent.russell@timelyportfolio.com", c("aut", "cre")) 8 | License: MIT + file LICENSE 9 | Encoding: UTF-8 10 | URL: https://github.com/react-R/roffice 11 | BugReports: https://github.com/react-R/roffice/issues 12 | LazyData: true 13 | ByteCompile: true 14 | RoxygenNote: 6.0.1 15 | Imports: 16 | htmltools, 17 | htmlwidgets, 18 | reactR 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: Kenton Russell 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(officeuiwidget) 4 | export(officeuiwidgetOutput) 5 | export(renderOfficeuiwidget) 6 | export(roffice_deps) 7 | import(htmlwidgets) 8 | -------------------------------------------------------------------------------- /R/dependencies.R: -------------------------------------------------------------------------------- 1 | #' Dependencies for "office-ui-fabric-react" 2 | #' 3 | #' @return htmltools::htmlDependency 4 | #' @export 5 | roffice_deps <- function() { 6 | htmltools::htmlDependency( 7 | name = "office-ui-fabric-react", 8 | version = "6.118.0", 9 | src = "htmlwidgets/office-ui-fabric-react", 10 | script = "office-ui-fabric-react.js", 11 | package = "roffice" 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /R/shiny.R: -------------------------------------------------------------------------------- 1 | #' Shiny bindings for officeuiwidget 2 | #' 3 | #' Output and render functions for using officeuiwidget within Shiny 4 | #' applications and interactive Rmd documents. 5 | #' 6 | #' @param outputId output variable to read from 7 | #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, 8 | #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 9 | #' string and have \code{'px'} appended. 10 | #' @param expr An expression that generates a officeuiwidget 11 | #' @param env The environment in which to evaluate \code{expr}. 12 | #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This 13 | #' is useful if you want to save an expression in a variable. 14 | #' 15 | #' @name officeuiwidget-shiny 16 | #' 17 | #' @export 18 | officeuiwidgetOutput <- function(outputId, width = '100%', height = '400px'){ 19 | htmlwidgets::shinyWidgetOutput(outputId, 'officeuiwidget', width, height, package = 'roffice') 20 | } 21 | 22 | #' @rdname officeuiwidget-shiny 23 | #' @export 24 | renderOfficeuiwidget <- function(expr, env = parent.frame(), quoted = FALSE) { 25 | if (!quoted) { expr <- substitute(expr) } # force quoted 26 | htmlwidgets::shinyRenderWidget(expr, officeuiwidgetOutput, env, quoted = TRUE) 27 | } 28 | -------------------------------------------------------------------------------- /R/widget.R: -------------------------------------------------------------------------------- 1 | #' 2 | #' 3 | #' 4 | #' 5 | #' @import htmlwidgets 6 | #' 7 | #' @export 8 | officeuiwidget <- function(...) { 9 | htmlwidgets::createWidget( 10 | name = 'officeuiwidget', 11 | list(tag = reactR::component("Fragment", c(list(...)))), 12 | width = NULL, 13 | height = NULL, 14 | package = 'roffice', 15 | elementId = NULL 16 | ) 17 | } 18 | 19 | # Magical 20 | officeuiwidget_html <- function(id, style, class, ...) { 21 | htmltools::tagList( 22 | reactR::html_dependency_corejs(), 23 | reactR::html_dependency_react(), 24 | reactR::html_dependency_reacttools(), 25 | roffice_deps(), 26 | htmltools::tags$div(id = id, class = class) 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Experimental and For Demonstration Purposes Only 2 | 3 | # roffice 4 | 5 | `roffice` is a package designed to demonstrate the new functionality included in [`reactR`](https://github.com/react-R/reactR) to leverage [`React`](https://reactjs.org/) and its diverse array of components as `htmlwidgets` in R. 6 | 7 | > Alan Dipert session at [rstudio::conf](http://www.cvent.com/events/rstudio-conf-austin/agenda-dd6d75526f3c4554b67c4de32aeffb47.aspx) 8 | 9 | In `roffice` we illustrate some alternate techniques for building an `htmlwidget` around the extensive set of components from the Microsoft [Fabric](https://developer.microsoft.com/en-us/fabric) project. Instead of using a `yarn` build with JavaScript modules, we use the `umd` build of Fabric. Many React libraries do not offer a standalone build. If the component or component set does provide a standalone build, then we can avoid the potentially difficult JavaScript/npm/yarn steps, and directly use only a couple of lines of JavaScript (see [officeuiwidget](https://github.com/react-R/roffice/blob/master/inst/htmlwidgets/officeuiwidget.js)). 10 | 11 | ``` 12 | // trick to include React Fragment component 13 | // which is like an empty container 14 | Fabric.Fragment = React.Fragment; 15 | 16 | // office-ui-fabric namespaces all the components with Fabric 17 | reactR.reactWidget('officeuiwidget', 'output', Fabric); 18 | ``` 19 | 20 | ## Installation 21 | 22 | You can install the released version of `roffice` from Github. We will also need to install the `enhancements` branch of `reactR`. 23 | 24 | ``` r 25 | devtools::install_github("react-R/reactR@enhancements") 26 | devtools::install_github("react-R/roffice") 27 | ``` 28 | 29 | ## Examples 30 | 31 | There are multiple examples [here](https://github.com/react-R/roffice/tree/master/inst/examples), but for the sake of including some code in this Readme. 32 | 33 | ### slider 34 | 35 | ``` r 36 | #devtools::install_github("react-R/reactR@enhancements") 37 | #devtools::install_github("react-R/roffice") 38 | 39 | library(reactR) 40 | library(roffice) 41 | 42 | # slider with just one prop 43 | officeuiwidget( 44 | reactR::React$Slider(label = "Basic Slider") 45 | # alternately 46 | # component("Slider", varArgs = list(label = "Basic Slider")) 47 | ) 48 | 49 | # slider with more props and a combination 50 | officeuiwidget( 51 | reactR::React$Slider(label = "Basic Slider"), 52 | reactR::React$Slider( 53 | label = "slider with props", 54 | min = 1, 55 | max = 5, 56 | step = 1, 57 | defaultValue = 2, 58 | showValue = TRUE 59 | ) 60 | ) 61 | ``` 62 | 63 | ### checkbox 64 | 65 | ``` 66 | # https://developer.microsoft.com/en-us/fabric#/components/toggle 67 | # 73 | officeuiwidget( 74 | reactR::React$Toggle( 75 | defaultChecked = TRUE, 76 | label = "Enabled and checked", 77 | onText = "On", 78 | offText = "Off" 79 | ) 80 | ) 81 | ``` 82 | 83 | ### colorpicker 84 | 85 | ``` 86 | # https://developer.microsoft.com/en-us/fabric#/components/colorpicker 87 | officeuiwidget( 88 | reactR::React$ColorPicker(color = "#ffffff") 89 | ) 90 | ``` 91 | 92 | ### datepicker 93 | 94 | ``` 95 | # https://developer.microsoft.com/en-us/fabric#/components/datepicker 96 | officeuiwidget( 97 | reactR::React$DatePicker() 98 | ) 99 | 100 | ``` 101 | 102 | ## Code of Conduct 103 | 104 | We would love help, comments, feedback, and other contributions, but please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. Violations, meanness, and any other behavior that is not inclusive and welcoming will not be tolerated. 105 | -------------------------------------------------------------------------------- /inst/examples/examples_shiny.R: -------------------------------------------------------------------------------- 1 | # currently Shiny communication is in progress so this code will not work as of now 2 | 3 | #devtools::install_github("react-R/reactR@enhancements") 4 | #devtools::install_github("react-R/roffice") 5 | 6 | library(reactR) 7 | library(roffice) 8 | library(shiny) 9 | 10 | #options(shiny.trace = TRUE) 11 | ui <- officeuiwidgetOutput("me") 12 | 13 | server <- function(input, output, session) { 14 | # slider with just one prop and some Shiny 15 | output$me <- renderOfficeuiwidget({ 16 | officeuiwidget( 17 | reactR::React$Slider(label = "Basic Slider", shinyEvent = "onChange") 18 | ) 19 | }) 20 | } 21 | 22 | shinyApp(ui, server) 23 | 24 | 25 | uiColor <- htmltools::tagList( 26 | officeuiwidgetOutput("mycolor"), 27 | plotOutput("rplot", height=400, width=400) 28 | ) 29 | serverColor <- function(input, output, session) { 30 | output$mycolor <- renderOfficeuiwidget({ 31 | # https://developer.microsoft.com/en-us/fabric#/components/colorpicker 32 | officeuiwidget( 33 | # using id prop 34 | reactR::React$ColorPicker(id = "colorpicker", color = "#ffffff", shinyEvent = "onColorChanged") 35 | ) 36 | }) 37 | 38 | output$rplot <- renderPlot({ 39 | color <- input$mycolor_colorpicker_onColorChanged 40 | plot(1:10, col=color, pch=16) 41 | }) 42 | } 43 | shinyApp(uiColor, serverColor) 44 | -------------------------------------------------------------------------------- /inst/examples/starter.R: -------------------------------------------------------------------------------- 1 | #devtools::install_github("react-R/reactR@enhancements") 2 | #devtools::install_github("react-R/roffice") 3 | 4 | library(reactR) 5 | library(roffice) 6 | 7 | # slider with just one prop 8 | officeuiwidget( 9 | reactR::React$Slider(label = "Basic Slider") 10 | # alternately 11 | # component("Slider", varArgs = list(label = "Basic Slider")) 12 | ) 13 | 14 | # slider with more props and a combination 15 | officeuiwidget( 16 | reactR::React$Slider(label = "Basic Slider"), 17 | reactR::React$Slider( 18 | label = "slider with props", 19 | min = 1, 20 | max = 5, 21 | step = 1, 22 | defaultValue = 2, 23 | showValue = TRUE 24 | ) 25 | ) 26 | 27 | # https://developer.microsoft.com/en-us/fabric#/components/toggle 28 | # 34 | officeuiwidget( 35 | reactR::React$Toggle( 36 | defaultChecked = TRUE, 37 | label = "Enabled and checked", 38 | onText = "On", 39 | offText = "Off" 40 | ) 41 | ) 42 | 43 | # https://developer.microsoft.com/en-us/fabric#/components/colorpicker 44 | officeuiwidget( 45 | reactR::React$ColorPicker(color = "#ffffff") 46 | ) 47 | 48 | 49 | # https://developer.microsoft.com/en-us/fabric#/components/datepicker 50 | officeuiwidget( 51 | reactR::React$DatePicker() 52 | ) 53 | -------------------------------------------------------------------------------- /inst/htmlwidgets/officeuiwidget.js: -------------------------------------------------------------------------------- 1 | // trick to include React Fragment component 2 | // which is like an empty container 3 | Fabric.Fragment = React.Fragment; 4 | 5 | // office-ui-fabric namespaces all the components with Fabric 6 | reactR.reactWidget('officeuiwidget', 'output', Fabric); 7 | -------------------------------------------------------------------------------- /man/officeuiwidget-shiny.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shiny.R 3 | \name{officeuiwidget-shiny} 4 | \alias{officeuiwidget-shiny} 5 | \alias{officeuiwidgetOutput} 6 | \alias{renderOfficeuiwidget} 7 | \title{Shiny bindings for officeuiwidget} 8 | \usage{ 9 | officeuiwidgetOutput(outputId, width = "100\%", height = "400px") 10 | 11 | renderOfficeuiwidget(expr, env = parent.frame(), quoted = FALSE) 12 | } 13 | \arguments{ 14 | \item{outputId}{output variable to read from} 15 | 16 | \item{width, height}{Must be a valid CSS unit (like \code{'100\%'}, 17 | \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a 18 | string and have \code{'px'} appended.} 19 | 20 | \item{expr}{An expression that generates a officeuiwidget} 21 | 22 | \item{env}{The environment in which to evaluate \code{expr}.} 23 | 24 | \item{quoted}{Is \code{expr} a quoted expression (with \code{quote()})? This 25 | is useful if you want to save an expression in a variable.} 26 | } 27 | \description{ 28 | Output and render functions for using officeuiwidget within Shiny 29 | applications and interactive Rmd documents. 30 | } 31 | -------------------------------------------------------------------------------- /man/officeuiwidget.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/widget.R 3 | \name{officeuiwidget} 4 | \alias{officeuiwidget} 5 | \title{} 6 | \usage{ 7 | officeuiwidget(...) 8 | } 9 | \description{ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /man/roffice_deps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dependencies.R 3 | \name{roffice_deps} 4 | \alias{roffice_deps} 5 | \title{Dependencies for "office-ui-fabric-react"} 6 | \usage{ 7 | roffice_deps() 8 | } 9 | \value{ 10 | htmltools::htmlDependency 11 | } 12 | \description{ 13 | Dependencies for "office-ui-fabric-react" 14 | } 15 | -------------------------------------------------------------------------------- /roffice.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 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | --------------------------------------------------------------------------------