Repository: react-R/reactR Branch: master Commit: 808b21f4f2e5 Files: 107 Total size: 585.6 KB Directory structure: gitextract_1rmdkxph/ ├── .Rbuildignore ├── .gitattributes ├── .github/ │ ├── .gitignore │ └── workflows/ │ └── R-CMD-check.yaml ├── .gitignore ├── CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R/ │ ├── babel.R │ ├── dependencies.R │ ├── meta.R │ ├── reacttools.R │ ├── scaffold_input.R │ ├── scaffold_utils.R │ └── scaffold_widget.R ├── README.Rmd ├── README.md ├── buildupdate/ │ └── getreact.R ├── cran-comments.md ├── docs/ │ ├── 404.html │ ├── CONDUCT.html │ ├── LICENSE-text.html │ ├── articles/ │ │ ├── index.html │ │ ├── intro_htmlwidgets.html │ │ ├── intro_htmlwidgets_files/ │ │ │ └── accessible-code-block-0.0.1/ │ │ │ └── empty-anchor.js │ │ ├── intro_inputs.html │ │ ├── intro_inputs_files/ │ │ │ └── accessible-code-block-0.0.1/ │ │ │ └── empty-anchor.js │ │ ├── intro_reactR.html │ │ └── intro_reactR_files/ │ │ ├── accessible-code-block-0.0.1/ │ │ │ └── empty-anchor.js │ │ ├── react-16.12.0/ │ │ │ ├── AUTHORS │ │ │ └── LICENSE.txt │ │ ├── react-16.7.0/ │ │ │ ├── AUTHORS │ │ │ └── LICENSE.txt │ │ ├── react-16.8.1/ │ │ │ ├── AUTHORS │ │ │ └── LICENSE.txt │ │ ├── react-16.8.6/ │ │ │ ├── AUTHORS │ │ │ └── LICENSE.txt │ │ ├── react-17.0.0/ │ │ │ ├── AUTHORS │ │ │ └── LICENSE.txt │ │ └── react-18.2.0/ │ │ ├── AUTHORS │ │ └── LICENSE.txt │ ├── authors.html │ ├── bootstrap-toc.css │ ├── bootstrap-toc.js │ ├── docsearch.css │ ├── docsearch.js │ ├── index.html │ ├── news/ │ │ └── index.html │ ├── pkgdown.css │ ├── pkgdown.js │ ├── pkgdown.yml │ ├── reference/ │ │ ├── React.html │ │ ├── babel_transform.html │ │ ├── component.html │ │ ├── createReactShinyInput.html │ │ ├── html_dependency_corejs.html │ │ ├── html_dependency_mobx.html │ │ ├── html_dependency_react.html │ │ ├── html_dependency_reacttools.html │ │ ├── index.html │ │ ├── reactMarkup.html │ │ ├── scaffoldReactShinyInput.html │ │ └── scaffoldReactWidget.html │ └── sitemap.xml ├── inst/ │ ├── examples/ │ │ ├── antd.R │ │ └── office-fabric.R │ ├── templates/ │ │ ├── input_app.R.txt │ │ ├── input_js.txt │ │ ├── input_r.txt │ │ ├── package.json.txt │ │ ├── webpack.config.js.txt │ │ ├── widget_app.R.txt │ │ ├── widget_js.txt │ │ ├── widget_r.txt │ │ └── widget_yaml.txt │ └── www/ │ ├── core-js/ │ │ ├── LICENSE │ │ └── package.json │ ├── mobx/ │ │ ├── LICENSE │ │ ├── mobx-react-lite.js │ │ ├── mobx-react.umd.js │ │ └── package.json │ ├── react/ │ │ ├── AUTHORS │ │ └── LICENSE.txt │ └── react-tools/ │ └── react-tools.js ├── js-tests/ │ └── react-tools.test.jsx ├── man/ │ ├── React.Rd │ ├── babel_transform.Rd │ ├── component.Rd │ ├── createReactShinyInput.Rd │ ├── html_dependency_corejs.Rd │ ├── html_dependency_mobx.Rd │ ├── html_dependency_react.Rd │ ├── html_dependency_reacttools.Rd │ ├── reactMarkup.Rd │ ├── scaffoldReactShinyInput.Rd │ └── scaffoldReactWidget.Rd ├── package.json ├── reactR.Rproj ├── srcjs/ │ ├── input.js │ ├── react-tools.js │ └── widget.js ├── vignettes/ │ ├── intro_htmlwidgets.Rmd │ ├── intro_inputs.Rmd │ └── intro_reactR.Rmd └── vite.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .Rbuildignore ================================================ ^CRAN-RELEASE$ ^node_modules$ ^js-tests$ ^srcjs$ ^pkgdown$ ^assets$ ^.*\.Rproj$ ^CONDUCT\.md$ ^README\.Rmd$ ^\.Rproj\.user$ ^buildupdate$ ^docs$ ^cran-comments\.md$ ^logo.svg$ ^package\.json$ ^vite\.config\.js$ ^package-lock\.json$ ^logo\.svg$ ^\.github$ ^CRAN-SUBMISSION$ ================================================ FILE: .gitattributes ================================================ /inst/www/react-tools/react-tools.js binary /inst/www/react-tools/react-tools.js.map binary ================================================ FILE: .github/.gitignore ================================================ *.html ================================================ FILE: .github/workflows/R-CMD-check.yaml ================================================ # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: branches: [main, master] pull_request: branches: [main, master] name: R-CMD-check jobs: R-CMD-check: runs-on: ${{ matrix.config.os }} name: ${{ matrix.config.os }} (${{ matrix.config.r }}) strategy: fail-fast: false matrix: config: - {os: macos-latest, r: 'release'} - {os: windows-latest, r: 'release'} - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - {os: ubuntu-latest, r: 'release'} - {os: ubuntu-latest, r: 'oldrel-1'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} R_KEEP_PKG_SOURCE: yes steps: - uses: actions/checkout@v3 - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r@v2 with: r-version: ${{ matrix.config.r }} http-user-agent: ${{ matrix.config.http-user-agent }} use-public-rspm: true - uses: r-lib/actions/setup-r-dependencies@v2 with: extra-packages: any::rcmdcheck needs: check - uses: r-lib/actions/check-r-package@v2 with: upload-snapshots: true ================================================ FILE: .gitignore ================================================ Meta doc .Rproj.user .Rhistory .RData .Ruserdata inst/doc node_modules reactR.Rcheck reactR_*.tar.gz *.swp .DS_Store ================================================ FILE: CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/ ================================================ FILE: DESCRIPTION ================================================ Package: reactR Type: Package Title: React Helpers Version: 0.6.1 Date: 2024-09-14 Authors@R: c( person( "Facebook", "Inc" , role = c("aut", "cph") , comment = "React library in lib, https://reactjs.org/; see AUTHORS for full list of contributors" ), person( "Michel","Weststrate", , role = c("aut", "cph") , comment = "mobx library in lib, https://github.com/mobxjs" ), person( "Kent", "Russell" , role = c("aut", "cre") , comment = "R interface" , email = "kent.russell@timelyportfolio.com" ), person( "Alan", "Dipert" , role = c("aut") , comment = "R interface" , email = "alan@rstudio.com" ), person( "Greg", "Lin" , role = c("aut") , comment = "R interface" , email = "glin@glin.io" ) ) Maintainer: Kent Russell Description: Make it easy to use 'React' in R with 'htmlwidget' scaffolds, helper dependency functions, an embedded 'Babel' 'transpiler', and examples. URL: https://github.com/react-R/reactR BugReports: https://github.com/react-R/reactR/issues License: MIT + file LICENSE LazyData: TRUE Encoding: UTF-8 Imports: htmltools Suggests: htmlwidgets (>= 1.5.3), rmarkdown, shiny, V8, knitr, usethis, jsonlite RoxygenNote: 7.3.2 VignetteBuilder: knitr ================================================ FILE: LICENSE ================================================ YEAR: 2018 COPYRIGHT HOLDER: Kent Russell ================================================ FILE: NAMESPACE ================================================ # Generated by roxygen2: do not edit by hand S3method("$",react_component_builder) S3method("$<-",react_component_builder) S3method("[[",react_component_builder) S3method("[[<-",react_component_builder) export(React) export(babel_transform) export(component) export(createReactShinyInput) export(html_dependency_corejs) export(html_dependency_mobx) export(html_dependency_react) export(html_dependency_reacttools) export(reactMarkup) export(scaffoldReactShinyInput) export(scaffoldReactWidget) importFrom(htmltools,htmlDependency) ================================================ FILE: NEWS.md ================================================ # reactR 0.6.1 * Fix issue where the `react-tools.umd.cjs` script could be blocked by the browser in some cases, such as apps deployed on shinyapps.io [#86](https://github.com/react-R/reactR/issues/86) # reactR 0.6.0 * retain `list` in `reactR::component` classes [#82](https://github.com/react-R/reactR/issues/82) * hydrate props/attribs that are tags assuming tag-like props/attribs should be slots[#67](https://github.com/react-R/reactR/issues/67) [#61](https://github.com/react-R/reactR/issues/61) * update build tools to `vite` from `webpack` * update js testing library from `karma` to `vitest` # reactR 0.5.0 * Update react to `18.2.0` # reactR 0.4.4 * Update react to `16.12.0` * Add `style-loader` and `css-loader` to webpack config [pull 50](https://github.com/react-R/reactR/pull/50) * Update to `PACKAGE::widget_html.WIDGETNAME` for new `htmlwidgets` convention [pull 49](https://github.com/react-R/reactR/pull/49) * Clean up template [pull 45](https://github.com/react-R/reactR/pull/45) # reactR 0.4.3 * Add element to Shiny input [pull 41](https://github.com/react-R/reactR/pull/41) * Upgrade npm dependencies # reactR 0.4.2 * Update react to `16.12.0` * Update core-js to `2.6.11` # reactR 0.4.1 * Add support for `shiny::registerInputHandler` in Shiny inputs; [pull 28](https://github.com/react-R/reactR/pull/28) * Add support for Shiny rate limit [pull 29](https://github.com/react-R/reactR/pull/29) * Update react to `16.8.6` * Add `mobx` dependencies available through `html_dependency_mobx()` # reactR 0.4.0 * Add Shiny input scaffold and functionality; [tutorial](https://react-r.github.io/reactR/articles/intro_inputs.html) and [pull 22](https://github.com/react-R/reactR/pull/22) thanks @alandipert # reactR 0.3.1 * Update react and react-dom to 16.8.1 * Add `usethis` R dependency * Ignore node_modules in `.Rbuildignore` and `.gitignore` * Set `{modules:false}` in `babel_transform` to avoid `"use strict"`; [pull 15](https://github.com/react-R/reactR/pull/15) * Use webpack to build `react-tools.js`; [pull 16](https://github.com/react-R/reactR/pull/16) * Attach component to the htmlwidget # reactR 0.3.0 * Add htmlwidget scaffold and helpers (see [tutorial](https://react-r.github.io/reactR/articles/intro_htmlwidgets.html)) * Update react and react-dom to 16.6.7 # reactR 0.2.1 * Update react and react-dom to 16.6.0 # reactR 0.2.0 * Update react and react-dom to 16.2.0 * Add core-js shim so that React will show up in RStudio Viewer # reactR 0.1.4 * Update react and react-dom to 16.1.1 # reactR 0.1.3 * Update react and react-dom to 16.0.0 * Update babel to 6.26.0 # reactR 0.1.2 * Update to react `15.5.0` * Update to babel `6.24.0` * Add fluent-ui(fabric) example * Build doc site with `pkgdown` # reactR 0.1.1 * Added a `NEWS.md` file to track changes to the package. * Provide offline babel-standalone for babel_transform # reactR 0.1.0 * Initial release ================================================ FILE: R/babel.R ================================================ #' Transform Code with Babel #' #' Helper function to use \code{V8} with \code{Babel} so we can #' avoid a JSX transformer with using \code{reactR}. #' #' @param code \code{character} #' #' @return transformed \code{character} #' @export #' #' @examples #' \dontrun{ #' library(reactR) #' babel_transform('
react div
') #' } babel_transform <- function(code=""){ stopifnot(requireNamespace("V8"), is.character(code)) ctx <- V8::v8() ctx$source( system.file( "www/babel/babel.min.js", package = "reactR" ) ) ctx$assign('code', code) ctx$get('Babel.transform(code,{ presets: [["es2015", {modules: false}],"react"] }).code') } ================================================ FILE: R/dependencies.R ================================================ #' Dependencies for React #' #' Add JavaScript 'React' dependency. For this to work in RStudio Viewer, also include #' \code{\link{html_dependency_corejs}}. #' #' @param offline \code{logical} to use local file dependencies. If \code{FALSE}, #' then the dependencies use the Facebook cdn as its \code{src}. #' To use with \code{JSX} see \code{\link{babel_transform}}. #' #' @return \code{\link[htmltools]{htmlDependency}} #' @importFrom htmltools htmlDependency #' @export #' #' @examples #' library(reactR) #' library(htmltools) #' #' tagList( #' tags$script( #' " #' ReactDOM.render( #' React.createElement( #' 'h1', #' null, #' 'Powered by React' #' ), #' document.body #' ) #' " #' ), #' #add core-js first to work in RStudio Viewer #' html_dependency_corejs(), #' html_dependency_react() #offline=FALSE for CDN #' ) html_dependency_react <- function(offline=TRUE){ hd <- htmltools::htmlDependency( name = "react", version = react_version(), src = system.file("www/react",package="reactR"), script = c("react.min.js", "react-dom.min.js") ) if(!offline) { hd$src <- list(href="//unpkg.com") hd$script <- c( "react/umd/react.production.min.js", "react-dom/umd/react-dom.production.min.js" ) } hd } #' Shim Dependency for React in RStudio Viewer #' #' Add this first for 'React' to work in RStudio Viewer. #' #' @return \code{\link[htmltools]{htmlDependency}} #' @importFrom htmltools htmlDependency #' @export html_dependency_corejs <- function() { #shim/polyfill for ES5 and ES6 so react will show up in RStudio Viewer #https://unpkg.com/core-js@2.5.3/ htmltools::htmlDependency( name = "core-js", version = "2.5.3", src = c(file=system.file("www/core-js/", package="reactR")), script = "shim.min.js" ) } #' Adds window.reactR.exposeComponents and window.reactR.hydrate #' #' @return \code{\link[htmltools]{htmlDependency}} #' @importFrom htmltools htmlDependency #' @export html_dependency_reacttools <- function(){ htmltools::htmlDependency( name = "reactwidget", src = "www/react-tools", version = "2.0.0", package = "reactR", script = c("react-tools.js") ) } #' Dependencies for 'mobx' #' #' Add JavaScript 'mobx' and 'mobx-react' dependency. When using with 'react', the order #' of the dependencies is important, so please add \code{html_dependency_react()} before #' \code{html_dependency_mobx()}. #' #' @param react \code{logical} to add react 'mobx' dependencies. #' #' @return \code{\link[htmltools]{htmlDependency}} #' @importFrom htmltools htmlDependency #' @export #' #' @examples #' if(interactive()) { #' #' library(htmltools) #' library(reactR) #' #' browsable( #' tagList( #' html_dependency_mobx(react = FALSE), #' div(id="test"), #' tags$script(HTML( #' " #' var obs = mobx.observable({val: null}) #' mobx.autorun(function() { #' document.querySelector('#test').innerText = obs.val #' }) #' setInterval( #' function() {obs.val++}, #' 1000 #' ) #' " #' )) #' ) #' ) #' } #' #' \dontrun{ #' # use with react #' library(htmltools) #' library(reactR) #' #' browsable( #' tagList( #' html_dependency_react(), #' html_dependency_mobx(), #' div(id="test"), #' tags$script(HTML(babel_transform( #' " #' var obs = mobx.observable({val: null}) #' var App = mobxReact.observer((props) =>
{props.obs.val}
) #' #' ReactDOM.render(, document.querySelector('#test')) #' #' setInterval( #' function() {obs.val++}, #' 1000 #' ) #' " #' ))) #' ) #' ) #' } html_dependency_mobx <- function(react = TRUE){ hd <- htmltools::htmlDependency( name = "mobx", version = "4.11.0", src = system.file("www/mobx",package="reactR"), script = c("mobx.umd.min.js") ) if(react) { hd$script <- c(hd$script,"mobx-react-lite.js", "mobx-react.umd.js") } hd } ================================================ FILE: R/meta.R ================================================ #'@keywords internal react_version <- function(){'18.2.0'} babel_version <- function(){'6.26.0'} ================================================ FILE: R/reacttools.R ================================================ # A robust name string is a valid # - CSS class # - JavaScript variable name # - R variable name robustName <- "^[[:alpha:]_][[:alnum:]_]*$" isUpper <- function(s) { grepl("^[[:upper:]]+$", s) } #' Create a React component #' #' @param name Name of the React component, which must start with an upper-case #' character. #' @param varArgs Attributes and children of the element to pass along to #' \code{\link[htmltools]{tag}} as \code{varArgs}. #' #' @return An htmltools \code{\link[htmltools]{tag}} object #' @export #' #' @examples #' component("ParentComponent", #' list( #' x = 1, #' y = 2, #' component("ChildComponent"), #' component("OtherChildComponent") #' ) #' ) component <- function(name, varArgs = list()) { if (length(name) == 0 || !isUpper(substring(name, 1, 1))) { stop("Component name must be specified and start with an upper case character") } component <- htmltools::tag(name, varArgs) structure(component, class = c("reactR_component", oldClass(component), "list")) } #' React component builder. #' #' \code{React} is a syntactically-convenient way to create instances of React #' components that can be sent to the browser for display. It is a list for #' which \link[=InternalMethods]{extract methods} are defined, allowing #' object creation syntax like \code{React$MyComponent(x = 1)} where #' \code{MyComponent} is a React component you have exposed to Shiny in #' JavaScript. #' #' Internally, the \code{\link{component}} function is used to create the #' component instance. #' #' @examples #' # Create an instance of ParentComponent with two children, #' # ChildComponent and OtherChildComponent. #' React$ParentComponent( #' x = 1, #' y = 2, #' React$ChildComponent(), #' React$OtherChildComponent() #' ) #' @export React <- structure( list(), class = "react_component_builder" ) #' @export `$.react_component_builder` <- function(x, name) { function(...) { component(name, list(...)) } } #' @export `[[.react_component_builder` <- `$.react_component_builder` #' @export `$<-.react_component_builder` <- function(x, name, value) { stop("Assigning to a component constructor is not allowed") } #' @export `[[<-.react_component_builder` <- `$<-.react_component_builder` #' Prepare data that represents a single-element character vector, a React #' component, or an htmltools tag for sending to the client. #' #' Tag lists as returned by \code{htmltools tagList} are not currently #' supported. #' #' @param tag character vector or React component or #' \code{\link[htmltools]{tag}} #' #' @return A reactR markup object suitable for being passed to #' \code{\link[htmlwidgets]{createWidget}} as widget instance data. #' @export reactMarkup <- function(tag) { stopifnot(inherits(tag, "shiny.tag") || (is.character(tag) && length(tag) == 1)) list(tag = tag, class = "reactR_markup") } #' Create a React-based input #' #' @param inputId The \code{input} slot that will be used to access the value. #' @param class Space-delimited list of CSS class names that should identify #' this input type in the browser. #' @param dependencies HTML dependencies to include in addition to those #' supporting React. Must contain at least one dependency, that of the input's #' implementation. #' @param default Initial value. #' @param configuration Static configuration data. #' @param container Function to generate an HTML element to contain the input. #' #' @return Shiny input suitable for inclusion in a UI. #' @export #' #' @examples #' myInput <- function(inputId, default = "") { #' # The value of createReactShinyInput should be returned from input constructor functions. #' createReactShinyInput( #' inputId, #' "myinput", #' # At least one htmlDependency must be provided -- the JavaScript implementation of the input. #' htmlDependency( #' name = "my-input", #' version = "1.0.0", #' src = "www/mypackage/myinput", #' package = "mypackage", #' script = "myinput.js" #' ), #' default #' ) #' } createReactShinyInput <- function(inputId, class, dependencies, default = NULL, configuration = list(), container = htmltools::tags$div) { if(length(dependencies) < 1) stop("Must include at least one HTML dependency.") value <- shiny::restoreInput(id = inputId, default = default) htmltools::tagList( html_dependency_corejs(), html_dependency_react(), html_dependency_reacttools(), container(id = inputId, class = class), htmltools::tags$script(id = sprintf("%s_value", inputId), type = "application/json", jsonlite::toJSON(value, auto_unbox = TRUE, null = "null", force = TRUE)), htmltools::tags$script(id = sprintf("%s_configuration", inputId), type = "application/json", jsonlite::toJSON(configuration, auto_unbox = TRUE, null = "null", force = TRUE)), dependencies ) } ================================================ FILE: R/scaffold_input.R ================================================ #' Create implementation scaffolding for a React.js-based Shiny input. #' #' Add the minimal code required to implement a React.js-based Shiny input to an #' R package. #' #' @param name Name of input #' @param npmPkgs Optional \href{https://www.npmjs.com/}{NPM} packages upon which #' this input is based which will be used to populate \code{package.json}. #' Should be a named list of names to #' \href{https://docs.npmjs.com/files/package.json/}{versions}. #' @param edit Automatically open the input's source files after creating the #' scaffolding. #' #' @note This function must be executed from the root directory of the package #' you wish to add the input to. #' #' @export scaffoldReactShinyInput <- function(name, npmPkgs = NULL, edit = interactive()) { assertNameValid(name) package <- getPackage() file <- renderFile( sprintf("R/%s.R", name), "templates/input_r.txt", "boilerplate for input constructor", list( name = name, capName = capitalize(name), package = package ) ) if (edit) fileEdit(file) renderFile( 'package.json', 'templates/package.json.txt', 'project metadata', list(npmPkgs = toDepJSON(npmPkgs)) ) renderFile( 'webpack.config.js', 'templates/webpack.config.js.txt', 'webpack configuration', list( name = name, outputPath = sprintf("inst/www/%s/%s", package, name) ) ) renderFile( sprintf('srcjs/%s.jsx', name), 'templates/input_js.txt', 'JavaScript implementation', list( name = name, package = package ) ) renderFile( 'app.R', 'templates/input_app.R.txt', 'example app', list( name = name, package = package ) ) usethis::use_build_ignore(c("node_modules", "srcjs", "app.R", "package.json", "webpack.config.js", "yarn.lock")) usethis::use_git_ignore(c("node_modules")) lapply(c("htmltools", "shiny", "reactR"), usethis::use_package) message("To install dependencies from npm run: yarn install") message("To build JavaScript run: yarn run webpack --mode=development") } ================================================ FILE: R/scaffold_utils.R ================================================ slurp <- function(file) { paste(readLines( system.file(file, package = 'reactR') ), collapse = "\n") } # invoke file.edit in a way that will bind to the RStudio editor # when running inside RStudio fileEdit <- function(file) { fileEditFunc <- eval(parse(text = "file.edit"), envir = globalenv()) fileEditFunc(file) } # Perform a series of pattern replacements on str. # Example: renderTemplate("foo ${x} bar ${y} baz ${x}", list(x = 1, y = 2)) # Produces: "foo 1 bar 2 baz 1" renderTemplate <- function(str, substitutions) { Reduce(function(str, name) { gsub(paste0("\\$\\{", name, "\\}"), substitutions[[name]], str) }, names(substitutions), str) } capitalize <- function(s) { gsub("^(.)", perl = TRUE, replacement = '\\U\\1', s) } toDepJSON <- function(npmPkgs) { if (is.null(npmPkgs)) { "" } else if (!length(names(npmPkgs))) { stop("Must specify npm package names in the names attributes of npmPkgs") } else { paste0(sprintf('"%s": "%s"', names(npmPkgs), npmPkgs), collapse = ",\n") } } # Wraps renderTemplate for convenient use from scaffold functions. renderFile <- function(outputFile, templateFile, description = '', substitutions = list()) { if (!file.exists(outputFile)) { dir.create(dirname(outputFile), recursive = TRUE, showWarnings = FALSE) cat(renderTemplate(slurp(templateFile), substitutions), file = outputFile) message("Created ", description, " ", outputFile) } else { message(outputFile, " already exists") } outputFile } getPackage <- function() { if (!file.exists('DESCRIPTION')) { stop("The current directory doesn't contain a package. You're either in the wrong directory, or need to create a package to house your widget.", call. = FALSE) } read.dcf('DESCRIPTION')[[1,"Package"]] } # Constraining names prevents the user from encountering obscure CSS problems # and JavaScript errors after scaffolding. assertNameValid <- function(name) { if (!grepl(robustName, name)) { msg <- sprintf("Name '%s' is invalid, names must begin with an alphabetic character and must contain only alphabetic and numeric characters", name) stop(msg, call. = FALSE) } } ================================================ FILE: R/scaffold_widget.R ================================================ #' Create implementation scaffolding for a React.js-based HTML widget #' #' Add the minimal code required to implement a React.js-based HTML widget to an #' R package. #' #' @param name Name of widget #' @param npmPkgs Optional \href{https://www.npmjs.com/}{NPM} packages upon which #' this widget is based which will be used to populate \code{package.json}. #' Should be a named list of names to #' \href{https://docs.npmjs.com/files/package.json/}{versions}. #' @param edit Automatically open the widget's JavaScript source file after #' creating the scaffolding. #' #' @note This function must be executed from the root directory of the package #' you wish to add the widget to. #' #' @export scaffoldReactWidget <- function(name, npmPkgs = NULL, edit = interactive()){ assertNameValid(name) package <- getPackage() addWidgetConstructor(name, package, edit) addWidgetYAML(name, edit) addPackageJSON(toDepJSON(npmPkgs)) addWebpackConfig(name) addWidgetJS(name, edit) addExampleApp(name) usethis::use_build_ignore(c("node_modules", "srcjs", "app.R", "package.json", "webpack.config.js", "yarn.lock")) usethis::use_git_ignore(c("node_modules")) lapply(c("htmltools", "htmlwidgets", "reactR"), usethis::use_package) message("To install dependencies from npm run: yarn install") message("To build JavaScript run: yarn run webpack --mode=development") } addWidgetConstructor <- function(name, package, edit){ file <- renderFile( sprintf("R/%s.R", name), "templates/widget_r.txt", "boilerplate for widget constructor", list( name = name, package = package, capName = capitalize(name) ) ) if (edit) fileEdit(file) } addWidgetYAML <- function(name, edit){ file <- renderFile( sprintf('inst/htmlwidgets/%s.yaml', name), "templates/widget_yaml.txt", "boilerplate for widget dependencies" ) if (edit) fileEdit(file) } addPackageJSON <- function(npmPkgs) { renderFile( 'package.json', 'templates/package.json.txt', 'project metadata', list(npmPkgs = npmPkgs) ) } addWebpackConfig <- function(name) { renderFile( 'webpack.config.js', 'templates/webpack.config.js.txt', 'webpack configuration', list( name = name, outputPath = 'inst/htmlwidgets' ) ) } addWidgetJS <- function(name, edit){ file <- renderFile( sprintf('srcjs/%s.jsx', name), 'templates/widget_js.txt', 'boilerplate for widget JavaScript bindings', list(name = name) ) if (edit) fileEdit(file) } addExampleApp <- function(name) { renderFile( 'app.R', 'templates/widget_app.R.txt', 'example app', list( name = name, capName = capitalize(name) ) ) } ================================================ FILE: README.Rmd ================================================ --- output: github_document --- # reactR reactR logo ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" ) ``` [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/reactR)](https://cran.r-project.org/package=reactR) [![R-CMD-check](https://github.com/react-R/reactR/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/react-R/reactR/actions/workflows/R-CMD-check.yaml) `reactR` provides a set of convenience functions for using [`React`](https://reactjs.org/) in `R` with `htmlwidget` constructor templates and local JavaScript dependencies. The `React` ecosystem is rich with components that can enhance `R` web and Shiny apps. `scaffoldReactWidget()` helps build `htmlwidgets` to integrate these `React` components as `R` `htmlwidgets`. `scaffoldReactShinyInput()` does the same for `Shiny` inputs. The local dependency functions are modeled after the `html_dependency_*` functions from RStudio's [`rmarkdown`](https://github.com/rstudio/rmarkdown) package. ## Installation You can install reactR from CRAN with `install.packages("reactR")`. For the development version, please use `devtools` as shown below. ```R # install.packages("devtools") devtools::install_github("react-R/reactR") ``` ## Creating htmlwidgets with React Components To wrap a `React` component as an `htmlwidget`, please see the tutorial [htmlwidgets with reactR](https://react-r.github.io/reactR/articles/intro_htmlwidgets.html). Also, there are a variety of examples in the [react-R Github organization](https://github.com/react-R). [`reactable`](https://github.com/glin/reactable) is a very well-built `htmlwidget` leveraging this functionality. ## Shiny Outputs and Inputs `htmlwidgets` built with `reactR` work well in Shiny as outputs. In version `0.4.0` Alan Dipert has added the ability to easily create React-based official `Shiny` inputs with helpers and scaffolds. Please see the [tutorial](https://react-r.github.io/reactR/articles/intro_inputs.html) for more details. ## Examples Below are examples of using `reactR` directly. ```R library(reactR) library(htmltools) browsable(tagList( tags$div(id = "app"), tags$script( " ReactDOM.render( React.createElement( 'h1', null, 'Powered by React' ), document.getElementById('app') ) " ), #add core-js first to work in RStudio Viewer html_dependency_corejs(), html_dependency_react() )) ``` `reactR` uses the `V8` package if available to transform `JSX` and `ES2015` code with `babel`. ```R library(reactR) library(htmltools) browsable( tagList( tags$div(id = "app"), tags$script( babel_transform('ReactDOM.render(

Powered By React/JSX

,document.getElementById("app"))') ), # add core-js shim first for React in older versions of RStudio Viewer #html_dependency_corejs(), html_dependency_react() ) ) ``` ## Contributing and Code of Conduct We welcome contributors and would love your participation. Please note that this project is released with a [Contributor Code of Conduct](https://github.com/react-R/reactR/blob/master/CONDUCT.md). By participating in this project you agree to abide by the terms. ================================================ FILE: README.md ================================================ # reactR reactR logo [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/reactR)](https://cran.r-project.org/package=reactR) [![R-CMD-check](https://github.com/react-R/reactR/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/react-R/reactR/actions/workflows/R-CMD-check.yaml) `reactR` provides a set of convenience functions for using [`React`](https://reactjs.org/) in `R` with `htmlwidget` constructor templates and local JavaScript dependencies. The `React` ecosystem is rich with components that can enhance `R` web and Shiny apps. `scaffoldReactWidget()` helps build `htmlwidgets` to integrate these `React` components as `R` `htmlwidgets`. `scaffoldReactShinyInput()` does the same for `Shiny` inputs. The local dependency functions are modeled after the `html_dependency_*` functions from RStudio’s [`rmarkdown`](https://github.com/rstudio/rmarkdown) package. ## Installation You can install reactR from CRAN with `install.packages("reactR")`. For the development version, please use `devtools` as shown below. ``` r # install.packages("devtools") devtools::install_github("react-R/reactR") ``` ## Creating htmlwidgets with React Components To wrap a `React` component as an `htmlwidget`, please see the tutorial [htmlwidgets with reactR](https://react-r.github.io/reactR/articles/intro_htmlwidgets.html). Also, there are a variety of examples in the [react-R Github organization](https://github.com/react-R). [`reactable`](https://github.com/glin/reactable) is a very well-built `htmlwidget` leveraging this functionality. ## Shiny Outputs and Inputs `htmlwidgets` built with `reactR` work well in Shiny as outputs. In version `0.4.0` Alan Dipert has added the ability to easily create React-based official `Shiny` inputs with helpers and scaffolds. Please see the [tutorial](https://react-r.github.io/reactR/articles/intro_inputs.html) for more details. ## Examples Below are examples of using `reactR` directly. ``` r library(reactR) library(htmltools) browsable(tagList( tags$div(id = "app"), tags$script( " ReactDOM.render( React.createElement( 'h1', null, 'Powered by React' ), document.getElementById('app') ) " ), #add core-js first to work in RStudio Viewer html_dependency_corejs(), html_dependency_react() )) ``` `reactR` uses the `V8` package if available to transform `JSX` and `ES2015` code with `babel`. ``` r library(reactR) library(htmltools) browsable( tagList( tags$div(id = "app"), tags$script( babel_transform('ReactDOM.render(

Powered By React/JSX

,document.getElementById("app"))') ), # add core-js shim first for React in older versions of RStudio Viewer #html_dependency_corejs(), html_dependency_react() ) ) ``` ## Contributing and Code of Conduct We welcome contributors and would love your participation. Please note that this project is released with a [Contributor Code of Conduct](https://github.com/react-R/reactR/blob/master/CONDUCT.md). By participating in this project you agree to abide by the terms. ================================================ FILE: buildupdate/getreact.R ================================================ # use the very nice rgithub # devtools::install_github("cscheid/rgithub") get_react_latest <- function(){ gsub( x=github::get.latest.release("facebook", "react")$content$tag_name, pattern="v", replacement="" ) } get_babel_latest <- function(){ gsub( x=github::get.latest.release("babel", "babel-standalone")$content$tag_name, pattern="release-", replacement="" ) } # get newest react download.file( url=sprintf( "https://unpkg.com/react@%s/umd/react.production.min.js", get_react_latest() ), destfile="./inst/www/react/react.min.js" ) # get newest react dom download.file( url=sprintf( "https://unpkg.com/react-dom@%s/umd/react-dom.production.min.js", get_react_latest() ), destfile="./inst/www/react/react-dom.min.js" ) # get newest babel download.file( url=sprintf( "https://unpkg.com/babel-standalone@%s/babel.min.js", get_babel_latest() ), destfile="./inst/www/babel/babel.min.js" ) # write function with newest version # for use when creating dependencies cat( sprintf( "#'@keywords internal\nreact_version <- function(){'%s'}\nbabel_version <- function(){'%s'}", get_react_latest(), get_babel_latest() ), file = "./R/meta.R" ) ================================================ FILE: cran-comments.md ================================================ ## Test environments * local Windows 10 install, R 4.3.1 * rhub check_for_cran * winbuilder * github actions check for cran - ubuntu, mac, windows ## R CMD check results 0 errors | 0 warnings | 0 note ## Reverse dependencies reactable - consulted with author who has tested and approved the changes ================================================ FILE: docs/404.html ================================================ Page not found (404) • reactR
Content not found. Please use links in the navbar.

Site built with pkgdown 2.0.7.

================================================ FILE: docs/CONDUCT.html ================================================ Contributor Code of Conduct • reactR

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/

Site built with pkgdown 2.0.7.

================================================ FILE: docs/LICENSE-text.html ================================================ License • reactR
YEAR: 2018
COPYRIGHT HOLDER: Kent Russell

Site built with pkgdown 2.0.7.

================================================ FILE: docs/articles/index.html ================================================ Articles • reactR

Site built with pkgdown 2.0.7.

================================================ FILE: docs/articles/intro_htmlwidgets.html ================================================ Authoring htmlwidgets powered by React with reactR • reactR

The htmlwidgets package provides a framework for creating R bindings to JavaScript libraries. Using the htmlwidgets package alone, it’s not necessarily straight-forward to create an R binding to a React-powered JavaScript library. The reactR package builds on the htmlwidgets framework to make it much easier to author htmlwidgets that are powered by React. This vignette will show you how to effectively leverage reactR to build an htmlwidgets package that interfaces with react-sparklines React JavaScript library.

Software pre-requisites

In order to develop a reactR widget, you’ll need to install R and optionally RStudio. If you’re on Windows, you should also install Rtools.

For an excellent general introduction to R package concepts, check out the R packages online book.

In addition, you’ll need to install the following JavaScript tools on your machine:

  • Node.js: JavaScript engine and runtime for development outside of browsers. Provides the node and npm commands.
  • Yarn: Command-line dependency management tool, provides the yarn command.

To follow along in this vignette, you’ll also need the following R packages:

install.packages(c("shiny", "devtools", "usethis", "htmlwidgets", "reactR"))

Scaffolding

To create a new widget you can call scaffoldReactWidget to generate the basic structure and build configuration. This function will:

  • Create the .R, .js, .yaml, and .json files required by your widget;
  • If provided, take an npm package name and version as a named list with name and version elements. For example, the npm package foo at version ^1.2.0 would be expressed as list(name = "foo", version = "^1.2.0"). The package, if provided, will be added to the new widget’s package.json as a build dependency.

The following R code will create an R package named sparklines, then provide the templating for creating an htmlwidget powered by the react-sparklines npm package:

# Create the R package
usethis::create_package("~/sparklines")
# Inject the widget templating
withr::with_dir(
  "~/sparklines", 
  reactR::scaffoldReactWidget("sparklines", list("react-sparklines" = "^1.7.0"), edit = FALSE)
)

Building and installing

Building the JavaScript

The next step is to navigate to the newly-created sparklines project and run the following R commands:

system("yarn install")
system("yarn run webpack")
  • yarn install downloads all of the dependencies listed in package.json and creates a new file, yarn.lock. You should add this file to revision control. It will be updated whenever you change dependencies and run yarn install. Note: you only need to run it after modifying package.json. For further documentation on yarn install, see the yarn documentation.

  • yarn run webpack compiles the ES2015 JavaScript source file at srcjs/sparklines.js into inst/htmlwidgets/sparklines.js. The later file is one actually used by the R package and includes all the relevant JavaScript dependencies in a version of JavaScript that most browsers understand. Note that, if you add --mode=development to the end of this command, it will include a source map is included with the compiled JavaScript, which makes JavaScript debugging much easier, but hopefully you won’t need to do much of any JavaScript debugging.

yarn run webpack is not strictly a yarn command. In fact, yarn run simply delegates to the webpack program. Webpack’s configuration is generated by scaffoldReactWidget in the file webpack.config.js, but you can always change this configuration and/or modify the yarn run webpack command to suit your needs.

Installing the R package

Now that the widget’s JavaScript is compiled, go ahead and install the R package:

devtools::document()
devtools::install(quick = TRUE)

Alternatively, in RStudio, you can use the keyboard shortcuts Ctrl+Shift+D and Ctrl-Shift-B to document and build the package. (On macOS, the shortcuts are Cmd+Shift+D and Cmd+Shift+B)

Run the included demo

Now that the widget’s JavaScript is compiled, and the R package is installed, run app.R to see a demo in action:

shiny::runApp()

Alternatively, in RStudio, you can open app.R and press Ctrl-Shift-Enter (Cmd-Shift-Enter on macOS). You should see something like the following appear in the Viewer pane:

Authoring a React binding

At this point, we’ve built some scaffolding for an htmlwidget powered by React. Let’s modify it to create an interface to the react-sparklines library. Authoring the interface requires some changes on both the JavaScript and R side, but most of the hard thinking will be in figuring how best to design your interface. To give you an example of how this could work, let’s build an interface to the Sparklines component of the react-sparklines library.

First, outline an interface

Note that the examples in this section are just to demonstrate API possibilities and need not be pasted into any file.

Consider the following example taken from the react-sparklines documentation.

import React from 'react';
import { Sparklines } from 'react-sparklines';

<Sparklines data={sampleData}>
  <SparklinesLine color="#56b45d" />
  <SparklinesSpots style={{ fill: "#56b45d" }} />
</Sparklines>

You have some choice in terms of how to design an R interface to this sort of React library, but usually it makes sense to have one function per component and have the arguments to that function feed into the properties of that React component. In other words, our goal is to create an R function that allows users of our package to recreate this example with the following code:

library(sparklines)
sparklines(
  data = sampleData,
  sparklinesLine(color = "#56b45d"),
  sparklinesSpots(style = list(fill = "#56b45d"))
)

The following sections show how to implement this R interface from our scaffolded widget.

R implementation

Consider the template that reactR::scaffoldReactWidget() provided for us:

sparklines <- function(message, width = NULL, height = NULL, elementId = NULL) {
  
  # describe a React component to send to the browser for rendering.
  content <- htmltools::tag("div", list(message))
  
  # create widget
  htmlwidgets::createWidget(
    name = 'sparklines',
    reactR::reactMarkup(content),
    width = width,
    height = height,
    package = 'sparklines',
    elementId = elementId
  )
}

This function is designed to simply display a message within an HTML div using reactR and htmlwidgets. The critical piece here that makes it all work is reactR::reactMarkup(). This function can prepare a payload containing a mix of HTML tags (constructed via htmltools::tag()), React components (constructed via reactR::component()), or character vectors in a such way that the reactR and htmlwidgets toolchain will understand and know how to render in the browser (assuming we’ve imported our React component appropriately, as we cover later). Thus, to send a <Sparklines> react component instead of an HTML <div>, we could simply change:

content <- htmltools::tag("div", list(message))

to

reactR::component("Sparklines", list(message))

Remember, though, that we’d like <Sparklines> to consume a data property and also accept other valid components (e.g., <SparklinesLine>, <SparklinesSpot>, etc) from this library as children. So, we could change the body and signature of sparklines() in the following way:

sparklines <- function(data, ..., width = NULL, height = NULL) {
  
  # describe a React component to send to the browser for rendering.
  content <- reactR::component(
    "Sparklines",
    list(data = data, ...)
  )
  
  # create widget
  htmlwidgets::createWidget(
    name = 'sparklines',
    reactR::reactMarkup(content),
    width = width,
    height = height,
    package = 'sparklines'
  )
}

At this point, we define functions that make it easy for the user to create the other components by adding these to R/sparklines.R

#' @export
sparklinesLine <- function(...) {
  reactR::React$SparklinesLine(...)
}

#' @export
sparklinesSpots <- function(...) {
  reactR::React$SparklinesSpots(...)
}

JavaScript changes

In order for the reactR toolchain to know how to render components from the ‘react-sparklines’ library, we need to register the React components on the JavaScript side. This can be done in the srcjs/sparklines.js file which currently looks like this:

import { reactWidget } from 'reactR';

reactWidget('sparklines', 'output', {});

First, reactWidget is imported from the 'reactR' JavaScript module. This function will register the React components we want within the reactR and htmlwidgets toolchain. Note that the 'reactR' JavaScript is an html dependency, but webpack is configured in webpack.config.js to consider it a module, so it’s available to us here via import syntax.

Then, there’s a call to reactWidget, and we pass it three arguments:

  1. The name of the widget ('sparklines')
  2. The type of the widget ('output')
  3. The React components that should be exposed to the widget. In this template, we didn’t have to include any because it’s just rendering an HTML div.

Instead of passing an empty object ({}) as the React components, we provide an object with all the components we need from the ‘react-sparklines’ module:

import { Sparklines, SparklinesLine, SparklinesSpots } from 'react-sparklines';
import { reactWidget } from 'reactR';

reactWidget('sparklines', 'output', {
  Sparklines: Sparklines,
  SparklinesLine: SparklinesLine,
  SparklinesSpots: SparklinesSpots
});

Go for a spin

Now that we’ve made the necessary changes to the JavaScript and R source code, it’s time to compile the JavaScript and install the R package:

system("yarn install")
system("yarn run webpack")
devtools::document()
devtools::install()
library(sparklines)
sparklines(rnorm(10), sparklinesLine())

This should open up the sparklines() widget in your browser. If it does, congratulations, you created a React-based htmlwidget!

Shiny integration

The scaffolding template already provides the glue you need to get your reactR widget to render in Shiny. The two relevant functions are renderSparklines() and sparklinesOutput(). You shouldn’t need to modify these functions — they should work out of the box. You will, however, want to modify the example Shiny app in the app.R file:

library(shiny)
library(sparklines)

ui <- fluidPage(
  titlePanel("Sparklines library"),
  sliderInput("n", label = "Number of samples", min = 2, max = 1000, value = 100),
  sparklinesOutput("myWidget")
)

server <- function(input, output, session) {
    output$myWidget <- renderSparklines({
        sparklines(
            rnorm(input$n),
            sparklinesLine()
        )
    })
}

shinyApp(ui, server)

Now, when you run shiny::runApp(), you should see your react-based htmlwidget rendering in shiny app!

Further learning

This tutorial walked you through the steps taken you create an R interface to the react-sparklines library. The full example package is accessible at https://github.com/react-R/sparklines-example. Our intention is keep creating example packages under the https://github.com/react-R organization, so head there if you’d like to see other examples of interfacing with React.

Site built with pkgdown 2.0.7.

================================================ FILE: docs/articles/intro_htmlwidgets_files/accessible-code-block-0.0.1/empty-anchor.js ================================================ // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> // v0.0.1 // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. document.addEventListener('DOMContentLoaded', function() { const codeList = document.getElementsByClassName("sourceCode"); for (var i = 0; i < codeList.length; i++) { var linkList = codeList[i].getElementsByTagName('a'); for (var j = 0; j < linkList.length; j++) { if (linkList[j].innerHTML === "") { linkList[j].setAttribute('aria-hidden', 'true'); } } } }); ================================================ FILE: docs/articles/intro_inputs.html ================================================ Authoring inputs powered by React with reactR • reactR

Shiny comes with a large library of input widgets for collecting input from the user and conveying input data to R.

If you want a kind of input not provided by Shiny — like a color picker, or a different kind of slider — you’ve always been able to build your own. Shiny’s input system is extensible. All that’s required is an understanding of certain conventions and a little custom JavaScript.

reactR provides additional tools to ease the creation of new Shiny inputs implemented using React. In the following tutorial, we will demonstrate these tools by implementing a new Shiny color picker input that wraps the react-color library.

Software pre-requisites

In order to develop a reactR Shiny input, you’ll need to install R and optionally RStudio. If you’re on Windows, you should also install Rtools.

For an excellent general introduction to R package concepts, check out the R packages online book.

In addition, you’ll need to install the following JavaScript tools on your machine:

  • Node.js: JavaScript engine and runtime for development outside of browsers. Provides the node and npm commands.
  • Yarn: Command-line dependency management tool, provides the yarn command.

To follow along in this vignette, you’ll also need the following R packages:

install.packages(c("shiny", "devtools", "usethis", "reactR"))

Scaffolding

To create a new widget you can call scaffoldReactShinyInput to generate the basic structure and build configuration. This function will:

  • Create the .R, .js, and .json files required by your input;
  • If provided, take an npm package name and version as a named list with name and version elements. For example, the npm package foo at version ^1.2.0 would be expressed as list(name = "foo", version = "^1.2.0"). The package, if provided, will be added to the new widget’s package.json as a build dependency.

The following R code will create an R package named colorpicker, then provide the templating for creating an input powered by the react-color library on npm:

# Create the R package (rstudio=TRUE is recommended if you're not already comfortable with your terminal)
usethis::create_package("~/colorpicker", rstudio = TRUE)
# Scaffold initial input implementation files
withr::with_dir(
  "~/colorpicker",
  reactR::scaffoldReactShinyInput("colorpicker", list("react-color" = "^2.17.0"), edit = FALSE)
)

Building and installing

Building the JavaScript

The next step is to navigate to the newly-created colorpicker project and run the following commands in the terminal. If you’re new the terminal, we recommend opening your newly created RStudio ~/colorpicker/colorpicker.Rproj project file, then running the following in the RStudio terminal tab:

yarn install
yarn run webpack
  • yarn install downloads all of the dependencies listed in package.json and creates a new file, yarn.lock. You should add this file to revision control. It will be updated whenever you change dependencies and run yarn install. Note: you only need to run it after modifying package.json. For further documentation on yarn install, see the yarn documentation.

  • yarn run webpack compiles the modern JavaScript with JSX source file at srcjs/colorpicker.jsx into www/colorpicker/colorpicker/colorpicker.js. The latter file is the one actually used by the R package and includes all the relevant JavaScript dependencies in a dialect of JavaScript that most browsers understand.

yarn run webpack is not strictly a yarn command. In fact, yarn run simply delegates to the webpack program. Webpack’s configuration is generated by scaffoldReactShinyInput in the file webpack.config.js, but you can always change this configuration and/or modify the yarn run webpack command to suit your needs.

Installing the R package

Now that the input’s JavaScript is compiled, go ahead and install the R package:

devtools::document()
devtools::install(quick = TRUE)

In RStudio, you can use the keyboard shortcuts Ctrl-Shift-D and Ctrl-Shift-B to document and build the package. (On macOS, the shortcuts are Cmd-Shift-D and Cmd-Shift-B)

Run the included demo

Now that the input’s JavaScript is compiled, and the R package is installed, run app.R to see a demo in action:

shiny::runApp()

In RStudio, you can open app.R and press Ctrl-Shift-Enter (Cmd-Shift-Enter on macOS). You should see something like the following appear in the Viewer pane:

Authoring a React input

At this point, we have a working (if simple) React-powered text input. Let’s modify it to create an interface to the react-color library.

Connecting Shiny with React

Consider the following example taken from the react-color documentation.

import React from 'react';
import { SketchPicker } from 'react-color';

class Component extends React.Component {

  render() {
    return <SketchPicker />;
  }
}

That JavaScript code produces a SketchPicker-type interface that looks like this:

However, that example doesn’t demonstrate a way to default to a particular color, or a way to cause something to happen when the color changes. To accomplish these, react-color components can optionally take the following props:

  • color: accepts a string of a hex color like '#333'
  • onChangeComplete: accepts a JavaScript function taking a single argument, the new color, that will be called when the new color is selected

Since this React component calls a configurable function (i.e., onChangeComplete) when the input (i.e., color) value changes, we can supply a function to inform Shiny about these changes. You could, in theory, do this by writing your own custom Shiny input wrapper around this component, but reactR provides some conventions to make it much easier. These conventions have two main parts (R and JavaScript):

  1. Use reactR::createReactShinyInput() to construct the user-facing R input and route any user-supplied options (e.g., the default input value and other configuration) to the React component. This part was already done for us in the R/colorpicker.R file of our colorpicker project:
colorpickerInput <- function(inputId, default = "") {
  reactR::createReactShinyInput(
    inputId = inputId,
    class = "colorpicker",
    dependencies = htmltools::htmlDependency(
      name = "colorpicker-input",
      version = "1.0.0",
      src = "www/colorpicker/colorpicker",
      package = "colorpicker",
      script = "colorpicker.js"
    ),
    default = default,
    configuration = list(),
    container = htmltools::tags$span
  )
}
  1. Design an intermediate React component that routes information from colorpickerInput() to the <SketchPicker> component and also inform Shiny when a new color is chosen. This intermediate component should be a functional component with three arguments:
  • configuration: The JSON equivalent of the configuration argument from reactR::createReactShinyInput(). In this particular example, configuration isn’t used.
  • value: The input’s values over time, beginning with the default supplied from reactR::createReactShinyInput().
  • setValue: A JavaScript function to call with the input’s new value when one is created. This function is not user supplied, but rather an internal hook for informing Shiny about changes to the component’s current state (i.e. value).

Consider the following intermediate component, PickerInput. Note how this intermediate component allows one to set the default value from R and also calls setValue() inside onChangeComplete in order to inform Shiny about new color values. Finally, reactR.reactShinyInput() registers this intermediate component as a custom Shiny input binding named colorpicker.

import { reactShinyInput } from 'reactR';
import { SketchPicker } from 'react-color';

const PickerInput = ({ configuration, value, setValue }) => {
  return (
    <SketchPicker
      color={ value }
      onChangeComplete={ color => setValue(color.hex) }
    />
  );
};

// Note the first argument here should match the `class` 
// argument of the reactR::createReactShinyInput() from step 1
reactShinyInput('.colorpicker', 'colorpicker', PickerInput);

Open the srcjs/colorpicker.jsx file in your colorpicker project and paste this code into it. After saving the file, run yarn run webpack in the terminal, re-install the package, then run shiny::runApp() again

When you select new colors, you should see the textOutput update accordingly.

You might have noticed that the input showed up initially without a color selected. That’s because in app.R we didn’t supply a default argument to the colorpickerInput function inside our ui.

Try replacing the call to colorpickerInput with this: colorpickerInput("textInput", default = "#a76161")

Now when you run the app, the color should start as a shade of red.

Further learning

This tutorial walked you through the steps taken to wrap the react-color library in a Shiny input. The full example package is accessible at https://github.com/react-R/colorpicker-example. Our intention is keep creating example packages under the https://github.com/react-R organization, so head there if you’d like to see other examples of interfacing with React.

Site built with pkgdown 2.0.7.

================================================ FILE: docs/articles/intro_inputs_files/accessible-code-block-0.0.1/empty-anchor.js ================================================ // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> // v0.0.1 // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. document.addEventListener('DOMContentLoaded', function() { const codeList = document.getElementsByClassName("sourceCode"); for (var i = 0; i < codeList.length; i++) { var linkList = codeList[i].getElementsByTagName('a'); for (var j = 0; j < linkList.length; j++) { if (linkList[j].innerHTML === "") { linkList[j].setAttribute('aria-hidden', 'true'); } } } }); ================================================ FILE: docs/articles/intro_reactR.html ================================================ Intro to reactR • reactR

Why reactR?

react has become incredibly popular, and the ecosystem around react is robust. reactR aims to allow R users to more easily incorporate react and JSX.

Install

install.packages("reactR")

# for the latest development version
#  install from Github
# devtools::install_github("timelyportfolio/reactR")

Quick Example

Let’s use react to render a simple h1 HTML element below.

## Warning: package 'htmltools' was built under R version 4.3.3
attachDependencies(
  tags$script(
  "
    ReactDOM.render(
      React.createElement(
        'h1',
        null,
        'Powered by React'
      ),
      document.getElementById('react-heading-here')
    )
  "
  ),
  html_dependency_react()
)

Blog Post

For more on how we can use R and React, see the blog post React in R. Also, there are many more examples in the Github repo at inst/examples.

Using JSX

JSX helps ease some of the burden caused by React.createElement. reactR provides a babel_transform() function to use JSX. Hopefully, in the future, we can convince RStudio to modify htmltools to work directly with JSX (see issue).

Site built with pkgdown 2.0.7.

================================================ FILE: docs/articles/intro_reactR_files/accessible-code-block-0.0.1/empty-anchor.js ================================================ // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> // v0.0.1 // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. document.addEventListener('DOMContentLoaded', function() { const codeList = document.getElementsByClassName("sourceCode"); for (var i = 0; i < codeList.length; i++) { var linkList = codeList[i].getElementsByTagName('a'); for (var j = 0; j < linkList.length; j++) { if (linkList[j].innerHTML === "") { linkList[j].setAttribute('aria-hidden', 'true'); } } } }); ================================================ FILE: docs/articles/intro_reactR_files/react-16.12.0/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: docs/articles/intro_reactR_files/react-16.12.0/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: docs/articles/intro_reactR_files/react-16.7.0/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: docs/articles/intro_reactR_files/react-16.7.0/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: docs/articles/intro_reactR_files/react-16.8.1/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: docs/articles/intro_reactR_files/react-16.8.1/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: docs/articles/intro_reactR_files/react-16.8.6/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: docs/articles/intro_reactR_files/react-16.8.6/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: docs/articles/intro_reactR_files/react-17.0.0/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: docs/articles/intro_reactR_files/react-17.0.0/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: docs/articles/intro_reactR_files/react-18.2.0/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: docs/articles/intro_reactR_files/react-18.2.0/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: docs/authors.html ================================================ Authors and Citation • reactR
  • Facebook Inc. Author, copyright holder.
    React library in lib, https://reactjs.org/; see AUTHORS for full list of contributors

  • Michel Weststrate. Author, copyright holder.
    mobx library in lib, https://github.com/mobxjs

  • Kent Russell. Author, maintainer.
    R interface

  • Alan Dipert. Author.
    R interface

  • Greg Lin. Author.
    R interface

Citation

Source: DESCRIPTION

Inc F, Weststrate M, Russell K, Dipert A, Lin G (2024). reactR: React Helpers. R package version 0.6.1, https://github.com/react-R/reactR.

@Manual{,
  title = {reactR: React Helpers},
  author = {Facebook Inc and Michel Weststrate and Kent Russell and Alan Dipert and Greg Lin},
  year = {2024},
  note = {R package version 0.6.1},
  url = {https://github.com/react-R/reactR},
}

Site built with pkgdown 2.0.7.

================================================ FILE: docs/bootstrap-toc.css ================================================ /*! * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) * Copyright 2015 Aidan Feldman * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ /* All levels of nav */ nav[data-toggle='toc'] .nav > li > a { display: block; padding: 4px 20px; font-size: 13px; font-weight: 500; color: #767676; } nav[data-toggle='toc'] .nav > li > a:hover, nav[data-toggle='toc'] .nav > li > a:focus { padding-left: 19px; color: #563d7c; text-decoration: none; background-color: transparent; border-left: 1px solid #563d7c; } nav[data-toggle='toc'] .nav > .active > a, nav[data-toggle='toc'] .nav > .active:hover > a, nav[data-toggle='toc'] .nav > .active:focus > a { padding-left: 18px; font-weight: bold; color: #563d7c; background-color: transparent; border-left: 2px solid #563d7c; } /* Nav: second level (shown on .active) */ nav[data-toggle='toc'] .nav .nav { display: none; /* Hide by default, but at >768px, show it */ padding-bottom: 10px; } nav[data-toggle='toc'] .nav .nav > li > a { padding-top: 1px; padding-bottom: 1px; padding-left: 30px; font-size: 12px; font-weight: normal; } nav[data-toggle='toc'] .nav .nav > li > a:hover, nav[data-toggle='toc'] .nav .nav > li > a:focus { padding-left: 29px; } nav[data-toggle='toc'] .nav .nav > .active > a, nav[data-toggle='toc'] .nav .nav > .active:hover > a, nav[data-toggle='toc'] .nav .nav > .active:focus > a { padding-left: 28px; font-weight: 500; } /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ nav[data-toggle='toc'] .nav > .active > ul { display: block; } ================================================ FILE: docs/bootstrap-toc.js ================================================ /*! * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) * Copyright 2015 Aidan Feldman * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ (function() { 'use strict'; window.Toc = { helpers: { // return all matching elements in the set, or their descendants findOrFilter: function($el, selector) { // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ // http://stackoverflow.com/a/12731439/358804 var $descendants = $el.find(selector); return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); }, generateUniqueIdBase: function(el) { var text = $(el).text(); var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); return anchor || el.tagName.toLowerCase(); }, generateUniqueId: function(el) { var anchorBase = this.generateUniqueIdBase(el); for (var i = 0; ; i++) { var anchor = anchorBase; if (i > 0) { // add suffix anchor += '-' + i; } // check if ID already exists if (!document.getElementById(anchor)) { return anchor; } } }, generateAnchor: function(el) { if (el.id) { return el.id; } else { var anchor = this.generateUniqueId(el); el.id = anchor; return anchor; } }, createNavList: function() { return $(''); }, createChildNavList: function($parent) { var $childList = this.createNavList(); $parent.append($childList); return $childList; }, generateNavEl: function(anchor, text) { var $a = $(''); $a.attr('href', '#' + anchor); $a.text(text); var $li = $('
  • '); $li.append($a); return $li; }, generateNavItem: function(headingEl) { var anchor = this.generateAnchor(headingEl); var $heading = $(headingEl); var text = $heading.data('toc-text') || $heading.text(); return this.generateNavEl(anchor, text); }, // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). getTopLevel: function($scope) { for (var i = 1; i <= 6; i++) { var $headings = this.findOrFilter($scope, 'h' + i); if ($headings.length > 1) { return i; } } return 1; }, // returns the elements for the top level, and the next below it getHeadings: function($scope, topLevel) { var topSelector = 'h' + topLevel; var secondaryLevel = topLevel + 1; var secondarySelector = 'h' + secondaryLevel; return this.findOrFilter($scope, topSelector + ',' + secondarySelector); }, getNavLevel: function(el) { return parseInt(el.tagName.charAt(1), 10); }, populateNav: function($topContext, topLevel, $headings) { var $context = $topContext; var $prevNav; var helpers = this; $headings.each(function(i, el) { var $newNav = helpers.generateNavItem(el); var navLevel = helpers.getNavLevel(el); // determine the proper $context if (navLevel === topLevel) { // use top level $context = $topContext; } else if ($prevNav && $context === $topContext) { // create a new level of the tree and switch to it $context = helpers.createChildNavList($prevNav); } // else use the current $context $context.append($newNav); $prevNav = $newNav; }); }, parseOps: function(arg) { var opts; if (arg.jquery) { opts = { $nav: arg }; } else { opts = arg; } opts.$scope = opts.$scope || $(document.body); return opts; } }, // accepts a jQuery object, or an options object init: function(opts) { opts = this.helpers.parseOps(opts); // ensure that the data attribute is in place for styling opts.$nav.attr('data-toggle', 'toc'); var $topContext = this.helpers.createChildNavList(opts.$nav); var topLevel = this.helpers.getTopLevel(opts.$scope); var $headings = this.helpers.getHeadings(opts.$scope, topLevel); this.helpers.populateNav($topContext, topLevel, $headings); } }; $(function() { $('nav[data-toggle="toc"]').each(function(i, el) { var $nav = $(el); Toc.init($nav); }); }); })(); ================================================ FILE: docs/docsearch.css ================================================ /* Docsearch -------------------------------------------------------------- */ /* Source: https://github.com/algolia/docsearch/ License: MIT */ .algolia-autocomplete { display: block; -webkit-box-flex: 1; -ms-flex: 1; flex: 1 } .algolia-autocomplete .ds-dropdown-menu { width: 100%; min-width: none; max-width: none; padding: .75rem 0; background-color: #fff; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, .1); box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); } @media (min-width:768px) { .algolia-autocomplete .ds-dropdown-menu { width: 175% } } .algolia-autocomplete .ds-dropdown-menu::before { display: none } .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { padding: 0; background-color: rgb(255,255,255); border: 0; max-height: 80vh; } .algolia-autocomplete .ds-dropdown-menu .ds-suggestions { margin-top: 0 } .algolia-autocomplete .algolia-docsearch-suggestion { padding: 0; overflow: visible } .algolia-autocomplete .algolia-docsearch-suggestion--category-header { padding: .125rem 1rem; margin-top: 0; font-size: 1.3em; font-weight: 500; color: #00008B; border-bottom: 0 } .algolia-autocomplete .algolia-docsearch-suggestion--wrapper { float: none; padding-top: 0 } .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { float: none; width: auto; padding: 0; text-align: left } .algolia-autocomplete .algolia-docsearch-suggestion--content { float: none; width: auto; padding: 0 } .algolia-autocomplete .algolia-docsearch-suggestion--content::before { display: none } .algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { padding-top: .75rem; margin-top: .75rem; border-top: 1px solid rgba(0, 0, 0, .1) } .algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { display: block; padding: .1rem 1rem; margin-bottom: 0.1; font-size: 1.0em; font-weight: 400 /* display: none */ } .algolia-autocomplete .algolia-docsearch-suggestion--title { display: block; padding: .25rem 1rem; margin-bottom: 0; font-size: 0.9em; font-weight: 400 } .algolia-autocomplete .algolia-docsearch-suggestion--text { padding: 0 1rem .5rem; margin-top: -.25rem; font-size: 0.8em; font-weight: 400; line-height: 1.25 } .algolia-autocomplete .algolia-docsearch-footer { width: 110px; height: 20px; z-index: 3; margin-top: 10.66667px; float: right; font-size: 0; line-height: 0; } .algolia-autocomplete .algolia-docsearch-footer--logo { background-image: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: 50%; background-size: 100%; overflow: hidden; text-indent: -9000px; width: 100%; height: 100%; display: block; transform: translate(-8px); } .algolia-autocomplete .algolia-docsearch-suggestion--highlight { color: #FF8C00; background: rgba(232, 189, 54, 0.1) } .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) } .algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { background-color: rgba(192, 192, 192, .15) } ================================================ FILE: docs/docsearch.js ================================================ $(function() { // register a handler to move the focus to the search bar // upon pressing shift + "/" (i.e. "?") $(document).on('keydown', function(e) { if (e.shiftKey && e.keyCode == 191) { e.preventDefault(); $("#search-input").focus(); } }); $(document).ready(function() { // do keyword highlighting /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ var mark = function() { var referrer = document.URL ; var paramKey = "q" ; if (referrer.indexOf("?") !== -1) { var qs = referrer.substr(referrer.indexOf('?') + 1); var qs_noanchor = qs.split('#')[0]; var qsa = qs_noanchor.split('&'); var keyword = ""; for (var i = 0; i < qsa.length; i++) { var currentParam = qsa[i].split('='); if (currentParam.length !== 2) { continue; } if (currentParam[0] == paramKey) { keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); } } if (keyword !== "") { $(".contents").unmark({ done: function() { $(".contents").mark(keyword); } }); } } }; mark(); }); }); /* Search term highlighting ------------------------------*/ function matchedWords(hit) { var words = []; var hierarchy = hit._highlightResult.hierarchy; // loop to fetch from lvl0, lvl1, etc. for (var idx in hierarchy) { words = words.concat(hierarchy[idx].matchedWords); } var content = hit._highlightResult.content; if (content) { words = words.concat(content.matchedWords); } // return unique words var words_uniq = [...new Set(words)]; return words_uniq; } function updateHitURL(hit) { var words = matchedWords(hit); var url = ""; if (hit.anchor) { url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; } else { url = hit.url + '?q=' + escape(words.join(" ")); } return url; } ================================================ FILE: docs/index.html ================================================ React Helpers • reactR

    CRAN_Status_Badge R-CMD-check

    reactR provides a set of convenience functions for using React in R with htmlwidget constructor templates and local JavaScript dependencies. The React ecosystem is rich with components that can enhance R web and Shiny apps. scaffoldReactWidget() helps build htmlwidgets to integrate these React components as R htmlwidgets. scaffoldReactShinyInput() does the same for Shiny inputs. The local dependency functions are modeled after the html_dependency_* functions from RStudio’s rmarkdown package.

    Installation

    You can install reactR from CRAN with install.packages("reactR"). For the development version, please use devtools as shown below.

    # install.packages("devtools")
    devtools::install_github("react-R/reactR")

    Creating htmlwidgets with React Components

    To wrap a React component as an htmlwidget, please see the tutorial htmlwidgets with reactR. Also, there are a variety of examples in the react-R Github organization.

    reactable is a very well-built htmlwidget leveraging this functionality.

    Shiny Outputs and Inputs

    htmlwidgets built with reactR work well in Shiny as outputs. In version 0.4.0 Alan Dipert has added the ability to easily create React-based official Shiny inputs with helpers and scaffolds. Please see the tutorial for more details.

    Examples

    Below are examples of using reactR directly.

    library(reactR)
    library(htmltools)
    
    browsable(tagList(
      tags$div(id = "app"),
      tags$script(
      "
        ReactDOM.render(
          React.createElement(
            'h1',
            null,
            'Powered by React'
          ),
          document.getElementById('app')
        )
      "
      ),
      #add core-js first to work in RStudio Viewer
      html_dependency_corejs(),
      html_dependency_react()
    ))

    reactR uses the V8 package if available to transform JSX and ES2015 code with babel.

    library(reactR)
    library(htmltools)
    
    browsable(
      tagList(
        tags$div(id = "app"),
        tags$script(
          babel_transform('ReactDOM.render(<h1>Powered By React/JSX</h1>,document.getElementById("app"))')
        ),
        # add core-js shim first for React in older versions of RStudio Viewer
        #html_dependency_corejs(),
        html_dependency_react()
      )
    )

    Contributing and Code of Conduct

    We welcome contributors and would love your participation. Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by the terms.

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/news/index.html ================================================ Changelog • reactR
    • Fix issue where the react-tools.umd.cjs script could be blocked by the browser in some cases, such as apps deployed on shinyapps.io #86
    • retain list in reactR::component classes #82
    • hydrate props/attribs that are tags assuming tag-like props/attribs should be slots#67 #61
    • update build tools to vite from webpack
    • update js testing library from karma to vitest
    • Update react to 18.2.0
    • Update react to 16.12.0

    • Add style-loader and css-loader to webpack config pull 50

    • Update to PACKAGE::widget_html.WIDGETNAME for new htmlwidgets convention pull 49

    • Clean up template pull 45

    • Add element to Shiny input pull 41

    • Upgrade npm dependencies

    • Update react to 16.12.0

    • Update core-js to 2.6.11

    • Update react and react-dom to 16.8.1
    • Add usethis R dependency
    • Ignore node_modules in .Rbuildignore and .gitignore
    • Set {modules:false} in babel_transform to avoid "use strict"; pull 15
    • Use webpack to build react-tools.js; pull 16
    • Attach component to the htmlwidget
    • Add htmlwidget scaffold and helpers (see tutorial)
    • Update react and react-dom to 16.6.7
    • Update react and react-dom to 16.6.0
    • Update react and react-dom to 16.2.0
    • Add core-js shim so that React will show up in RStudio Viewer
    • Update react and react-dom to 16.1.1
    • Update react and react-dom to 16.0.0
    • Update babel to 6.26.0
    • Update to react 15.5.0
    • Update to babel 6.24.0
    • Add fluent-ui(fabric) example
    • Build doc site with pkgdown
    • Added a NEWS.md file to track changes to the package.
    • Provide offline babel-standalone for babel_transform
    • Initial release

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/pkgdown.css ================================================ /* Sticky footer */ /** * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css * * .Site -> body > .container * .Site-content -> body > .container .row * .footer -> footer * * Key idea seems to be to ensure that .container and __all its parents__ * have height set to 100% * */ html, body { height: 100%; } body { position: relative; } body > .container { display: flex; height: 100%; flex-direction: column; } body > .container .row { flex: 1 0 auto; } footer { margin-top: 45px; padding: 35px 0 36px; border-top: 1px solid #e5e5e5; color: #666; display: flex; flex-shrink: 0; } footer p { margin-bottom: 0; } footer div { flex: 1; } footer .pkgdown { text-align: right; } footer p { margin-bottom: 0; } img.icon { float: right; } /* Ensure in-page images don't run outside their container */ .contents img { max-width: 100%; height: auto; } /* Fix bug in bootstrap (only seen in firefox) */ summary { display: list-item; } /* Typographic tweaking ---------------------------------*/ .contents .page-header { margin-top: calc(-60px + 1em); } dd { margin-left: 3em; } /* Section anchors ---------------------------------*/ a.anchor { display: none; margin-left: 5px; width: 20px; height: 20px; background-image: url(./link.svg); background-repeat: no-repeat; background-size: 20px 20px; background-position: center center; } h1:hover .anchor, h2:hover .anchor, h3:hover .anchor, h4:hover .anchor, h5:hover .anchor, h6:hover .anchor { display: inline-block; } /* Fixes for fixed navbar --------------------------*/ .contents h1, .contents h2, .contents h3, .contents h4 { padding-top: 60px; margin-top: -40px; } /* Navbar submenu --------------------------*/ .dropdown-submenu { position: relative; } .dropdown-submenu>.dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; border-radius: 0 6px 6px 6px; } .dropdown-submenu:hover>.dropdown-menu { display: block; } .dropdown-submenu>a:after { display: block; content: " "; float: right; width: 0; height: 0; border-color: transparent; border-style: solid; border-width: 5px 0 5px 5px; border-left-color: #cccccc; margin-top: 5px; margin-right: -10px; } .dropdown-submenu:hover>a:after { border-left-color: #ffffff; } .dropdown-submenu.pull-left { float: none; } .dropdown-submenu.pull-left>.dropdown-menu { left: -100%; margin-left: 10px; border-radius: 6px 0 6px 6px; } /* Sidebar --------------------------*/ #pkgdown-sidebar { margin-top: 30px; position: -webkit-sticky; position: sticky; top: 70px; } #pkgdown-sidebar h2 { font-size: 1.5em; margin-top: 1em; } #pkgdown-sidebar h2:first-child { margin-top: 0; } #pkgdown-sidebar .list-unstyled li { margin-bottom: 0.5em; } /* bootstrap-toc tweaks ------------------------------------------------------*/ /* All levels of nav */ nav[data-toggle='toc'] .nav > li > a { padding: 4px 20px 4px 6px; font-size: 1.5rem; font-weight: 400; color: inherit; } nav[data-toggle='toc'] .nav > li > a:hover, nav[data-toggle='toc'] .nav > li > a:focus { padding-left: 5px; color: inherit; border-left: 1px solid #878787; } nav[data-toggle='toc'] .nav > .active > a, nav[data-toggle='toc'] .nav > .active:hover > a, nav[data-toggle='toc'] .nav > .active:focus > a { padding-left: 5px; font-size: 1.5rem; font-weight: 400; color: inherit; border-left: 2px solid #878787; } /* Nav: second level (shown on .active) */ nav[data-toggle='toc'] .nav .nav { display: none; /* Hide by default, but at >768px, show it */ padding-bottom: 10px; } nav[data-toggle='toc'] .nav .nav > li > a { padding-left: 16px; font-size: 1.35rem; } nav[data-toggle='toc'] .nav .nav > li > a:hover, nav[data-toggle='toc'] .nav .nav > li > a:focus { padding-left: 15px; } nav[data-toggle='toc'] .nav .nav > .active > a, nav[data-toggle='toc'] .nav .nav > .active:hover > a, nav[data-toggle='toc'] .nav .nav > .active:focus > a { padding-left: 15px; font-weight: 500; font-size: 1.35rem; } /* orcid ------------------------------------------------------------------- */ .orcid { font-size: 16px; color: #A6CE39; /* margins are required by official ORCID trademark and display guidelines */ margin-left:4px; margin-right:4px; vertical-align: middle; } /* Reference index & topics ----------------------------------------------- */ .ref-index th {font-weight: normal;} .ref-index td {vertical-align: top; min-width: 100px} .ref-index .icon {width: 40px;} .ref-index .alias {width: 40%;} .ref-index-icons .alias {width: calc(40% - 40px);} .ref-index .title {width: 60%;} .ref-arguments th {text-align: right; padding-right: 10px;} .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} .ref-arguments .name {width: 20%;} .ref-arguments .desc {width: 80%;} /* Nice scrolling for wide elements --------------------------------------- */ table { display: block; overflow: auto; } /* Syntax highlighting ---------------------------------------------------- */ pre, code, pre code { background-color: #f8f8f8; color: #333; } pre, pre code { white-space: pre-wrap; word-break: break-all; overflow-wrap: break-word; } pre { border: 1px solid #eee; } pre .img, pre .r-plt { margin: 5px 0; } pre .img img, pre .r-plt img { background-color: #fff; } code a, pre a { color: #375f84; } a.sourceLine:hover { text-decoration: none; } .fl {color: #1514b5;} .fu {color: #000000;} /* function */ .ch,.st {color: #036a07;} /* string */ .kw {color: #264D66;} /* keyword */ .co {color: #888888;} /* comment */ .error {font-weight: bolder;} .warning {font-weight: bolder;} /* Clipboard --------------------------*/ .hasCopyButton { position: relative; } .btn-copy-ex { position: absolute; right: 0; top: 0; visibility: hidden; } .hasCopyButton:hover button.btn-copy-ex { visibility: visible; } /* headroom.js ------------------------ */ .headroom { will-change: transform; transition: transform 200ms linear; } .headroom--pinned { transform: translateY(0%); } .headroom--unpinned { transform: translateY(-100%); } /* mark.js ----------------------------*/ mark { background-color: rgba(255, 255, 51, 0.5); border-bottom: 2px solid rgba(255, 153, 51, 0.3); padding: 1px; } /* vertical spacing after htmlwidgets */ .html-widget { margin-bottom: 10px; } /* fontawesome ------------------------ */ .fab { font-family: "Font Awesome 5 Brands" !important; } /* don't display links in code chunks when printing */ /* source: https://stackoverflow.com/a/10781533 */ @media print { code a:link:after, code a:visited:after { content: ""; } } /* Section anchors --------------------------------- Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 */ div.csl-bib-body { } div.csl-entry { clear: both; } .hanging-indent div.csl-entry { margin-left:2em; text-indent:-2em; } div.csl-left-margin { min-width:2em; float:left; } div.csl-right-inline { margin-left:2em; padding-left:1em; } div.csl-indent { margin-left: 2em; } ================================================ FILE: docs/pkgdown.js ================================================ /* http://gregfranko.com/blog/jquery-best-practices/ */ (function($) { $(function() { $('.navbar-fixed-top').headroom(); $('body').css('padding-top', $('.navbar').height() + 10); $(window).resize(function(){ $('body').css('padding-top', $('.navbar').height() + 10); }); $('[data-toggle="tooltip"]').tooltip(); var cur_path = paths(location.pathname); var links = $("#navbar ul li a"); var max_length = -1; var pos = -1; for (var i = 0; i < links.length; i++) { if (links[i].getAttribute("href") === "#") continue; // Ignore external links if (links[i].host !== location.host) continue; var nav_path = paths(links[i].pathname); var length = prefix_length(nav_path, cur_path); if (length > max_length) { max_length = length; pos = i; } } // Add class to parent
  • , and enclosing
  • if in dropdown if (pos >= 0) { var menu_anchor = $(links[pos]); menu_anchor.parent().addClass("active"); menu_anchor.closest("li.dropdown").addClass("active"); } }); function paths(pathname) { var pieces = pathname.split("/"); pieces.shift(); // always starts with / var end = pieces[pieces.length - 1]; if (end === "index.html" || end === "") pieces.pop(); return(pieces); } // Returns -1 if not found function prefix_length(needle, haystack) { if (needle.length > haystack.length) return(-1); // Special case for length-0 haystack, since for loop won't run if (haystack.length === 0) { return(needle.length === 0 ? 0 : -1); } for (var i = 0; i < haystack.length; i++) { if (needle[i] != haystack[i]) return(i); } return(haystack.length); } /* Clipboard --------------------------*/ function changeTooltipMessage(element, msg) { var tooltipOriginalTitle=element.getAttribute('data-original-title'); element.setAttribute('data-original-title', msg); $(element).tooltip('show'); element.setAttribute('data-original-title', tooltipOriginalTitle); } if(ClipboardJS.isSupported()) { $(document).ready(function() { var copyButton = ""; $("div.sourceCode").addClass("hasCopyButton"); // Insert copy buttons: $(copyButton).prependTo(".hasCopyButton"); // Initialize tooltips: $('.btn-copy-ex').tooltip({container: 'body'}); // Initialize clipboard: var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { text: function(trigger) { return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); } }); clipboardBtnCopies.on('success', function(e) { changeTooltipMessage(e.trigger, 'Copied!'); e.clearSelection(); }); clipboardBtnCopies.on('error', function() { changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); }); }); } })(window.jQuery || window.$) ================================================ FILE: docs/pkgdown.yml ================================================ pandoc: 3.1.11 pkgdown: 2.0.7 pkgdown_sha: ~ articles: intro_htmlwidgets: intro_htmlwidgets.html intro_inputs: intro_inputs.html intro_reactR: intro_reactR.html last_built: 2024-09-14T13:01Z ================================================ FILE: docs/reference/React.html ================================================ React component builder. — React • reactR

    React is a syntactically-convenient way to create instances of React components that can be sent to the browser for display. It is a list for which extract methods are defined, allowing object creation syntax like React$MyComponent(x = 1) where MyComponent is a React component you have exposed to Shiny in JavaScript.

    React

    Format

    An object of class react_component_builder of length 0.

    Details

    Internally, the component function is used to create the component instance.

    Examples

    # Create an instance of ParentComponent with two children,
    # ChildComponent and OtherChildComponent.
    React$ParentComponent(
      x = 1,
      y = 2,
      React$ChildComponent(),
      React$OtherChildComponent()
    )
    #> <ParentComponent x="1" y="2">
    #>   <ChildComponent></ChildComponent>
    #>   <OtherChildComponent></OtherChildComponent>
    #> </ParentComponent>
    

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/babel_transform.html ================================================ Transform Code with Babel — babel_transform • reactR

    Helper function to use V8 with Babel so we can avoid a JSX transformer with using reactR.

    babel_transform(code = "")

    Arguments

    code

    character

    Value

    transformed character

    Examples

    if (FALSE) {
    library(reactR)
    babel_transform('<div>react div</div>')
    }
    

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/component.html ================================================ Create a React component — component • reactR

    Create a React component

    component(name, varArgs = list())

    Arguments

    name

    Name of the React component, which must start with an upper-case character.

    varArgs

    Attributes and children of the element to pass along to tag as varArgs.

    Value

    An htmltools tag object

    Examples

    component("ParentComponent",
      list(
        x = 1,
        y = 2,
        component("ChildComponent"),
        component("OtherChildComponent")
      )
    )
    #> <ParentComponent x="1" y="2">
    #>   <ChildComponent></ChildComponent>
    #>   <OtherChildComponent></OtherChildComponent>
    #> </ParentComponent>
    

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/createReactShinyInput.html ================================================ Create a React-based input — createReactShinyInput • reactR

    Create a React-based input

    createReactShinyInput(
      inputId,
      class,
      dependencies,
      default = NULL,
      configuration = list(),
      container = htmltools::tags$div
    )

    Arguments

    inputId

    The input slot that will be used to access the value.

    class

    Space-delimited list of CSS class names that should identify this input type in the browser.

    dependencies

    HTML dependencies to include in addition to those supporting React. Must contain at least one dependency, that of the input's implementation.

    default

    Initial value.

    configuration

    Static configuration data.

    container

    Function to generate an HTML element to contain the input.

    Value

    Shiny input suitable for inclusion in a UI.

    Examples

    myInput <- function(inputId, default = "") {
      # The value of createReactShinyInput should be returned from input constructor functions.
      createReactShinyInput(
        inputId,
        "myinput",
        # At least one htmlDependency must be provided -- the JavaScript implementation of the input.
        htmlDependency(
          name = "my-input",
          version = "1.0.0",
          src = "www/mypackage/myinput",
          package = "mypackage",
          script = "myinput.js"
        ),
        default
      )
    }
    

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/html_dependency_corejs.html ================================================ Shim Dependency for React in RStudio Viewer — html_dependency_corejs • reactR

    Add this first for 'React' to work in RStudio Viewer.

    html_dependency_corejs()

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/html_dependency_mobx.html ================================================ Dependencies for 'mobx' — html_dependency_mobx • reactR

    Add JavaScript 'mobx' and 'mobx-react' dependency. When using with 'react', the order of the dependencies is important, so please add html_dependency_react() before html_dependency_mobx().

    html_dependency_mobx(react = TRUE)

    Arguments

    react

    logical to add react 'mobx' dependencies.

    Examples

    if(interactive()) {
    
    library(htmltools)
    library(reactR)
    
    browsable(
      tagList(
        html_dependency_mobx(react = FALSE),
        div(id="test"),
        tags$script(HTML(
    "
      var obs = mobx.observable({val: null})
      mobx.autorun(function() {
        document.querySelector('#test').innerText = obs.val
      })
      setInterval(
        function() {obs.val++},
        1000
      )
    "
        ))
      )
    )
    }
    
    if (FALSE) {
    # use with react
    library(htmltools)
    library(reactR)
    
    browsable(
      tagList(
        html_dependency_react(),
        html_dependency_mobx(),
        div(id="test"),
        tags$script(HTML(babel_transform(
    "
      var obs = mobx.observable({val: null})
      var App = mobxReact.observer((props) => <div>{props.obs.val}</div>)
    
      ReactDOM.render(<App obs = {obs}/>, document.querySelector('#test'))
    
      setInterval(
        function() {obs.val++},
        1000
      )
    "
        )))
      )
    )
    }
    

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/html_dependency_react.html ================================================ Dependencies for React — html_dependency_react • reactR

    Add JavaScript 'React' dependency. For this to work in RStudio Viewer, also include html_dependency_corejs.

    html_dependency_react(offline = TRUE)

    Arguments

    offline

    logical to use local file dependencies. If FALSE, then the dependencies use the Facebook cdn as its src. To use with JSX see babel_transform.

    Examples

    library(reactR)
    library(htmltools)
    #> Warning: package 'htmltools' was built under R version 4.3.3
    
    tagList(
      tags$script(
      "
        ReactDOM.render(
          React.createElement(
            'h1',
            null,
            'Powered by React'
          ),
          document.body
        )
      "
      ),
       #add core-js first to work in RStudio Viewer
      html_dependency_corejs(),
      html_dependency_react() #offline=FALSE for CDN
    )
    #> <script>
    #>     ReactDOM.render(
    #>       React.createElement(
    #>         'h1',
    #>         null,
    #>         'Powered by React'
    #>       ),
    #>       document.body
    #>     )
    #>   </script>
    

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/html_dependency_reacttools.html ================================================ Adds window.reactR.exposeComponents and window.reactR.hydrate — html_dependency_reacttools • reactR

    Adds window.reactR.exposeComponents and window.reactR.hydrate

    html_dependency_reacttools()

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/index.html ================================================ Function reference • reactR

    All functions

    babel_transform()

    Transform Code with Babel

    component()

    Create a React component

    createReactShinyInput()

    Create a React-based input

    html_dependency_corejs()

    Shim Dependency for React in RStudio Viewer

    html_dependency_mobx()

    Dependencies for 'mobx'

    html_dependency_react()

    Dependencies for React

    html_dependency_reacttools()

    Adds window.reactR.exposeComponents and window.reactR.hydrate

    React

    React component builder.

    reactMarkup()

    Prepare data that represents a single-element character vector, a React component, or an htmltools tag for sending to the client.

    scaffoldReactShinyInput()

    Create implementation scaffolding for a React.js-based Shiny input.

    scaffoldReactWidget()

    Create implementation scaffolding for a React.js-based HTML widget

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/reactMarkup.html ================================================ Prepare data that represents a single-element character vector, a React component, or an htmltools tag for sending to the client. — reactMarkup • reactR

    Tag lists as returned by htmltools tagList are not currently supported.

    reactMarkup(tag)

    Arguments

    tag

    character vector or React component or tag

    Value

    A reactR markup object suitable for being passed to

    createWidget as widget instance data.

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/scaffoldReactShinyInput.html ================================================ Create implementation scaffolding for a React.js-based Shiny input. — scaffoldReactShinyInput • reactR

    Add the minimal code required to implement a React.js-based Shiny input to an R package.

    scaffoldReactShinyInput(name, npmPkgs = NULL, edit = interactive())

    Arguments

    name

    Name of input

    npmPkgs

    Optional NPM packages upon which this input is based which will be used to populate package.json. Should be a named list of names to versions.

    edit

    Automatically open the input's source files after creating the scaffolding.

    Note

    This function must be executed from the root directory of the package you wish to add the input to.

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/reference/scaffoldReactWidget.html ================================================ Create implementation scaffolding for a React.js-based HTML widget — scaffoldReactWidget • reactR

    Add the minimal code required to implement a React.js-based HTML widget to an R package.

    scaffoldReactWidget(name, npmPkgs = NULL, edit = interactive())

    Arguments

    name

    Name of widget

    npmPkgs

    Optional NPM packages upon which this widget is based which will be used to populate package.json. Should be a named list of names to versions.

    edit

    Automatically open the widget's JavaScript source file after creating the scaffolding.

    Note

    This function must be executed from the root directory of the package you wish to add the widget to.

    Site built with pkgdown 2.0.7.

    ================================================ FILE: docs/sitemap.xml ================================================ /404.html /articles/index.html /articles/intro_htmlwidgets.html /articles/intro_inputs.html /articles/intro_reactR.html /authors.html /CONDUCT.html /index.html /LICENSE-text.html /news/index.html /reference/babel_transform.html /reference/component.html /reference/createReactShinyInput.html /reference/html_dependency_corejs.html /reference/html_dependency_mobx.html /reference/html_dependency_react.html /reference/html_dependency_reacttools.html /reference/index.html /reference/React.html /reference/reactMarkup.html /reference/scaffoldReactShinyInput.html /reference/scaffoldReactWidget.html ================================================ FILE: inst/examples/antd.R ================================================ library(htmltools) library(reactR) library(pipeR) antd <- htmlDependency( name = "antd", version = "2.13.10", src = c(href="https://unpkg.com/antd@2.13.10/dist"), script = "antd.min.js", stylesheet = "antd.min.css" ) ### menu #### tl <- tagList( tags$div(id="app",style="width:25%;"), tags$script(HTML(babel_transform(' var menu = Navigation One Navigation Two ReactDOM.render(menu, document.querySelector("#app")) '))) ) browsable( tagList( tl, html_dependency_react(), antd ) ) ### steps #### steps <- tag( "antd.Steps", list( current=noquote("{1}"), tag("antd.Steps.Step", list(title="Finished", description="This is a description." )), tag("antd.Steps.Step", list(title="In Progress",description="This is a description." )), tag("antd.Steps.Step", list(title="Waiting", description="This is a description." )) ) ) tagList( tags$div(id="stepapp"), steps %>>% { sprintf( " const steps = %s; ReactDOM.render(steps, document.querySelector('#stepapp')); ", . ) } %>>% babel_transform() %>>% HTML %>>% tags$script() ) %>>% attachDependencies( list( html_dependency_react(), antd ) ) %>>% browsable() ### steps with button #### steps_button <- list( list( title= 'Data', content= 'Raw Data' ), list( title= 'Model', content= 'Code for Model' ), list( title= 'Plot', content= 'Beautiful Plot' ) ) %>>% jsonlite::toJSON(auto_unbox=TRUE) content_data <- tags$pre( HTML(paste0( capture.output(str(iris,max.level=1)), collapse="
    " )) ) content_model <- tags$pre("lm(Petal.Width~Petal.Length, data=iris)") content_plot <- HTML( svglite::htmlSVG({plot(lm(Petal.Length~Petal.Width,data=iris),which=1)},standalone=FALSE) ) tagList( tags$div(id="stepapp", style="width:30%;"), steps_button %>>% { sprintf( ' const steps = %s; steps[0].content = %s; steps[1].content = %s; steps[2].content = class App extends React.Component { constructor(props) { super(props); this.state = { current: 0, }; } next() { const current = this.state.current + 1; this.setState({ current }); } prev() { const current = this.state.current - 1; this.setState({ current }); } render() { const { current } = this.state; return (
    {steps.map(item => )}
    {steps[this.state.current].content}
    { this.state.current < steps.length - 1 && this.next()}>Next } { this.state.current === steps.length - 1 && message.success("Processing complete!")}>Done } { this.state.current > 0 && this.prev()}> Previous }
    ); } } ReactDOM.render(, document.querySelector("#stepapp")); ', ., content_data, content_model, base64enc::dataURI(rsvg::rsvg_png(charToRaw(content_plot)),mime="image/png") ) } %>>% babel_transform() %>>% HTML %>>% tags$script() ) %>>% attachDependencies( list( html_dependency_react(offline=FALSE), antd ) ) %>>% browsable() ================================================ FILE: inst/examples/office-fabric.R ================================================ library(htmltools) library(reactR) fabric <- htmlDependency( name = "office-fabric-ui-react", version = "7.121.12", src = c(href="https://unpkg.com/office-ui-fabric-react@7.121.12/dist/"), script = "office-ui-fabric-react.min.js", stylesheet = "css/fabric.min.css" ) browsable( tagList( html_dependency_react(), fabric ) ) browsable( tagList( html_dependency_react(), fabric, tags$div(id = "app-button"), tags$script(HTML(babel_transform( " let btn =
    Command button Create account
    ReactDOM.render(btn, document.querySelector('#app-button')); " ))) ) ) browsable( tagList( html_dependency_react(), fabric, tags$div(id="pivot-example"), tags$script(HTML(babel_transform( " class PivotBasicExample extends React.Component { render() { return (
    Pivot #1 Pivot #2 Pivot #3
    ); } } ReactDOM.render(, document.querySelector('#pivot-example')); " ))) ) ) ================================================ FILE: inst/templates/input_app.R.txt ================================================ library(shiny) library(${package}) ui <- fluidPage( titlePanel("reactR Input Example"), ${name}Input("textInput"), textOutput("textOutput") ) server <- function(input, output, session) { output$textOutput <- renderText({ sprintf("You entered: %s", input$textInput) }) } shinyApp(ui, server) ================================================ FILE: inst/templates/input_js.txt ================================================ import { reactShinyInput } from 'reactR'; const TextInput = ({ configuration, value, setValue }) => { return setValue(e.target.value)}/>; }; reactShinyInput('.${name}', '${package}.${name}', TextInput); ================================================ FILE: inst/templates/input_r.txt ================================================ #' #' #' #' #' @importFrom reactR createReactShinyInput #' @importFrom htmltools htmlDependency tags #' #' @export ${name}Input <- function(inputId, default = "") { reactR::createReactShinyInput( inputId, "${name}", htmltools::htmlDependency( name = "${name}-input", version = "1.0.0", src = "www/${package}/${name}", package = "${package}", script = "${name}.js" ), default, list(), htmltools::tags$span ) } #' #' #' #' #' @export update${capName}Input <- function(session, inputId, value, configuration = NULL) { message <- list(value = value) if (!is.null(configuration)) message$configuration <- configuration session$sendInputMessage(inputId, message); } ================================================ FILE: inst/templates/package.json.txt ================================================ { "private": true, "dependencies": { ${npmPkgs} }, "devDependencies": { "webpack": "^4.27.1", "webpack-cli": "^3.1.2", "@babel/core": "^7.2.0", "babel-loader": "^8.0.4", "@babel/preset-env": "^7.2.0", "@babel/preset-react": "^7.0.0", "css-loader": "^5.0.1", "style-loader": "^2.0.0" }, "scripts": { "watch": "webpack --watch", "build": "webpack" } } ================================================ FILE: inst/templates/webpack.config.js.txt ================================================ var path = require('path'); module.exports = { entry: path.join(__dirname, 'srcjs', '${name}.jsx'), output: { path: path.join(__dirname, '${outputPath}'), filename: '${name}.js' }, module: { rules: [ { test: /\.jsx?$/, loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-react'] } }, // For CSS so that import "path/style.css"; works { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, externals: { 'react': 'window.React', 'react-dom': 'window.ReactDOM', 'reactR': 'window.reactR' }, stats: { colors: true }, devtool: 'source-map' }; ================================================ FILE: inst/templates/widget_app.R.txt ================================================ library(shiny) library(${name}) ui <- fluidPage( titlePanel("reactR HTMLWidget Example"), ${name}Output('widgetOutput') ) server <- function(input, output, session) { output$widgetOutput <- render${capName}( ${name}("Hello world!") ) } shinyApp(ui, server) ================================================ FILE: inst/templates/widget_js.txt ================================================ import { reactWidget } from 'reactR'; reactWidget('${name}', 'output', {}, {}); ================================================ FILE: inst/templates/widget_r.txt ================================================ #' #' #' #' #' @import htmlwidgets #' #' @export ${name} <- function(message, width = NULL, height = NULL, elementId = NULL) { # describe a React component to send to the browser for rendering. component <- reactR::reactMarkup(htmltools::tag("div", list(message))) # create widget htmlwidgets::createWidget( name = '${name}', component, width = width, height = height, package = '${package}', elementId = elementId ) } #' Called by HTMLWidgets to produce the widget's root element. #' @noRd widget_html.${name} <- function(id, style, class, ...) { htmltools::tagList( # Necessary for RStudio viewer version < 1.2 reactR::html_dependency_corejs(), reactR::html_dependency_react(), reactR::html_dependency_reacttools(), htmltools::tags$div(id = id, class = class, style = style) ) } #' Shiny bindings for ${name} #' #' Output and render functions for using ${name} within Shiny #' applications and interactive Rmd documents. #' #' @param outputId output variable to read from #' @param width,height Must be a valid CSS unit (like \code{'100\%'}, #' \code{'400px'}, \code{'auto'}) or a number, which will be coerced to a #' string and have \code{'px'} appended. #' @param expr An expression that generates a ${name} #' @param env The environment in which to evaluate \code{expr}. #' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This #' is useful if you want to save an expression in a variable. #' #' @name ${name}-shiny #' #' @export ${name}Output <- function(outputId, width = '100%', height = '400px'){ htmlwidgets::shinyWidgetOutput(outputId, '${name}', width, height, package = '${package}') } #' @rdname ${name}-shiny #' @export render${capName} <- function(expr, env = parent.frame(), quoted = FALSE) { if (!quoted) { expr <- substitute(expr) } # force quoted htmlwidgets::shinyRenderWidget(expr, ${name}Output, env, quoted = TRUE) } ================================================ FILE: inst/templates/widget_yaml.txt ================================================ # (uncomment to add a dependency) # dependencies: # - name: # version: # src: # script: # stylesheet: ================================================ FILE: inst/www/core-js/LICENSE ================================================ Copyright (c) 2014-2017 Denis Pushkarev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: inst/www/core-js/package.json ================================================ { "devDependencies": { "@babel/cli": "^7.7.7", "@babel/core": "^7.7.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4", "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", "@babel/plugin-proposal-optional-chaining": "^7.7.5", "@babel/plugin-transform-arrow-functions": "^7.7.4", "@babel/plugin-transform-block-scoped-functions": "^7.7.4", "@babel/plugin-transform-block-scoping": "^7.7.4", "@babel/plugin-transform-classes": "^7.7.4", "@babel/plugin-transform-computed-properties": "^7.7.4", "@babel/plugin-transform-destructuring": "^7.7.4", "@babel/plugin-transform-exponentiation-operator": "^7.7.4", "@babel/plugin-transform-literals": "^7.7.4", "@babel/plugin-transform-member-expression-literals": "^7.7.4", "@babel/plugin-transform-parameters": "^7.7.7", "@babel/plugin-transform-property-literals": "^7.7.4", "@babel/plugin-transform-shorthand-properties": "^7.7.4", "@babel/plugin-transform-spread": "^7.7.4", "@babel/plugin-transform-template-literals": "^7.7.4", "babel-loader": "^8.0.6", "babel-plugin-transform-es2015-modules-simple-commonjs": "~0.3.0", "babel-plugin-transform-for-of-as-array": "^1.1.1", "es-observable": "git+https://github.com/tc39/proposal-observable.git#bf4d87144b6189e793593868e3c022eb51a7d292", "eslint": "^6.8.0", "eslint-import-resolver-webpack": "^0.12.0", "eslint-plugin-import": "^2.19.1", "eslint-plugin-node": "^10.0.0", "eslint-plugin-optimize-regex": "^1.1.7", "eslint-plugin-qunit": "^4.0.0", "eslint-plugin-sonarjs": "^0.5.0", "eslint-plugin-unicorn": "^15.0.0", "grunt": "^1.0.4", "grunt-cli": "^1.3.2", "grunt-contrib-clean": "^2.0.0", "grunt-contrib-copy": "^1.0.0", "grunt-contrib-uglify": "^4.0.1", "grunt-karma": "^3.0.2", "grunt-webpack": "^3.1.3", "karma": "^4.4.1", "karma-chrome-launcher": "^3.1.0", "karma-phantomjs-launcher": "~1.0.4", "karma-qunit": "^4.0.0", "lerna": "^3.19.0", "moon-unit": "^0.2.2", "phantomjs-prebuilt": "~2.1.16", "promises-aplus-tests": "^2.1.2", "puppeteer": "~2.0.0", "qunit": "~2.9.3", "webpack": "^4.41.4" }, "license": "MIT", "repository": { "type": "git", "url": "https://github.com/zloirock/core-js.git" }, "scripts": { "bootstrap": "lerna bootstrap --no-ci", "build": "grunt clean copy && npm run bootstrap && npm run build-compat && grunt bundle uglify", "build-compat": "npm run build-compat-data && npm run build-compat-entries && npm run build-compat-modules-by-versions", "build-compat-data": "node packages/core-js-compat/src/build-data", "build-compat-entries": "node packages/core-js-compat/src/build-entries", "build-compat-modules-by-versions": "node packages/core-js-compat/src/build-modules-by-versions", "lint": "grunt clean copy && npm run bootstrap && npm run build-compat && eslint ./", "unit-tests": "grunt clean copy && npm run bootstrap && npm run build-compat && grunt bundle webpack:helpers webpack:tests karma:tests", "unit-tests-pure": "grunt clean copy && npm run build-compat && grunt webpack:helpers webpack:pure karma:pure", "bundle-promises-tests": "grunt webpack:promises-aplus-tests", "promises-tests": "promises-aplus-tests tests/promises-aplus/adapter --timeout 1000", "observables-tests": "babel node_modules/es-observable/test/ -d tests/bundles/observables-tests/ && node tests/observables/adapter && node tests/observables/adapter-pure", "commonjs-tests": "node tests/commonjs", "commonjs-entries-content": "node tests/commonjs-entries-content", "targets-parser-tests": "node tests/targets-parser", "test": "grunt clean copy && npm run bootstrap && npm run build-compat && eslint ./ && grunt webpack:helpers webpack:tests bundle uglify karma:tests webpack:helpers webpack:pure karma:pure && npm run promises-tests && npm run observables-tests && npm run commonjs-tests && npm run commonjs-entries-content && npm run targets-parser-tests" }, "engines": { "node": ">=8.9.0" } } ================================================ FILE: inst/www/mobx/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Michel Weststrate Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: inst/www/mobx/mobx-react-lite.js ================================================ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('mobx'), require('react')) : typeof define === 'function' && define.amd ? define(['exports', 'mobx', 'react'], factory) : (global = global || self, factory(global.mobxReactLite = {}, global.mobx, global.React)); }(this, function (exports, mobx, React) { 'use strict'; var React__default = 'default' in React ? React['default'] : React; if (!React.useState) { throw new Error("mobx-react-lite requires React with Hooks support"); } if (!mobx.spy) { throw new Error("mobx-react-lite requires mobx at least version 4 to be available"); } function useObservable(initialValue) { var observableRef = React.useRef(null); if (!observableRef.current) { observableRef.current = mobx.observable(initialValue); } return observableRef.current; } function useComputed(func, inputs) { if (inputs === void 0) { inputs = []; } var computed = React.useMemo(function () { return mobx.computed(func); }, inputs); return computed.get(); } var doNothingDisposer = function () { // empty }; /** * Adds an observable effect (reaction, autorun, or anything else that returns a disposer) that will be registered upon component creation and disposed upon unmounting. * Returns the generated disposer for early disposal. * * @export * @template D * @param {() => D} disposerGenerator A function that returns the disposer of the wanted effect. * @param {ReadonlyArray} [inputs=[]] If you want the effect to be automatically re-created when some variable(s) are changed then pass them in this array. * @returns {D} */ function useDisposable(disposerGenerator, inputs) { if (inputs === void 0) { inputs = []; } var disposerRef = React.useRef(null); var earlyDisposedRef = React.useRef(false); React.useEffect(function () { return lazyCreateDisposer(false); }, inputs); function lazyCreateDisposer(earlyDisposal) { // ensure that we won't create a new disposer if it was early disposed if (earlyDisposedRef.current) { return doNothingDisposer; } if (!disposerRef.current) { var newDisposer = disposerGenerator(); if (typeof newDisposer !== "function") { var error = new Error("generated disposer must be a function"); { // tslint:disable-next-line:no-console console.error(error); return doNothingDisposer; } } disposerRef.current = newDisposer; } return function () { if (disposerRef.current) { disposerRef.current(); disposerRef.current = null; } if (earlyDisposal) { earlyDisposedRef.current = true; } }; } return lazyCreateDisposer(true); } var globalIsUsingStaticRendering = false; function useStaticRendering(enable) { globalIsUsingStaticRendering = enable; } function isUsingStaticRendering() { return globalIsUsingStaticRendering; } /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function printDebugValue(v) { if (!v.current) { return ""; } return mobx.getDependencyTree(v.current); } var EMPTY_ARRAY = []; function useUnmount(fn) { React.useEffect(function () { return fn; }, EMPTY_ARRAY); } function useForceUpdate() { var _a = __read(React.useState(0), 2), setTick = _a[1]; var update = React.useCallback(function () { setTick(function (tick) { return tick + 1; }); }, []); return update; } function isPlainObject(value) { if (!value || typeof value !== "object") { return false; } var proto = Object.getPrototypeOf(value); return !proto || proto === Object.prototype; } var EMPTY_OBJECT = {}; function useObserver(fn, baseComponentName, options) { if (baseComponentName === void 0) { baseComponentName = "observed"; } if (options === void 0) { options = EMPTY_OBJECT; } if (isUsingStaticRendering()) { return fn(); } var wantedForceUpdateHook = options.useForceUpdate || useForceUpdate; var forceUpdate = wantedForceUpdateHook(); var reaction = React.useRef(null); if (!reaction.current) { reaction.current = new mobx.Reaction("observer(" + baseComponentName + ")", function () { forceUpdate(); }); } var dispose = function () { if (reaction.current && !reaction.current.isDisposed) { reaction.current.dispose(); } }; React.useDebugValue(reaction, printDebugValue); useUnmount(function () { dispose(); }); // render the original component, but have the // reaction track the observables, so that rendering // can be invalidated (see above) once a dependency changes var rendering; var exception; reaction.current.track(function () { try { rendering = fn(); } catch (e) { exception = e; } }); if (exception) { dispose(); throw exception; // re-throw any exceptions catched during rendering } return rendering; } // n.b. base case is not used for actual typings or exported in the typing files function observer(baseComponent, options) { // The working of observer is explained step by step in this talk: https://www.youtube.com/watch?v=cPF4iBedoF0&feature=youtu.be&t=1307 if (isUsingStaticRendering()) { return baseComponent; } var realOptions = __assign({ forwardRef: false }, options); var baseComponentName = baseComponent.displayName || baseComponent.name; var wrappedComponent = function (props, ref) { return useObserver(function () { return baseComponent(props, ref); }, baseComponentName); }; wrappedComponent.displayName = baseComponentName; // memo; we are not intested in deep updates // in props; we assume that if deep objects are changed, // this is in observables, which would have been tracked anyway var memoComponent; if (realOptions.forwardRef) { // we have to use forwardRef here because: // 1. it cannot go before memo, only after it // 2. forwardRef converts the function into an actual component, so we can't let the baseComponent do it // since it wouldn't be a callable function anymore memoComponent = React.memo(React.forwardRef(wrappedComponent)); } else { memoComponent = React.memo(wrappedComponent); } copyStaticProperties(baseComponent, memoComponent); memoComponent.displayName = baseComponentName; return memoComponent; } // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js var hoistBlackList = { $$typeof: true, render: true, compare: true, type: true }; function copyStaticProperties(base, target) { Object.keys(base).forEach(function (key) { if (base.hasOwnProperty(key) && !hoistBlackList[key]) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(base, key)); } }); } function ObserverComponent(_a) { var children = _a.children, render = _a.render; var component = children || render; if (typeof component !== "function") { return null; } return useObserver(component); } ObserverComponent.propTypes = { children: ObserverPropsCheck, render: ObserverPropsCheck }; ObserverComponent.displayName = "Observer"; function ObserverPropsCheck(props, key, componentName, location, propFullName) { var extraKey = key === "children" ? "render" : "children"; var hasProp = typeof props[key] === "function"; var hasExtraProp = typeof props[extraKey] === "function"; if (hasProp && hasExtraProp) { return new Error("MobX Observer: Do not use children and render in the same time in`" + componentName); } if (hasProp || hasExtraProp) { return null; } return new Error("Invalid prop `" + propFullName + "` of type `" + typeof props[key] + "` supplied to" + " `" + componentName + "`, expected `function`."); } function useAsObservableSourceInternal(current, usedByLocalStore) { if (usedByLocalStore && current === undefined) { return undefined; } var _a = __read(React__default.useState(function () { return mobx.observable(current, {}, { deep: false }); }), 1), res = _a[0]; mobx.runInAction(function () { Object.assign(res, current); }); return res; } function useAsObservableSource(current) { return useAsObservableSourceInternal(current, false); } function useLocalStore(initializer, current) { var source = useAsObservableSourceInternal(current, true); return React__default.useState(function () { var local = mobx.observable(initializer(source)); if (isPlainObject(local)) { mobx.runInAction(function () { Object.keys(local).forEach(function (key) { var value = local[key]; if (typeof value === "function") { local[key] = wrapInTransaction(value, local); } }); }); } return local; })[0]; } // tslint:disable-next-line: ban-types function wrapInTransaction(fn, context) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return mobx.transaction(function () { return fn.apply(context, args); }); }; } exports.Observer = ObserverComponent; exports.isUsingStaticRendering = isUsingStaticRendering; exports.observer = observer; exports.useAsObservableSource = useAsObservableSource; exports.useComputed = useComputed; exports.useDisposable = useDisposable; exports.useForceUpdate = useForceUpdate; exports.useLocalStore = useLocalStore; exports.useObservable = useObservable; exports.useObserver = useObserver; exports.useStaticRendering = useStaticRendering; Object.defineProperty(exports, '__esModule', { value: true }); })); ================================================ FILE: inst/www/mobx/mobx-react.umd.js ================================================ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("react-dom"),require("mobx-react-lite"),require("react"),require("mobx")):"function"==typeof define&&define.amd?define(["exports","react-dom","mobx-react-lite","react","mobx"],r):r(e.mobxReact={},e.ReactDOM,e.mobxReactLite,e.React,e.mobx)}(this,function(e,r,t,n,o){var i="default"in n?n.default:n,a=0,c={};function s(e){return c[e]||(c[e]=function(e){if("function"==typeof Symbol)return Symbol(e);var r="__$mobx-react "+e+" ("+a+")";return a++,r}(e)),c[e]}function u(e,r){if(f(e,r))return!0;if("object"!=typeof e||null===e||"object"!=typeof r||null===r)return!1;var t=Object.keys(e),n=Object.keys(r);if(t.length!==n.length)return!1;for(var o=0;o0;)n[o]=arguments[o+2];r.locks++;try{var i;return null!=e&&(i=e.apply(this,n)),i}finally{r.locks--,0===r.locks&&r.methods.forEach(function(e){e.apply(t,n)})}}function h(e,r){return function(){for(var t=[],n=arguments.length;n--;)t[n]=arguments[n];y.call.apply(y,[this,e,r].concat(t))}}function v(e,r,t){var n=function(e,r){var t=e[d]=e[d]||{},n=t[r]=t[r]||{};return n.locks=n.locks||0,n.methods=n.methods||[],n}(e,r);n.methods.indexOf(t)<0&&n.methods.push(t);var o=Object.getOwnPropertyDescriptor(e,r);if(!o||!o[b]){var i=function e(r,t,n,o,i){var a,c=h(i,o);return(a={})[b]=!0,a.get=function(){return c},a.set=function(i){if(this===r)c=h(i,o);else{var a=e(this,t,n,o,i);Object.defineProperty(this,t,a)}},a.configurable=!0,a.enumerable=n,a}(e,r,o?o.enumerable:void 0,n,e[r]);Object.defineProperty(e,r,i)}}var m=o.$mobx||"$mobx",g=s("isUnmounted"),O=s("skipRender"),w=s("isForcingUpdate");function j(e,r){return t.isUsingStaticRendering()&&console.warn("[mobx-react] It seems that a re-rendering of a React component is triggered while in static (server-side) mode. Please make sure components are rendered only once server-side."),this.state!==r||!u(this.props,e)}function x(e,r){var t=s("reactProp_"+r+"_valueHolder"),n=s("reactProp_"+r+"_atomHolder");function i(){return this[n]||l(this,n,o.createAtom("reactive "+r)),this[n]}Object.defineProperty(e,r,{configurable:!0,enumerable:!0,get:function(){return i.call(this).reportObserved(),this[t]},set:function(e){this[w]||u(this[t],e)?l(this,t,e):(l(this,t,e),l(this,O,!0),i.call(this).reportChanged(),l(this,O,!1))}})}var P="function"==typeof n.forwardRef&&n.forwardRef(function(e,r){}).$$typeof;function R(e){if(!0===e.isMobxInjector&&console.warn("Mobx observer: You are trying to use 'observer' on a component that already has 'inject'. Please apply 'observer' before applying 'inject'"),P&&e.$$typeof===P){var r=e.render;if("function"!=typeof r)throw new Error("render property of ForwardRef was not a function");return n.forwardRef(function(){var e=arguments;return i.createElement(t.Observer,null,function(){return r.apply(void 0,e)})})}return"function"!=typeof e||e.prototype&&e.prototype.render||e.isReactClass||n.Component.isPrototypeOf(e)?function(e){var r=e.prototype;if(r.componentWillReact)throw new Error("The componentWillReact life-cycle event is no longer supported");if(e.__proto__!==n.PureComponent)if(r.shouldComponentUpdate){if(r.shouldComponentUpdate!==j)throw new Error("It is not allowed to use shouldComponentUpdate in observer based components.")}else r.shouldComponentUpdate=j;x(r,"props"),x(r,"state");var i=r.render;return r.render=function(){return function(e){var r=this;if(!0===t.isUsingStaticRendering())return e.call(this);l(this,O,!1),l(this,w,!1);var i=this.displayName||this.name||this.constructor&&(this.constructor.displayName||this.constructor.name)||"",a=e.bind(this),c=!1,s=new o.Reaction(i+".render()",function(){if(!c&&(c=!0,!0!==r[g])){var e=!0;try{l(r,w,!0),r[O]||n.Component.prototype.forceUpdate.call(r),e=!1}finally{l(r,w,!1),e&&s.dispose()}}});function u(){c=!1;var e=void 0,r=void 0;if(s.track(function(){try{r=o._allowStateChanges(!1,a)}catch(r){e=r}}),e)throw e;return r}return s.reactComponent=this,u[m]=s,this.render=u,u.call(this)}.call(this,i)},v(r,"componentWillUnmount",function(){!0!==t.isUsingStaticRendering()&&(this.render[m]&&this.render[m].dispose(),this[g]=!0)}),e}(e):t.observer(e)}var C={children:!0,key:!0,ref:!0},E=n.createContext({}),S=function(e){function r(r,t){e.call(this,r,t),this.state=Object.assign({},t,U(r))}return e&&(r.__proto__=e),(r.prototype=Object.create(e&&e.prototype)).constructor=r,r.prototype.render=function(){return n.createElement(E.Provider,{value:this.state},n.Children.only(this.props.children))},r.getDerivedStateFromProps=function(e,r){if("production"!==process.env.NODE_ENV&&!u(r,Object.assign({},r,U(e))))throw new Error("MobX Provider: The set of provided stores has changed. Please avoid changing stores as the change might not propagate to all children");return r},r}(n.Component);function U(e){var r={};if(!e)return r;for(var t in e)_(t)&&(r[t]=e[t]);return r}function _(e){return!C[e]&&"suppressChangedStoreWarning"!==e}function k(e,r,t,o){var a=function(e,r){var t=e.displayName||e.name||e.constructor&&e.constructor.name||"Component";return r?"inject-with-"+r+"("+t+")":"inject("+t+")"}(r,t),c=function(t){function o(){t.apply(this,arguments)}return t&&(o.__proto__=t),(o.prototype=Object.create(t&&t.prototype)).constructor=o,o.prototype.render=function(){var t=this.props,o=t.forwardRef,i=function(e,r){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&-1===r.indexOf(n)&&(t[n]=e[n]);return t}(t,["forwardRef"]);return Object.assign(i,e(this.context||{},i)||{}),o&&!function(e){return!(e.prototype&&e.prototype.render)}(r)&&(i.ref=this.props.forwardRef),n.createElement(r,i)},o}(n.Component);c.contextType=E,o&&(c=R(c)),c.isMobxInjector=!0;var s,u,f,l=i.forwardRef(function(e,r){return i.createElement(c,Object.assign({},e,{forwardRef:r}))});return s=r,u=l,f=Object.getOwnPropertyNames(Object.getPrototypeOf(s)),Object.getOwnPropertyNames(s).forEach(function(e){p[e]||-1!==f.indexOf(e)||Object.defineProperty(u,e,Object.getOwnPropertyDescriptor(s,e))}),l.wrappedComponent=r,l.displayName=a,l}S.contextType=E;var A=s("disposeOnUnmountProto"),M=s("disposeOnUnmountInst");function T(){var e=this;(this[A]||[]).concat(this[M]||[]).forEach(function(r){var t="string"==typeof r?e[r]:r;null!=t&&(Array.isArray(t)?t.map(function(e){return e()}):t())})}function D(e){function r(r,t,n,i,a,c){for(var s=[],u=arguments.length-6;u-- >0;)s[u]=arguments[u+6];return o.untracked(function(){return i=i||"<>",c=c||n,null==t[n]?r?new Error("The "+a+" `"+c+"` is marked as required in `"+i+"`, but its value is `"+(null===t[n]?"null":"undefined")+"`."):null:e.apply(void 0,[t,n,i,a,c].concat(s))})}var t=r.bind(null,!1);return t.isRequired=r.bind(null,!0),t}function $(e){var r=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":function(e,r){return"symbol"===e||"Symbol"===r["@@toStringTag"]||"function"==typeof Symbol&&r instanceof Symbol}(r,e)?"symbol":r}function q(e,r){return D(function(t,n,i,a,c){return o.untracked(function(){if(e&&$(t[n])===r.toLowerCase())return null;var a;switch(r){case"Array":a=o.isObservableArray;break;case"Object":a=o.isObservableObject;break;case"Map":a=o.isObservableMap;break;default:throw new Error("Unexpected mobxType: "+r)}var s=t[n];if(!a(s)){var u=function(e){var r=$(e);if("object"===r){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return r}(s),f=e?" or javascript `"+r.toLowerCase()+"`":"";return new Error("Invalid prop `"+c+"` of type `"+u+"` supplied to `"+i+"`, expected `mobx.Observable"+r+"`"+f+".")}return null})})}function N(e,r){return D(function(t,n,i,a,c){for(var s=[],u=arguments.length-5;u-- >0;)s[u]=arguments[u+5];return o.untracked(function(){if("function"!=typeof r)return new Error("Property `"+c+"` of component `"+i+"` has invalid PropType notation.");var o=q(e,"Array")(t,n,i);if(o instanceof Error)return o;for(var u=t[n],f=0;f/node_modules/" ] }, "husky": { "hooks": { "pre-commit": "lint-staged" } } } ================================================ FILE: inst/www/react/AUTHORS ================================================ 39 <8398a7@gmail.com> Aaron Franks Aaron Gelter Adam Bloomston Adam Krebs Adam Mark Adam Solove Adam Timberlake Adam Zapletal Ahmad Wali Sidiqi Alan Plum Alan Souza Alan deLevie Alastair Hole Alex Alex Boatwright Alex Boyd Alex Dajani Alex Lopatin Alex Mykyta Alex Pien Alex Smith Alex Zelenskiy Alexander Shtuchkin Alexander Solovyov Alexander Tseung Alexandre Gaudencio Alexey Raspopov Alexey Shamrin Ali Ukani Andre Z Sanchez Andreas Savvides Andreas Svensson Andres Kalle Andres Suarez Andrew Clark Andrew Cobby Andrew Davey Andrew Henderson Andrew Kulakov Andrew Rasmussen Andrew Sokolov Andrew Zich Andrey Popp <8mayday@gmail.com> Anthony van der Hoorn Anto Aravinth Antonio Ruberto Antti Ahti Anuj Tomar AoDev April Arcus Areeb Malik Aria Buckles Aria Stewart Arian Faurtosh Artem Nezvigin Austin Wright Ayman Osman Baraa Hamodi Bartosz Kaszubowski Basarat Ali Syed Battaile Fauber Beau Smith Ben Alpert Ben Anderson Ben Brooks Ben Foxall Ben Halpern Ben Jaffe Ben Moss Ben Newman Ben Ripkens Benjamin Keen Benjamin Leiken Benjamin Woodruff Benjy Cui Bill Blanchard Bill Fisher Blaine Hatab Blaine Kasten Bob Eagan Bob Ralian Bob Renwick Bobby Bojan Mihelac Bradley Spaulding Brandon Bloom Brandon Tilley Brenard Cubacub Brian Cooke Brian Holt Brian Hsu Brian Kim Brian Kung Brian Reavis Brian Rue Bruno Škvorc Cam Song Cam Spiers Cameron Chamberlain Cameron Matheson Carter Chung Cassus Adam Banko Cat Chen Cedric Sohrauer Cesar William Alvarenga Changsoon Bok Charles Marsh Chase Adams Cheng Lou Chitharanjan Das Chris Bolin Chris Grovers Chris Ha Chris Rebert Chris Sciolla Christian Alfoni Christian Oliff Christian Roman Christoffer Sawicki Christoph Pojer Christopher Monsanto Clay Allsopp Connor McSheffrey Conor Hastings Cory House Cotton Hou Craig Akimoto Cristovao Verstraeten Damien Pellier Dan Abramov Dan Fox Dan Schafer Daniel Carlsson Daniel Cousens Daniel Friesen Daniel Gasienica Daniel Hejl Daniel Hejl Daniel Lo Nigro Daniel Mané Daniel Miladinov Daniel Rodgers-Pryor Daniel Schonfeld Danny Ben-David Darcy Daryl Lau Darío Javier Cravero Dave Galbraith David Baker David Ed Mellum David Goldberg David Granado David Greenspan David Hellsing David Hu David Khourshid David Mininger David Neubauer David Percy Dean Shi Denis Sokolov Deniss Jacenko Dennis Johnson Devon Blandin Devon Harvey Dmitrii Abramov Dmitriy Rozhkov Dmitry Blues Dmitry Mazuro Domenico Matteo Don Abrams Dongsheng Liu Dustan Kasten Dustin Getz Dylan Harrington Eduardo Garcia Edvin Erikson Elaine Fang Enguerran Eric Clemmons Eric Eastwood Eric Florenzano Eric O'Connell Eric Schoffstall Erik Harper Espen Hovlandsdal Evan Coonrod Evan Vosberg Fabio M. Costa Federico Rampazzo Felipe Oliveira Carvalho Felix Gnass Felix Kling Fernando Correia Frankie Bagnardi François-Xavier Bois Fred Zhao Freddy Rangel Fyodor Ivanishchev G Scott Olson G. Kay Lee Gabe Levi Gajus Kuizinas Gareth Nicholson Garren Smith Gavin McQuistin Geert Pasteels Geert-Jan Brits George A Sisco III Georgii Dolzhykov Gilbert Glen Mailer Grant Timmerman Greg Hurrell Greg Perkins Greg Roodt Gregory Guangqiang Dong Guido Bouman Harry Hull Harry Marr Harry Moreno Harshad Sabne Hekar Khani Hendrik Swanepoel Henrik Nyh Henry Wong Henry Zhu Hideo Matsumoto Hou Chia Huang-Wei Chang Hugo Agbonon Hugo Jobling Hyeock Kwon Héliton Nordt Ian Obermiller Ignacio Carbajo Igor Scekic Ilia Pavlenkov Ilya Shuklin Ilyá Belsky Ingvar Stepanyan Irae Carvalho Isaac Salier-Hellendag Iurii Kucherov Ivan Kozik Ivan Krechetov Ivan Vergiliev J. Andrew Brassington J. Renée Beach JD Isaacks JJ Weber JW Jack Zhang Jackie Wung Jacob Gable Jacob Greenleaf Jae Hun Ro Jaeho Lee Jaime Mingo Jake Worth Jakub Malinowski James James Brantly James Burnett James Friend James Ide James Long James Pearce James Seppi James South James Wen Jamie Wong Jamis Charles Jamison Dance Jan Hancic Jan Kassens Jan Raasch Jared Forsyth Jason Jason Bonta Jason Ly Jason Miller Jason Quense Jason Trill Jason Webster Jay Jaeho Lee Jean Lauliac Jed Watson Jeff Barczewski Jeff Carpenter Jeff Chan Jeff Hicken Jeff Kolesky Jeff Morrison Jeff Welch Jeffrey Lin Jeremy Fairbank Jesse Skinner Jignesh Kakadiya Jim OBrien Jim Sproch Jimmy Jea Jing Chen Jinwoo Oh Jinxiu Lee Jiyeon Seo Jody McIntyre Joe Critchley Joe Stein Joel Auterson Johannes Baiter Johannes Emerich Johannes Lumpe John Heroy John Ryan John Watson John-David Dalton Jon Beebe Jon Chester Jon Hester Jon Madison Jon Scott Clark Jon Tewksbury Jonas Enlund Jonas Gebhardt Jonathan Hsu Jonathan Persson Jordan Harband Jordan Walke Jorrit Schippers Joseph Nudell Joseph Savona Josh Bassett Josh Duck Josh Perez Josh Yudaken Joshua Evans Joshua Go Joshua Goldberg Joshua Ma João Valente Juan Serrano Julen Ruiz Aizpuru Julian Viereck Julien Bordellier Julio Lopez Jun Wu Juraj Dudak Justas Brazauskas Justin Jaffray Justin Robison Justin Woo Kale Kamron Batman Karl Mikkelsen Karpich Dmitry Keito Uchiyama Ken Powers Kent C. Dodds Kevin Cheng <09chengk@gmail.com> Kevin Coughlin Kevin Huang Kevin Lau Kevin Old Kevin Robinson Kewei Jiang Kier Borromeo KimCoding Kirk Steven Hansen Kit Randel Kohei TAKATA Koo Youngmin Krystian Karczewski Kunal Mehta Kurt Ruppel Kyle Kelley Kyle Mathews Laurence Rowe Laurent Etiemble Lee Byron Lee Jaeyoung Lei Leland Richardson Leon Fedotov Leon Yip Leonardo YongUk Kim Levi Buzolic Levi McCallum Lily Logan Allen Lovisa Svallingson Ludovico Fischer Luigy Leon Luke Horvat MIKAMI Yoshiyuki Maher Beg Manas Marcin K. Marcin Kwiatkowski Marcin Szczepanski Mariano Desanze Marjan Mark Anderson Mark Funk Mark Hintz Mark IJbema Mark Murphy Mark Richardson Mark Rushakoff Mark Sun Marlon Landaverde Marshall Roch Martin Andert Martin Hujer Martin Jul Martin Konicek Martin Mihaylov Masaki KOBAYASHI Mathieu M-Gosselin Mathieu Savy Matias Singers Matsunoki Matt Brookes Matt Dunn-Rankin Matt Harrison Matt Huggins Matt Stow Matt Zabriskie Matthew Dapena-Tretter Matthew Herbst Matthew Hodgson Matthew Johnston Matthew King Matthew Looi Matthew Miner Matthias Le Brun Matti Nelimarkka Mattijs Kneppers Max F. Albrecht <1@178.is> Max Heiber Max Stoiber Maxi Ferreira Maxim Abramchuk Merrick Christensen Mert Kahyaoğlu Michael Chan Michael McDermott Michael Randers-Pehrson Michael Ridgway Michael Warner Michael Wiencek Michael Ziwisky Michal Srb Michelle Todd Mihai Parparita Mike D Pilsbury Mike Groseclose Mike Nordick Mikolaj Dadela Miles Johnson Minwe LUO Miorel Palii Morhaus Moshe Kolodny Mouad Debbar Murad Murray M. Moss Nadeesha Cabral Naman Goel Nate Hunzaker Nate Lee Nathan Smith Nathan White Nee <944316342@qq.com> Neri Marschik Nguyen Truong Duy Nicholas Bergson-Shilcock Nicholas Clawson Nick Balestra Nick Fitzgerald Nick Gavalas Nick Merwin Nick Presta Nick Raienko Nick Thompson Nick Williams Niklas Boström Ning Xia Niole Nelson Oiva Eskola Oleg Oleksii Markhovskyi Oliver Zeigermann Olivier Tassinari Owen Coutts Pablo Lacerda de Miranda Paolo Moretti Pascal Hartig Patrick Patrick Laughlin Patrick Stapleton Paul Benigeri Paul Harper Paul O’Shannessy Paul Seiffert Paul Shen Pedro Nauck Pete Hunt Peter Blazejewicz Peter Cottle Peter Jaros Peter Newnham Petri Lehtinen Petri Lievonen Pieter Vanderwerff Pouja Nikray Prathamesh Sonpatki Prayag Verma Preston Parry Rafael Rafal Dittwald Rainer Oviir Rajat Sehgal Rajiv Tirumalareddy Ram Kaniyur Randall Randall Ray Raymond Ha Reed Loden Remko Tronçon Richard D. Worth Richard Feldman Richard Kho Richard Littauer Richard Livesey Richard Wood Rick Beerendonk Rick Ford Riley Tomasek Rob Arnold Robert Binna Robert Knight Robert Sedovsek Robin Berjon Robin Frischmann Roman Pominov Roman Vanesyan Russ Ryan Seddon Sahat Yalkabov Saif Hakim Saiichi Hashimoto Sam Beveridge Sam Saccone Sam Selikoff Samy Al Zahrani Sander Spies Scott Burch Scott Feeney Sean Kinsey Sebastian Markbåge Sebastian McKenzie Seoh Char Sercan Eraslan Serg Sergey Generalov Sergey Rubanov Seyi Adebajo Shane O'Sullivan Shaun Trennery ShihChi Huang Shim Won Shinnosuke Watanabe Shogun Sea Shota Kubota Shripad K Sibi Simen Bekkhus Simon Højberg Simon Welsh Simone Vittori Soichiro Kawamura Sophia Westwood Sota Ohara Spencer Handley Stefan Dombrowski Stephen Murphy Sterling Cobb Steve Baker <_steve_@outlook.com> Steven Luscher Steven Vachon Stoyan Stefanov Sundeep Malladi Sunny Juneja Sven Helmberger Sverre Johansen Sébastien Lorber Sławomir Laskowski Taeho Kim Tay Yang Shun Ted Kim Tengfei Guo Teodor Szente Thomas Aylott Thomas Boyt Thomas Broadley Thomas Reggi Thomas Röggla Thomas Shaddox Thomas Shafer ThomasCrvsr Tienchai Wirojsaksaree Tim Routowicz Tim Schaub Timothy Yung Timur Carpeev Tobias Reiss Tom Duncalf Tom Haggie Tom Hauburger Tom MacWright Tom Occhino Tomasz Kołodziejski Tomoya Suzuki Tony Spiro Toru Kobayashi Trinh Hoang Nhu Tsung Hung Tyler Brock Ustin Zarubin Vadim Chernysh Varun Rau Vasiliy Loginevskiy Victor Alvarez Victor Homyakov Victor Koenders Ville Immonen Vincent Riemer Vincent Siao Vipul A M Vitaly Kramskikh Vitor Balocco Vjeux Volkan Unsal Wander Wang Wayne Larsen WickyNilliams Wincent Colaiuta Wout Mertens Xavier Morel XuefengWu Yakov Dalinchuk Yasar icli YouBao Nong Yuichi Hagio Yuriy Dybskiy Yutaka Nakajima Yuval Dekel Zach Bruggeman Zach Ramaekers Zacharias Zeke Sikelianos Zhangjd adraeth arush brafdlog chen clariroid claudiopro cutbko davidxi dongmeng.ldm iamchenxin iamdoron iawia002 imagentleman koh-taka kohashi85 laiso leeyoungalias li.li maxprafferty rgarifullin songawee sugarshin wali-s yiminghe youmoo zhangjg zwhitchcox Árni Hermann Reynisson 元彦 凌恒 张敏 ================================================ FILE: inst/www/react/LICENSE.txt ================================================ MIT License Copyright (c) 2013-present, Facebook, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: inst/www/react-tools/react-tools.js ================================================ (function(s,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(s=typeof globalThis<"u"?globalThis:s||self,u(s.reactR={}))})(this,function(s){"use strict";function u(n,t){if(typeof t=="string")return t;if(t.name[0]===t.name[0].toUpperCase()&&!n.hasOwnProperty(t.name))throw new Error("Unknown component: "+t.name);for(let i in t.attribs)g(t.attribs[i])&&(t.attribs[i]=u(n,t.attribs[i]));for(var a=n.hasOwnProperty(t.name)?n[t.name]:t.name,r=[a,t.attribs],e=0;e{this.props.message.toUpperCase()}; } } const FunctionalShout = ({ message }) => { return {message.toUpperCase()}; } class TodoList extends React.Component { render() { return
      {this.props.children.map((child, i) => { return
    1. {child}
    2. ; })}
    } } // Converts a parse-xml style tree to an htmltools::tag style tree of JSON. function objectToTag(obj) { return { name: obj.name, attribs: obj.attributes, children: obj.children.map(child => { if (child.type === 'text') { return child.text; } else { return objectToTag(child); } }) } } // Converts a string of markup to an htmltools::tag style tree of JSON. function stringToTag(str) { return objectToTag(parseXml(str).children[0]); } // Compares two parse-xml style trees for "deep" equality function xmlEqual(x1, x2) { if (x1.type === 'text' && x2.type === 'text' && x1.text === x2.text) return true; return x1.name === x2.name // Test attributes for equality && Object.keys(x1).length === Object.keys(x2).length && Object.keys(x1).every(k => x1[k] === x2[k]) // Test children for equality && x1.children.length === x2.children.length && x1.children.every((child, i) => xmlEqual(child, x2.children[i])) } describe('window.reactR', () => { describe('#hydrate() with HTML', () => { it('hydrates an HTML5 component with a text child', () => { const markup = '

    Hello

    '; assert.equal( renderToString(parse(markup)), renderToString(hydrate({}, stringToTag(markup))) ) }) it('hydrates nested HTML5 components', () => { const markup = '

    Hello

    Oh, hello.

    ' assert.equal( renderToString(parse(markup)), renderToString(hydrate({}, stringToTag(markup))) ) }) }); describe('#hydrate() with Components', () => { it('should throw an exception with an unknown component', () => { assert.throws(() => { hydrate({ Shout: Shout }, stringToTag('')) }, Error, /Unknown component/); }); }) }); ================================================ FILE: man/React.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/reacttools.R \docType{data} \name{React} \alias{React} \title{React component builder.} \format{ An object of class \code{react_component_builder} of length 0. } \usage{ React } \description{ \code{React} is a syntactically-convenient way to create instances of React components that can be sent to the browser for display. It is a list for which \link[=InternalMethods]{extract methods} are defined, allowing object creation syntax like \code{React$MyComponent(x = 1)} where \code{MyComponent} is a React component you have exposed to Shiny in JavaScript. } \details{ Internally, the \code{\link{component}} function is used to create the component instance. } \examples{ # Create an instance of ParentComponent with two children, # ChildComponent and OtherChildComponent. React$ParentComponent( x = 1, y = 2, React$ChildComponent(), React$OtherChildComponent() ) } \keyword{datasets} ================================================ FILE: man/babel_transform.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/babel.R \name{babel_transform} \alias{babel_transform} \title{Transform Code with Babel} \usage{ babel_transform(code = "") } \arguments{ \item{code}{\code{character}} } \value{ transformed \code{character} } \description{ Helper function to use \code{V8} with \code{Babel} so we can avoid a JSX transformer with using \code{reactR}. } \examples{ \dontrun{ library(reactR) babel_transform('
    react div
    ') } } ================================================ FILE: man/component.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/reacttools.R \name{component} \alias{component} \title{Create a React component} \usage{ component(name, varArgs = list()) } \arguments{ \item{name}{Name of the React component, which must start with an upper-case character.} \item{varArgs}{Attributes and children of the element to pass along to \code{\link[htmltools]{tag}} as \code{varArgs}.} } \value{ An htmltools \code{\link[htmltools]{tag}} object } \description{ Create a React component } \examples{ component("ParentComponent", list( x = 1, y = 2, component("ChildComponent"), component("OtherChildComponent") ) ) } ================================================ FILE: man/createReactShinyInput.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/reacttools.R \name{createReactShinyInput} \alias{createReactShinyInput} \title{Create a React-based input} \usage{ createReactShinyInput( inputId, class, dependencies, default = NULL, configuration = list(), container = htmltools::tags$div ) } \arguments{ \item{inputId}{The \code{input} slot that will be used to access the value.} \item{class}{Space-delimited list of CSS class names that should identify this input type in the browser.} \item{dependencies}{HTML dependencies to include in addition to those supporting React. Must contain at least one dependency, that of the input's implementation.} \item{default}{Initial value.} \item{configuration}{Static configuration data.} \item{container}{Function to generate an HTML element to contain the input.} } \value{ Shiny input suitable for inclusion in a UI. } \description{ Create a React-based input } \examples{ myInput <- function(inputId, default = "") { # The value of createReactShinyInput should be returned from input constructor functions. createReactShinyInput( inputId, "myinput", # At least one htmlDependency must be provided -- the JavaScript implementation of the input. htmlDependency( name = "my-input", version = "1.0.0", src = "www/mypackage/myinput", package = "mypackage", script = "myinput.js" ), default ) } } ================================================ FILE: man/html_dependency_corejs.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/dependencies.R \name{html_dependency_corejs} \alias{html_dependency_corejs} \title{Shim Dependency for React in RStudio Viewer} \usage{ html_dependency_corejs() } \value{ \code{\link[htmltools]{htmlDependency}} } \description{ Add this first for 'React' to work in RStudio Viewer. } ================================================ FILE: man/html_dependency_mobx.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/dependencies.R \name{html_dependency_mobx} \alias{html_dependency_mobx} \title{Dependencies for 'mobx'} \usage{ html_dependency_mobx(react = TRUE) } \arguments{ \item{react}{\code{logical} to add react 'mobx' dependencies.} } \value{ \code{\link[htmltools]{htmlDependency}} } \description{ Add JavaScript 'mobx' and 'mobx-react' dependency. When using with 'react', the order of the dependencies is important, so please add \code{html_dependency_react()} before \code{html_dependency_mobx()}. } \examples{ if(interactive()) { library(htmltools) library(reactR) browsable( tagList( html_dependency_mobx(react = FALSE), div(id="test"), tags$script(HTML( " var obs = mobx.observable({val: null}) mobx.autorun(function() { document.querySelector('#test').innerText = obs.val }) setInterval( function() {obs.val++}, 1000 ) " )) ) ) } \dontrun{ # use with react library(htmltools) library(reactR) browsable( tagList( html_dependency_react(), html_dependency_mobx(), div(id="test"), tags$script(HTML(babel_transform( " var obs = mobx.observable({val: null}) var App = mobxReact.observer((props) =>
    {props.obs.val}
    ) ReactDOM.render(, document.querySelector('#test')) setInterval( function() {obs.val++}, 1000 ) " ))) ) ) } } ================================================ FILE: man/html_dependency_react.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/dependencies.R \name{html_dependency_react} \alias{html_dependency_react} \title{Dependencies for React} \usage{ html_dependency_react(offline = TRUE) } \arguments{ \item{offline}{\code{logical} to use local file dependencies. If \code{FALSE}, then the dependencies use the Facebook cdn as its \code{src}. To use with \code{JSX} see \code{\link{babel_transform}}.} } \value{ \code{\link[htmltools]{htmlDependency}} } \description{ Add JavaScript 'React' dependency. For this to work in RStudio Viewer, also include \code{\link{html_dependency_corejs}}. } \examples{ library(reactR) library(htmltools) tagList( tags$script( " ReactDOM.render( React.createElement( 'h1', null, 'Powered by React' ), document.body ) " ), #add core-js first to work in RStudio Viewer html_dependency_corejs(), html_dependency_react() #offline=FALSE for CDN ) } ================================================ FILE: man/html_dependency_reacttools.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/dependencies.R \name{html_dependency_reacttools} \alias{html_dependency_reacttools} \title{Adds window.reactR.exposeComponents and window.reactR.hydrate} \usage{ html_dependency_reacttools() } \value{ \code{\link[htmltools]{htmlDependency}} } \description{ Adds window.reactR.exposeComponents and window.reactR.hydrate } ================================================ FILE: man/reactMarkup.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/reacttools.R \name{reactMarkup} \alias{reactMarkup} \title{Prepare data that represents a single-element character vector, a React component, or an htmltools tag for sending to the client.} \usage{ reactMarkup(tag) } \arguments{ \item{tag}{character vector or React component or \code{\link[htmltools]{tag}}} } \value{ A reactR markup object suitable for being passed to \code{\link[htmlwidgets]{createWidget}} as widget instance data. } \description{ Tag lists as returned by \code{htmltools tagList} are not currently supported. } ================================================ FILE: man/scaffoldReactShinyInput.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/scaffold_input.R \name{scaffoldReactShinyInput} \alias{scaffoldReactShinyInput} \title{Create implementation scaffolding for a React.js-based Shiny input.} \usage{ scaffoldReactShinyInput(name, npmPkgs = NULL, edit = interactive()) } \arguments{ \item{name}{Name of input} \item{npmPkgs}{Optional \href{https://www.npmjs.com/}{NPM} packages upon which this input is based which will be used to populate \code{package.json}. Should be a named list of names to \href{https://docs.npmjs.com/files/package.json/}{versions}.} \item{edit}{Automatically open the input's source files after creating the scaffolding.} } \description{ Add the minimal code required to implement a React.js-based Shiny input to an R package. } \note{ This function must be executed from the root directory of the package you wish to add the input to. } ================================================ FILE: man/scaffoldReactWidget.Rd ================================================ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/scaffold_widget.R \name{scaffoldReactWidget} \alias{scaffoldReactWidget} \title{Create implementation scaffolding for a React.js-based HTML widget} \usage{ scaffoldReactWidget(name, npmPkgs = NULL, edit = interactive()) } \arguments{ \item{name}{Name of widget} \item{npmPkgs}{Optional \href{https://www.npmjs.com/}{NPM} packages upon which this widget is based which will be used to populate \code{package.json}. Should be a named list of names to \href{https://docs.npmjs.com/files/package.json/}{versions}.} \item{edit}{Automatically open the widget's JavaScript source file after creating the scaffolding.} } \description{ Add the minimal code required to implement a React.js-based HTML widget to an R package. } \note{ This function must be executed from the root directory of the package you wish to add the widget to. } ================================================ FILE: package.json ================================================ { "name": "react-tools", "private": true, "type": "module", "scripts": { "build": "vite build", "test": "vitest run" }, "devDependencies": { "@rgrove/parse-xml": "^4.1.0", "html-react-parser": "^5.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", "vite": "^5.0.11", "vitest": "^1.2.1" } } ================================================ FILE: reactR.Rproj ================================================ Version: 1.0 RestoreWorkspace: Default SaveWorkspace: Default AlwaysSaveHistory: Default EnableCodeIndexing: Yes UseSpacesForTab: Yes NumSpacesForTab: 2 Encoding: UTF-8 RnwWeave: Sweave LaTeX: XeLaTeX AutoAppendNewline: Yes StripTrailingWhitespace: Yes BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source PackageRoxygenize: rd,collate,namespace ================================================ FILE: srcjs/input.js ================================================ /* * This default receiveMessage implementation expects data to contain whole * configuration and value properties. If either is present, it will be set and * the component will be re-rendered. Because receiveMessage is typically used * by input authors to perform incremental updates, this default implementation * can be overriden by the user with the receiveMessage arguments to * reactShinyInput. */ function defaultReceiveMessage(el, { configuration, value }) { let dirty = false; if (configuration !== undefined) { this.setInputConfiguration(el, configuration); dirty = true; } if (value !== undefined) { this.setInputValue(el, value); dirty = true; } if (dirty) { this.getCallback(el)(); this.render(el); } } const defaultOptions = { receiveMessage: defaultReceiveMessage, type: false, ratePolicy: null }; /** * Installs a new Shiny input binding based on a React component. * * @param {string} selector - jQuery selector that should identify the set of * container elements within the scope argument of Shiny.InputBinding.find. * @param {string} name - A name such as 'acme.FooInput' that should uniquely * identify the component. * @param {Object} component - React Component, either class or function. * @param {Object} options - Additional configuration options. Supported * options are: * - receiveMessage: Implementation of Shiny.InputBinding to use in place of * the default. Typically overridden as an optimization to perform * incremental value updates. * - type: `false`, a string, or a function. * - `false` (the default): denotes that the value produced by this input * should not be intercepted by any handlers registered in R on the * server using shiny::registerInputHandler(). * - string: denotes the input's *type* and should correspond to the * type parameter of shiny::registerInputHandler(). * - function: A function called with `this` bound to the InputBinding * instance and passed a single argument, the input's containing DOM * element. The function should return either `false` or a string * corresponding to the type parameter of shiny::registerInputHandler(). * - ratePolicy: A rate policy object as defined in the documentation for * getRatePolicy(): https://shiny.rstudio.com/articles/building-inputs.html * A rate policy object has two members: * - `policy`: Valid values are the strings "direct", "debounce", and * "throttle". "direct" means that all events are sent immediately. * - `delay`: Number indicating the number of milliseconds that should be * used when debouncing or throttling. Has no effect if the policy is * direct. * The specified rate policy is only applied when `true` is passed as the * second argument to the `setValue` function passed as a prop to the * input component. * */ export function reactShinyInput(selector, name, component, options) { options = Object.assign({}, defaultOptions, options); Shiny.inputBindings.register(new class extends Shiny.InputBinding { /* * Methods override those in Shiny.InputBinding */ find(scope) { return $(scope).find(selector); } getValue(el) { return this.getInputValue(el); } setValue(el, value, rateLimited = false) { /* * We have to check whether $(el).data('callback') is undefined here * in case shiny::renderUI() is involved. If an input is contained in a * shiny::uiOutput(), the following strange thing happens occasionally: * * 1. setValue() is bound to an el in this.render(), below * 2. An event that will call setValue() is enqueued * 3. While the event is still enqueued, el is unbound and removed * from the DOM by the JS code associated with shiny::uiOutput() * - That code uses jQuery .html() in output_binding_html.js * - .html() removes el from the DOM and clears ist data and events * 4. By the time the setValue() bound to the original el is invoked, * el has been unbound and its data cleared. * * Since the original input is gone along with its callback, it * seems to make the most sense to do nothing. */ if ($(el).data('callback') !== undefined) { this.setInputValue(el, value); this.getCallback(el)(rateLimited); this.render(el); } } initialize(el) { $(el).data('value', JSON.parse($(el).next().text())); $(el).data('configuration', JSON.parse($(el).next().next().text())); } subscribe(el, callback) { $(el).data('callback', callback); this.render(el); } unsubscribe(el) { ReactDOM.render(null, el); } receiveMessage(el, data) { options.receiveMessage.call(this, el, data); } getType(el) { if (typeof options.type === 'function') { return options.type.call(this, el); } else if (options.type === false || typeof options.type === 'string') { return options.type; } else { throw new Error('options.type must be false, a string, or a function'); } } getRatePolicy() { return options.ratePolicy; } /* * Methods not present in Shiny.InputBinding but accessible to users * through `this` in receiveMessage */ getInputValue(el) { return $(el).data('value'); } setInputValue(el, value) { $(el).data('value', value); } getInputConfiguration(el) { return $(el).data('configuration'); } setInputConfiguration(el, configuration) { $(el).data('configuration', configuration); } getCallback(el) { return $(el).data('callback'); } render(el) { const element = React.createElement(component, { configuration: this.getInputConfiguration(el), value: this.getValue(el), setValue: this.setValue.bind(this, el), el: el }); ReactDOM.render(element, el); } }, name); } ================================================ FILE: srcjs/react-tools.js ================================================ import { reactWidget, hydrate } from './widget'; import { reactShinyInput } from './input'; export { reactShinyInput, reactWidget, hydrate }; ================================================ FILE: srcjs/widget.js ================================================ /** * Recursively transforms tag, a JSON representation of an instance of a * React component and its children, into a React element suitable for * passing to ReactDOM.render. * @param {Object} components * @param {Object} tag */ export function hydrate(components, tag) { if (typeof tag === 'string') return tag; if (tag.name[0] === tag.name[0].toUpperCase() && !components.hasOwnProperty(tag.name)) { throw new Error("Unknown component: " + tag.name); } // thanks https://github.com/stla // https://github.com/react-R/reactR/issues/61 // attribs that are slots will likely contain tags that also need hydration // convert any attribs that contain object that matches tag structure for(let attrib in tag.attribs) { if(isTag(tag.attribs[attrib])) { tag.attribs[attrib] = hydrate(components, tag.attribs[attrib]); } } var elem = components.hasOwnProperty(tag.name) ? components[tag.name] : tag.name, args = [elem, tag.attribs]; for (var i = 0; i < tag.children.length; i++) { args.push(hydrate(components, tag.children[i])); } return React.createElement.apply(React, args); } export const defaultOptions = { // The name of the property on the root tag to use for the width, if // it's updated. widthProperty: "width", // The name of the property on the root tag to use for the height, if // it's updated. heightProperty: "height", // Whether or not to append the string 'px' to the width and height // properties when they change. appendPx: false, // Whether or not to dynamically update the width and height properties // of the last known tag when the computed width and height change in // the browser. renderOnResize: false }; export function mergeOptions(options) { var merged = {}; for (var k in defaultOptions) { merged[k] = defaultOptions[k]; } for (var k in options) { if (!defaultOptions.hasOwnProperty(k)) { throw new Error("Unrecognized option: " + k); } merged[k] = options[k]; } return merged; } export function formatDimension(dim, options) { if (options.appendPx) { return dim + 'px'; } else { return dim; } } export function isTag(value) { return (typeof value === 'object') && value.hasOwnProperty('name') && value.hasOwnProperty('attribs') && value.hasOwnProperty('children'); } /** * Creates an HTMLWidget that is updated by rendering a React component. * React component constructors are made available by specifying them by * name in the components object. * @param {string} name * @param {string} type * @param {Object} components * @param {Object} options */ export function reactWidget(name, type, components, options) { var actualOptions = mergeOptions(options); window.HTMLWidgets.widget({ name: name, type: type, factory: function (el, width, height) { var lastValue, instance = {}, renderValue = (function (value) { if (actualOptions.renderOnResize) { // value.tag might be a primitive string, in which // case there is no attribs property. if (typeof value.tag === 'object') { value.tag.attribs[actualOptions["widthProperty"]] = formatDimension(width); value.tag.attribs[actualOptions["heightProperty"]] = formatDimension(height); } lastValue = value; } // with functional stateless components this will be null // see https://reactjs.org/docs/react-dom.html#render for more details this.instance.component = ReactDOM.render(hydrate(components, value.tag), el); }); return { instance: instance, renderValue: renderValue, resize: function (newWidth, newHeight) { if (actualOptions.renderOnResize) { width = newWidth; height = newHeight; renderValue(lastValue); } } }; } }) } ================================================ FILE: vignettes/intro_htmlwidgets.Rmd ================================================ --- title: "Authoring htmlwidgets powered by React with reactR" author: - Alan Dipert - Carson Sievert date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{htmlwidgets with reactR} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, echo=FALSE, include=FALSE} knitr::opts_chunk$set(eval = FALSE) ``` The [htmlwidgets](https://www.htmlwidgets.org) package provides a framework for creating R bindings to JavaScript libraries. Using the **htmlwidgets** package alone, it's not necessarily straight-forward to create an R binding to a [React](https://reactjs.org/)-powered JavaScript library. The **reactR** package builds on the **htmlwidgets** framework to make it much easier to author **htmlwidgets** that are powered by React. This vignette will show you how to effectively leverage **reactR** to build an **htmlwidgets** package that interfaces with [react-sparklines](https://github.com/borisyankov/react-sparklines) React JavaScript library. ## Software pre-requisites In order to develop a **reactR** widget, you'll need to install R and optionally RStudio. If you're on Windows, you should also install [Rtools](https://cran.r-project.org/bin/windows/Rtools/). > For an excellent general introduction to R package concepts, check out the [R packages](https://r-pkgs.org/) online book. In addition, you'll need to install the following JavaScript tools on your machine: * [Node.js](https://nodejs.org): JavaScript engine and runtime for development outside of browsers. Provides the `node` and `npm` commands. * [Yarn](https://classic.yarnpkg.com/en/): Command-line dependency management tool, provides the `yarn` command. To follow along in this vignette, you'll also need the following R packages: ```{r} install.packages(c("shiny", "devtools", "usethis", "htmlwidgets", "reactR")) ``` ## Scaffolding To create a new widget you can call `scaffoldReactWidget` to generate the basic structure and build configuration. This function will: * Create the .R, .js, .yaml, and .json files required by your widget; * If provided, take an [npm](https://www.npmjs.com/) package name and version as a named list with `name` and `version` elements. For example, the npm package `foo` at version `^1.2.0` would be expressed as `list(name = "foo", version = "^1.2.0")`. The package, if provided, will be added to the new widget's `package.json` as a build dependency. The following R code will create an R package named **sparklines**, then provide the templating for creating an htmlwidget powered by the `react-sparklines` npm package: ```{r} # Create the R package usethis::create_package("~/sparklines") # Inject the widget templating withr::with_dir( "~/sparklines", reactR::scaffoldReactWidget("sparklines", list("react-sparklines" = "^1.7.0"), edit = FALSE) ) ``` ## Building and installing ### Building the JavaScript The next step is to navigate to the newly-created `sparklines` project and run the following R commands: ```{r} system("yarn install") system("yarn run webpack") ``` * `yarn install` downloads all of the dependencies listed in `package.json` and creates a new file, `yarn.lock`. You should add this file to revision control. It will be updated whenever you change dependencies and run `yarn install`. **Note: you only need to run it after modifying package.json**. For further documentation on `yarn install`, see the [yarn documentation](https://classic.yarnpkg.com/en/docs/cli/install/). * `yarn run webpack` compiles the [ES2015](https://babeljs.io/docs/en/learn/) JavaScript source file at `srcjs/sparklines.js` into `inst/htmlwidgets/sparklines.js`. The later file is one actually used by the R package and includes all the relevant JavaScript dependencies in a version of JavaScript that most browsers understand. Note that, if you add `--mode=development` to the end of this command, it will include a [source map](https://firefox-source-docs.mozilla.org/devtools-user/debugger/how_to/use_a_source_map/index.html) is included with the compiled JavaScript, which makes JavaScript debugging much easier, but hopefully you won't need to do much of any JavaScript debugging. `yarn run webpack` is not strictly a `yarn` command. In fact, `yarn run` simply delegates to the [webpack](https://webpack.js.org/) program. Webpack's configuration is generated by `scaffoldReactWidget` in the file `webpack.config.js`, but you can always change this configuration and/or modify the `yarn run webpack` command to suit your needs. ### Installing the R package Now that the widget's JavaScript is compiled, go ahead and install the R package: ```{r} devtools::document() devtools::install(quick = TRUE) ``` Alternatively, in RStudio, you can use the keyboard shortcuts `Ctrl+Shift+D` and `Ctrl-Shift-B` to document and build the package. (On macOS, the shortcuts are `Cmd+Shift+D` and `Cmd+Shift+B`) ## Run the included demo Now that the widget's JavaScript is compiled, and the R package is installed, run `app.R` to see a demo in action: ```{r} shiny::runApp() ``` Alternatively, in RStudio, you can open `app.R` and press `Ctrl-Shift-Enter` (`Cmd-Shift-Enter` on macOS). You should see something like the following appear in the Viewer pane: ![](./widget_app.jpg) ## Authoring a React binding At this point, we've built some scaffolding for an htmlwidget powered by React. Let's modify it to create an interface to the `react-sparklines` library. Authoring the interface requires some changes on both the JavaScript and R side, but most of the hard thinking will be in figuring how best to design your interface. To give you an example of how this could work, let's build an interface to the `Sparklines` component of the react-sparklines library. ### First, outline an interface > Note that the examples in this section are just to demonstrate API possibilities and need not be pasted into any file. Consider the following example taken from the [react-sparklines documentation](http://borisyankov.github.io/react-sparklines/). ```js import React from 'react'; import { Sparklines } from 'react-sparklines'; ``` You have some choice in terms of how to design an R interface to this sort of React library, but usually it makes sense to have one function per component and have the arguments to that function feed into the properties of that React component. In other words, our goal is to create an R function that allows users of our package to recreate this example with the following code: ```r library(sparklines) sparklines( data = sampleData, sparklinesLine(color = "#56b45d"), sparklinesSpots(style = list(fill = "#56b45d")) ) ``` The following sections show how to implement this R interface from our scaffolded widget. ### R implementation Consider the template that `reactR::scaffoldReactWidget()` provided for us: ```{r} sparklines <- function(message, width = NULL, height = NULL, elementId = NULL) { # describe a React component to send to the browser for rendering. content <- htmltools::tag("div", list(message)) # create widget htmlwidgets::createWidget( name = 'sparklines', reactR::reactMarkup(content), width = width, height = height, package = 'sparklines', elementId = elementId ) } ``` This function is designed to simply display a message within an HTML div using **reactR** and **htmlwidgets**. The critical piece here that makes it all work is `reactR::reactMarkup()`. This function can prepare a payload containing a mix of HTML tags (constructed via `htmltools::tag()`), React components (constructed via `reactR::component()`), or character vectors in a such way that the **reactR** and **htmlwidgets** toolchain will understand and know how to render in the browser (assuming we've imported our React component appropriately, as we cover later). Thus, to send a `` react component instead of an HTML `
    `, we could simply change: ```r content <- htmltools::tag("div", list(message)) ``` to ```r reactR::component("Sparklines", list(message)) ``` Remember, though, that we'd like `` to consume a `data` property and also accept other valid components (e.g., ``, ``, etc) from this library as children. So, we could change the body and signature of `sparklines()` in the following way: ```{r} sparklines <- function(data, ..., width = NULL, height = NULL) { # describe a React component to send to the browser for rendering. content <- reactR::component( "Sparklines", list(data = data, ...) ) # create widget htmlwidgets::createWidget( name = 'sparklines', reactR::reactMarkup(content), width = width, height = height, package = 'sparklines' ) } ``` At this point, we define functions that make it easy for the user to create the other components by adding these to `R/sparklines.R` ```{r} #' @export sparklinesLine <- function(...) { reactR::React$SparklinesLine(...) } #' @export sparklinesSpots <- function(...) { reactR::React$SparklinesSpots(...) } ``` ### JavaScript changes In order for the **reactR** toolchain to know how to render components from the 'react-sparklines' library, we need to register the React components on the JavaScript side. This can be done in the `srcjs/sparklines.js` file which currently looks like this: ```{js} import { reactWidget } from 'reactR'; reactWidget('sparklines', 'output', {}); ``` First, `reactWidget` is [imported](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) from the `'reactR'` JavaScript module. This function will register the React components we want within the **reactR** and **htmlwidgets** toolchain. Note that the `'reactR'` JavaScript is an html dependency, but webpack is configured in `webpack.config.js` to consider it a module, so it's available to us here via `import` syntax. Then, there's a call to `reactWidget`, and we pass it three arguments: 1. The name of the widget (`'sparklines'`) 1. The type of the widget (`'output'`) 1. The React components that should be exposed to the widget. In this template, we didn't have to include any because it's just rendering an HTML div. Instead of passing an empty object (`{}`) as the React components, we provide an object with all the components we need from the 'react-sparklines' module: ```{js} import { Sparklines, SparklinesLine, SparklinesSpots } from 'react-sparklines'; import { reactWidget } from 'reactR'; reactWidget('sparklines', 'output', { Sparklines: Sparklines, SparklinesLine: SparklinesLine, SparklinesSpots: SparklinesSpots }); ``` ### Go for a spin Now that we've made the necessary changes to the JavaScript and R source code, it's time to compile the JavaScript and install the R package: ```{r} system("yarn install") system("yarn run webpack") devtools::document() devtools::install() library(sparklines) sparklines(rnorm(10), sparklinesLine()) ``` This should open up the `sparklines()` widget in your browser. If it does, congratulations, you created a React-based htmlwidget! ### Shiny integration The scaffolding template already provides the glue you need to get your **reactR** widget to render in **Shiny**. The two relevant functions are `renderSparklines()` and `sparklinesOutput()`. You shouldn't need to modify these functions — they should work out of the box. You will, however, want to modify the example **Shiny** app in the `app.R` file: ```{r} library(shiny) library(sparklines) ui <- fluidPage( titlePanel("Sparklines library"), sliderInput("n", label = "Number of samples", min = 2, max = 1000, value = 100), sparklinesOutput("myWidget") ) server <- function(input, output, session) { output$myWidget <- renderSparklines({ sparklines( rnorm(input$n), sparklinesLine() ) }) } shinyApp(ui, server) ``` Now, when you run `shiny::runApp()`, you should see your react-based htmlwidget rendering in **shiny** app! ![](./widget_app_improved.jpg) ## Further learning This tutorial walked you through the steps taken you create an R interface to the react-sparklines library. The full example package is accessible at . Our intention is keep creating example packages under the organization, so head there if you'd like to see other examples of interfacing with React. ================================================ FILE: vignettes/intro_inputs.Rmd ================================================ --- title: "Authoring inputs powered by React with reactR" author: - Alan Dipert and Carson Sievert date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Shiny inputs with reactR} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, echo=FALSE, include=FALSE} knitr::opts_chunk$set(eval = FALSE) ``` [Shiny](https://shiny.posit.co/) comes with a large library of input [widgets](https://shiny.posit.co/r/gallery/widgets/widget-gallery/) for collecting input from the user and conveying input data to R. If you want a kind of input *not* provided by Shiny — like a color picker, or a different kind of slider — you've always been able to build your own. Shiny's input system is [extensible](https://shiny.rstudio.com/articles/building-inputs.html). All that's required is an understanding of certain conventions and a little custom JavaScript. reactR provides additional tools to ease the creation of new Shiny inputs implemented using React. In the following tutorial, we will demonstrate these tools by implementing a new Shiny color picker input that wraps the [react-color](https://github.com/casesandberg/react-color) library. ## Software pre-requisites In order to develop a **reactR** Shiny input, you'll need to install R and optionally RStudio. If you're on Windows, you should also install [Rtools](https://cran.r-project.org/bin/windows/Rtools/). > For an excellent general introduction to R package concepts, check out the [R > packages](https://r-pkgs.org/) online book. In addition, you'll need to install the following JavaScript tools on your machine: * [Node.js](https://nodejs.org): JavaScript engine and runtime for development outside of browsers. Provides the `node` and `npm` commands. * [Yarn](https://classic.yarnpkg.com/en/): Command-line dependency management tool, provides the `yarn` command. To follow along in this vignette, you'll also need the following R packages: ```{r} install.packages(c("shiny", "devtools", "usethis", "reactR")) ``` ## Scaffolding To create a new widget you can call `scaffoldReactShinyInput` to generate the basic structure and build configuration. This function will: * Create the .R, .js, and .json files required by your input; * If provided, take an [npm](https://www.npmjs.com/) package name and version as a named list with `name` and `version` elements. For example, the npm package `foo` at version `^1.2.0` would be expressed as `list(name = "foo", version = "^1.2.0")`. The package, if provided, will be added to the new widget's `package.json` as a build dependency. The following R code will create an R package named **colorpicker**, then provide the templating for creating an input powered by the `react-color` library on npm: ```{r} # Create the R package (rstudio=TRUE is recommended if you're not already comfortable with your terminal) usethis::create_package("~/colorpicker", rstudio = TRUE) # Scaffold initial input implementation files withr::with_dir( "~/colorpicker", reactR::scaffoldReactShinyInput("colorpicker", list("react-color" = "^2.17.0"), edit = FALSE) ) ``` ## Building and installing ### Building the JavaScript The next step is to navigate to the newly-created `colorpicker` project and run the following commands in the terminal. If you're new the terminal, we recommend opening your newly created RStudio `~/colorpicker/colorpicker.Rproj` project file, then running the following in the RStudio terminal tab: ``` yarn install yarn run webpack ``` * `yarn install` downloads all of the dependencies listed in `package.json` and creates a new file, `yarn.lock`. You should add this file to revision control. It will be updated whenever you change dependencies and run `yarn install`. **Note: you only need to run it after modifying package.json**. For further documentation on `yarn install`, see the [yarn documentation](https://classic.yarnpkg.com/en/docs/cli/install/). * `yarn run webpack` compiles the [modern JavaScript](https://babeljs.io/docs/en/babel-preset-env) with [JSX](https://babeljs.io/docs/en/babel-preset-react) source file at `srcjs/colorpicker.jsx` into `www/colorpicker/colorpicker/colorpicker.js`. The latter file is the one actually used by the R package and includes all the relevant JavaScript dependencies in a dialect of JavaScript that most browsers understand. `yarn run webpack` is not strictly a `yarn` command. In fact, `yarn run` simply delegates to the [webpack](https://webpack.js.org/) program. Webpack's configuration is generated by `scaffoldReactShinyInput` in the file `webpack.config.js`, but you can always change this configuration and/or modify the `yarn run webpack` command to suit your needs. ### Installing the R package Now that the input's JavaScript is compiled, go ahead and install the R package: ```{r} devtools::document() devtools::install(quick = TRUE) ``` In RStudio, you can use the keyboard shortcuts `Ctrl-Shift-D` and `Ctrl-Shift-B` to document and build the package. (On macOS, the shortcuts are `Cmd-Shift-D` and `Cmd-Shift-B`) ## Run the included demo Now that the input's JavaScript is compiled, and the R package is installed, run `app.R` to see a demo in action: ```{r} shiny::runApp() ``` In RStudio, you can open `app.R` and press `Ctrl-Shift-Enter` (`Cmd-Shift-Enter` on macOS). You should see something like the following appear in the Viewer pane: ![](./input_app.jpg) ## Authoring a React input At this point, we have a working (if simple) React-powered text input. Let's modify it to create an interface to the `react-color` library. ### Connecting Shiny with React Consider the following example taken from the [react-color documentation](http://casesandberg.github.io/react-color/). ```js import React from 'react'; import { SketchPicker } from 'react-color'; class Component extends React.Component { render() { return ; } } ``` That JavaScript code produces a `SketchPicker`-type interface that looks like this: ![](./input_sketchpicker.jpg) However, that example doesn't demonstrate a way to default to a particular color, or a way to cause something to happen when the color changes. To accomplish these, `react-color` components can [optionally take](http://casesandberg.github.io/react-color/#api) the following [props](https://reactjs.org/docs/components-and-props.html): * [`color`](http://casesandberg.github.io/react-color/#api-color): accepts a string of a hex color like `'#333'` * [`onChangeComplete`](http://casesandberg.github.io/react-color/#api-onChangeComplete): accepts a JavaScript function taking a single argument, the new `color`, that will be called when the new color is selected Since this React component calls a configurable function (i.e., `onChangeComplete`) when the input (i.e., color) value changes, we can supply a function to inform Shiny about these changes. You could, in theory, do this by writing your own custom Shiny input wrapper around this component, but `reactR` provides some conventions to make it much easier. These conventions have two main parts (R and JavaScript): 1. Use `reactR::createReactShinyInput()` to construct the user-facing R input and route any user-supplied options (e.g., the `default` input value and other `configuration`) to the React component. This part was already done for us in the `R/colorpicker.R` file of our colorpicker project: ```r colorpickerInput <- function(inputId, default = "") { reactR::createReactShinyInput( inputId = inputId, class = "colorpicker", dependencies = htmltools::htmlDependency( name = "colorpicker-input", version = "1.0.0", src = "www/colorpicker/colorpicker", package = "colorpicker", script = "colorpicker.js" ), default = default, configuration = list(), container = htmltools::tags$span ) } ``` 2. Design an *intermediate* React component that routes information from `colorpickerInput()` to the `` component and also inform Shiny when a new color is chosen. This intermediate component should be a [functional component](https://reactjs.org/docs/components-and-props.html#function-and-class-components) with three arguments: * `configuration`: The JSON equivalent of the `configuration` argument from `reactR::createReactShinyInput()`. In this particular example, `configuration` isn't used. * `value`: The input's values over time, beginning with the `default` supplied from `reactR::createReactShinyInput()`. * `setValue`: A JavaScript function to call with the input's new value when one is created. This function is not user supplied, but rather an internal hook for informing Shiny about changes to the component's current state (i.e. value). Consider the following intermediate component, `PickerInput`. Note how this intermediate component allows one to set the default `value` from R and also calls `setValue()` inside `onChangeComplete` in order to inform Shiny about new color values. Finally, `reactR.reactShinyInput()` registers this intermediate component as a custom Shiny input binding named `colorpicker`. ```js import { reactShinyInput } from 'reactR'; import { SketchPicker } from 'react-color'; const PickerInput = ({ configuration, value, setValue }) => { return ( setValue(color.hex) } /> ); }; // Note the first argument here should match the `class` // argument of the reactR::createReactShinyInput() from step 1 reactShinyInput('.colorpicker', 'colorpicker', PickerInput); ``` Open the `srcjs/colorpicker.jsx` file in your colorpicker project and paste this code into it. After saving the file, run `yarn run webpack` in the terminal, re-install the package, then run `shiny::runApp()` again When you select new colors, you should see the `textOutput` update accordingly. You might have noticed that the input showed up initially without a color selected. That's because in `app.R` we didn't supply a `default` argument to the `colorpickerInput` function inside our `ui`. Try replacing the call to `colorpickerInput` with this: `colorpickerInput("textInput", default = "#a76161")` Now when you run the app, the color should start as a shade of red. ## Further learning This tutorial walked you through the steps taken to wrap the `react-color` library in a Shiny input. The full example package is accessible at . Our intention is keep creating example packages under the organization, so head there if you'd like to see other examples of interfacing with React. ================================================ FILE: vignettes/intro_reactR.Rmd ================================================ --- title: "Intro to reactR" author: "Kent Russell" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Intro to reactR} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Why reactR? [`react`](https://reactjs.org/) has become incredibly popular, and the ecosystem around `react` is robust. `reactR` aims to allow `R` users to more easily incorporate `react` and `JSX`. ## Install ``` install.packages("reactR") # for the latest development version # install from Github # devtools::install_github("timelyportfolio/reactR") ``` ## Quick Example Let's use `react` to render a simple `h1` HTML element below.
    ```{r} library(reactR) library(htmltools) attachDependencies( tags$script( " ReactDOM.render( React.createElement( 'h1', null, 'Powered by React' ), document.getElementById('react-heading-here') ) " ), html_dependency_react() ) ``` ## Blog Post For more on how we can use R and React, see the blog post [React in R](https://www.jsinr.me/2017/11/19/react-in-r/). Also, there are many more examples in the Github repo at [inst/examples](https://github.com/react-R/reactR/tree/master/inst/examples). ## Using JSX [`JSX`](https://reactjs.org/docs/jsx-in-depth.html) helps ease some of the burden caused by `React.createElement`. `reactR` provides a `babel_transform()` function to use `JSX`. Hopefully, in the future, we can convince RStudio to modify `htmltools` to work directly with `JSX` (see [issue](https://github.com/rstudio/htmltools/pull/72)). ================================================ FILE: vite.config.js ================================================ import { resolve, join } from 'path'; import { defineConfig } from 'vite'; export default defineConfig({ define: { 'process.env.NODE_ENV': '"production"' }, build: { outDir: join(__dirname, "inst/www/react-tools/"), lib: { // Could also be a dictionary or array of multiple entry points entry: resolve(__dirname, 'srcjs/react-tools.js'), name: 'reactR', fileName: () => 'react-tools.js', formats: ['umd'], }, rollupOptions: { external: ['react', 'react-dom', 'jquery', 'shiny'], output: { globals: { 'react': 'React', 'react-dom': 'ReactDOM', 'jquery': '$', 'shiny': 'Shiny' }, }, }, }, });