Rails - Importmaps
How to install RBUI within a Rails app that uses Importmaps.
Tailwind plugins not compatible with importmaps
Creating a Rails app
1
Generate a new Rails application
In case you don't have a Rails application set up yet, let's start by generating one. The demo uses importmaps (Rails default). Read more about Importmaps in Rails here.
rails new CHANGE_TO_NAME_OF_APP --css=tailwind
Once that is created, navigate to the app
cd CHANGE_TO_NAME_OF_APP
Install the gem
1
Install Phlex
Run the following in the terminal to install phlex for Rails
bundle add phlex-rails
After the gem is installed, run the generator to create necessary files.
bin/rails generate phlex:install
Refer to the Phlex installation guide for Rails for more information.
2
Install RBUI gem
Run the following in the terminal to install the RBUI Component Library
bundle add phlex_ui
3
Include RBUI module
Include RBUI module in your application_component.rb
file
class ApplicationComponent < Phlex::HTML include RBUI end
Install JS
1
Install package
Run the following in the terminal to install RBUI JS package
bin/importmap pin rbui-js
2
Import package
Import the package in your app/javascript/application.js
file
import 'rbui-js';
Install Styles
1
Install TailwindCSS
In this guide we have already installed TailwindCSS, however if you have not done this make sure to follow the TailwindCSS installation guide
2
Update Tailwind Configuration
Add the following to your tailwind.config.js
file
// For importing tailwind styles from rbui gem const execSync = require('child_process').execSync; // Import rbui gem path (To make sure Tailwind loads classes used by rbui gem) const outputRBUI = execSync('bundle show phlex_ui', { encoding: 'utf-8' }); const rbui_path = outputRBUI.trim() + '/**/*.rb'; const defaultTheme = require('tailwindcss/defaultTheme') module.exports = { darkMode: ["class"], content: [ './app/views/**/*.{erb,haml,html,slim,rb}', './app/helpers/**/*.rb', './app/assets/stylesheets/**/*.css', './app/javascript/**/*.js', rbui_path ], 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))", }, 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)", ...defaultTheme.fontFamily.sans], }, }, }, # Not compatible with importmaps plugins: [ require("tailwindcss-animate"), ], }
3
Add CSS variables
Add the following to your app/assets/stylesheets/application.tailwind.css
file
@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; --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%; --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; } }