react-R/reactR

Use Plots or other HTML Based inputs in ReactR Components possible?

Closed this issue · 4 comments

Hello everybody,

I played around with the reactsTrap example and created a custom Flipcard with received props.

function ActionButton({ configuration }) {
  return (
    <div>
      <div className="flip-card">
        <div className="flip-card-inner">
          <div className="flip-card-front">
            <img
              src={
                "https://www.tageblatt.lu/wp-content/uploads/2019/12/17735_cx__cy__cw__ch_-740x493.jpg"
              }
              style={{ width: 300, height: 500 }}
            />
          </div>
          <div className="flip-card-back">{configuration.label}</div>
        </div>
      </div>
    </div>
  );
}

The R file looks like this:

action_button <- function(
  inputId,
  label
) {
  reactR::createReactShinyInput(
    inputId,
    "action_button",
    htmltools::htmlDependency(
      name = "action_button-input",
      version = "1.0.0",
      src = "www/reactstrapTest",
      package = "reactstrapTest",
      script = "main.js"
    ),
    default = 0,
    configuration = list(
      label = label
    ),
    htmltools::tags$div
  )
}

The example works pretty fine and I am able to pass a label as plain text. What I desire to do is to pass more complex html Elements as props, for example a Plot from HighcharteR.

Passing everything else than plain text results in an Error:

action_button("bla", label = tags$p("test"))
Error: No method asJSON S3 class: shiny.tag

Is it possible to pass more complex objects there?

stla commented

You have to pass URLencode(as.character(tags$p("test"))) to React. Then, in React:

import parse from "html-react-parser";

function unescapeHtml(html) {
  let el = document.createElement("div");
  return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
    el.innerHTML = enc;
    return el.innerText;
  });
}

parse(unescapeHtml(decodeURI(label))) 

Key Question

Should reactR do more to help here?

Helpers

Also @stla #61 provides some additional helpers to support cases where shiny.tag is somewhere other than children.

For instance, I think we can view the struggle with this simple example.

> str(component("MyDiv", list(htmltools::tags$div(), slotprop = htmltools::tags$div())))
List of 3
 $ name    : chr "MyDiv"
 $ attribs :List of 1
  ..$ slotprop:List of 3
  .. ..$ name    : chr "div"
  .. ..$ attribs : Named list()
  .. ..$ children: list()
  .. ..- attr(*, "class")= chr "shiny.tag"
 $ children:List of 1
  ..$ :List of 3
  .. ..$ name    : chr "div"
  .. ..$ attribs : Named list()
  .. ..$ children: list()
  .. ..- attr(*, "class")= chr "shiny.tag"
 - attr(*, "class")= chr [1:3] "reactR_component" "shiny.tag" "list"

> component("MyDiv", list(htmltools::tags$div(), slotprop = htmltools::tags$div()))
<MyDiv slotprop="&lt;div&gt;&lt;/div&gt;">
  <div></div>
</MyDiv>

I have added hydrate of tag-like attributes/props in develop. I'd love it if someone could help me test. Seems to be working but wondering if I might be missing something or potentially causing negative side effects. Thanks.

closing since I believe 0.6.0 release fixes/resolves this issue. Please feel free to reopen to continue the discussion. Thanks @Coding-Crashkurse for the issue!