Rails - JS Bundler
How to install PhlexUI within a Rails app that employs JS bundling.
Creating a Rails app
1
In case you don't have a Rails application set up yet, let's start by generating one. The demo uses esbuild, however feel free to change esbuild to use bun, webpack or rollup.js. Read more about JS bundlers in Rails here.
rails new CHANGE_TO_NAME_OF_APP --css=tailwind --javascript=esbuild
Once that is created, navigate to the app
cd CHANGE_TO_NAME_OF_APP
Install the gem
1
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
Run the following in the terminal to install the PhlexUI Component Library
bundle add phlex_ui
3
Include PhlexUI module in your application_component.rb
file
class ApplicationComponent < Phlex::HTML include PhlexUI end
4
Let's make the components come to life by adding some JavaScript.
Install JS
1
Run the following in the terminal to install PhlexUI JS package
yarn add phlex_ui
2
Import the package in your app/javascript/application.js
file
import 'phlex_ui';
Install Styles
1
Most will already have TailwindCSS installed, however if you do not, first follow the TailwindCSS installation guide
2
Run the following in the terminal to install the dependencies
yarn add tailwindcss-animate
3
Add the following to your tailwind.config.js
file
// For importing tailwind styles from phlex_ui/phlex_ui_pro gem const execSync = require('child_process').execSync; // Import phlex_ui gem path (To make sure Tailwind loads classes used by phlex_ui gem) const outputPhlexUI = execSync('bundle show phlex_ui', { encoding: 'utf-8' }); const phlex_ui_path = outputPhlexUI.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', phlex_ui_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))", }, warning: { DEFAULT: "hsl(var(--warning))", foreground: "hsl(var(--warning-foreground))", }, success: { DEFAULT: "hsl(var(--success))", foreground: "hsl(var(--success-foreground))", }, muted: { DEFAULT: "hsl(var(--muted))", foreground: "hsl(var(--muted-foreground))", }, accent: { DEFAULT: "hsl(var(--accent))", foreground: "hsl(var(--accent-foreground))", }, }, borderRadius: { lg: `var(--radius)`, md: `calc(var(--radius) - 2px)`, sm: "calc(var(--radius) - 4px)", }, fontFamily: { sans: defaultTheme.fontFamily.sans, }, }, }, plugins: [ require("tailwindcss-animate"), ], }
4
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: 0 0% 3.9%; --primary: 0 0% 9%; --primary-foreground: 0 0% 98%; --secondary: 0 0% 96.1%; --secondary-foreground: 0 0% 9%; --muted: 0 0% 96.1%; --muted-foreground: 0 0% 45.1%; --accent: 0 0% 96.1%; --accent-foreground: 0 0% 9%; --destructive: 350 89% 60%; --destructive-foreground: 0 0% 100%; --warning: 38 92% 50%; --warning-foreground: 0 0% 100%; --success: 87 100% 37%; --success-foreground: 0 0% 100%; --border: 0 0% 89.8%; --input: 0 0% 89.8%; --ring: 0 0% 3.9%; --radius: 0.5rem; } .dark { --background: 0 0% 3.9%; --foreground: 0 0% 98%; --primary: 0 0% 98%; --primary-foreground: 0 0% 9%; --secondary: 0 0% 14.9%; --secondary-foreground: 0 0% 98%; --muted: 0 0% 14.9%; --muted-foreground: 0 0% 63.9%; --accent: 0 0% 14.9%; --accent-foreground: 0 0% 98%; --destructive: 350 89% 60%; --destructive-foreground: 0 0% 100%; --warning: 38 92% 50%; --warning-foreground: 0 0% 100%; --success: 84 81% 44%; --success-foreground: 0 0% 100%; --border: 0 0% 14.9%; --input: 0 0% 14.9%; --ring: 0 0% 83.1%; } } @layer base { * { @apply border-border; } body { @apply bg-background text-foreground; font-feature-settings: "rlig" 1, "calt" 1; } }