diff --git a/gem/lib/generators/ruby_ui/install/templates/tailwind.css.erb b/gem/lib/generators/ruby_ui/install/templates/tailwind.css.erb index dc7fa4035..15fd9f3ea 100644 --- a/gem/lib/generators/ruby_ui/install/templates/tailwind.css.erb +++ b/gem/lib/generators/ruby_ui/install/templates/tailwind.css.erb @@ -1,7 +1,7 @@ @import "tailwindcss"; <% if using_importmap? %> -@import "../../../vendor/javascript/tw-animate-css.js"; +@import "../../../vendor/javascript/tw-animate-css.css"; <% else %> @import "tw-animate-css"; <% end %> diff --git a/gem/lib/generators/ruby_ui/javascript_utils.rb b/gem/lib/generators/ruby_ui/javascript_utils.rb index d8f50995d..62a08b5d6 100644 --- a/gem/lib/generators/ruby_ui/javascript_utils.rb +++ b/gem/lib/generators/ruby_ui/javascript_utils.rb @@ -1,6 +1,8 @@ module RubyUI module Generators module JavascriptUtils + TW_ANIMATE_CSS_VERSION = "1.4.0" + def install_js_package(package) if using_importmap? pin_with_importmap(package) @@ -21,6 +23,8 @@ def pin_with_importmap(package) case package when "motion" pin_motion + when "tw-animate-css" + pin_tw_animate_css when "tippy.js" pin_tippy_js else @@ -29,23 +33,34 @@ def pin_with_importmap(package) end def using_importmap? - File.exist?(Rails.root.join("config/importmap.rb")) && File.exist?(Rails.root.join("bin/importmap")) + File.exist?(rails_root.join("config/importmap.rb")) && File.exist?(rails_root.join("bin/importmap")) end - def using_bun? = File.exist?(Rails.root.join("bun.lock")) + def using_bun? = File.exist?(rails_root.join("bun.lock")) + + def using_npm? = File.exist?(rails_root.join("package-lock.json")) - def using_npm? = File.exist?(Rails.root.join("package-lock.json")) + def using_pnpm? = File.exist?(rails_root.join("pnpm-lock.yaml")) - def using_pnpm? = File.exist?(Rails.root.join("pnpm-lock.yaml")) + def using_yarn? = File.exist?(rails_root.join("yarn.lock")) - def using_yarn? = File.exist?(Rails.root.join("yarn.lock")) + def pin_tw_animate_css + say <<~TEXT + WARNING: Installing tw-animate-css as a CSS asset because Importmap cannot pin CSS-only package exports. + TEXT + + empty_directory rails_root.join("vendor/javascript") + # CDN serves "tw-animate.css"; we save as "tw-animate-css.css" to match package name. Do not "correct" the URL. + get "https://cdn.jsdelivr.net/npm/tw-animate-css@#{TW_ANIMATE_CSS_VERSION}/dist/tw-animate.css", + rails_root.join("vendor/javascript/tw-animate-css.css") + end def pin_motion say <<~TEXT WARNING: Installing motion from CDN because `bin/importmap pin motion` doesn't download the correct file. TEXT - inject_into_file Rails.root.join("config/importmap.rb"), <<~RUBY + inject_into_file rails_root.join("config/importmap.rb"), <<~RUBY pin "motion", to: "https://cdn.jsdelivr.net/npm/motion@11.11.17/+esm"\n RUBY end @@ -55,11 +70,13 @@ def pin_tippy_js WARNING: Installing tippy.js from CDN because `bin/importmap pin tippy.js` doesn't download the correct file. TEXT - inject_into_file Rails.root.join("config/importmap.rb"), <<~RUBY + inject_into_file rails_root.join("config/importmap.rb"), <<~RUBY pin "tippy.js", to: "https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/+esm" pin "@popperjs/core", to: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/+esm"\n RUBY end + + def rails_root = Rails.root end end end diff --git a/gem/test/generators/javascript_utils_test.rb b/gem/test/generators/javascript_utils_test.rb new file mode 100644 index 000000000..2a981a62d --- /dev/null +++ b/gem/test/generators/javascript_utils_test.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "test_helper" +require "fileutils" +require "pathname" +require "tmpdir" +require_relative "../../lib/generators/ruby_ui/javascript_utils" + +class JavascriptUtilsTest < Minitest::Test + class FakeInstaller + include RubyUI::Generators::JavascriptUtils + + attr_reader :download_source, :download_destination + + def initialize(root) + @root = Pathname.new(root) + end + + def say(*) = nil + + def empty_directory(path) + FileUtils.mkdir_p(path) + end + + def get(source, destination) + @download_source = source + @download_destination = destination + FileUtils.touch(destination) + end + + def rails_root = @root + end + + def test_tw_animate_css_is_downloaded_as_css_asset_for_importmap + Dir.mktmpdir do |root| + installer = FakeInstaller.new(root) + + installer.pin_with_importmap("tw-animate-css") + + assert_equal "https://cdn.jsdelivr.net/npm/tw-animate-css@1.4.0/dist/tw-animate.css", installer.download_source + assert_equal Pathname.new(root).join("vendor/javascript/tw-animate-css.css"), installer.download_destination + assert File.exist?(installer.download_destination) + end + end +end