diff --git a/lib/generators/ruby_ui/install/install_generator.rb b/lib/generators/ruby_ui/install/install_generator.rb index ae2a71f5..32dbb27f 100644 --- a/lib/generators/ruby_ui/install/install_generator.rb +++ b/lib/generators/ruby_ui/install/install_generator.rb @@ -1,192 +1,71 @@ -require "net/http" -require_relative "../base_generator" +require "rails/generators" -# TODO: make ejctectec components work without the gem module RubyUI module Generators - class InstallGenerator < RubyUI::Generators::BaseGenerator + class InstallGenerator < Rails::Generators::Base namespace "ruby_ui:install" - if defined?(Rails::Generators::Base) - source_root File.expand_path("templates", __dir__) + source_root File.expand_path("templates", __dir__) - def confirm_installation - return if yes?("You need tailwindcss installed. Continue? (y/n)") - say "Installation cancelled.", :red - exit - end + def install_phlex_rails + say "Checking for phlex-rails" - def add_phlex_rails - say "Checking for Phlex Rails" - if gem_installed?("phlex-rails") - say "Phlex Rails is already installed", :green + if gem_installed?("phlex-rails") + if Gem::Specification.find_by_name("phlex-rails").version < "2.0.0.beta2" + say "You need to upgrade to phlex-rails 2 to use RubyUI", :red + exit else - say "Adding Phlex Rails" - run "bundle add phlex-rails --version=\"~> 2.0.0.beta2\"" + say "phlex-rails is already installed", :green end + else + say "Adding phlex-rails to Gemfile" + run %(bundle add phlex-rails --github="phlex-ruby/phlex-rails") - say "Adding tailwind_merge" - run "bundle add tailwind_merge" - - say "run phlex install" + say "Running phlex-rails structure" run "bin/rails generate phlex:install" end + end - def install_stuff - # make default option no - # extend the yes func to have a default option y/(n) and also allow for enter to accedpt the default - - if ENV["TEST_DATA"] == "true" - say "Do you want to set up the dev test data?" - say "Add index controller" - run "bin/rails generate controller static index --no-helper --no-assets --no-test-framework --no-jbuilder" - - say "Add index view" - run "bin/rails g phlex:view Static::Index" - - append_to_file "app/controllers/static_controller.rb", after: " def index" do - # remove view because phlex is removing view - "\n render Static::IndexView" - end - - template "index_view.rb", "app/views/static/index_view.rb", force: true - - say "Add index route" - append_to_file "config/routes.rb", after: "Rails.application.routes.draw do" do - "\n root to: \"static#index\"\n" - end - end - - tailwind_config_path = Rails.root.join("config/tailwind.config.js") - if !File.exist?(tailwind_config_path) - say "Tailwind CSS is required for RubyUI", :red - end - - say "Add ruby_ui initializer" - template "base_store_initializer.rb", "config/initializers/ruby_ui.rb" - - if using_importmap? - say "Using importmaps, adding tailwind-animate" - run "bin/importmap pin tailwindcss-animate" - - # Remove the default pin - gsub_file "config/importmap.rb", /^pin "tailwindcss-animate".*$\n/, "" - - # Add the vendor-specific pin - append_to_file "config/importmap.rb" do - 'pin "tailwindcss-animate", to: "tailwindcss-animate.js", preload: true' + "\n" - end - - else - say "Not using importmaps, adding tailwind-animate via yarn" - run "yarn add tailwindcss-animate" - end - - # check if tailwind.config is in config dir or in root or ask to specify a path - say "update tailwind.config.js" - template "tailwind.config.js", "config/tailwind.config.js", force: true, assigns: {using_importmap: using_importmap?} + def install_tailwind_merge + say "Checking for tailwind_merge" - say "Add CSS variables" - template "application.tailwind.css", "app/assets/stylesheets/application.tailwind.css", force: true + if gem_installed?("tailwind_merge") + say "tailwind_merge is already installed", :green + else + say "Adding phlex-rails to Gemfile" + run %(bundle add tailwind_merge) end + end - def pin_ruby_ui_js - stimulus_path = Rails.root.join("app/javascript/application.js") - package_name = "ruby_ui_js" - - say "Add RubyUI Stimulus controllers" - # run "mkdir -p app/javascript/controllers/ruby_ui_js" - template "index.js", "app/components/ruby_ui/index.js" - - if using_importmap? - gsub_file "app/components/ruby_ui/index.js", /^import { application }.*$/ do - 'import { application } from "controllers/application";' - end - - append_to_file Rails.root.join("config/initializers/assets.rb") do - "Rails.application.config.assets.paths << Rails.root.join(\"app/components\")\n" - end - - say "Pin #{package_name}" - append_to_file Rails.root.join("config/importmap.rb") do - "pin_all_from \"app/components/ruby_ui\", under: \"ruby_ui\"\n" - end - - run "bin/importmap pin #{package_name}" - append_to_file stimulus_path, "\nimport \"ruby_ui\";\n" - - manifest_path = Rails.root.join("app/assets/config/manifest.js") - if File.exist?(manifest_path) - append_to_file manifest_path, "\n//= link ruby_ui/index.js\n" - end - - fix_import_maps! - else - say "Add ruby_ui_js package" - run "yarn add #{package_name}" - - append_to_file stimulus_path, "\nimport \"../components/ruby_ui\";\n" + def install_ruby_ui_initializer + say "Creating RubyUI initializer" + template "ruby_ui.rb.erb", Rails.root.join("config/initializers/ruby_ui.rb") + end - run "yarn build" - end - end - - def include_ruby_ui - message = "Include RubyUI in your global component layout?\n This allows to call RubyUI.Button {\"button\"} / RubyUI::Button.new {\"button\"} with Button {\"button\"} (y/n)" - if yes?(message) - say "Add RubyUI to your global component layout" - insert_into_file "app/views/application_view.rb", after: "class ApplicationView < ApplicationComponent\n" do - " include RubyUI\n" - end - end + def add_ruby_ui_module_to_components_base + say "Adding RubyUI Kit to Components::Base" + insert_into_file Rails.root.join("app/components/base.rb"), after: "include Components" do + "\n include RubyUI" end + end - else - def self.source_root - File.expand_path("templates", __dir__) - end + def add_tailwind_css + say "Adding RubyUI styles to application css" + template "application.tailwind.css.erb", Rails.root.join("app/assets/stylesheets/application.tailwind.css") + end - def add_stylesheet_link - puts "This generator can only be run in a Rails environment." - end + def add_tailwind_config + say "Adding RubyUI config to tailwind config" + template "tailwind.config.js.erb", Rails.root.join("tailwind.config.js") + end - def revoke - puts "This generator can only be run in a Rails environment." - end + def add_ruby_ui_base + say "Adding RubyUI::Base component" + template "../../../../ruby_ui/base.rb", Rails.root.join("app/components/ruby_ui/base.rb") end private - def fix_import_maps! - importmap_config_path = Rails.root.join("config/importmap.rb") - - gsub_file importmap_config_path, /^pin "date-fns".*$/ do - 'pin "date-fns", to: "https://ga.jspm.io/npm:date-fns@3.3.1/index.mjs"' - end - run "bin/importmap pin @popperjs/core@2.11.8/+esm --from jsdelivr" - - run "mv vendor/javascript/@popperjs--core--+esm.js vendor/javascript/stupid-popper-lib-2024.js" - - append_to_file importmap_config_path do - 'pin "@popperjs/core", to: "stupid-popper-lib-2024.js"' - end - - uri = URI "https://ga.jspm.io/npm:chart.js@3.9.1/dist/chart.min.js" - request = Net::HTTP::Get.new uri - - response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| - http.request(request) - } - - File.write(Rails.root.join("vendor/javascript/chart.js--auto.js"), response.body) if response.is_a?(Net::HTTPSuccess) - - append_to_file Rails.root.join("app/views/layouts/application.html.erb"), before: "" do - "" - end - end - def gem_installed?(name) Gem::Specification.find_all_by_name(name).any? end diff --git a/lib/generators/ruby_ui/install/templates/.keep b/lib/generators/ruby_ui/install/templates/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/generators/ruby_ui/install/templates/application.tailwind.css.tt b/lib/generators/ruby_ui/install/templates/application.tailwind.css.erb similarity index 99% rename from lib/generators/ruby_ui/install/templates/application.tailwind.css.tt rename to lib/generators/ruby_ui/install/templates/application.tailwind.css.erb index 582befe7..e1bb6c14 100644 --- a/lib/generators/ruby_ui/install/templates/application.tailwind.css.tt +++ b/lib/generators/ruby_ui/install/templates/application.tailwind.css.erb @@ -24,14 +24,14 @@ --input: 240 5.9% 90%; --ring: 240 5.9% 10%; --radius: 0.5rem; - + /* ruby_ui especific */ --warning: 38 92% 50%; --warning-foreground: 0 0% 100%; --success: 87 100% 37%; --success-foreground: 0 0% 100%; } - + .dark { --background: 240 10% 3.9%; --foreground: 0 0% 98%; @@ -65,6 +65,7 @@ * { @apply border-border; } + body { @apply bg-background text-foreground; font-feature-settings: "rlig" 1, "calt" 1; diff --git a/lib/generators/ruby_ui/install/templates/base_store_initializer.rb.tt b/lib/generators/ruby_ui/install/templates/base_store_initializer.rb.tt deleted file mode 100644 index c99d685f..00000000 --- a/lib/generators/ruby_ui/install/templates/base_store_initializer.rb.tt +++ /dev/null @@ -1,10 +0,0 @@ -#RubyUI.setup do |config| - - # Setting a namespace allows you to access RubyUI components through this namespace. - # For example, with namespace set to "UI", you can use: - # UI::Button.new instead of RubyUI::Button.new - # UI::Card.new instead of RubyUI::Card.new - # This can help avoid naming conflicts and allows for cleaner, more concise code. - # If you prefer to use RubyUI components directly, you can leave this unset. - # config.namespace = "UI" -#end diff --git a/lib/generators/ruby_ui/install/templates/index.js.tt b/lib/generators/ruby_ui/install/templates/index.js.tt deleted file mode 100644 index 871cbee8..00000000 --- a/lib/generators/ruby_ui/install/templates/index.js.tt +++ /dev/null @@ -1,10 +0,0 @@ -import { application } from "../../../app/javascript/controllers/application"; - -// Import all controller files -// import ComboboxController from "./combobox/combobox_controller"; - -// Register all controllers -// application.register("ruby-ui--combobox", ComboboxController); - -import RubyUI from "ruby_ui_js"; -RubyUI.initialize(application); diff --git a/lib/generators/ruby_ui/install/templates/index_view.rb.tt b/lib/generators/ruby_ui/install/templates/index_view.rb.tt deleted file mode 100644 index 0218e28d..00000000 --- a/lib/generators/ruby_ui/install/templates/index_view.rb.tt +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -class Static::IndexView < ApplicationView - def template - render RubyUI::Button.new { "click me" } - br {} - - # UI.Button { "click me" } - - AlertDialog do - AlertDialogTrigger do - Button { "Show dialog" } - end - AlertDialogContent do - AlertDialogHeader do - AlertDialogTitle { "Are you absolutely sure?" } - AlertDialogDescription { "This action cannot be undone. This will permanently delete your account and remove your data from our servers." } - end - AlertDialogFooter do - AlertDialogCancel { "Cancel" } - AlertDialogAction { "Continue" } # Will probably be a link to a controller action (e.g. delete account) - end - end - end - h1 { "Static::Index" } - p { "Find me in app/views/static/index_view.rb" } - end -end - diff --git a/lib/generators/ruby_ui/install/templates/ruby_ui.rb.erb b/lib/generators/ruby_ui/install/templates/ruby_ui.rb.erb new file mode 100644 index 00000000..a5b0a4d0 --- /dev/null +++ b/lib/generators/ruby_ui/install/templates/ruby_ui.rb.erb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module RubyUI + extend Phlex::Kit +end + +# Allow using RubyUI instead RubyUi +Rails.autoloaders.main.inflector.inflect( + "ruby_ui" => "RubyUI" +) + +# Allow using RubyUI::ComponentName instead Components::RubyUI::ComponentName +Rails.autoloaders.main.push_dir( + "#{Rails.root}/app/components/ruby_ui", namespace: RubyUI +) + +# Allow using RubyUI::ComponentName instead RubyUI::ComponentName::ComponentName +Rails.autoloaders.main.collapse(Rails.root.join("app/components/ruby_ui/*")) diff --git a/lib/generators/ruby_ui/install/templates/tailwind.config.js.tt b/lib/generators/ruby_ui/install/templates/tailwind.config.js.erb similarity index 72% rename from lib/generators/ruby_ui/install/templates/tailwind.config.js.tt rename to lib/generators/ruby_ui/install/templates/tailwind.config.js.erb index 038bdb94..490640ef 100644 --- a/lib/generators/ruby_ui/install/templates/tailwind.config.js.tt +++ b/lib/generators/ruby_ui/install/templates/tailwind.config.js.erb @@ -1,22 +1,13 @@ -// For importing tailwind styles from ruby_ui gem -const execSync = require('child_process').execSync; - -// Import ruby_ui gem path -const outputRubyUI = execSync('bundle show ruby_ui', { encoding: 'utf-8' }); -const ruby_ui_path = outputRubyUI.trim() + '/**/*.rb'; - -const defaultTheme = require('tailwindcss/defaultTheme') - module.exports = { - darkMode: ["class"], content: [ - './app/views/**/*.{erb,haml,html,slim,rb}', - './app/components/ruby_ui/**/*.rb', + './app/views/**/*.rb', // Phlex views + './app/components/**/*.rb', // Phlex components + './app/views/**/*.html.erb', './app/helpers/**/*.rb', './app/assets/stylesheets/**/*.css', - './app/javascript/**/*.js', - ruby_ui_path + './app/javascript/**/*.js' ], + darkMode: ["class"], theme: { container: { center: true, @@ -76,15 +67,8 @@ module.exports = { sm: "calc(var(--radius) - 4px)", }, fontFamily: { - sans: ["var(--font-sans)", ...defaultTheme.fontFamily.sans], + sans: ["var(--font-sans)", 'ui-sans-serif', 'system-ui', 'sans-serif', '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"', '"Noto Color Emoji"'], }, }, }, - plugins: [ - <% if using_importmap? %> - require("../vendor/javascript/tailwindcss-animate"), - <% else %> - require("tailwindcss-animate"), - <% end %> - ], }