From ad1ce002234495fe2bb8fdd9e8839fbb48565433 Mon Sep 17 00:00:00 2001 From: Gaetan Craig-Riou Date: Wed, 10 Sep 2025 15:03:31 +1000 Subject: [PATCH] Generate a better stimulus name for component controller Using the helper `definitionsFromContext` generate quite long name for stimulus controller in component, ie : `tag-list-input-component--tag-list-input`. This custom loader will generate much more readable name, ie L `tag-list-input`. It's expecting the following pattern : ofn_component/ofn_controller.js and will fall back to the default of replacing "_" by "- and "/" by "--" for controller not matching the pattern. --- .../example_component/example_controller.js | 3 +- app/webpacker/controllers/index.js | 31 ++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/components/example_component/example_controller.js b/app/components/example_component/example_controller.js index 72957edffd..87aff838cc 100644 --- a/app/components/example_component/example_controller.js +++ b/app/components/example_component/example_controller.js @@ -1,4 +1,5 @@ -// This controller will be called "example-component--example", ie "component-subdirectory--js-file-name" +// This controller will be called "example", ie "js-file-name" minus the "_controller.js" +// see controller/index.js for more info import { Controller } from "stimulus"; export default class extends Controller {} diff --git a/app/webpacker/controllers/index.js b/app/webpacker/controllers/index.js index 55c57a46ce..b02807e3d8 100644 --- a/app/webpacker/controllers/index.js +++ b/app/webpacker/controllers/index.js @@ -6,14 +6,37 @@ import StimulusReflex from "stimulus_reflex"; import consumer from "../channels/consumer"; import controller from "../controllers/application_controller"; import CableReady from "cable_ready"; -import RailsNestedForm from '@stimulus-components/rails-nested-form/dist/stimulus-rails-nested-form.umd.js' // the default module entry point is broken +import RailsNestedForm from "@stimulus-components/rails-nested-form/dist/stimulus-rails-nested-form.umd.js"; // the default module entry point is broken const application = Application.start(); const context = require.context("controllers", true, /_controller\.js$/); -const contextComponents = require.context("../../components", true, /_controller\.js$/); +application.load(definitionsFromContext(context)); -application.load(definitionsFromContext(context).concat(definitionsFromContext(contextComponents))); -application.register('nested-form', RailsNestedForm); +// Load component controller, but generate a shorter controller name than "definitionsFromContext" would +// - for controller in a component subdirectory, get rid of the component folder and use +// the controller name, ie: +// ./tag_rule_group_form_component/tag_rule_group_form_controller.js -> tag-rule-group-form +// - for controller that don't match the pattern above, replace "_" by "-" and "/" by "--", ie: +// ./vertical_ellipsis_menu/component_controller.js -> vertical-ellipsis-menu--component +// +const contextComponents = require.context("../../components", true, /_controller\.js$/); +contextComponents.keys().forEach((path) => { + const module = contextComponents(path); + + // Check whether a module has the default export defined + if (!module.default) return; + + const identifier = path + .replace(/^\.\//, "") + .replace(/^\w+_component\//, "") + .replace(/_controller\.js$/, "") + .replace(/\//g, "--") + .replace(/_/g, "-"); + + application.register(identifier, module.default); +}); + +application.register("nested-form", RailsNestedForm); application.consumer = consumer; StimulusReflex.initialize(application, { controller, isolate: true });