Rails - JS Bundler
How to install RubyUI within a Rails app that employs JS bundling.
RubyUI
Using RubyUI CLI
We provide a Ruby gem with useful generators to help you to setup RubyUI components in your apps.
1
Add RubyUI gem to your Gemfile
bundle add ruby_ui --group development --require false
2
Run the install command
rails g ruby_ui:install
Manual
You can install the dependencies manually if you prefer
1
Add Phlex Rails to your app
bundle add phlex-rails --github phlex-ruby/phlex-rails --branch main
Phlex compatibility
2
Install Phlex Rails
bin/rails g phlex:install
3
Install tailwind_merge
RubyUI components use tailwind_merge to avoid conflicts between TailwindCSS classes
bundle add tailwind_merge
4
Create RubyUI initializer
Add this code to config/initializers/ruby_ui.rb
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/*"))
5
Include RubyUI kit in your base component
Include RubyUI
module in app/components/base.rb
module Components class Base < Phlex::HTML include Components include RubyUI ...
6
Create the RubyUI base component
Every RubyUI component inherit from RubyUI::Base
Copy and paste the code snippet below into the app/components/ruby_ui/base.rb
file.
require "tailwind_merge" module RubyUI class Base < Phlex::HTML TAILWIND_MERGER = ::TailwindMerge::Merger.new.freeze unless defined?(TAILWIND_MERGER) attr_reader :attrs def initialize(**user_attrs) @attrs = mix(default_attrs, user_attrs) @attrs[:class] = TAILWIND_MERGER.merge(@attrs[:class]) if @attrs[:class] end private def default_attrs {} end end end
7
Include RubyUI styles in your CSS
Include RubyUI styles in app/assets/stylesheets/application.tailwind.css
Your CSS file will look like this:
@tailwind base; @tailwind components; @tailwind utilities; @layer base { :root { --background: 0 0% 100%; --foreground: 240 10% 3.9%; --card: 0 0% 100%; --card-foreground: 240 10% 3.9%; --popover: 0 0% 100%; --popover-foreground: 240 10% 3.9%; --primary: 240 5.9% 10%; --primary-foreground: 0 0% 98%; --secondary: 240 4.8% 95.9%; --secondary-foreground: 240 5.9% 10%; --muted: 240 4.8% 95.9%; --muted-foreground: 240 3.8% 46.1%; --accent: 240 4.8% 95.9%; --accent-foreground: 240 5.9% 10%; --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 98%; --border: 240 5.9% 90%; --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%; --card: 240 10% 3.9%; --card-foreground: 0 0% 98%; --popover: 240 10% 3.9%; --popover-foreground: 0 0% 98%; --primary: 0 0% 98%; --primary-foreground: 240 5.9% 10%; --secondary: 240 3.7% 15.9%; --secondary-foreground: 0 0% 98%; --muted: 240 3.7% 15.9%; --muted-foreground: 240 5% 64.9%; --accent: 240 3.7% 15.9%; --accent-foreground: 0 0% 98%; --destructive: 0 62.8% 30.6%; --destructive-foreground: 0 0% 98%; --border: 240 3.7% 15.9%; --input: 240 3.7% 15.9%; --ring: 240 4.9% 83.9%; /* ruby_ui especific */ --warning: 38 92% 50%; --warning-foreground: 0 0% 100%; --success: 84 81% 44%; --success-foreground: 0 0% 100%; } } @layer base { * { @apply border-border; } body { @apply bg-background text-foreground; font-feature-settings: "rlig" 1, "calt" 1; /* docs specific */ /* https://css-tricks.com/snippets/css/system-font-stack/ */ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; } }
8
Install tailwindcss-animate plugin
Some RubyUI components utilize CSS animations to create smooth transitions.
yarn add tailwindcss-animate
9
Include RubyUI TailwindCSS theme
Include RubyUI theme config in tailwind.config.js
Your config file will look like this:
module.exports = { content: [ './app/views/**/*.rb', // Phlex views './app/components/**/*.rb', // Phlex components './app/views/**/*.html.erb', './app/helpers/**/*.rb', './app/assets/stylesheets/**/*.css', './app/javascript/**/*.js' ], darkMode: ["class"], theme: { container: { center: true, padding: "2rem", screens: { "2xl": "1400px", }, }, extend: { colors: { border: "hsl(var(--border))", input: "hsl(var(--input))", ring: "hsl(var(--ring))", background: "hsl(var(--background))", foreground: "hsl(var(--foreground))", primary: { DEFAULT: "hsl(var(--primary))", foreground: "hsl(var(--primary-foreground))", }, secondary: { DEFAULT: "hsl(var(--secondary))", foreground: "hsl(var(--secondary-foreground))", }, destructive: { DEFAULT: "hsl(var(--destructive))", foreground: "hsl(var(--destructive-foreground))", }, muted: { DEFAULT: "hsl(var(--muted))", foreground: "hsl(var(--muted-foreground))", }, accent: { DEFAULT: "hsl(var(--accent))", foreground: "hsl(var(--accent-foreground))", }, popover: { DEFAULT: "hsl(var(--popover))", foreground: "hsl(var(--popover-foreground))", }, card: { DEFAULT: "hsl(var(--card))", foreground: "hsl(var(--card-foreground))", }, /* ruby_ui especific */ warning: { DEFAULT: "hsl(var(--warning))", foreground: "hsl(var(--warning-foreground))", }, success: { DEFAULT: "hsl(var(--success))", foreground: "hsl(var(--success-foreground))", }, }, borderRadius: { lg: `var(--radius)`, md: `calc(var(--radius) - 2px)`, sm: "calc(var(--radius) - 4px)", }, fontFamily: { sans: ["var(--font-sans)", 'ui-sans-serif', 'system-ui', 'sans-serif', '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"', '"Noto Color Emoji"'], }, }, }, plugins: [ require("tailwindcss-animate"), ], }