R/stimulus-assets.R

Defines functions stimulus_assets

Documented in stimulus_assets

#' @title Stimulus Assets
#'
#' @description Stimulus JS assets from specified controller files. This
#' will automatically copy them into single directory and define the controllers
#' in the page after registering the Stimulus application. Anything in
#' `<name>_controller.js` is converted into snake case.
#'
#' @param app_version (str) a string that indicates the version
#' @param controllers (chr) paths to controller JS files
#' @param libs        (pth) path to be directed
#'
#' @family Stimulus
#'
#' @export
stimulus_assets <- function(controllers,
                            app_version,
                            libs = "assets") {

  # Return NULL if no controllers
  if (length(controllers) == 0) return(NULL)

  # Assertions
  controller_dir <- dir_create(pkg_user("controllers"))
  assert_string(app_version)
  assert_string(libs)

  copy_controller <- function(controller, controller_dir) {
    new_path <- path(controller_dir, path_file(controller))
    file_copy(controller, new_path, overwrite = TRUE)
    return(new_path)
  }

  # Copy to the user directory
  controllers <-
    controllers %>%
    map(
      function(controller, controller_dir) {
        if (is_dir(controller)) {
          map_chr(
            list.files(
              controller,
              pattern = "_controller.js$",
              full.names = TRUE
            ),
            copy_controller,
            controller_dir = controller_dir
          )
        } else {
          copy_controller(controller, controller_dir)
        }
      },
      controller_dir = controller_dir
    ) %>%
    flatten_chr()

  controller_files <-
    path_rel(controllers, start = controller_dir)
  controller_names <-
    path_file(controllers) %>%
    str_remove("\\_controller.js$") %>%
    to_snake_case()
  controllers <-
    map2(controller_files, controller_names, ~list(file = .x, name = .y))

  tagList(
    html_dependency(
      name    = "stimulus",
      version = "2.0.0",
      src     = c(href = "https://unpkg.com/stimulus@2.0.0", file = "stimulus"),
      script  = "dist/stimulus.umd.js",
      package = pkg_name
    ),
    html_dependency(
      name    = "stimulus-controllers",
      version = app_version,
      src     = controller_dir,
      script  = map(controller_files, ~list(src = ., type = "module")),
      all_files = FALSE
    ),
    html_script(
      type = "module",
      text = "
    {{#controllers}}
    import {{name}} from './{{libs}}/stimulus-controllers-{{version}}/{{file}}';
    {{/controllers}}
    const application = Stimulus.Application.start();
    {{#controllers}}
    application.register('{{name}}', {{name}});
    {{/controllers}}
      ",
    version     = app_version,
    libs        = libs,
    controllers = controllers,
    in_head     = TRUE,
    singleton   = TRUE
    )
  ) %>%
    add_class("stimulus_assets")

}
tjpalanca/hotwire.R documentation built on Dec. 23, 2021, 10:59 a.m.