plutonium 0.50.0 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/skills/plutonium/SKILL.md +85 -102
- data/.claude/skills/plutonium-app/SKILL.md +572 -0
- data/.claude/skills/plutonium-auth/SKILL.md +163 -300
- data/.claude/skills/plutonium-behavior/SKILL.md +838 -0
- data/.claude/skills/plutonium-resource/SKILL.md +1176 -0
- data/.claude/skills/plutonium-tenancy/SKILL.md +655 -0
- data/.claude/skills/plutonium-testing/SKILL.md +6 -5
- data/.claude/skills/plutonium-ui/SKILL.md +900 -0
- data/CHANGELOG.md +27 -2
- data/Rakefile +2 -1
- data/app/assets/plutonium.css +1 -11
- data/app/assets/plutonium.js +1009 -1214
- data/app/assets/plutonium.js.map +3 -3
- data/app/assets/plutonium.min.js +52 -51
- data/app/assets/plutonium.min.js.map +3 -3
- data/docs/.vitepress/config.ts +37 -27
- data/docs/getting-started/index.md +22 -29
- data/docs/getting-started/installation.md +37 -80
- data/docs/getting-started/tutorial/index.md +4 -5
- data/docs/guides/adding-resources.md +66 -377
- data/docs/guides/authentication.md +94 -463
- data/docs/guides/authorization.md +124 -370
- data/docs/guides/creating-packages.md +94 -296
- data/docs/guides/custom-actions.md +121 -441
- data/docs/guides/index.md +22 -42
- data/docs/guides/multi-tenancy.md +116 -187
- data/docs/guides/nested-resources.md +103 -431
- data/docs/guides/search-filtering.md +123 -240
- data/docs/guides/testing.md +5 -4
- data/docs/guides/theming.md +157 -407
- data/docs/guides/troubleshooting.md +5 -3
- data/docs/guides/user-invites.md +106 -425
- data/docs/guides/user-profile.md +76 -243
- data/docs/index.md +1 -1
- data/docs/reference/app/generators.md +517 -0
- data/docs/reference/app/index.md +158 -0
- data/docs/reference/app/packages.md +146 -0
- data/docs/reference/app/portals.md +377 -0
- data/docs/reference/auth/accounts.md +230 -0
- data/docs/reference/auth/index.md +88 -0
- data/docs/reference/auth/profile.md +185 -0
- data/docs/reference/behavior/controllers.md +395 -0
- data/docs/reference/behavior/index.md +22 -0
- data/docs/reference/behavior/interactions.md +341 -0
- data/docs/reference/behavior/policies.md +417 -0
- data/docs/reference/index.md +56 -49
- data/docs/reference/resource/actions.md +423 -0
- data/docs/reference/resource/definition.md +508 -0
- data/docs/reference/resource/index.md +50 -0
- data/docs/reference/resource/model.md +348 -0
- data/docs/reference/resource/query.md +305 -0
- data/docs/reference/tenancy/entity-scoping.md +361 -0
- data/docs/reference/tenancy/index.md +36 -0
- data/docs/reference/tenancy/invites.md +393 -0
- data/docs/reference/tenancy/nested-resources.md +267 -0
- data/docs/reference/testing/index.md +287 -0
- data/docs/reference/ui/assets.md +400 -0
- data/docs/reference/ui/components.md +165 -0
- data/docs/reference/ui/displays.md +104 -0
- data/docs/reference/ui/forms.md +284 -0
- data/docs/reference/ui/index.md +30 -0
- data/docs/reference/ui/layouts.md +106 -0
- data/docs/reference/ui/pages.md +189 -0
- data/docs/reference/ui/tables.md +117 -0
- data/docs/superpowers/specs/2026-05-09-typeahead-endpoint-design.md +203 -0
- data/docs/superpowers/specs/2026-05-12-skill-compaction-design.md +99 -0
- data/docs/superpowers/specs/2026-05-13-docs-restructure-design.md +186 -0
- data/gemfiles/rails_7.gemfile.lock +1 -1
- data/gemfiles/rails_8.0.gemfile.lock +1 -1
- data/gemfiles/rails_8.1.gemfile.lock +1 -1
- data/lib/generators/pu/core/update/update_generator.rb +0 -20
- data/lib/generators/pu/invites/install_generator.rb +1 -0
- data/lib/plutonium/definition/base.rb +1 -1
- data/lib/plutonium/definition/{views.rb → index_views.rb} +21 -20
- data/lib/plutonium/helpers/turbo_helper.rb +11 -0
- data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +14 -0
- data/lib/plutonium/resource/controller.rb +1 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +19 -1
- data/lib/plutonium/resource/controllers/typeahead.rb +180 -0
- data/lib/plutonium/resource/policy.rb +7 -0
- data/lib/plutonium/routing/mapper_extensions.rb +15 -0
- data/lib/plutonium/ui/component/methods.rb +4 -0
- data/lib/plutonium/ui/form/base.rb +6 -2
- data/lib/plutonium/ui/form/components/json.rb +58 -0
- data/lib/plutonium/ui/form/components/resource_select.rb +62 -8
- data/lib/plutonium/ui/form/components/secure_association.rb +98 -22
- data/lib/plutonium/ui/form/concerns/typeahead_attributes.rb +83 -0
- data/lib/plutonium/ui/form/resource.rb +0 -4
- data/lib/plutonium/ui/grid/resource.rb +1 -1
- data/lib/plutonium/ui/layout/base.rb +1 -0
- data/lib/plutonium/ui/page/base.rb +0 -7
- data/lib/plutonium/ui/page/index.rb +4 -4
- data/lib/plutonium/ui/table/resource.rb +1 -1
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +8 -0
- data/lib/tasks/release.rake +15 -1
- data/package.json +10 -10
- data/src/css/slim_select.css +4 -0
- data/src/js/controllers/slim_select_controller.js +61 -0
- data/src/js/turbo/turbo_actions.js +33 -0
- data/yarn.lock +553 -543
- metadata +44 -33
- data/.claude/skills/plutonium-assets/SKILL.md +0 -512
- data/.claude/skills/plutonium-controller/SKILL.md +0 -396
- data/.claude/skills/plutonium-create-resource/SKILL.md +0 -303
- data/.claude/skills/plutonium-definition/SKILL.md +0 -1223
- data/.claude/skills/plutonium-entity-scoping/SKILL.md +0 -317
- data/.claude/skills/plutonium-forms/SKILL.md +0 -465
- data/.claude/skills/plutonium-installation/SKILL.md +0 -331
- data/.claude/skills/plutonium-interaction/SKILL.md +0 -413
- data/.claude/skills/plutonium-invites/SKILL.md +0 -408
- data/.claude/skills/plutonium-model/SKILL.md +0 -440
- data/.claude/skills/plutonium-nested-resources/SKILL.md +0 -360
- data/.claude/skills/plutonium-package/SKILL.md +0 -198
- data/.claude/skills/plutonium-policy/SKILL.md +0 -456
- data/.claude/skills/plutonium-portal/SKILL.md +0 -410
- data/.claude/skills/plutonium-views/SKILL.md +0 -651
- data/docs/reference/assets/index.md +0 -496
- data/docs/reference/controller/index.md +0 -412
- data/docs/reference/definition/actions.md +0 -462
- data/docs/reference/definition/fields.md +0 -383
- data/docs/reference/definition/index.md +0 -326
- data/docs/reference/definition/query.md +0 -351
- data/docs/reference/generators/index.md +0 -648
- data/docs/reference/interaction/index.md +0 -449
- data/docs/reference/model/features.md +0 -248
- data/docs/reference/model/index.md +0 -218
- data/docs/reference/policy/index.md +0 -456
- data/docs/reference/portal/index.md +0 -379
- data/docs/reference/views/forms.md +0 -411
- data/docs/reference/views/index.md +0 -544
|
@@ -1,496 +0,0 @@
|
|
|
1
|
-
# Assets Reference
|
|
2
|
-
|
|
3
|
-
Complete reference for styling, theming, and frontend assets.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
Plutonium uses:
|
|
8
|
-
- **TailwindCSS** for styling
|
|
9
|
-
- **Stimulus** for JavaScript interactions
|
|
10
|
-
- **Turbo** for navigation and forms
|
|
11
|
-
|
|
12
|
-
## Setup Custom Assets
|
|
13
|
-
|
|
14
|
-
Run the assets generator to set up your own TailwindCSS build:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
rails generate pu:core:assets
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
This:
|
|
21
|
-
1. Installs required npm packages (`@radioactive-labs/plutonium`, TailwindCSS plugins)
|
|
22
|
-
2. Creates `tailwind.config.js` that extends Plutonium's config
|
|
23
|
-
3. Imports Plutonium CSS into your `application.tailwind.css`
|
|
24
|
-
4. Registers Plutonium's Stimulus controllers
|
|
25
|
-
5. Updates Plutonium config to use your assets
|
|
26
|
-
|
|
27
|
-
## Asset Configuration
|
|
28
|
-
|
|
29
|
-
Configure assets in the initializer:
|
|
30
|
-
|
|
31
|
-
```ruby
|
|
32
|
-
# config/initializers/plutonium.rb
|
|
33
|
-
Plutonium.configure do |config|
|
|
34
|
-
config.load_defaults 1.0
|
|
35
|
-
|
|
36
|
-
# Custom assets
|
|
37
|
-
config.assets.stylesheet = "application" # Your CSS file
|
|
38
|
-
config.assets.script = "application" # Your JS file
|
|
39
|
-
config.assets.logo = "my_logo.png" # Logo image
|
|
40
|
-
config.assets.favicon = "my_favicon.ico" # Favicon
|
|
41
|
-
end
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## TailwindCSS Configuration
|
|
45
|
-
|
|
46
|
-
### Generated Config
|
|
47
|
-
|
|
48
|
-
```javascript
|
|
49
|
-
// tailwind.config.js
|
|
50
|
-
const { execSync } = require('child_process');
|
|
51
|
-
const plutoniumGemPath = execSync("bundle show plutonium").toString().trim();
|
|
52
|
-
const plutoniumTailwindConfig = require(`${plutoniumGemPath}/tailwind.options.js`)
|
|
53
|
-
|
|
54
|
-
module.exports = {
|
|
55
|
-
darkMode: plutoniumTailwindConfig.darkMode,
|
|
56
|
-
plugins: [
|
|
57
|
-
// Add your plugins here
|
|
58
|
-
].concat(plutoniumTailwindConfig.plugins),
|
|
59
|
-
theme: plutoniumTailwindConfig.merge(
|
|
60
|
-
plutoniumTailwindConfig.theme,
|
|
61
|
-
{
|
|
62
|
-
// Your custom theme overrides
|
|
63
|
-
},
|
|
64
|
-
),
|
|
65
|
-
content: [
|
|
66
|
-
`${__dirname}/app/**/*.{erb,haml,html,slim,rb}`,
|
|
67
|
-
`${__dirname}/app/javascript/**/*.js`,
|
|
68
|
-
`${__dirname}/packages/**/app/**/*.{erb,haml,html,slim,rb}`,
|
|
69
|
-
].concat(plutoniumTailwindConfig.content),
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### CSS Imports
|
|
74
|
-
|
|
75
|
-
```css
|
|
76
|
-
/* app/assets/stylesheets/application.tailwind.css */
|
|
77
|
-
@import "gem:plutonium/src/css/plutonium.css";
|
|
78
|
-
|
|
79
|
-
@import "tailwindcss";
|
|
80
|
-
@config '../../../tailwind.config.js';
|
|
81
|
-
|
|
82
|
-
/* Your custom styles */
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### What Plutonium CSS Includes
|
|
86
|
-
|
|
87
|
-
- Core utility classes
|
|
88
|
-
- EasyMDE (markdown editor) styles
|
|
89
|
-
- Slim Select styles
|
|
90
|
-
- International telephone input styles
|
|
91
|
-
- Flatpickr (date picker) styles
|
|
92
|
-
|
|
93
|
-
## Color System
|
|
94
|
-
|
|
95
|
-
### Customizing Colors
|
|
96
|
-
|
|
97
|
-
Override Plutonium's color palette in your Tailwind config:
|
|
98
|
-
|
|
99
|
-
```javascript
|
|
100
|
-
// tailwind.config.js
|
|
101
|
-
theme: plutoniumTailwindConfig.merge(
|
|
102
|
-
plutoniumTailwindConfig.theme,
|
|
103
|
-
{
|
|
104
|
-
extend: {
|
|
105
|
-
colors: {
|
|
106
|
-
primary: {
|
|
107
|
-
50: '#eff6ff',
|
|
108
|
-
100: '#dbeafe',
|
|
109
|
-
200: '#bfdbfe',
|
|
110
|
-
300: '#93c5fd',
|
|
111
|
-
400: '#60a5fa',
|
|
112
|
-
500: '#3b82f6', // Your brand color
|
|
113
|
-
600: '#2563eb',
|
|
114
|
-
700: '#1d4ed8',
|
|
115
|
-
800: '#1e40af',
|
|
116
|
-
900: '#1e3a8a',
|
|
117
|
-
950: '#172554',
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
),
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Default Color Palette
|
|
126
|
-
|
|
127
|
-
Plutonium includes these semantic colors:
|
|
128
|
-
|
|
129
|
-
| Color | Usage |
|
|
130
|
-
|-------|-------|
|
|
131
|
-
| `primary` | Primary brand color (turquoise by default) |
|
|
132
|
-
| `secondary` | Secondary color (navy by default) |
|
|
133
|
-
| `success` | Success states (green) |
|
|
134
|
-
| `info` | Informational states (blue) |
|
|
135
|
-
| `warning` | Warning states (amber) |
|
|
136
|
-
| `danger` | Error/danger states (red) |
|
|
137
|
-
| `accent` | Accent highlights (coral pink) |
|
|
138
|
-
|
|
139
|
-
## Dark Mode
|
|
140
|
-
|
|
141
|
-
Plutonium uses `selector` strategy for dark mode:
|
|
142
|
-
|
|
143
|
-
```javascript
|
|
144
|
-
darkMode: "selector"
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Toggle dark mode by adding/removing the `dark` class on `<html>`:
|
|
148
|
-
|
|
149
|
-
```javascript
|
|
150
|
-
document.documentElement.classList.toggle('dark');
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Plutonium includes a `color-mode` Stimulus controller that handles this automatically.
|
|
154
|
-
|
|
155
|
-
## Component Themes
|
|
156
|
-
|
|
157
|
-
Plutonium components use a theme system based on Phlexi. Each component type has a theme class with named style tokens.
|
|
158
|
-
|
|
159
|
-
### Form Theme
|
|
160
|
-
|
|
161
|
-
```ruby
|
|
162
|
-
class PostDefinition < ResourceDefinition
|
|
163
|
-
class Form < Form
|
|
164
|
-
class Theme < Plutonium::UI::Form::Theme
|
|
165
|
-
def self.theme
|
|
166
|
-
super.merge({
|
|
167
|
-
# Container
|
|
168
|
-
base: "bg-white dark:bg-gray-800 shadow-md rounded-lg p-6",
|
|
169
|
-
fields_wrapper: "grid grid-cols-2 gap-6",
|
|
170
|
-
actions_wrapper: "flex justify-end mt-6 space-x-2",
|
|
171
|
-
|
|
172
|
-
# Labels
|
|
173
|
-
label: "block mb-2 text-base font-bold",
|
|
174
|
-
invalid_label: "text-red-700 dark:text-red-500",
|
|
175
|
-
valid_label: "text-green-700 dark:text-green-500",
|
|
176
|
-
neutral_label: "text-gray-500 dark:text-gray-400",
|
|
177
|
-
|
|
178
|
-
# Inputs
|
|
179
|
-
input: "w-full p-2 border rounded-md shadow-sm",
|
|
180
|
-
invalid_input: "bg-red-50 border-red-500 text-red-900",
|
|
181
|
-
valid_input: "bg-green-50 border-green-500 text-green-900",
|
|
182
|
-
neutral_input: "border-gray-300 dark:border-gray-600",
|
|
183
|
-
|
|
184
|
-
# Hints & Errors
|
|
185
|
-
hint: "mt-2 text-sm text-gray-500",
|
|
186
|
-
error: "mt-2 text-sm text-red-600",
|
|
187
|
-
|
|
188
|
-
# Buttons
|
|
189
|
-
button: "px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700",
|
|
190
|
-
})
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### Display Theme
|
|
198
|
-
|
|
199
|
-
```ruby
|
|
200
|
-
class PostDefinition < ResourceDefinition
|
|
201
|
-
class Display < Display
|
|
202
|
-
class Theme < Plutonium::UI::Display::Theme
|
|
203
|
-
def self.theme
|
|
204
|
-
super.merge({
|
|
205
|
-
fields_wrapper: "grid grid-cols-3 gap-8",
|
|
206
|
-
label: "text-sm font-bold text-gray-500 mb-1",
|
|
207
|
-
string: "text-lg text-gray-900 dark:text-white",
|
|
208
|
-
link: "text-primary-600 hover:underline",
|
|
209
|
-
markdown: "prose dark:prose-invert max-w-none",
|
|
210
|
-
})
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Table Theme
|
|
218
|
-
|
|
219
|
-
```ruby
|
|
220
|
-
class PostDefinition < ResourceDefinition
|
|
221
|
-
class Table < Table
|
|
222
|
-
class Theme < Plutonium::UI::Table::Theme
|
|
223
|
-
def self.theme
|
|
224
|
-
super.merge({
|
|
225
|
-
wrapper: "overflow-x-auto shadow-md rounded-lg",
|
|
226
|
-
base: "w-full text-sm text-gray-500",
|
|
227
|
-
header: "text-xs uppercase bg-gray-100 dark:bg-gray-700",
|
|
228
|
-
header_cell: "px-6 py-3",
|
|
229
|
-
body_row: "bg-white border-b dark:bg-gray-800",
|
|
230
|
-
body_cell: "px-6 py-4",
|
|
231
|
-
})
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Theme Keys Reference
|
|
239
|
-
|
|
240
|
-
#### Form Theme Keys
|
|
241
|
-
|
|
242
|
-
| Key | Description |
|
|
243
|
-
|-----|-------------|
|
|
244
|
-
| `base` | Form container |
|
|
245
|
-
| `fields_wrapper` | Grid wrapper for fields |
|
|
246
|
-
| `actions_wrapper` | Submit button container |
|
|
247
|
-
| `wrapper` | Individual field wrapper |
|
|
248
|
-
| `inner_wrapper` | Inner field wrapper |
|
|
249
|
-
| `label` | Label base styles |
|
|
250
|
-
| `invalid_label` | Label when field invalid |
|
|
251
|
-
| `valid_label` | Label when field valid |
|
|
252
|
-
| `neutral_label` | Label default state |
|
|
253
|
-
| `input` | Input base styles |
|
|
254
|
-
| `invalid_input` | Input when invalid |
|
|
255
|
-
| `valid_input` | Input when valid |
|
|
256
|
-
| `neutral_input` | Input default state |
|
|
257
|
-
| `hint` | Hint text |
|
|
258
|
-
| `error` | Error message |
|
|
259
|
-
| `button` | Submit button |
|
|
260
|
-
| `checkbox` | Checkbox input |
|
|
261
|
-
| `select` | Select dropdown |
|
|
262
|
-
|
|
263
|
-
#### Display Theme Keys
|
|
264
|
-
|
|
265
|
-
| Key | Description |
|
|
266
|
-
|-----|-------------|
|
|
267
|
-
| `fields_wrapper` | Grid wrapper |
|
|
268
|
-
| `label` | Field label |
|
|
269
|
-
| `description` | Field description |
|
|
270
|
-
| `string` | String values |
|
|
271
|
-
| `text` | Text values |
|
|
272
|
-
| `link` | URL links |
|
|
273
|
-
| `email` | Email links |
|
|
274
|
-
| `phone` | Phone links |
|
|
275
|
-
| `markdown` | Markdown content |
|
|
276
|
-
| `json` | JSON display |
|
|
277
|
-
|
|
278
|
-
#### Table Theme Keys
|
|
279
|
-
|
|
280
|
-
| Key | Description |
|
|
281
|
-
|-----|-------------|
|
|
282
|
-
| `wrapper` | Table container |
|
|
283
|
-
| `base` | Table element |
|
|
284
|
-
| `header` | Header row |
|
|
285
|
-
| `header_cell` | Header cell |
|
|
286
|
-
| `body_row` | Body row |
|
|
287
|
-
| `body_cell` | Body cell |
|
|
288
|
-
| `sort_icon` | Sort indicator |
|
|
289
|
-
|
|
290
|
-
## Using Tokens in Components
|
|
291
|
-
|
|
292
|
-
### The `tokens` Helper
|
|
293
|
-
|
|
294
|
-
Conditionally apply classes:
|
|
295
|
-
|
|
296
|
-
```ruby
|
|
297
|
-
class MyComponent < Plutonium::UI::Component::Base
|
|
298
|
-
def initialize(active:)
|
|
299
|
-
@active = active
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def view_template
|
|
303
|
-
div(class: tokens(
|
|
304
|
-
"base-class",
|
|
305
|
-
active?: "bg-primary-500 text-white",
|
|
306
|
-
inactive?: "bg-gray-200 text-gray-700"
|
|
307
|
-
)) {
|
|
308
|
-
"Content"
|
|
309
|
-
}
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
private
|
|
313
|
-
|
|
314
|
-
def active? = @active
|
|
315
|
-
def inactive? = !@active
|
|
316
|
-
end
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### The `classes` Helper
|
|
320
|
-
|
|
321
|
-
Returns a hash suitable for splatting:
|
|
322
|
-
|
|
323
|
-
```ruby
|
|
324
|
-
div(**classes("p-4", "rounded", active?: "ring-2")) { }
|
|
325
|
-
# => <div class="p-4 rounded ring-2">
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
### Conditional Tokens with Then/Else
|
|
329
|
-
|
|
330
|
-
For if/else class logic, pass a hash with `:then` and `:else` keys:
|
|
331
|
-
|
|
332
|
-
```ruby
|
|
333
|
-
class MyComponent < Plutonium::UI::Component::Base
|
|
334
|
-
def initialize(status:)
|
|
335
|
-
@status = status
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
def view_template
|
|
339
|
-
div(class: tokens(
|
|
340
|
-
"badge",
|
|
341
|
-
published?: { then: "bg-green-500", else: "bg-gray-500" }
|
|
342
|
-
)) { @status }
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
private
|
|
346
|
-
|
|
347
|
-
def published? = @status == "published"
|
|
348
|
-
end
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## Stimulus Controllers
|
|
352
|
-
|
|
353
|
-
Plutonium includes Stimulus controllers. Register them in your application:
|
|
354
|
-
|
|
355
|
-
```javascript
|
|
356
|
-
// app/javascript/controllers/index.js
|
|
357
|
-
import { application } from "./application"
|
|
358
|
-
|
|
359
|
-
import { registerControllers } from "@radioactive-labs/plutonium"
|
|
360
|
-
registerControllers(application)
|
|
361
|
-
|
|
362
|
-
// Your custom controllers...
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### Built-in Controllers
|
|
366
|
-
|
|
367
|
-
See the [register_controllers.js source](https://github.com/radioactive-labs/plutonium-core/blob/master/src/js/controllers/register_controllers.js) for the current list of controllers.
|
|
368
|
-
|
|
369
|
-
Key controllers include:
|
|
370
|
-
|
|
371
|
-
| Controller | Purpose |
|
|
372
|
-
|------------|---------|
|
|
373
|
-
| `form` | Form handling (pre-submit, etc.) |
|
|
374
|
-
| `nested-resource-form-fields` | Nested form management |
|
|
375
|
-
| `slim-select` | Enhanced select boxes |
|
|
376
|
-
| `flatpickr` | Date/time pickers |
|
|
377
|
-
| `easymde` | Markdown editor |
|
|
378
|
-
| `color-mode` | Dark/light mode toggle |
|
|
379
|
-
| `sidebar` | Sidebar navigation |
|
|
380
|
-
| `remote-modal` | Remote modal dialogs |
|
|
381
|
-
| `intl-tel-input` | International phone input |
|
|
382
|
-
| `attachment-input` | File attachment handling |
|
|
383
|
-
|
|
384
|
-
### Custom Controllers
|
|
385
|
-
|
|
386
|
-
Add your own controllers alongside Plutonium's:
|
|
387
|
-
|
|
388
|
-
```javascript
|
|
389
|
-
// app/javascript/controllers/custom_controller.js
|
|
390
|
-
import { Controller } from "@hotwired/stimulus"
|
|
391
|
-
|
|
392
|
-
export default class extends Controller {
|
|
393
|
-
connect() {
|
|
394
|
-
console.log("Custom controller connected")
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
Register in your index:
|
|
400
|
-
|
|
401
|
-
```javascript
|
|
402
|
-
import CustomController from "./custom_controller"
|
|
403
|
-
application.register("custom", CustomController)
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
## Icons
|
|
407
|
-
|
|
408
|
-
Plutonium uses Tabler Icons via Phlex:
|
|
409
|
-
|
|
410
|
-
```ruby
|
|
411
|
-
# In views
|
|
412
|
-
render Phlex::TablerIcons::Home.new(class: "w-5 h-5")
|
|
413
|
-
render Phlex::TablerIcons::User.new(class: "w-5 h-5 text-gray-500")
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
### Icon Sizes
|
|
417
|
-
|
|
418
|
-
```ruby
|
|
419
|
-
Phlex::TablerIcons::Home.new(class: "w-4 h-4") # Small
|
|
420
|
-
Phlex::TablerIcons::Home.new(class: "w-5 h-5") # Default
|
|
421
|
-
Phlex::TablerIcons::Home.new(class: "w-6 h-6") # Large
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
## Typography
|
|
425
|
-
|
|
426
|
-
Plutonium uses Lato font by default. The layout loads it from Google Fonts.
|
|
427
|
-
|
|
428
|
-
Override in your layout:
|
|
429
|
-
|
|
430
|
-
```ruby
|
|
431
|
-
class MyLayout < Plutonium::UI::Layout::ResourceLayout
|
|
432
|
-
def render_fonts
|
|
433
|
-
# Your custom fonts
|
|
434
|
-
link(rel: "preconnect", href: "https://fonts.googleapis.com")
|
|
435
|
-
link(href: "https://fonts.googleapis.com/css2?family=Inter&display=swap", rel: "stylesheet")
|
|
436
|
-
end
|
|
437
|
-
end
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
Update Tailwind config:
|
|
441
|
-
|
|
442
|
-
```javascript
|
|
443
|
-
theme: {
|
|
444
|
-
fontFamily: {
|
|
445
|
-
'body': ['Inter', 'sans-serif'],
|
|
446
|
-
'sans': ['Inter', 'sans-serif'],
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
## Custom Styles
|
|
452
|
-
|
|
453
|
-
### Adding Custom Utilities
|
|
454
|
-
|
|
455
|
-
```css
|
|
456
|
-
@layer utilities {
|
|
457
|
-
.text-gradient {
|
|
458
|
-
background: linear-gradient(to right, var(--tw-gradient-from), var(--tw-gradient-to));
|
|
459
|
-
-webkit-background-clip: text;
|
|
460
|
-
-webkit-text-fill-color: transparent;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
.animate-fade-in {
|
|
464
|
-
animation: fadeIn 0.3s ease-in-out;
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
@keyframes fadeIn {
|
|
469
|
-
from { opacity: 0; }
|
|
470
|
-
to { opacity: 1; }
|
|
471
|
-
}
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### Component Classes
|
|
475
|
-
|
|
476
|
-
```css
|
|
477
|
-
@layer components {
|
|
478
|
-
.btn {
|
|
479
|
-
@apply px-4 py-2 rounded font-medium transition-colors;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.btn-primary {
|
|
483
|
-
@apply bg-primary-600 text-white hover:bg-primary-700;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
.card {
|
|
487
|
-
@apply bg-white rounded-lg shadow p-6;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
## Related
|
|
493
|
-
|
|
494
|
-
- [Theming Guide](/guides/theming)
|
|
495
|
-
- [Views Reference](/reference/views/)
|
|
496
|
-
- [Forms Reference](/reference/views/forms)
|