block by timelyportfolio c686384b058d1bc2f2149a5330da66c0

React office-ui-fabric rating component used with R Shiny

As an extension to the blog post React in R, I thought it would be helpful to demonstrate how we can combine a React component with R Shiny.

screenshot of react working with R shiny

Code

library(htmltools)
library(shiny)
library(reactR)

fabric <- htmlDependency(
  name = "office-fabric-ui-react",
  version = "5.23.0",
  src = c(href="https://unpkg.com/office-ui-fabric-react/dist"),
  script = "office-ui-fabric-react.js",
  stylesheet = "css/fabric.min.css"
)

tl <- tagList(
  reactR::html_dependency_react(),
  fabric,
  tags$h3("React Rating from office-ui-fabric"),
  tags$div(id="react-rating"),
  tags$h3("Rating Communicated through Shiny"),
  textOutput("rtextrating"),
  tags$script(HTML(babel_transform(
"
    // office-ui-fabric rating example
    //   amended to work without Typescript
    //   https://developer.microsoft.com/en-us/fabric#/components/rating
    class RatingBasicExample extends React.Component {
      constructor(props) {
        super(props)

        this.state = {largeStarRating: null}

        this._onLargeStarChanged = this._onLargeStarChanged.bind(this)
      }

      _onLargeStarChanged(rating) {
        this.setState({largeStarRating: rating})

        // now communicate the change to Shiny
        if(Shiny && Shiny.onInputChange) {
          Shiny.onInputChange(
            'largeStarRating',
            rating
          )
        }
      }

      render() {
        return (
          <Fabric.Rating
            id={ 'largeRatingStar' }
            min={ 1 }
            max={ 5 }
            size={ Fabric.RatingSize.Large }
            rating={ this.state.largeStarRating }
            onChanged={ this._onLargeStarChanged }
          />
        )
      }
    }

    ReactDOM.render(
      <RatingBasicExample />,
      document.querySelector('#react-rating')
    )
"
  )))
)

ui <- tl

server <- function(input, output, session) {
  observeEvent(input$largeStarRating, {
    print(input$largeStarRating)
    output$rtextrating <- renderText(paste0(
      "React tells Shiny you rated me a ", input$largeStarRating
    ))
  })
}

shinyApp(ui, server, options=list("launch.browser"=TRUE))