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.
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
and npm
commands.yarn
command.To follow along in this vignette, you’ll also need the following R packages:
To create a new widget you can call
scaffoldReactShinyInput
to generate the basic structure and
build configuration. This function will:
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)
)
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.
Now that the input’s JavaScript is compiled, go ahead and install the R package:
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
)
Now that the input’s JavaScript is compiled, and the R package is
installed, run app.R
to see a demo in action:
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:
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.