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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium/SKILL.md +85 -102
  3. data/.claude/skills/plutonium-app/SKILL.md +572 -0
  4. data/.claude/skills/plutonium-auth/SKILL.md +163 -300
  5. data/.claude/skills/plutonium-behavior/SKILL.md +838 -0
  6. data/.claude/skills/plutonium-resource/SKILL.md +1176 -0
  7. data/.claude/skills/plutonium-tenancy/SKILL.md +655 -0
  8. data/.claude/skills/plutonium-testing/SKILL.md +6 -5
  9. data/.claude/skills/plutonium-ui/SKILL.md +900 -0
  10. data/CHANGELOG.md +27 -2
  11. data/Rakefile +2 -1
  12. data/app/assets/plutonium.css +1 -11
  13. data/app/assets/plutonium.js +1009 -1214
  14. data/app/assets/plutonium.js.map +3 -3
  15. data/app/assets/plutonium.min.js +52 -51
  16. data/app/assets/plutonium.min.js.map +3 -3
  17. data/docs/.vitepress/config.ts +37 -27
  18. data/docs/getting-started/index.md +22 -29
  19. data/docs/getting-started/installation.md +37 -80
  20. data/docs/getting-started/tutorial/index.md +4 -5
  21. data/docs/guides/adding-resources.md +66 -377
  22. data/docs/guides/authentication.md +94 -463
  23. data/docs/guides/authorization.md +124 -370
  24. data/docs/guides/creating-packages.md +94 -296
  25. data/docs/guides/custom-actions.md +121 -441
  26. data/docs/guides/index.md +22 -42
  27. data/docs/guides/multi-tenancy.md +116 -187
  28. data/docs/guides/nested-resources.md +103 -431
  29. data/docs/guides/search-filtering.md +123 -240
  30. data/docs/guides/testing.md +5 -4
  31. data/docs/guides/theming.md +157 -407
  32. data/docs/guides/troubleshooting.md +5 -3
  33. data/docs/guides/user-invites.md +106 -425
  34. data/docs/guides/user-profile.md +76 -243
  35. data/docs/index.md +1 -1
  36. data/docs/reference/app/generators.md +517 -0
  37. data/docs/reference/app/index.md +158 -0
  38. data/docs/reference/app/packages.md +146 -0
  39. data/docs/reference/app/portals.md +377 -0
  40. data/docs/reference/auth/accounts.md +230 -0
  41. data/docs/reference/auth/index.md +88 -0
  42. data/docs/reference/auth/profile.md +185 -0
  43. data/docs/reference/behavior/controllers.md +395 -0
  44. data/docs/reference/behavior/index.md +22 -0
  45. data/docs/reference/behavior/interactions.md +341 -0
  46. data/docs/reference/behavior/policies.md +417 -0
  47. data/docs/reference/index.md +56 -49
  48. data/docs/reference/resource/actions.md +423 -0
  49. data/docs/reference/resource/definition.md +508 -0
  50. data/docs/reference/resource/index.md +50 -0
  51. data/docs/reference/resource/model.md +348 -0
  52. data/docs/reference/resource/query.md +305 -0
  53. data/docs/reference/tenancy/entity-scoping.md +361 -0
  54. data/docs/reference/tenancy/index.md +36 -0
  55. data/docs/reference/tenancy/invites.md +393 -0
  56. data/docs/reference/tenancy/nested-resources.md +267 -0
  57. data/docs/reference/testing/index.md +287 -0
  58. data/docs/reference/ui/assets.md +400 -0
  59. data/docs/reference/ui/components.md +165 -0
  60. data/docs/reference/ui/displays.md +104 -0
  61. data/docs/reference/ui/forms.md +284 -0
  62. data/docs/reference/ui/index.md +30 -0
  63. data/docs/reference/ui/layouts.md +106 -0
  64. data/docs/reference/ui/pages.md +189 -0
  65. data/docs/reference/ui/tables.md +117 -0
  66. data/docs/superpowers/specs/2026-05-09-typeahead-endpoint-design.md +203 -0
  67. data/docs/superpowers/specs/2026-05-12-skill-compaction-design.md +99 -0
  68. data/docs/superpowers/specs/2026-05-13-docs-restructure-design.md +186 -0
  69. data/gemfiles/rails_7.gemfile.lock +1 -1
  70. data/gemfiles/rails_8.0.gemfile.lock +1 -1
  71. data/gemfiles/rails_8.1.gemfile.lock +1 -1
  72. data/lib/generators/pu/core/update/update_generator.rb +0 -20
  73. data/lib/generators/pu/invites/install_generator.rb +1 -0
  74. data/lib/plutonium/definition/base.rb +1 -1
  75. data/lib/plutonium/definition/{views.rb → index_views.rb} +21 -20
  76. data/lib/plutonium/helpers/turbo_helper.rb +11 -0
  77. data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +14 -0
  78. data/lib/plutonium/resource/controller.rb +1 -0
  79. data/lib/plutonium/resource/controllers/crud_actions.rb +19 -1
  80. data/lib/plutonium/resource/controllers/typeahead.rb +180 -0
  81. data/lib/plutonium/resource/policy.rb +7 -0
  82. data/lib/plutonium/routing/mapper_extensions.rb +15 -0
  83. data/lib/plutonium/ui/component/methods.rb +4 -0
  84. data/lib/plutonium/ui/form/base.rb +6 -2
  85. data/lib/plutonium/ui/form/components/json.rb +58 -0
  86. data/lib/plutonium/ui/form/components/resource_select.rb +62 -8
  87. data/lib/plutonium/ui/form/components/secure_association.rb +98 -22
  88. data/lib/plutonium/ui/form/concerns/typeahead_attributes.rb +83 -0
  89. data/lib/plutonium/ui/form/resource.rb +0 -4
  90. data/lib/plutonium/ui/grid/resource.rb +1 -1
  91. data/lib/plutonium/ui/layout/base.rb +1 -0
  92. data/lib/plutonium/ui/page/base.rb +0 -7
  93. data/lib/plutonium/ui/page/index.rb +4 -4
  94. data/lib/plutonium/ui/table/resource.rb +1 -1
  95. data/lib/plutonium/version.rb +1 -1
  96. data/lib/plutonium.rb +8 -0
  97. data/lib/tasks/release.rake +15 -1
  98. data/package.json +10 -10
  99. data/src/css/slim_select.css +4 -0
  100. data/src/js/controllers/slim_select_controller.js +61 -0
  101. data/src/js/turbo/turbo_actions.js +33 -0
  102. data/yarn.lock +553 -543
  103. metadata +44 -33
  104. data/.claude/skills/plutonium-assets/SKILL.md +0 -512
  105. data/.claude/skills/plutonium-controller/SKILL.md +0 -396
  106. data/.claude/skills/plutonium-create-resource/SKILL.md +0 -303
  107. data/.claude/skills/plutonium-definition/SKILL.md +0 -1223
  108. data/.claude/skills/plutonium-entity-scoping/SKILL.md +0 -317
  109. data/.claude/skills/plutonium-forms/SKILL.md +0 -465
  110. data/.claude/skills/plutonium-installation/SKILL.md +0 -331
  111. data/.claude/skills/plutonium-interaction/SKILL.md +0 -413
  112. data/.claude/skills/plutonium-invites/SKILL.md +0 -408
  113. data/.claude/skills/plutonium-model/SKILL.md +0 -440
  114. data/.claude/skills/plutonium-nested-resources/SKILL.md +0 -360
  115. data/.claude/skills/plutonium-package/SKILL.md +0 -198
  116. data/.claude/skills/plutonium-policy/SKILL.md +0 -456
  117. data/.claude/skills/plutonium-portal/SKILL.md +0 -410
  118. data/.claude/skills/plutonium-views/SKILL.md +0 -651
  119. data/docs/reference/assets/index.md +0 -496
  120. data/docs/reference/controller/index.md +0 -412
  121. data/docs/reference/definition/actions.md +0 -462
  122. data/docs/reference/definition/fields.md +0 -383
  123. data/docs/reference/definition/index.md +0 -326
  124. data/docs/reference/definition/query.md +0 -351
  125. data/docs/reference/generators/index.md +0 -648
  126. data/docs/reference/interaction/index.md +0 -449
  127. data/docs/reference/model/features.md +0 -248
  128. data/docs/reference/model/index.md +0 -218
  129. data/docs/reference/policy/index.md +0 -456
  130. data/docs/reference/portal/index.md +0 -379
  131. data/docs/reference/views/forms.md +0 -411
  132. 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)