ultimate_turbo_modal 2.2.1 → 2.2.2
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/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/VERSION +1 -1
- data/javascript/modal_controller.js +5 -1
- data/javascript/package.json +1 -1
- data/lib/generators/ultimate_turbo_modal/base.rb +117 -0
- data/lib/generators/ultimate_turbo_modal/install_generator.rb +46 -95
- data/lib/generators/ultimate_turbo_modal/update_generator.rb +13 -1
- data/lib/ultimate_turbo_modal/base.rb +1 -1
- data/lib/ultimate_turbo_modal.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8076c3d9802abd28ef2ff1858b7268f730455c69a214dfb2f8e04d3695c8f68f
|
|
4
|
+
data.tar.gz: fa211158221a41661229457a63874690eac7e07fb19159045362eb0341d4ccee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9414a16b2a0de555727b258403230d5a65564e1158b95c61904cca0fd0b9280fe5433eaeb156962b1dbb1bbcdfe25a86d1ec7b1a65c03209211e5b97abb2fde7
|
|
7
|
+
data.tar.gz: 783c9c2af43c3b31e8e974642545ac094e2c5faf1925c84947186e215ba809daac4a6236afa7fc1e24768379f1a12376515982a48cd08350274a9a8a2230fc7b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [2.2.2] - 2026-03-12
|
|
2
|
+
|
|
3
|
+
- Added `close` function on Stimulus Controller. Thanks @bendangelo
|
|
4
|
+
- Focus bug fix. Thanks @pasl
|
|
5
|
+
- Refactor generator and fix [bug #33](https://github.com/cmer/ultimate_turbo_modal/issues/33).
|
|
6
|
+
|
|
1
7
|
## [2.2.1] - 2025-08-08
|
|
2
8
|
|
|
3
9
|
- Added `rails generate ultimate_turbo_modal:update` for easy updates
|
data/Gemfile.lock
CHANGED
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.2.
|
|
1
|
+
2.2.2
|
|
@@ -96,6 +96,10 @@ export default class extends Controller {
|
|
|
96
96
|
this.hideModal();
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
close() {
|
|
100
|
+
this.hideModal();
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
refreshPage() {
|
|
100
104
|
window.Turbo.visit(window.location.href, { action: "replace" });
|
|
101
105
|
}
|
|
@@ -178,7 +182,7 @@ export default class extends Controller {
|
|
|
178
182
|
initialFocus: () => {
|
|
179
183
|
// Try to focus the first focusable element, or the modal itself
|
|
180
184
|
const firstFocusable = this.contentTarget.querySelector(
|
|
181
|
-
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
185
|
+
'button:not([tabindex="-1"]), [href]:not([tabindex="-1"]), input:not([tabindex="-1"]), select:not([tabindex="-1"]), textarea:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])'
|
|
182
186
|
);
|
|
183
187
|
return firstFocusable || this.contentTarget;
|
|
184
188
|
}
|
data/javascript/package.json
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "pathname"
|
|
5
|
+
|
|
6
|
+
module UltimateTurboModal
|
|
7
|
+
module Generators
|
|
8
|
+
class Base < Rails::Generators::Base
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def package_name
|
|
12
|
+
"ultimate_turbo_modal"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Add JS dependency (for install flow)
|
|
16
|
+
def add_js_dependency
|
|
17
|
+
say "Attempting to set up JavaScript dependencies...", :yellow
|
|
18
|
+
|
|
19
|
+
version_spec = "#{package_name}@#{UltimateTurboModal::VERSION}"
|
|
20
|
+
|
|
21
|
+
if uses_importmaps?
|
|
22
|
+
say "Detected Importmaps. Pinning #{version_spec}...", :green
|
|
23
|
+
run "bin/importmap pin #{version_spec}"
|
|
24
|
+
say "✅ Pinned '#{package_name}' via importmap.", :green
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if uses_javascript_bundler?
|
|
29
|
+
say "Detected jsbundling-rails (Yarn/npm/Bun). Adding #{package_name} package...", :green
|
|
30
|
+
if uses_yarn?
|
|
31
|
+
run "yarn add #{version_spec}"
|
|
32
|
+
say "✅ Added '#{package_name}' using Yarn.", :green
|
|
33
|
+
elsif uses_npm?
|
|
34
|
+
run "npm install --save #{version_spec}"
|
|
35
|
+
say "✅ Added '#{package_name}' using npm.", :green
|
|
36
|
+
elsif uses_bun?
|
|
37
|
+
run "bun add #{version_spec}"
|
|
38
|
+
say "✅ Added '#{package_name}' using Bun.", :green
|
|
39
|
+
else
|
|
40
|
+
say "Attempting to add with Yarn. If you use npm or Bun, please add manually.", :yellow
|
|
41
|
+
run "yarn add #{version_spec}"
|
|
42
|
+
say "If this failed or you use npm/bun, please run:", :yellow
|
|
43
|
+
say "npm install --save #{version_spec}", :cyan
|
|
44
|
+
say "# or", :cyan
|
|
45
|
+
say "bun add #{version_spec}", :cyan
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
say "Could not automatically detect Importmaps or jsbundling-rails.", :yellow
|
|
49
|
+
say "Please manually add the '#{package_name}' JavaScript package.", :yellow
|
|
50
|
+
say "If using Importmaps: bin/importmap pin #{version_spec}", :cyan
|
|
51
|
+
say "If using Yarn: yarn add #{version_spec}", :cyan
|
|
52
|
+
say "If using npm: npm install --save #{version_spec}", :cyan
|
|
53
|
+
say "If using Bun: bun add #{version_spec}", :cyan
|
|
54
|
+
say "Then, import it in your app/javascript/application.js:", :yellow
|
|
55
|
+
say "import '#{package_name}'", :cyan
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Install all JS dependencies (for update flow)
|
|
60
|
+
def install_all_js_dependencies
|
|
61
|
+
if uses_importmaps?
|
|
62
|
+
version_spec = "#{package_name}@#{UltimateTurboModal::VERSION}"
|
|
63
|
+
say "Detected Importmaps. Ensuring pin for #{version_spec}...", :green
|
|
64
|
+
run "bin/importmap pin #{version_spec}"
|
|
65
|
+
say "✅ Pinned '#{package_name}' via importmap.", :green
|
|
66
|
+
return
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
unless uses_javascript_bundler?
|
|
70
|
+
say "Could not detect Importmaps or jsbundling-rails. Skipping JS install step.", :yellow
|
|
71
|
+
return
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
say "Installing JavaScript dependencies...", :yellow
|
|
75
|
+
if uses_yarn?
|
|
76
|
+
run "yarn install"
|
|
77
|
+
say "✅ Installed dependencies with Yarn.", :green
|
|
78
|
+
elsif uses_npm?
|
|
79
|
+
run "npm install"
|
|
80
|
+
say "✅ Installed dependencies with npm.", :green
|
|
81
|
+
elsif uses_bun?
|
|
82
|
+
run "bun install"
|
|
83
|
+
say "✅ Installed dependencies with Bun.", :green
|
|
84
|
+
else
|
|
85
|
+
say "Attempting to install with Yarn. If you use npm or Bun, please run the appropriate command.", :yellow
|
|
86
|
+
run "yarn install"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def uses_importmaps?
|
|
91
|
+
File.exist?(rails_root_join("config", "importmap.rb"))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def uses_javascript_bundler?
|
|
95
|
+
File.exist?(rails_root_join("package.json"))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def uses_yarn?
|
|
99
|
+
File.exist?(rails_root_join("yarn.lock"))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def uses_npm?
|
|
103
|
+
File.exist?(rails_root_join("package-lock.json")) && !uses_yarn? && !uses_bun?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def uses_bun?
|
|
107
|
+
File.exist?(rails_root_join("bun.lockb"))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def rails_root_join(*args)
|
|
111
|
+
Pathname.new(destination_root).join(*args)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "rails/generators"
|
|
4
|
-
|
|
4
|
+
require_relative "base"
|
|
5
5
|
|
|
6
6
|
module UltimateTurboModal
|
|
7
7
|
module Generators
|
|
8
|
-
class InstallGenerator <
|
|
8
|
+
class InstallGenerator < UltimateTurboModal::Generators::Base
|
|
9
9
|
source_root File.expand_path("templates", __dir__)
|
|
10
10
|
|
|
11
11
|
desc "Installs UltimateTurboModal: copies initializer/flavor, sets up JS, registers Stimulus controller, adds Turbo Frame."
|
|
@@ -17,99 +17,61 @@ module UltimateTurboModal
|
|
|
17
17
|
|
|
18
18
|
# Step 2: Setup Javascript Dependencies (Yarn/npm/Bun or Importmap)
|
|
19
19
|
def setup_javascript_dependencies
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
say "\nAttempting to set up JavaScript dependencies...", :yellow
|
|
23
|
-
|
|
24
|
-
if uses_importmaps?
|
|
25
|
-
say "Detected Importmaps. Pinning #{package_name}...", :green
|
|
26
|
-
run "bin/importmap pin #{package_name}"
|
|
27
|
-
|
|
28
|
-
say "\n✅ Pinned '#{package_name}' via importmap.", :green
|
|
29
|
-
|
|
30
|
-
elsif uses_javascript_bundler?
|
|
31
|
-
say "Detected jsbundling-rails (Yarn/npm/Bun). Adding #{package_name} package...", :green
|
|
32
|
-
if uses_yarn?
|
|
33
|
-
run "yarn add #{package_name}"
|
|
34
|
-
say "\n✅ Added '#{package_name}' using Yarn.", :green
|
|
35
|
-
elsif uses_npm?
|
|
36
|
-
run "npm install --save #{package_name}"
|
|
37
|
-
say "\n✅ Added '#{package_name}' using npm.", :green
|
|
38
|
-
elsif uses_bun?
|
|
39
|
-
run "bun add #{package_name}"
|
|
40
|
-
say "\n✅ Added '#{package_name}' using Bun.", :green
|
|
41
|
-
else
|
|
42
|
-
# Default or fallback: Try yarn, but provide instructions for others
|
|
43
|
-
say "Attempting to add with Yarn. If you use npm or Bun, please add manually.", :yellow
|
|
44
|
-
run "yarn add #{package_name}"
|
|
45
|
-
say "\n✅ Attempted to add '#{package_name}' using Yarn.", :green
|
|
46
|
-
say " If this failed or you use npm/bun, please run:", :yellow
|
|
47
|
-
say " npm install --save #{package_name}", :cyan
|
|
48
|
-
say " # or", :cyan
|
|
49
|
-
say " bun add #{package_name}\n", :cyan
|
|
50
|
-
end
|
|
51
|
-
else
|
|
52
|
-
# Fallback instructions if neither is clearly detected
|
|
53
|
-
say "\nCould not automatically detect Importmaps or jsbundling-rails.", :yellow
|
|
54
|
-
say "Please manually add the '#{package_name}' JavaScript package.", :yellow
|
|
55
|
-
say "If using Importmaps: bin/importmap pin #{package_name}", :cyan
|
|
56
|
-
say "If using Yarn: yarn add #{package_name}", :cyan
|
|
57
|
-
say "If using npm: npm install --save #{package_name}", :cyan
|
|
58
|
-
say "If using Bun: bun add #{package_name}", :cyan
|
|
59
|
-
say "Then, import it in your app/javascript/application.js:", :yellow
|
|
60
|
-
say "import '#{package_name}'\n", :cyan
|
|
61
|
-
end
|
|
20
|
+
add_js_dependency
|
|
62
21
|
end
|
|
63
22
|
|
|
64
23
|
# Step 3: Register Stimulus Controller
|
|
65
24
|
def setup_stimulus_controller
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
controller_name = "UltimateTurboModalController"
|
|
69
|
-
stimulus_identifier = "modal"
|
|
25
|
+
index_path = rails_root_join("app", "javascript", "controllers", "index.js")
|
|
26
|
+
application_path = rails_root_join("app", "javascript", "controllers", "application.js")
|
|
27
|
+
controller_name = "UltimateTurboModalController"
|
|
28
|
+
stimulus_identifier = "modal"
|
|
70
29
|
|
|
71
|
-
import_line = "import { #{controller_name} } from \"#{
|
|
30
|
+
import_line = "import { #{controller_name} } from \"#{package_name}\"\n"
|
|
72
31
|
register_line = "application.register(\"#{stimulus_identifier}\", #{controller_name})\n"
|
|
73
32
|
|
|
74
|
-
|
|
33
|
+
# Determine which file contains Application.start() — it may be index.js or application.js
|
|
34
|
+
target_path, file_content = find_stimulus_target(index_path, application_path)
|
|
35
|
+
|
|
36
|
+
say "\nAttempting to register Stimulus controller...", :yellow
|
|
75
37
|
|
|
76
|
-
unless
|
|
77
|
-
say "❌ Stimulus controllers
|
|
38
|
+
unless target_path
|
|
39
|
+
say "❌ Stimulus controllers file not found.", :red
|
|
78
40
|
say " Please manually add the following lines to your Stimulus setup:", :yellow
|
|
79
41
|
say " #{import_line.strip}", :cyan
|
|
80
42
|
say " #{register_line.strip}\n", :cyan
|
|
81
|
-
return
|
|
43
|
+
return
|
|
82
44
|
end
|
|
83
45
|
|
|
84
|
-
|
|
85
|
-
file_content = File.read(stimulus_controller_path)
|
|
46
|
+
say " Target file: #{target_path}", :yellow
|
|
86
47
|
|
|
87
|
-
# Insert the import statement after
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
48
|
+
# Insert the import statement after an existing import from @hotwired/stimulus or ./application
|
|
49
|
+
import_anchor = /import .* from ["'](?:@hotwired\/stimulus|\.\/application)["']\n/
|
|
50
|
+
if file_content.include?(import_line)
|
|
51
|
+
say "⏩ Import statement already exists.", :blue
|
|
52
|
+
elsif file_content.match?(import_anchor)
|
|
53
|
+
insert_into_file target_path, import_line, after: import_anchor
|
|
92
54
|
say "✅ Added import statement.", :green
|
|
93
|
-
elsif
|
|
94
|
-
|
|
95
|
-
insert_into_file stimulus_controller_path, import_line, before: /import/
|
|
55
|
+
elsif file_content.match?(/import/)
|
|
56
|
+
insert_into_file target_path, import_line, before: /import/
|
|
96
57
|
say "✅ Added import statement (fallback position).", :green
|
|
97
58
|
else
|
|
98
|
-
|
|
59
|
+
prepend_to_file target_path, import_line
|
|
60
|
+
say "✅ Added import statement (prepended to file).", :green
|
|
99
61
|
end
|
|
100
62
|
|
|
101
|
-
|
|
102
63
|
# Insert the register statement after Application.start()
|
|
103
|
-
register_anchor = /Application\.start
|
|
104
|
-
if file_content.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
say "
|
|
109
|
-
say " Please manually add this line after your Stimulus application starts:", :yellow
|
|
110
|
-
say " #{register_line.strip}\n", :cyan
|
|
64
|
+
register_anchor = /Application\.start\(\)\n/
|
|
65
|
+
if file_content.include?(register_line)
|
|
66
|
+
say "⏩ Controller registration already exists.", :blue
|
|
67
|
+
elsif file_content.match?(register_anchor)
|
|
68
|
+
insert_into_file target_path, register_line, after: register_anchor
|
|
69
|
+
say "✅ Added controller registration.", :green
|
|
111
70
|
else
|
|
112
|
-
|
|
71
|
+
say "❌ Could not find `Application.start()` line in #{target_path}.", :red
|
|
72
|
+
say " Please manually add these lines to your Stimulus setup:", :yellow
|
|
73
|
+
say " #{import_line.strip}", :cyan
|
|
74
|
+
say " #{register_line.strip}\n", :cyan
|
|
113
75
|
end
|
|
114
76
|
end
|
|
115
77
|
|
|
@@ -196,28 +158,17 @@ module UltimateTurboModal
|
|
|
196
158
|
end
|
|
197
159
|
end
|
|
198
160
|
|
|
199
|
-
def
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def uses_yarn?
|
|
208
|
-
File.exist?(rails_root_join("yarn.lock"))
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def uses_npm?
|
|
212
|
-
File.exist?(rails_root_join("package-lock.json")) && !uses_yarn? && !uses_bun?
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def uses_bun?
|
|
216
|
-
File.exist?(rails_root_join("bun.lockb"))
|
|
217
|
-
end
|
|
161
|
+
def find_stimulus_target(index_path, application_path)
|
|
162
|
+
[index_path, application_path].each do |path|
|
|
163
|
+
next unless File.exist?(path)
|
|
164
|
+
content = File.read(path)
|
|
165
|
+
return [path, content] if content.match?(/Application\.start\(\)/)
|
|
166
|
+
end
|
|
218
167
|
|
|
219
|
-
|
|
220
|
-
|
|
168
|
+
# Fall back to index.js even without Application.start()
|
|
169
|
+
if File.exist?(index_path)
|
|
170
|
+
[index_path, File.read(index_path)]
|
|
171
|
+
end
|
|
221
172
|
end
|
|
222
173
|
end
|
|
223
174
|
end
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
require "rails/generators"
|
|
4
4
|
require "json"
|
|
5
5
|
require "pathname"
|
|
6
|
+
require_relative "base"
|
|
6
7
|
|
|
7
8
|
module UltimateTurboModal
|
|
8
9
|
module Generators
|
|
9
|
-
class UpdateGenerator <
|
|
10
|
+
class UpdateGenerator < UltimateTurboModal::Generators::Base
|
|
10
11
|
source_root File.expand_path("templates", __dir__)
|
|
11
12
|
|
|
12
13
|
desc "Updates UltimateTurboModal: aligns npm package version to gem version and refreshes the configured flavor initializer."
|
|
@@ -29,6 +30,13 @@ module UltimateTurboModal
|
|
|
29
30
|
package_name = "ultimate_turbo_modal"
|
|
30
31
|
new_version = UltimateTurboModal::VERSION.to_s
|
|
31
32
|
|
|
33
|
+
# Special case: demo app links to local JS package; never update its version
|
|
34
|
+
if json.dig("dependencies", package_name) == "link:../javascript" ||
|
|
35
|
+
json.dig("devDependencies", package_name) == "link:../javascript"
|
|
36
|
+
say "Detected local link for '#{package_name}' (link:../javascript). Skipping version update.", :blue
|
|
37
|
+
return
|
|
38
|
+
end
|
|
39
|
+
|
|
32
40
|
updated = false
|
|
33
41
|
|
|
34
42
|
%w[dependencies devDependencies].each do |section|
|
|
@@ -49,6 +57,10 @@ module UltimateTurboModal
|
|
|
49
57
|
end
|
|
50
58
|
end
|
|
51
59
|
|
|
60
|
+
def install_js_dependencies
|
|
61
|
+
install_all_js_dependencies
|
|
62
|
+
end
|
|
63
|
+
|
|
52
64
|
def copy_flavor_file
|
|
53
65
|
flavor = detect_flavor
|
|
54
66
|
unless flavor
|
data/lib/ultimate_turbo_modal.rb
CHANGED
|
@@ -5,6 +5,7 @@ require "phlex/deferred_render_with_main_content"
|
|
|
5
5
|
require "ultimate_turbo_modal/configuration"
|
|
6
6
|
require "ultimate_turbo_modal/railtie"
|
|
7
7
|
require "ultimate_turbo_modal/base"
|
|
8
|
+
require "generators/ultimate_turbo_modal/base"
|
|
8
9
|
require "generators/ultimate_turbo_modal/install_generator"
|
|
9
10
|
require "generators/ultimate_turbo_modal/update_generator"
|
|
10
11
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ultimate_turbo_modal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.2.
|
|
4
|
+
version: 2.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carl Mercier
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-03-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: phlex-rails
|
|
@@ -177,6 +177,7 @@ files:
|
|
|
177
177
|
- javascript/scripts/update-version.js
|
|
178
178
|
- javascript/styles/vanilla.css
|
|
179
179
|
- javascript/yarn.lock
|
|
180
|
+
- lib/generators/ultimate_turbo_modal/base.rb
|
|
180
181
|
- lib/generators/ultimate_turbo_modal/install_generator.rb
|
|
181
182
|
- lib/generators/ultimate_turbo_modal/templates/flavors/custom.rb
|
|
182
183
|
- lib/generators/ultimate_turbo_modal/templates/flavors/tailwind.rb
|