Skip to content

Commit 449d3c3

Browse files
Merge pull request #22 from react-R/input-binding
Easy React-based input bindings
2 parents c0c08fd + 38aca8b commit 449d3c3

30 files changed

+1365
-439
lines changed

.Rbuildignore

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
^pkgdown$
55
^assets$
66
^.*\.Rproj$
7-
^\.Rproj\.user$
8-
^\build
97
^CONDUCT\.md$
10-
^cran-comments\.md$
11-
^docs$
8+
^README\.Rmd$
9+
^\.Rproj\.user$
1210
^\.travis\.yml$
13-
^\assets
11+
^build$
12+
^docs$
13+
^cran-comments\.md$
1414
^karma\.conf\.js$
15+
^logo.svg$
1516
^package\.json$
17+
^webpack\.config\.js$
1618
^yarn\.lock$
17-
^README\.Rmd$
18-
logo.svg
19-
webpack.config.js
19+
^logo\.svg$

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
Meta
2+
doc
13
.Rproj.user
24
.Rhistory
35
.RData
@@ -7,3 +9,4 @@ node_modules
79
reactR.Rcheck
810
reactR_*.tar.gz
911
*.swp
12+
.DS_Store

DESCRIPTION

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: reactR
22
Type: Package
33
Title: React Helpers
4-
Version: 0.3.1
5-
Date: 2019-01-26
4+
Version: 0.4.0
5+
Date: 2019-04-10
66
Authors@R: c(
77
person(
88
"Facebook", "Inc"
@@ -39,6 +39,7 @@ Suggests:
3939
shiny,
4040
V8,
4141
knitr,
42-
usethis
42+
usethis,
43+
jsonlite
4344
RoxygenNote: 6.1.1
4445
VignetteBuilder: knitr

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ S3method("[[<-",react_component_builder)
77
export(React)
88
export(babel_transform)
99
export(component)
10+
export(createReactShinyInput)
1011
export(html_dependency_corejs)
1112
export(html_dependency_react)
1213
export(html_dependency_reacttools)
1314
export(reactMarkup)
15+
export(scaffoldReactShinyInput)
1416
export(scaffoldReactWidget)
1517
importFrom(htmltools,htmlDependency)

R/reacttools.R

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# A robust name string is a valid
2+
# - CSS class
3+
# - JavaScript variable name
4+
# - R variable name
5+
robustName <- "^[[:alpha:]_][[:alnum:]_]*$"
6+
17
isUpper <- function(s) {
28
grepl("^[[:upper:]]+$", s)
39
}
@@ -92,3 +98,57 @@ reactMarkup <- function(tag) {
9298
list(tag = tag, class = "reactR_markup")
9399
}
94100

101+
#' Create a React-based input
102+
#'
103+
#' @param inputId The \code{input} slot that will be used to access the value.
104+
#' @param class Space-delimited list of CSS class names that should identify
105+
#' this input type in the browser.
106+
#' @param dependencies HTML dependencies to include in addition to those
107+
#' supporting React. Must contain at least one dependency, that of the input's
108+
#' implementation.
109+
#' @param default Initial value.
110+
#' @param configuration Static configuration data.
111+
#' @param container Function to generate an HTML element to contain the input.
112+
#'
113+
#' @return Shiny input suitable for inclusion in a UI.
114+
#' @export
115+
#'
116+
#' @examples
117+
#' myInput <- function(inputId, default = "") {
118+
#' # The value of createReactShinyInput should be returned from input constructor functions.
119+
#' createReactShinyInput(
120+
#' inputId,
121+
#' "myinput",
122+
#' # At least one htmlDependency must be provided -- the JavaScript implementation of the input.
123+
#' htmlDependency(
124+
#' name = "my-input",
125+
#' version = "1.0.0",
126+
#' src = "www/mypackage/myinput",
127+
#' package = "mypackage",
128+
#' script = "myinput.js"
129+
#' ),
130+
#' default
131+
#' )
132+
#' }
133+
createReactShinyInput <- function(inputId,
134+
class,
135+
dependencies,
136+
default = NULL,
137+
configuration = list(),
138+
container = htmltools::tags$div) {
139+
if(length(dependencies) < 1) stop("Must include at least one HTML dependency.")
140+
value <- shiny::restoreInput(id = inputId, default = default)
141+
htmltools::tagList(
142+
html_dependency_corejs(),
143+
html_dependency_react(),
144+
html_dependency_reacttools(),
145+
container(id = inputId, class = class),
146+
htmltools::tags$script(id = sprintf("%s_value", inputId),
147+
type = "application/json",
148+
jsonlite::toJSON(value, auto_unbox = TRUE)),
149+
htmltools::tags$script(id = sprintf("%s_configuration", inputId),
150+
type = "application/json",
151+
jsonlite::toJSON(configuration, auto_unbox = TRUE)),
152+
dependencies
153+
)
154+
}

R/scaffold.R

Lines changed: 0 additions & 163 deletions
This file was deleted.

R/scaffold_input.R

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#' Create implementation scaffolding for a React.js-based Shiny input.
2+
#'
3+
#' Add the minimal code required to implement a React.js-based Shiny input to an
4+
#' R package.
5+
#'
6+
#' @param name Name of input
7+
#' @param npmPkgs Optional \href{https://npmjs.com/}{NPM} packages upon which
8+
#' this input is based which will be used to populate \code{package.json}.
9+
#' Should be a named list of names to
10+
#' \href{https://docs.npmjs.com/files/package.json#dependencies}{versions}.
11+
#' @param edit Automatically open the input's source files after creating the
12+
#' scaffolding.
13+
#'
14+
#' @note This function must be executed from the root directory of the package
15+
#' you wish to add the input to.
16+
#'
17+
#' @export
18+
scaffoldReactShinyInput <- function(name, npmPkgs = NULL, edit = interactive()) {
19+
assertNameValid(name)
20+
package <- getPackage()
21+
22+
file <- renderFile(
23+
sprintf("R/%s.R", name),
24+
"templates/input_r.txt",
25+
"boilerplate for input constructor",
26+
list(
27+
name = name,
28+
capName = capitalize(name),
29+
package = package
30+
)
31+
)
32+
if (edit) fileEdit(file)
33+
34+
renderFile(
35+
'package.json',
36+
'templates/package.json.txt',
37+
'project metadata',
38+
list(npmPkgs = toDepJSON(npmPkgs))
39+
)
40+
41+
renderFile(
42+
'webpack.config.js',
43+
'templates/webpack.config.js.txt',
44+
'webpack configuration',
45+
list(
46+
name = name,
47+
outputPath = sprintf("inst/www/%s/%s", package, name)
48+
)
49+
)
50+
51+
renderFile(
52+
sprintf('srcjs/%s.jsx', name),
53+
'templates/input_js.txt',
54+
'JavaScript implementation',
55+
list(
56+
name = name,
57+
package = package
58+
)
59+
)
60+
61+
renderFile(
62+
'app.R',
63+
'templates/input_app.R.txt',
64+
'example app',
65+
list(
66+
name = name,
67+
package = package
68+
)
69+
)
70+
71+
usethis::use_build_ignore(c("node_modules", "srcjs", "app.R", "package.json", "webpack.config.js", "yarn.lock"))
72+
usethis::use_git_ignore(c("node_modules"))
73+
lapply(c("htmltools", "shiny", "reactR"), usethis::use_package)
74+
75+
message("To install dependencies from npm run: yarn install")
76+
message("To build JavaScript run: yarn run webpack --mode=development")
77+
}
78+

0 commit comments

Comments
 (0)