stimulus-rails 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -8
- data/app/assets/javascripts/stimulus/loaders/autoloader.js +43 -12
- data/app/helpers/stimulus/stimulus_helper.rb +2 -2
- data/lib/install/application.js +1 -0
- data/lib/install/stimulus_with_asset_pipeline.rb +23 -0
- data/lib/install/stimulus_with_webpacker.rb +10 -0
- data/lib/stimulus-rails.rb +3 -3
- data/lib/stimulus/engine.rb +2 -3
- data/lib/stimulus/importmap_helper.rb +13 -7
- data/lib/stimulus/version.rb +1 -1
- data/lib/tasks/stimulus_tasks.rake +19 -1
- metadata +9 -8
- data/app/assets/javascripts/stimulus/loaders/preloader.js.erb +0 -20
- data/lib/install/stimulus.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89d46eae3d2f08243301a422cd4c81aceb024d2c9ad5d03c9c48d816bd3c0616
|
4
|
+
data.tar.gz: bcc92cdbbf0f10beb7bfae41100674e16a64864db47bfda5c16a586f5395e8f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46f93ef00d23543f8ad325115d8a7c992fb2e9d231ec7fb42452aaabc4f3b629cb3fa4177a878f5c31596fec8aafe0d97a4908730d641c439cc39597d4336bca
|
7
|
+
data.tar.gz: 02a943d267d807a0981f65d82084e215e47ca35160eb14e67da6af5015598c16caac400304e66e1d377922a3854414945bdc7500f818740237b411266b92be67
|
data/README.md
CHANGED
@@ -12,19 +12,25 @@ If you want to use Stimulus with a bundler, you should use [Webpacker](https://g
|
|
12
12
|
2. Run `./bin/bundle install`.
|
13
13
|
3. Run `./bin/rails stimulus:install`
|
14
14
|
|
15
|
-
|
15
|
+
If using the asset pipeline to manage JavaScript, the last command will:
|
16
16
|
|
17
|
-
1. Create an example controller in app/assets/javascripts/controllers/hello_controller.js
|
18
|
-
2. Append the include tags to the `<head>` of your application.html.erb
|
19
|
-
3. Initialize your importmap.json in app/assets/javascripts/importmap.json.erb
|
20
|
-
4. Ensure JavaScript is included in your app/config/manifest.js file for compilation.
|
17
|
+
1. Create an example controller in `app/assets/javascripts/controllers/hello_controller.js`.
|
18
|
+
2. Append the include tags to the `<head>` of your `app/views/layouts/application.html.erb`.
|
19
|
+
3. Initialize your `importmap.json` in `app/assets/javascripts/importmap.json.erb`.
|
20
|
+
4. Ensure JavaScript is included in your `app/assets/config/manifest.js` file for compilation.
|
21
21
|
|
22
|
+
If using Webpacker to manage JavaScript, the last command will:
|
23
|
+
|
24
|
+
1. Import the controllers directory in the application pack.
|
25
|
+
2. Create a controllers directory at `app/javascripts/controllers`.
|
26
|
+
3. Create an example controller in `app/javascripts/controllers/hello_controller.js`.
|
27
|
+
4. Install the Stimulus NPM package.
|
22
28
|
|
23
29
|
## Usage
|
24
30
|
|
25
31
|
With the Stimulus include tags added, you'll automatically have activated Stimulus through the controller autoloader. You can now easily add new Stimulus controllers that'll be loaded via ESM dynamic imports.
|
26
32
|
|
27
|
-
For example, a more advanced hello_controller could look like this:
|
33
|
+
For example, a more advanced `hello_controller` could look like this:
|
28
34
|
|
29
35
|
```javascript
|
30
36
|
// app/assets/javascripts/controllers/hello_controller.js
|
@@ -43,13 +49,13 @@ And it'll be activated and registered automatically when encountering the data-c
|
|
43
49
|
|
44
50
|
```html
|
45
51
|
<div data-controller="hello">
|
46
|
-
<input data-target="
|
52
|
+
<input data-hello-target="name" type="text">
|
47
53
|
|
48
54
|
<button data-action="click->hello#greet">
|
49
55
|
Greet
|
50
56
|
</button>
|
51
57
|
|
52
|
-
<span data-target="
|
58
|
+
<span data-hello-target="output">
|
53
59
|
</span>
|
54
60
|
</div>
|
55
61
|
```
|
@@ -1,21 +1,52 @@
|
|
1
1
|
import { Application } from "stimulus"
|
2
2
|
|
3
3
|
const application = Application.start()
|
4
|
+
const { controllerAttribute } = application.schema
|
5
|
+
const registeredControllers = {}
|
4
6
|
|
5
|
-
function
|
6
|
-
|
7
|
-
|
7
|
+
function autoloadControllersWithin(element) {
|
8
|
+
queryControllerNamesWithin(element).forEach(loadController)
|
9
|
+
}
|
10
|
+
|
11
|
+
function queryControllerNamesWithin(element) {
|
12
|
+
return Array.from(element.querySelectorAll(`[${controllerAttribute}]`)).map(extractControllerNamesFrom).flat()
|
13
|
+
}
|
14
|
+
|
15
|
+
function extractControllerNamesFrom(element) {
|
16
|
+
return element.getAttribute(controllerAttribute).split(/\s+/).filter(content => content.length)
|
17
|
+
}
|
8
18
|
|
9
|
-
|
10
|
-
|
19
|
+
function loadController(name) {
|
20
|
+
import(controllerFilename(name))
|
21
|
+
.then(module => registerController(name, module))
|
22
|
+
.catch(error => console.log(`Failed to autoload controller: ${name}`, error))
|
23
|
+
}
|
11
24
|
|
12
|
-
|
13
|
-
|
14
|
-
}).catch(error => console.log(`Failed to autoload controller: ${controllerName}`))
|
15
|
-
})
|
16
|
-
})
|
25
|
+
function controllerFilename(name) {
|
26
|
+
return `${name.replace(/--/g, "/").replace(/-/g, "_")}_controller`
|
17
27
|
}
|
18
28
|
|
19
|
-
|
29
|
+
function registerController(name, module) {
|
30
|
+
if (name in registeredControllers) return
|
31
|
+
|
32
|
+
application.register(name, module.default)
|
33
|
+
registeredControllers[name] = true
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
new MutationObserver((mutationsList) => {
|
38
|
+
for (const { attributeName, target, type } of mutationsList) {
|
39
|
+
switch (type) {
|
40
|
+
case "attributes": {
|
41
|
+
if (attributeName == controllerAttribute && target.hasAttribute(controllerAttribute)) {
|
42
|
+
extractControllerNamesFrom(target).forEach(loadController)
|
43
|
+
}
|
44
|
+
}
|
45
|
+
case "childList": {
|
46
|
+
autoloadControllersWithin(target)
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}).observe(document.body, { attributeFilter: [controllerAttribute], subtree: true, childList: true })
|
20
51
|
|
21
|
-
|
52
|
+
autoloadControllersWithin(document)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Stimulus::StimulusHelper
|
2
2
|
def stimulus_include_tags
|
3
|
-
[
|
3
|
+
safe_join [
|
4
4
|
javascript_include_tag("stimulus/libraries/es-module-shims", type: "module"),
|
5
5
|
tag.script(type: "importmap-shim", src: asset_path("importmap.json")),
|
6
6
|
javascript_include_tag("stimulus/libraries/stimulus", type: "module-shim"),
|
7
7
|
javascript_include_tag("stimulus/loaders/autoloader", type: "module-shim")
|
8
|
-
]
|
8
|
+
], "\n"
|
9
9
|
end
|
10
10
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
import "controllers"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
say "Copying Stimulus JavaScript"
|
2
|
+
directory "#{__dir__}/app/assets/javascripts", "app/assets/javascripts"
|
3
|
+
empty_directory_with_keep_file "app/assets/javascripts/libraries"
|
4
|
+
|
5
|
+
say "Add app/assets/javascripts to asset pipeline manifest"
|
6
|
+
append_to_file Rails.root.join("app/assets/config/manifest.js").to_s, "//= link_tree ../javascripts\n"
|
7
|
+
|
8
|
+
APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb")
|
9
|
+
|
10
|
+
if APPLICATION_LAYOUT_PATH.exist?
|
11
|
+
say "Add Stimulus include tags in application layout"
|
12
|
+
insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, "\n <%= stimulus_include_tags %>", before: /\s*<\/head>/
|
13
|
+
else
|
14
|
+
say "Default application.html.erb is missing!", :red
|
15
|
+
say " Add <%= stimulus_include_tags %> within the <head> tag in your custom layout."
|
16
|
+
end
|
17
|
+
|
18
|
+
say "Turn off development debug mode"
|
19
|
+
comment_lines Rails.root.join("config/environments/development.rb"), /config.assets.debug = true/
|
20
|
+
|
21
|
+
say "Turn off rack-mini-profiler"
|
22
|
+
comment_lines Rails.root.join("Gemfile"), /rack-mini-profiler/
|
23
|
+
run "bin/bundle", capture: true
|
@@ -0,0 +1,10 @@
|
|
1
|
+
say "Appending Stimulus setup code to #{Webpacker.config.source_entry_path}/application.js"
|
2
|
+
append_to_file "#{Webpacker.config.source_entry_path}/application.js" do
|
3
|
+
"\n" + open("#{__dir__}/application.js").read
|
4
|
+
end
|
5
|
+
|
6
|
+
say "Creating controllers directory"
|
7
|
+
directory "#{__dir__}/app/assets/javascripts/controllers", "#{Webpacker.config.source_path}/controllers"
|
8
|
+
|
9
|
+
say "Installing all Stimulus dependencies"
|
10
|
+
run "yarn add stimulus"
|
data/lib/stimulus-rails.rb
CHANGED
data/lib/stimulus/engine.rb
CHANGED
@@ -2,8 +2,7 @@ require "stimulus/importmap_helper"
|
|
2
2
|
|
3
3
|
module Stimulus
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
-
|
6
|
-
config.eager_load_namespaces << Stimulus
|
5
|
+
config.autoload_once_paths = %w( #{root}/app/helpers )
|
7
6
|
|
8
7
|
initializer "stimulus.assets" do
|
9
8
|
Rails.application.config.assets.precompile += %w( importmap.json stimulus/manifest )
|
@@ -11,7 +10,7 @@ module Stimulus
|
|
11
10
|
|
12
11
|
initializer "stimulus.helpers" do
|
13
12
|
ActiveSupport.on_load(:action_controller_base) do
|
14
|
-
helper Stimulus::
|
13
|
+
helper Stimulus::StimulusHelper
|
15
14
|
end
|
16
15
|
|
17
16
|
Rails.application.config.assets.configure do |env|
|
@@ -5,19 +5,25 @@ module Stimulus::ImportmapHelper
|
|
5
5
|
|
6
6
|
def importmap_list_from(*paths)
|
7
7
|
Array(paths).flat_map do |path|
|
8
|
-
absolute_path = Rails.root.join(path)
|
9
|
-
|
8
|
+
if (absolute_path = Rails.root.join(path)).exist?
|
9
|
+
find_javascript_files_in_tree(absolute_path).collect do |filename|
|
10
|
+
module_filename = filename.relative_path_from(absolute_path)
|
11
|
+
module_name = importmap_module_name_from(module_filename)
|
12
|
+
module_path = asset_path(absolute_path.basename.join(module_filename))
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
%("#{module_name}": "#{asset_path("#{dirname}/#{module_filename.basename}")}")
|
14
|
+
%("#{module_name}": "#{module_path}")
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end.join(",\n")
|
17
|
+
end.compact.join(",\n")
|
16
18
|
end
|
17
19
|
|
18
20
|
private
|
19
21
|
# Strip off the extension and any versioning data for an absolute module name.
|
20
22
|
def importmap_module_name_from(filename)
|
21
|
-
filename.
|
23
|
+
filename.to_s.remove(filename.extname).split("@").first
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_javascript_files_in_tree(path)
|
27
|
+
Dir[path.join("**/*.js{,m}")].collect { |file| Pathname.new(file) }.select(&:file?)
|
22
28
|
end
|
23
29
|
end
|
data/lib/stimulus/version.rb
CHANGED
@@ -1,6 +1,24 @@
|
|
1
|
+
def run_stimulus_install_template(path) system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb", __dir__)}" end
|
2
|
+
|
1
3
|
namespace :stimulus do
|
2
4
|
desc "Install Stimulus into the app"
|
3
5
|
task :install do
|
4
|
-
|
6
|
+
if defined?(Webpacker::Engine)
|
7
|
+
Rake::Task["stimulus:install:webpacker"].invoke
|
8
|
+
else
|
9
|
+
Rake::Task["stimulus:install:asset_pipeline"].invoke
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
namespace :install do
|
14
|
+
desc "Install Stimulus on the app with the asset pipeline"
|
15
|
+
task :asset_pipeline do
|
16
|
+
run_stimulus_install_template "stimulus_with_asset_pipeline"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Install Stimulus on the app with webpacker"
|
20
|
+
task :webpacker do
|
21
|
+
run_stimulus_install_template "stimulus_with_webpacker"
|
22
|
+
end
|
5
23
|
end
|
6
24
|
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stimulus-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
8
8
|
- Javan Mahkmali
|
9
9
|
- David Heinemeier Hansson
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-01-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: 6.0.0
|
29
|
-
description:
|
29
|
+
description:
|
30
30
|
email: david@loudthinking.com
|
31
31
|
executables: []
|
32
32
|
extensions: []
|
@@ -40,12 +40,13 @@ files:
|
|
40
40
|
- app/assets/javascripts/stimulus/libraries/stimulus.js
|
41
41
|
- app/assets/javascripts/stimulus/libraries/stimulus@2.js
|
42
42
|
- app/assets/javascripts/stimulus/loaders/autoloader.js
|
43
|
-
- app/assets/javascripts/stimulus/loaders/preloader.js.erb
|
44
43
|
- app/assets/javascripts/stimulus/manifest.js
|
45
44
|
- app/helpers/stimulus/stimulus_helper.rb
|
46
45
|
- lib/install/app/assets/javascripts/controllers/hello_controller.js
|
47
46
|
- lib/install/app/assets/javascripts/importmap.json.erb
|
48
|
-
- lib/install/
|
47
|
+
- lib/install/application.js
|
48
|
+
- lib/install/stimulus_with_asset_pipeline.rb
|
49
|
+
- lib/install/stimulus_with_webpacker.rb
|
49
50
|
- lib/stimulus-rails.rb
|
50
51
|
- lib/stimulus/engine.rb
|
51
52
|
- lib/stimulus/importmap_helper.rb
|
@@ -57,7 +58,7 @@ licenses:
|
|
57
58
|
metadata:
|
58
59
|
homepage_uri: https://stimulus.hotwire.dev
|
59
60
|
source_code_uri: https://github.com/hotwired/stimulus-rails
|
60
|
-
post_install_message:
|
61
|
+
post_install_message:
|
61
62
|
rdoc_options: []
|
62
63
|
require_paths:
|
63
64
|
- lib
|
@@ -73,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
74
|
version: '0'
|
74
75
|
requirements: []
|
75
76
|
rubygems_version: 3.1.2
|
76
|
-
signing_key:
|
77
|
+
signing_key:
|
77
78
|
specification_version: 4
|
78
79
|
summary: A modest JavaScript framework for the HTML you already have.
|
79
80
|
test_files: []
|
@@ -1,20 +0,0 @@
|
|
1
|
-
// Experimental: Not currently exposed.
|
2
|
-
import { Application } from "stimulus"
|
3
|
-
|
4
|
-
const application = Application.start()
|
5
|
-
|
6
|
-
async function preloadControllers() {
|
7
|
-
const imports = await fetch("<%= asset_path "importmap.json" %>").then(r => r.json()).then(json => json.imports)
|
8
|
-
|
9
|
-
for (const name in imports) {
|
10
|
-
if (name.startsWith("controllers/")) {
|
11
|
-
let controllerName = name.replace(/controllers\//, "").replace("_controller", "")
|
12
|
-
|
13
|
-
import(imports[name]).then((module) => {
|
14
|
-
application.register(controllerName, module.default)
|
15
|
-
}).catch(error => console.log(error))
|
16
|
-
}
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
|
-
preloadControllers()
|
data/lib/install/stimulus.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
say "Copying Stimulus JavaScript"
|
2
|
-
directory "#{__dir__}/app/assets/javascripts", "app/assets/javascripts"
|
3
|
-
empty_directory "app/assets/javascripts/libraries"
|
4
|
-
|
5
|
-
say "Add app/javascripts to asset pipeline manifest"
|
6
|
-
append_to_file Rails.root.join("app/assets/config/manifest.js").to_s, "//= link_tree ../javascripts\n"
|
7
|
-
|
8
|
-
say "Add Stimulus include tags in application layout"
|
9
|
-
insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, "\n <%= stimulus_include_tags %>", before: /\s*<\/head>/
|
10
|
-
|
11
|
-
say "Turn off development debug mode"
|
12
|
-
comment_lines Rails.root.join("config/environments/development.rb"), /config.assets.debug = true/
|
13
|
-
|
14
|
-
say "Turn off rack-mini-profiler"
|
15
|
-
comment_lines Rails.root.join("Gemfile"), /rack-mini-profiler/
|
16
|
-
run "bin/bundle", capture: true
|