
plutonium-assets
by radioactive-labs
Build production-ready Rails apps in minutes, not days. Convention-driven, fully customizable, AI-ready.
SKILL.md
name: plutonium-assets description: Plutonium asset setup - TailwindCSS configuration, Stimulus controllers, and Phlexi component themes
Plutonium Assets & Setup
Plutonium uses TailwindCSS 4 for styling with a customizable theme system for components.
Note: For CSS design tokens (
--pu-*variables) and component classes (.pu-btn,.pu-input, etc.), see theplutonium-themingskill.
Asset Configuration
Configure assets in the initializer:
# config/initializers/plutonium.rb
Plutonium.configure do |config|
config.load_defaults 1.0
# Custom assets
config.assets.stylesheet = "application" # Your CSS file
config.assets.script = "application" # Your JS file
config.assets.logo = "my_logo.png" # Logo image
config.assets.favicon = "my_favicon.ico" # Favicon
end
Setup Custom Assets
Run the assets generator to set up your own TailwindCSS build:
rails generate pu:core:assets
This:
- Installs required npm packages (
@radioactive-labs/plutonium, TailwindCSS plugins) - Creates
tailwind.config.jsthat extends Plutonium's config - Imports Plutonium CSS into your
application.tailwind.css - Registers Plutonium's Stimulus controllers
- Updates Plutonium config to use your assets
TailwindCSS Configuration
Generated Config
// tailwind.config.js
const { execSync } = require('child_process');
const plutoniumGemPath = execSync("bundle show plutonium").toString().trim();
const plutoniumTailwindConfig = require(`${plutoniumGemPath}/tailwind.options.js`)
module.exports = {
darkMode: plutoniumTailwindConfig.darkMode,
plugins: [
// Add your plugins here
].concat(plutoniumTailwindConfig.plugins),
theme: plutoniumTailwindConfig.merge(
plutoniumTailwindConfig.theme,
{
// Your custom theme overrides
},
),
content: [
`${__dirname}/app/**/*.{erb,haml,html,slim,rb}`,
`${__dirname}/app/javascript/**/*.js`,
`${__dirname}/packages/**/app/**/*.{erb,haml,html,slim,rb}`,
].concat(plutoniumTailwindConfig.content),
}
Customizing Colors
Override Plutonium's color palette:
// tailwind.config.js
theme: plutoniumTailwindConfig.merge(
plutoniumTailwindConfig.theme,
{
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6', // Your brand color
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554',
},
secondary: {
// Your secondary palette
},
},
},
},
),
Default Color Palette
Plutonium includes these semantic colors:
| Color | Usage |
|---|---|
primary | Primary brand color (turquoise by default) |
secondary | Secondary color (navy by default) |
success | Success states (green) |
info | Informational states (blue) |
warning | Warning states (amber) |
danger | Error/danger states (red) |
accent | Accent highlights (coral pink) |
Dark Mode
Plutonium uses selector strategy for dark mode:
darkMode: "selector"
Toggle dark mode by adding/removing the dark class on <html>:
// Toggle dark mode
document.documentElement.classList.toggle('dark');
Plutonium includes a color mode selector component that handles this automatically.
CSS Imports
Application Stylesheet
/* app/assets/stylesheets/application.tailwind.css */
@import "gem:plutonium/src/css/plutonium.css";
@import "tailwindcss";
@config '../../../tailwind.config.js';
/* Your custom styles */
What Plutonium CSS Includes
- Core utility classes
- EasyMDE (markdown editor) styles
- Slim Select styles
- International telephone input styles
- Flatpickr (date picker) styles
Component Themes (Phlexi)
Plutonium components use a theme system based on Phlexi for customizing Form, Display, and Table components. Each component type has a theme class with named style tokens.
Note: This is different from the CSS design token system (
.pu-*classes). For pre-built component classes, seeplutonium-theming.
Form Theme
class PostDefinition < ResourceDefinition
class Form < Form
class Theme < Plutonium::UI::Form::Theme
def self.theme
super.merge({
# Container
base: "bg-white dark:bg-gray-800 shadow-md rounded-lg p-6",
fields_wrapper: "grid grid-cols-2 gap-6",
actions_wrapper: "flex justify-end mt-6 space-x-2",
# Labels
label: "block mb-2 text-base font-bold",
invalid_label: "text-red-700 dark:text-red-500",
valid_label: "text-green-700 dark:text-green-500",
neutral_label: "text-gray-500 dark:text-gray-400",
# Inputs
input: "w-full p-2 border rounded-md shadow-sm",
invalid_input: "bg-red-50 border-red-500 text-red-900",
valid_input: "bg-green-50 border-green-500 text-green-900",
neutral_input: "border-gray-300 dark:border-gray-600",
# Hints & Errors
hint: "mt-2 text-sm text-gray-500",
error: "mt-2 text-sm text-red-600",
# Buttons
button: "px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700",
})
end
end
end
end
Display Theme
class PostDefinition < ResourceDefinition
class Display < Display
class Theme < Plutonium::UI::Display::Theme
def self.theme
super.merge({
fields_wrapper: "grid grid-cols-3 gap-8",
label: "text-sm font-bold text-gray-500 mb-1",
string: "text-lg text-gray-900 dark:text-white",
link: "text-primary-600 hover:underline",
markdown: "prose dark:prose-invert max-w-none",
})
end
end
end
end
Table Theme
class PostDefinition < ResourceDefinition
class Table < Table
class Theme < Plutonium::UI::Table::Theme
def self.theme
super.merge({
wrapper: "overflow-x-auto shadow-md rounded-lg",
base: "w-full text-sm text-gray-500",
header: "text-xs uppercase bg-gray-100 dark:bg-gray-700",
header_cell: "px-6 py-3",
body_row: "bg-white border-b dark:bg-gray-800",
body_cell: "px-6 py-4",
})
end
end
end
end
Theme Keys Reference
Form Theme Keys
| Key | Description |
|---|---|
base | Form container |
fields_wrapper | Grid wrapper for fields |
actions_wrapper | Submit button container |
wrapper | Individual field wrapper |
inner_wrapper | Inner field wrapper |
label | Label base styles |
invalid_label | Label when field invalid |
valid_label | Label when field valid |
neutral_label | Label default state |
input | Input base styles |
invalid_input | Input when invalid |
valid_input | Input when valid |
neutral_input | Input default state |
hint | Hint text |
error | Error message |
button | Submit button |
checkbox | Checkbox input |
select | Select dropdown |
Display Theme Keys
| Key | Description |
|---|---|
fields_wrapper | Grid wrapper |
label | Field label |
description | Field description |
string | String values |
text | Text values |
link | URL links |
email | Email links |
phone | Phone links |
markdown | Markdown content |
json | JSON display |
Table Theme Keys
| Key | Description |
|---|---|
wrapper | Table container |
base | Table element |
header | Header row |
header_cell | Header cell |
body_row | Body row |
body_cell | Body cell |
sort_icon | Sort indicator |
Using Tokens in Components
The tokens Helper
Conditionally apply classes:
class MyComponent < Plutonium::UI::Component::Base
def initialize(active:)
@active = active
end
def view_template
div(class: tokens(
"base-class",
active?: "bg-primary-500 text-white",
inactive?: "bg-gray-200 text-gray-700"
)) {
"Content"
}
end
private
def active? = @active
def inactive? = !@active
end
The classes Helper
Returns a hash suitable for splatting:
div(**classes("p-4", "rounded", active?: "ring-2")) { }
# => <div class="p-4 rounded ring-2">
Conditional Tokens with Hash
tokens(
"base",
condition?: { then: "if-true", else: "if-false" }
)
Stimulus Controllers
Plutonium includes Stimulus controllers. Register them in your application:
// app/javascript/controllers/index.js
import { application } from "./application"
import { registerControllers } from "@radioactive-labs/plutonium"
registerControllers(application)
// Your custom controllers...
Available Controllers
color-mode- Dark/light mode toggleform- Form handling (pre-submit, etc.)nested-resource-form-fields- Nested form managementslim-select- Enhanced select boxesflatpickr- Date/time pickerseasymde- Markdown editor- Various UI controllers
Custom Stimulus Controllers
Add your own controllers alongside Plutonium's:
// app/javascript/controllers/custom_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
console.log("Custom controller connected")
}
}
Register in your index:
import CustomController from "./custom_controller"
application.register("custom", CustomController)
Typography
Plutonium uses Lato font by default. The layout loads it from Google Fonts.
Override in your layout:
class MyLayout < Plutonium::UI::Layout::ResourceLayout
def render_fonts
# Your custom fonts
link(rel: "preconnect", href: "https://fonts.googleapis.com")
link(href: "https://fonts.googleapis.com/css2?family=Inter&display=swap", rel: "stylesheet")
end
end
Update Tailwind config:
theme: {
fontFamily: {
'body': ['Inter', 'sans-serif'],
'sans': ['Inter', 'sans-serif'],
}
}
Related Skills
plutonium-theming- CSS design tokens and component classes (.pu-*)plutonium-views- Layout customizationplutonium-forms- Form themingplutonium-installation- Initial setup
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon
