|
1 | 1 | module RubyUI |
2 | 2 | module Generators |
3 | | - class ComponentGenerator < RubyUI::Generators::BaseGenerator |
| 3 | + class ComponentGenerator < Rails::Generators::Base |
4 | 4 | namespace "ruby_ui:component" |
5 | 5 |
|
6 | | - source_root File.expand_path("../../..", __dir__) |
| 6 | + source_root File.expand_path("../../ruby_ui", __dir__) |
7 | 7 | argument :component_name, type: :string, required: true |
8 | 8 |
|
9 | | - def copy_component |
10 | | - return puts "This generator can only be run in a Rails environment." unless defined?(Rails::Generators::Base) |
| 9 | + def generate_component |
| 10 | + if component_not_found? |
| 11 | + say "Component not found: #{component_name}", :red |
| 12 | + exit |
| 13 | + end |
11 | 14 |
|
12 | | - copy_common_files |
13 | | - copy_component_files |
| 15 | + say "Generating component files" |
14 | 16 | end |
15 | 17 |
|
16 | | - private |
| 18 | + def copy_main_component_file |
| 19 | + say "Generating main component" |
17 | 20 |
|
18 | | - def copy_common_files |
19 | | - template "#{template_dir}/index.js", "#{destination_path}/index.js" unless File.exist?("#{destination_path}/index.js") |
20 | | - copy_file File.join(source_path, "base.rb"), File.join(destination_path, "base.rb") |
| 21 | + copy_file File.join(component_folder_path, "#{component_folder_name}.rb"), |
| 22 | + Rails.root.join("app/components/ruby_ui", "#{component_folder_name}.rb") |
21 | 23 | end |
22 | 24 |
|
23 | | - def copy_component_files |
24 | | - puts "Component #{component} not found in ruby_ui gem" if component_source.empty? |
| 25 | + def copy_subcomponents_files |
| 26 | + return if subcomponent_file_paths.empty? |
25 | 27 |
|
26 | | - component_files = Dir.glob("#{component_source}/*") |
| 28 | + say "Generating subcomponents" |
27 | 29 |
|
28 | | - component_files.each do |file| |
29 | | - copy_file file, File.join(destination_path, component, File.basename(file)) |
| 30 | + subcomponent_file_paths.each do |file_path| |
| 31 | + component_file_name = file_path.split("/").last |
| 32 | + copy_file file_path, Rails.root.join("app/components/ruby_ui", component_folder_name, component_file_name) |
30 | 33 | end |
31 | | - update_index_file |
32 | | - end |
33 | | - |
34 | | - def update_index_file |
35 | | - index_path = File.join(destination_root, "app/components/ruby_ui/index.js") |
36 | | - |
37 | | - ruby_ui_index_content = File.read(index_path) |
38 | | - |
39 | | - updated_ruby_ui_index_content = add_controller_registration(ruby_ui_index_content) |
40 | | - |
41 | | - File.write(index_path, updated_ruby_ui_index_content) |
42 | 34 | end |
43 | 35 |
|
44 | | - def add_controller_registration(ruby_ui_index_content) |
45 | | - valid_controllers = get_valid_controllers |
| 36 | + def copy_js_files |
| 37 | + return if js_controller_file_paths.empty? |
46 | 38 |
|
47 | | - ruby_ui_index_content = update_imports(ruby_ui_index_content, valid_controllers) |
48 | | - update_registrations(ruby_ui_index_content, valid_controllers) |
49 | | - # Uncomment the following line if you want to update exports |
50 | | - # ruby_ui_index_content = update_exports(ruby_ui_index_content, valid_controllers) |
51 | | - end |
52 | | - |
53 | | - def get_valid_controllers |
54 | | - all_js_controllers = Dir.glob(File.join(destination_path, "**", "*_controller.js")) |
| 39 | + say "Generating Stimulus controllers" |
55 | 40 |
|
56 | | - all_js_controllers.map do |controller_file| |
57 | | - controller_info(controller_file) |
| 41 | + js_controller_file_paths.each do |file_path| |
| 42 | + component_file_name = file_path.split("/").last |
| 43 | + copy_file file_path, Rails.root.join("app/javascript/controllers/ruby_ui", component_file_name) |
58 | 44 | end |
59 | | - end |
60 | | - |
61 | | - def controller_info(controller_file) |
62 | | - # Get the relative path from the destination path to the controller file |
63 | | - relative_path = Pathname.new(controller_file).relative_path_from(Pathname.new(destination_path)) |
64 | | - |
65 | | - # Extract the file name without the .js extension |
66 | | - file_name = relative_path.basename(".js").to_s |
67 | | - |
68 | | - # Remove '_controller' suffix to get the component name |
69 | | - component_name = file_name.sub(/_controller$/, "") |
70 | | - |
71 | | - # Create the new controller name by camelizing the component name and adding 'Controller' |
72 | | - new_controller = "#{component_name.camelize}Controller" |
73 | 45 |
|
74 | | - # Build the new import path |
75 | | - new_import_path = new_import_path("./#{relative_path.dirname}/#{file_name}") |
76 | | - |
77 | | - # Create the registration name by dasherizing the component name and prefixing with 'ruby-ui--' |
78 | | - registration_name = "ruby-ui--#{component_name.dasherize}" |
79 | | - |
80 | | - # Return a hash with import, registration, and export statements |
81 | | - { |
82 | | - # Import statement for importmaps |
83 | | - import: "import #{new_controller} from \"#{new_import_path}\";", |
84 | | - |
85 | | - # Registration statement for the Stimulus controller |
86 | | - registration: "application.register(\"#{registration_name}\", #{new_controller});", |
87 | | - |
88 | | - # Export statement for the controller |
89 | | - export: "export { default as #{new_controller} } from \"#{new_import_path}\";" |
90 | | - } |
| 46 | + say "Updating Stimulus controllers manifest" |
| 47 | + run "rake stimulus:manifest:update" |
91 | 48 | end |
92 | 49 |
|
93 | | - def new_import_path(relative_path) |
94 | | - if using_importmap? |
95 | | - "ruby_ui/#{relative_path.sub(/^\.\//, "")}" |
96 | | - else |
97 | | - relative_path |
| 50 | + def copy_dependencies |
| 51 | + case component_folder_name |
| 52 | + when "masked_input" |
| 53 | + copy_masked_input_dependencies |
98 | 54 | end |
99 | 55 | end |
100 | 56 |
|
101 | | - def update_imports(content, controllers) |
102 | | - imports = controllers.map { |c| c[:import] }.sort.join("\n") |
103 | | - content.sub(/\/\/ Import all controller files.*?(?=\n\n)/m, "// Import all controller files\n#{imports}") |
104 | | - end |
| 57 | + private |
105 | 58 |
|
106 | | - def update_registrations(content, controllers) |
107 | | - registrations = controllers.map { |c| c[:registration] }.sort.join("\n") |
108 | | - content.sub(/\/\/ Register all controllers.*?(?=\n\n)/m, "// Register all controllers\n#{registrations}") |
109 | | - end |
| 59 | + def component_not_found? = !Dir.exist?(component_folder_path) |
110 | 60 |
|
111 | | - def update_exports(content, controllers) |
112 | | - exports = controllers.map { |c| c[:export] }.sort.join("\n") |
113 | | - content.sub(/\/\/ Export all controllers.*?(?=\n\n)/m, "// Export all controllers so user of npm package can lazy load controllers\n#{exports}") |
114 | | - end |
| 61 | + def component_folder_name = component_name.underscore |
115 | 62 |
|
116 | | - def component |
117 | | - @component ||= component_name.downcase |
118 | | - end |
| 63 | + def component_folder_path = File.join(self.class.source_root, component_folder_name) |
119 | 64 |
|
120 | | - def source_path |
121 | | - @source_path ||= "lib/ruby_ui" |
122 | | - end |
| 65 | + def main_component_file_path = File.join(component_folder_path, "#{component_folder_name}.rb") |
123 | 66 |
|
124 | | - def destination_path |
125 | | - @destination_path ||= "app/components/ruby_ui" |
126 | | - end |
| 67 | + def subcomponent_file_paths = Dir.glob(File.join(component_folder_path, "*.rb")) - [main_component_file_path] |
127 | 68 |
|
128 | | - def component_source |
129 | | - @component_source ||= File.join(self.class.source_root, source_path, component) |
130 | | - end |
| 69 | + def js_controller_file_paths = Dir.glob(File.join(component_folder_path, "*.js")) |
| 70 | + |
| 71 | + def copy_masked_input_dependencies |
| 72 | + say "Generating masked input dependencies" |
131 | 73 |
|
132 | | - def template_dir |
133 | | - @template_dir ||= File.join(__dir__, "templates") |
| 74 | + run "bin/rails generate ruby_ui:component Input" |
134 | 75 | end |
135 | 76 | end |
136 | 77 | end |
|
0 commit comments