From 52898b122e7e8e00b05c70a9419eacb4116281c1 Mon Sep 17 00:00:00 2001 From: Seth Horsley Date: Tue, 17 Sep 2024 00:54:21 +0300 Subject: [PATCH] =?UTF-8?q?Add=20component=20generator=20=F0=9F=A6=BE=20(#?= =?UTF-8?q?97)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * install generator working * got it working 🦾 * js overriding is working * moved index.js to lib/rbui/index.js * fix a few thangs 🦾 * final commit * remove phlex_ui refs * fix index.js --- lib/generators/rbui/component_generator.rb | 108 ++++++++++++++++++ .../install/templates/tailwind.config.js.tt | 1 + lib/generators/rbui/templates/index.js.tt | 29 +++++ lib/rbui.rb | 1 + index.js => lib/rbui/index.js | 0 lib/rbui/railtie.rb | 35 ++++++ package.json | 5 +- 7 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 lib/generators/rbui/component_generator.rb create mode 100644 lib/generators/rbui/templates/index.js.tt rename index.js => lib/rbui/index.js (100%) diff --git a/lib/generators/rbui/component_generator.rb b/lib/generators/rbui/component_generator.rb new file mode 100644 index 0000000..a1ed956 --- /dev/null +++ b/lib/generators/rbui/component_generator.rb @@ -0,0 +1,108 @@ +module RBUI + module Generators + class ComponentGenerator < defined?(Rails::Generators::Base) ? Rails::Generators::Base : Object + namespace "rbui:component" + + source_root File.expand_path("../../..", __dir__) + argument :component_name, type: :string, required: true + + def copy_component + return puts "This generator can only be run in a Rails environment." unless defined?(Rails::Generators::Base) + + copy_common_files + copy_component_files + end + + private + + def copy_common_files + template "#{template_dir}/index.js", "#{destination_path}/index.js" unless File.exist?("#{destination_path}/index.js") + copy_file File.join(source_path, "base.rb"), File.join(destination_path, "base.rb") + + append_to_file "app/javascript/application.js", "\nimport \"../components/rbui\";\n" + end + + def copy_component_files + puts "Component #{component} not found in rbui gem" if component_source.empty? + + component_files = Dir.glob("#{component_source}/*") + + component_files.each do |file| + copy_file file, File.join(destination_path, component, File.basename(file)) + end + update_index_file + end + + def update_index_file + index_path = File.join(destination_root, "app/components/rbui/index.js") + content = File.read(index_path) + + update_last_updated_date(content) + update_controller_registration(content) + + File.write(index_path, content) + end + + def update_last_updated_date(content) + content.sub!(/Last updated: .*/, "Last updated: #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}") + end + + def update_controller_registration(content) + all_js_controllers = Dir.glob(File.join(destination_path, "**", "*_controller.js")) + + # Collect all valid controller information + valid_controllers = all_js_controllers.map do |controller_file| + relative_path = Pathname.new(controller_file).relative_path_from(Pathname.new(destination_path)) + file_name = relative_path.basename(".js").to_s + component_name = file_name.sub(/_controller$/, "") + new_controller = "#{component_name.camelize}Controller" + new_path = "./#{relative_path.dirname}/#{file_name}" + registration_name = "rbui--#{component_name.dasherize}" + + { + import: "import #{new_controller} from \"#{new_path}\";", + registration: "RBUI.unload(\"#{registration_name}\");\napplication.register(\"#{registration_name}\", #{new_controller});", + export: "export { default as #{new_controller} } from \"#{new_path}\";" + } + end + + # Update imports + imports = valid_controllers.map { |c| c[:import] }.sort + import_block = imports.join("\n") + content.sub!(/\/\/ Import all controller files.*?(?=\n\n)/m, "// Import all controller files\n#{import_block}") + + # Update registrations + registrations = valid_controllers.map { |c| c[:registration] }.sort + registration_block = registrations.join("\n") + content.sub!(/\/\/ Register all controllers.*?(?=\n\n)/m, "// Register all controllers\n#{registration_block}") + + # Update exports + exports = valid_controllers.map { |c| c[:export] }.sort + export_block = exports.join("\n") + content.sub!(/\/\/ Export all controllers.*?(?=\n\n)/m, "// Export all controllers so user of npm package can lazy load controllers\n#{export_block}") + + content + end + + def component + @component ||= component_name.downcase + end + + def source_path + @source_path ||= "lib/rbui" + end + + def destination_path + @destination_path ||= "app/components/rbui" + end + + def component_source + @component_source ||= File.join(self.class.source_root, source_path, component) + end + + def template_dir + @template_dir ||= File.join(__dir__, "templates") + end + end + end +end diff --git a/lib/generators/rbui/install/templates/tailwind.config.js.tt b/lib/generators/rbui/install/templates/tailwind.config.js.tt index 58ad8ce..9900696 100644 --- a/lib/generators/rbui/install/templates/tailwind.config.js.tt +++ b/lib/generators/rbui/install/templates/tailwind.config.js.tt @@ -11,6 +11,7 @@ module.exports = { darkMode: ["class"], content: [ './app/views/**/*.{erb,haml,html,slim,rb}', + './app/components/rbui/**/*.rb', './app/helpers/**/*.rb', './app/assets/stylesheets/**/*.css', './app/javascript/**/*.js', diff --git a/lib/generators/rbui/templates/index.js.tt b/lib/generators/rbui/templates/index.js.tt new file mode 100644 index 0000000..1199605 --- /dev/null +++ b/lib/generators/rbui/templates/index.js.tt @@ -0,0 +1,29 @@ +/** + * IMPORTANT: DO NOT EDIT THIS FILE MANUALLY + * -------------------------------------------- + * This file is automatically generated and managed. + * + * Last updated: [DATE] + */ + +// Load and export all of the stimulus controllers +import { Application } from "@hotwired/stimulus"; + +const application = Application.start(); + +// Configure Stimulus development experience +application.debug = false; +window.Stimulus = application; + +import { application as RBUI } from "rbui-js"; + +// Import all controller files + +// Register all controllers + +// Export all controllers so user of npm package can lazy load controllers + +// Export application +export { application }; + + diff --git a/lib/rbui.rb b/lib/rbui.rb index d1f6f2c..fe854de 100644 --- a/lib/rbui.rb +++ b/lib/rbui.rb @@ -46,4 +46,5 @@ def self.create_namespace_module # If you need to require generators (assuming they're needed) if defined?(Rails::Generators) require_relative "generators/rbui/install/install_generator" + require_relative "generators/rbui/component_generator" end diff --git a/index.js b/lib/rbui/index.js similarity index 100% rename from index.js rename to lib/rbui/index.js diff --git a/lib/rbui/railtie.rb b/lib/rbui/railtie.rb index 39288f7..992832d 100644 --- a/lib/rbui/railtie.rb +++ b/lib/rbui/railtie.rb @@ -12,6 +12,41 @@ class Railtie < ::Rails::Railtie Rails::Generators.namespace(RBUI::Generators, as: "rbui") end end + + # Add component loading + config.to_prepare do + # Define the path to the RBUI components + rbui_components_path = Rails.root.join("app/components/rbui") + + # Check if the RBUI components directory exists + if Dir.exist?(rbui_components_path) + # Find all Ruby files in the RBUI components directory and its subdirectories + Dir[rbui_components_path.join("**", "*.rb")].each do |file| + # Get the relative path of the file from the RBUI components directory + relative_path = Pathname.new(file).relative_path_from(rbui_components_path) + + # Convert the file path to a component name + # e.g., "form/input.rb" becomes ["Form", "Input"] + component_name_parts = relative_path.to_s.chomp(".rb").split("/").map(&:camelize) + + # Create the full component name with RBUI namespace + # e.g., "RBUI::Form::Input" + full_component_name = "RBUI::#{component_name_parts.join("::")}" + + begin + # Check if the component is already defined + if defined?(full_component_name.constantize) + # If it's defined, load (or reload) the file + load file + end + rescue NameError + # If the constant isn't defined (i.e., the component doesn't exist), + # we'll skip this file and move to the next one + next + end + end + end + end end end end diff --git a/package.json b/package.json index 19472d7..acdafbc 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "rbui-js", "version": "0.0.1-alpha.0", + "main": "lib/rbui/index.js", "description": "Stimulus controllers for RbUI Component Library", - "main": "index.js", "homepage": "https://rbui.dev", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -35,4 +35,5 @@ "devDependencies": { "globals": "^15.8.0" } -} \ No newline at end of file +} +