keller-mark / anyhtmlwidget

Bringing core concepts from anywidget to R
https://keller-mark.github.io/anyhtmlwidget/
Other
13 stars 1 forks source link

Provide `htmlwidget` without `print()` #29

Open timelyportfolio opened 3 months ago

timelyportfolio commented 3 months ago

Sorry to be such a pest, but I am really, really excited about this project.

Currently render() in static mode calls invoke_static() which prints the htmlwidget https://github.com/keller-mark/anyhtmlwidget/blob/main/R/widget.R#L266C3-L266C11. I can foresee many cases where we might want to get the htmlwidget without print even potentially when in a mode other than static.

Would you consider a pull request that either provides an additional public function that creates the htmlwidget and return() instead of print() regardless of mode? For instance, .get_htmlwidget but certainly not wed to this function name? Or as another option (less attractive in my opinion) change print(w) to return(w) in invoke_static?

As an example, I will copy the code from https://github.com/keller-mark/anyhtmlwidget/discussions/26. In this example, the widget will be printed 5 times and then the tagList instead of just getting the desired tagList with 5 widgets.

library(anyhtmlwidget)

esm <- "
function render({ el, model }) {
  el.style.border = '4px solid red';
  let count = () => model.get('count');
  let btn = document.createElement('button');
  btn.innerHTML = `count is ${count()}`;
  btn.addEventListener('click', () => {
    model.set('count', count() + 1);
    model.save_changes();
  });
  model.on('change:count', () => {
    btn.innerHTML = `count is ${count()}`;
  });
  el.appendChild(btn);
}
export default { render };
"

widget <- AnyHtmlWidget$new(
  .esm = esm,
  .mode = "static",
  .height='400px',
  count = 1
)

# make 5 button anyhtmlwidgets
#   to demonstrate duplication of esm
library(htmltools)
browsable(
  tagList(
    lapply(1:5, function(x) widget$render())
  )
)

Thanks so much.