diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 425253225..f778d38f9 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,6 +7,10 @@ title: Changelog ## main +* Improve Stimulus controller template to import from `stimulus` or `@hotwired/stimulus`. + + *Mario Schüttel* + * Fix bug where `helpers` would instantiate and use a new `view_context` in each component. *Blake Williams*, *Ian C. Anderson* diff --git a/lib/rails/generators/stimulus/component_generator.rb b/lib/rails/generators/stimulus/component_generator.rb index cf62f9cf5..88f15e5cb 100644 --- a/lib/rails/generators/stimulus/component_generator.rb +++ b/lib/rails/generators/stimulus/component_generator.rb @@ -12,6 +12,12 @@ def create_stimulus_controller template "component_controller.js", destination end + def stimulus_module + return "stimulus" if legacy_stimulus? + + "@hotwired/stimulus" + end + private def destination @@ -21,6 +27,11 @@ def destination File.join(component_path, class_path, "#{file_name}_component_controller.js") end end + + def legacy_stimulus? + package_json_pathname = Rails.root.join("package.json") + package_json_pathname.exist? && JSON.parse(package_json_pathname.read).dig("dependencies", "stimulus").present? + end end end end diff --git a/lib/rails/generators/stimulus/templates/component_controller.js.tt b/lib/rails/generators/stimulus/templates/component_controller.js.tt index 44fd951a9..ef9f9f2bc 100644 --- a/lib/rails/generators/stimulus/templates/component_controller.js.tt +++ b/lib/rails/generators/stimulus/templates/component_controller.js.tt @@ -1,4 +1,4 @@ -import { Controller } from "stimulus"; +import { Controller } from "<%= stimulus_module %>"; export default class extends Controller { connect() { diff --git a/test/generators/component_generator_test.rb b/test/generators/component_generator_test.rb index dc50b49e9..4aa70b14f 100644 --- a/test/generators/component_generator_test.rb +++ b/test/generators/component_generator_test.rb @@ -216,10 +216,22 @@ def test_component_with_stimulus_and_inline assert_file "app/components/user_component_controller.js" end + def test_component_with_legacy_stimulus_and_sidecar + with_package_json({ dependencies: { "stimulus": "0.0.0" } }) do + run_generator %w[user --stimulus --sidecar] + + assert_file "app/components/user_component/user_component_controller.js" do |file| + assert_match(/import { Controller } from "stimulus"/, file) + end + end + end + def test_component_with_stimulus_and_sidecar run_generator %w[user --stimulus --sidecar] - assert_file "app/components/user_component/user_component_controller.js" + assert_file "app/components/user_component/user_component_controller.js" do |file| + assert_match(/import { Controller } from "@hotwired\/stimulus"/, file) + end end def test_component_with_stimulus_and_sidecar_and_inline @@ -231,4 +243,14 @@ def test_component_with_stimulus_and_sidecar_and_inline assert_file "app/components/user_component/user_component_controller.js" end + + private + + def with_package_json(content, &block) + package_json_pathname = Rails.root.join("package.json") + package_json_pathname.write(JSON.generate(content)) + yield + ensure + package_json_pathname.delete + end end