plutonium 0.50.0 → 0.52.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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium/SKILL.md +85 -102
  3. data/.claude/skills/plutonium-app/SKILL.md +574 -0
  4. data/.claude/skills/plutonium-auth/SKILL.md +167 -302
  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 +674 -0
  8. data/.claude/skills/plutonium-testing/SKILL.md +9 -6
  9. data/.claude/skills/plutonium-ui/SKILL.md +900 -0
  10. data/CHANGELOG.md +44 -2
  11. data/Rakefile +2 -1
  12. data/app/assets/plutonium.css +1 -11
  13. data/app/assets/plutonium.js +1010 -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 +38 -29
  18. data/docs/.vitepress/theme/components/HomeAudienceSplit.vue +53 -0
  19. data/docs/.vitepress/theme/components/HomeCta.vue +108 -0
  20. data/docs/.vitepress/theme/components/HomeHero.vue +70 -0
  21. data/docs/.vitepress/theme/components/HomeInTheBox.vue +74 -0
  22. data/docs/.vitepress/theme/components/HomePillars.vue +42 -0
  23. data/docs/.vitepress/theme/components/HomeStopWriting.vue +49 -0
  24. data/docs/.vitepress/theme/components/HomeWalkthrough.vue +111 -0
  25. data/docs/.vitepress/theme/components/SectionLanding.vue +115 -0
  26. data/docs/.vitepress/theme/custom.css +144 -0
  27. data/docs/.vitepress/theme/index.ts +58 -1
  28. data/docs/getting-started/index.md +33 -57
  29. data/docs/getting-started/installation.md +37 -80
  30. data/docs/getting-started/tutorial/02-first-resource.md +17 -8
  31. data/docs/getting-started/tutorial/03-authentication.md +31 -23
  32. data/docs/getting-started/tutorial/05-custom-actions.md +9 -4
  33. data/docs/getting-started/tutorial/06-nested-resources.md +7 -1
  34. data/docs/getting-started/tutorial/07-author-portal.md +8 -0
  35. data/docs/getting-started/tutorial/08-customizing-ui.md +4 -0
  36. data/docs/getting-started/tutorial/index.md +4 -5
  37. data/docs/guides/adding-resources.md +66 -377
  38. data/docs/guides/authentication.md +98 -462
  39. data/docs/guides/authorization.md +124 -370
  40. data/docs/guides/creating-packages.md +93 -298
  41. data/docs/guides/custom-actions.md +126 -441
  42. data/docs/guides/customizing-ui.md +258 -0
  43. data/docs/guides/index.md +49 -52
  44. data/docs/guides/multi-tenancy.md +123 -186
  45. data/docs/guides/nested-resources.md +137 -396
  46. data/docs/guides/search-filtering.md +127 -238
  47. data/docs/guides/testing.md +10 -5
  48. data/docs/guides/theming.md +168 -405
  49. data/docs/guides/troubleshooting.md +5 -3
  50. data/docs/guides/user-invites.md +112 -425
  51. data/docs/guides/user-profile.md +82 -241
  52. data/docs/index.md +10 -219
  53. data/docs/public/asciinema/home-scaffold.cast +305 -0
  54. data/docs/public/images/guides/custom-actions-bulk.png +0 -0
  55. data/docs/public/images/guides/multi-tenancy-dashboard.png +0 -0
  56. data/docs/public/images/guides/multi-tenancy-welcome.png +0 -0
  57. data/docs/public/images/guides/nested-inputs.png +0 -0
  58. data/docs/public/images/guides/nested-resources-tab.png +0 -0
  59. data/docs/public/images/guides/search-filtering-index.png +0 -0
  60. data/docs/public/images/guides/search-filtering-panel.png +0 -0
  61. data/docs/public/images/guides/theming-after.png +0 -0
  62. data/docs/public/images/guides/theming-before.png +0 -0
  63. data/docs/public/images/guides/user-invites-landing.png +0 -0
  64. data/docs/public/images/guides/user-profile-edit.png +0 -0
  65. data/docs/public/images/guides/user-profile-show.png +0 -0
  66. data/docs/public/images/home-index.png +0 -0
  67. data/docs/public/images/home-new.png +0 -0
  68. data/docs/public/images/home-show.png +0 -0
  69. data/docs/public/images/tutorial/02-empty-index.png +0 -0
  70. data/docs/public/images/tutorial/02-index-with-posts.png +0 -0
  71. data/docs/public/images/tutorial/02-new-form-modal.png +0 -0
  72. data/docs/public/images/tutorial/02-new-form.png +0 -0
  73. data/docs/public/images/tutorial/03-create-account.png +0 -0
  74. data/docs/public/images/tutorial/03-login.png +0 -0
  75. data/docs/public/images/tutorial/04-admin-index.png +0 -0
  76. data/docs/public/images/tutorial/05-actions-menu.png +0 -0
  77. data/docs/public/images/tutorial/05-row-actions.png +0 -0
  78. data/docs/public/images/tutorial/06-comments-tab.png +0 -0
  79. data/docs/public/images/tutorial/06-post-with-comments.png +0 -0
  80. data/docs/public/images/tutorial/07-author-dashboard.png +0 -0
  81. data/docs/public/images/tutorial/07-author-portal.png +0 -0
  82. data/docs/public/images/tutorial/08-customized-index.png +0 -0
  83. data/docs/reference/app/generators.md +517 -0
  84. data/docs/reference/app/index.md +158 -0
  85. data/docs/reference/app/packages.md +146 -0
  86. data/docs/reference/app/portals.md +377 -0
  87. data/docs/reference/auth/accounts.md +229 -0
  88. data/docs/reference/auth/index.md +88 -0
  89. data/docs/reference/auth/profile.md +185 -0
  90. data/docs/reference/behavior/controllers.md +395 -0
  91. data/docs/reference/behavior/index.md +22 -0
  92. data/docs/reference/behavior/interactions.md +341 -0
  93. data/docs/reference/behavior/policies.md +417 -0
  94. data/docs/reference/index.md +67 -48
  95. data/docs/reference/resource/actions.md +423 -0
  96. data/docs/reference/resource/definition.md +508 -0
  97. data/docs/reference/resource/index.md +50 -0
  98. data/docs/reference/resource/model.md +348 -0
  99. data/docs/reference/resource/query.md +305 -0
  100. data/docs/reference/tenancy/entity-scoping.md +368 -0
  101. data/docs/reference/tenancy/index.md +36 -0
  102. data/docs/reference/tenancy/invites.md +400 -0
  103. data/docs/reference/tenancy/nested-resources.md +267 -0
  104. data/docs/reference/testing/index.md +287 -0
  105. data/docs/reference/ui/assets.md +400 -0
  106. data/docs/reference/ui/components.md +165 -0
  107. data/docs/reference/ui/displays.md +104 -0
  108. data/docs/reference/ui/forms.md +284 -0
  109. data/docs/reference/ui/index.md +30 -0
  110. data/docs/reference/ui/layouts.md +106 -0
  111. data/docs/reference/ui/pages.md +189 -0
  112. data/docs/reference/ui/tables.md +121 -0
  113. data/docs/superpowers/plans/2026-05-15-public-pages-overhaul.md +1648 -0
  114. data/docs/superpowers/plans/2026-05-15-public-pages-overhaul.md.tasks.json +109 -0
  115. data/docs/superpowers/specs/2026-05-09-typeahead-endpoint-design.md +203 -0
  116. data/docs/superpowers/specs/2026-05-12-skill-compaction-design.md +99 -0
  117. data/docs/superpowers/specs/2026-05-13-docs-restructure-design.md +186 -0
  118. data/docs/superpowers/specs/2026-05-15-public-pages-overhaul-design.md +263 -0
  119. data/gemfiles/rails_7.gemfile.lock +1 -1
  120. data/gemfiles/rails_8.0.gemfile.lock +1 -1
  121. data/gemfiles/rails_8.1.gemfile.lock +1 -1
  122. data/lib/generators/pu/core/assets/assets_generator.rb +10 -0
  123. data/lib/generators/pu/core/update/update_generator.rb +0 -20
  124. data/lib/generators/pu/invites/install_generator.rb +45 -0
  125. data/lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/user_invitations_controller.rb.tt +1 -0
  126. data/lib/generators/pu/profile/conn_generator.rb +2 -2
  127. data/lib/generators/pu/res/conn/conn_generator.rb +33 -6
  128. data/lib/generators/pu/res/model/templates/model.rb.tt +4 -0
  129. data/lib/generators/pu/rodauth/account_generator.rb +2 -1
  130. data/lib/generators/pu/rodauth/admin_generator.rb +0 -2
  131. data/lib/generators/pu/rodauth/migration_generator.rb +0 -2
  132. data/lib/generators/pu/rodauth/views_generator.rb +0 -2
  133. data/lib/generators/pu/saas/membership/USAGE +4 -1
  134. data/lib/generators/pu/saas/setup_generator.rb +16 -4
  135. data/lib/generators/pu/saas/welcome/templates/app/controllers/welcome_controller.rb.tt +1 -1
  136. data/lib/plutonium/definition/base.rb +1 -1
  137. data/lib/plutonium/definition/{views.rb → index_views.rb} +21 -20
  138. data/lib/plutonium/helpers/turbo_helper.rb +30 -0
  139. data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +14 -0
  140. data/lib/plutonium/resource/controller.rb +1 -0
  141. data/lib/plutonium/resource/controllers/crud_actions.rb +23 -5
  142. data/lib/plutonium/resource/controllers/interactive_actions.rb +3 -3
  143. data/lib/plutonium/resource/controllers/typeahead.rb +180 -0
  144. data/lib/plutonium/resource/policy.rb +7 -0
  145. data/lib/plutonium/routing/mapper_extensions.rb +15 -0
  146. data/lib/plutonium/ui/component/methods.rb +5 -0
  147. data/lib/plutonium/ui/form/base.rb +23 -3
  148. data/lib/plutonium/ui/form/components/json.rb +58 -0
  149. data/lib/plutonium/ui/form/components/resource_select.rb +62 -8
  150. data/lib/plutonium/ui/form/components/secure_association.rb +103 -22
  151. data/lib/plutonium/ui/form/concerns/typeahead_attributes.rb +83 -0
  152. data/lib/plutonium/ui/form/interaction.rb +1 -1
  153. data/lib/plutonium/ui/form/resource.rb +0 -4
  154. data/lib/plutonium/ui/form/theme.rb +1 -1
  155. data/lib/plutonium/ui/grid/resource.rb +1 -1
  156. data/lib/plutonium/ui/layout/base.rb +1 -0
  157. data/lib/plutonium/ui/page/base.rb +0 -7
  158. data/lib/plutonium/ui/page/edit.rb +1 -1
  159. data/lib/plutonium/ui/page/index.rb +4 -4
  160. data/lib/plutonium/ui/page/new.rb +1 -1
  161. data/lib/plutonium/ui/table/components/filter_form.rb +12 -4
  162. data/lib/plutonium/ui/table/resource.rb +1 -1
  163. data/lib/plutonium/version.rb +1 -1
  164. data/lib/plutonium.rb +8 -0
  165. data/lib/tasks/release.rake +15 -1
  166. data/package.json +13 -10
  167. data/src/css/slim_select.css +4 -0
  168. data/src/js/controllers/form_controller.js +5 -4
  169. data/src/js/controllers/slim_select_controller.js +61 -0
  170. data/src/js/turbo/turbo_actions.js +33 -0
  171. data/yarn.lock +661 -544
  172. metadata +86 -33
  173. data/.claude/skills/plutonium-assets/SKILL.md +0 -512
  174. data/.claude/skills/plutonium-controller/SKILL.md +0 -396
  175. data/.claude/skills/plutonium-create-resource/SKILL.md +0 -303
  176. data/.claude/skills/plutonium-definition/SKILL.md +0 -1223
  177. data/.claude/skills/plutonium-entity-scoping/SKILL.md +0 -317
  178. data/.claude/skills/plutonium-forms/SKILL.md +0 -465
  179. data/.claude/skills/plutonium-installation/SKILL.md +0 -331
  180. data/.claude/skills/plutonium-interaction/SKILL.md +0 -413
  181. data/.claude/skills/plutonium-invites/SKILL.md +0 -408
  182. data/.claude/skills/plutonium-model/SKILL.md +0 -440
  183. data/.claude/skills/plutonium-nested-resources/SKILL.md +0 -360
  184. data/.claude/skills/plutonium-package/SKILL.md +0 -198
  185. data/.claude/skills/plutonium-policy/SKILL.md +0 -456
  186. data/.claude/skills/plutonium-portal/SKILL.md +0 -410
  187. data/.claude/skills/plutonium-views/SKILL.md +0 -651
  188. data/docs/reference/assets/index.md +0 -496
  189. data/docs/reference/controller/index.md +0 -412
  190. data/docs/reference/definition/actions.md +0 -462
  191. data/docs/reference/definition/fields.md +0 -383
  192. data/docs/reference/definition/index.md +0 -326
  193. data/docs/reference/definition/query.md +0 -351
  194. data/docs/reference/generators/index.md +0 -648
  195. data/docs/reference/interaction/index.md +0 -449
  196. data/docs/reference/model/features.md +0 -248
  197. data/docs/reference/model/index.md +0 -218
  198. data/docs/reference/policy/index.md +0 -456
  199. data/docs/reference/portal/index.md +0 -379
  200. data/docs/reference/views/forms.md +0 -411
  201. data/docs/reference/views/index.md +0 -544
@@ -0,0 +1,258 @@
1
+ # Customizing the UI
2
+
3
+ Plutonium's UI is built on Phlex, Tailwind 4, and Stimulus. Almost everything you see — pages, forms, displays, tables, components, layouts, even the design tokens — is open for override. This guide is the map. Each section shows the smallest useful example for one kind of customization, then points to the reference for the full surface.
4
+
5
+ When you're not sure where to start, read this top to bottom. When you know what you need, jump to the right section and follow the link to reference.
6
+
7
+ ## The override pattern
8
+
9
+ Customization in Plutonium is overrides via **nested classes inside the definition**, never replacement of the root class. The pattern looks the same everywhere:
10
+
11
+ ```ruby
12
+ class PostDefinition < ResourceDefinition
13
+ class ShowPage < ShowPage; end # override show page
14
+ class Form < Form; end # override form
15
+ class Table < Table; end # override index table
16
+ class Display < Display; end # override show display
17
+ end
18
+ ```
19
+
20
+ Each nested class inherits from Plutonium's defaults and lets you override only the methods you care about. Don't reimplement the whole layer — use the render hooks below.
21
+
22
+ → See [Reference › UI › Pages](/reference/ui/pages) for the full hook list.
23
+
24
+ ## Adding chrome to a page
25
+
26
+ Most page customization is "I want to add something before/after this section." Use the render hooks; don't override `view_template`.
27
+
28
+ ```ruby
29
+ class PostDefinition < ResourceDefinition
30
+ class ShowPage < ShowPage
31
+ def render_before_content
32
+ div(class: "pu-card pu-card-body") do
33
+ plain "This post has #{object.comments.count} comments"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ ```
39
+
40
+ Hooks exist around the header, breadcrumbs, page header, toolbar, content, and footer — pick the one closest to where you want the thing to appear.
41
+
42
+ → See [Reference › UI › Pages](/reference/ui/pages) › Page hooks.
43
+
44
+ ## Customizing a form layout
45
+
46
+ The default form renders every permitted field in a single grid. To group fields into sections or columns, override `form_template`:
47
+
48
+ ```ruby
49
+ class Form < Form
50
+ def form_template
51
+ section("Basic") do
52
+ render_resource_field :title
53
+ render_resource_field :slug
54
+ end
55
+ section("Publishing") do
56
+ render_resource_field :published_at
57
+ render_resource_field :category
58
+ end
59
+ render_actions # REQUIRED — without this, no submit button
60
+ end
61
+
62
+ private
63
+
64
+ def section(title, &)
65
+ div(class: "mb-8") do
66
+ h3(class: "text-lg font-semibold mb-4 text-[var(--pu-text)]") { title }
67
+ fields_wrapper(&)
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ → See [Reference › UI › Forms](/reference/ui/forms) for `render_resource_field`, field tags (`flatpickr_tag`, `easymde_tag`, `uppy_tag`, etc.), and Phlexi themes.
74
+
75
+ ## Customizing a display
76
+
77
+ The show page renders a `Display` for the record. Override `display_template` to add hero blocks, group fields, or interleave custom panels:
78
+
79
+ ```ruby
80
+ class Display < Display
81
+ def display_template
82
+ div(class: "pu-card pu-card-body mb-4") do
83
+ h1 { object.title }
84
+ p(class: "text-[var(--pu-text-muted)]") { object.excerpt }
85
+ end
86
+ Block { fields_wrapper { render_fields } }
87
+ render_associations if present_associations?
88
+ end
89
+ end
90
+ ```
91
+
92
+ → See [Reference › UI › Displays](/reference/ui/displays).
93
+
94
+ ## Replacing a table with a grid
95
+
96
+ By default the index page renders a `Table`. To use cards instead, override `view_template` on the nested `Table`:
97
+
98
+ ```ruby
99
+ class Table < Table
100
+ def view_template
101
+ render_toolbar
102
+ render_scopes_pills
103
+ if collection.empty?
104
+ render_empty_card
105
+ else
106
+ div(class: "grid grid-cols-3 gap-4") do
107
+ collection.each { |post| render PostCardComponent.new(post:) }
108
+ end
109
+ end
110
+ render_footer
111
+ end
112
+ end
113
+ ```
114
+
115
+ → See [Reference › UI › Tables](/reference/ui/tables).
116
+
117
+ ## Writing a custom Phlex component
118
+
119
+ When you need a piece of UI that's reused across pages, write a Phlex component. Inherit from `Plutonium::UI::Component::Base` and you get the component kit (`PageHeader`, `Panel`, `Block`), resource URL helpers, and a `helpers` proxy for Rails helpers.
120
+
121
+ ```ruby
122
+ class PostCardComponent < Plutonium::UI::Component::Base
123
+ def initialize(post:) = @post = post
124
+
125
+ def view_template
126
+ div(class: "pu-card pu-card-body") do
127
+ h3(class: "font-bold text-[var(--pu-text)]") { @post.title }
128
+ p(class: "text-[var(--pu-text-muted)] mt-2") { @post.excerpt }
129
+ a(href: resource_url_for(@post), class: "pu-btn pu-btn-sm pu-btn-ghost") { "Read more" }
130
+ end
131
+ end
132
+ end
133
+ ```
134
+
135
+ Use it directly in a page, or wire it as a field in the definition:
136
+
137
+ ```ruby
138
+ display :card, as: PostCardComponent
139
+ ```
140
+
141
+ → See [Reference › UI › Components](/reference/ui/components).
142
+
143
+ ## Phlexi themes (recolor without rewriting)
144
+
145
+ If all you want is to recolor or restyle the form/display/table, write a `Theme` class instead of overriding the template. Always `super.merge(...)` — never replace wholesale:
146
+
147
+ ```ruby
148
+ class Form < Form
149
+ class Theme < Plutonium::UI::Form::Theme
150
+ def self.theme
151
+ super.merge(
152
+ base: "bg-[var(--pu-card-bg)] shadow-md rounded-lg p-6",
153
+ fields_wrapper: "grid grid-cols-2 gap-6",
154
+ label: "block mb-2 text-base font-bold",
155
+ )
156
+ end
157
+ end
158
+ end
159
+ ```
160
+
161
+ → See [Reference › UI › Forms](/reference/ui/forms) › Theme keys, [Reference › UI › Displays](/reference/ui/displays) › Theme, [Reference › UI › Tables](/reference/ui/tables) › Theme.
162
+
163
+ ## Modals and slideovers
164
+
165
+ By default `:new` and `:edit` render in a slideover panel. Switch to a centered modal or a full standalone page from the definition:
166
+
167
+ ```ruby
168
+ class PostDefinition < ResourceDefinition
169
+ modal :slideover # default — slide-in from the right
170
+ # modal :centered # centered dialog
171
+ # modal false # full standalone page
172
+ end
173
+ ```
174
+
175
+ → See [Reference › Resource › Actions](/reference/resource/actions) for per-action `modal:` options on interactive actions.
176
+
177
+ ## Layouts and the shell
178
+
179
+ The layout is the chrome around every resource page — topbar, sidebar, flash region, scripts. Two ways to customize it:
180
+
181
+ ```bash
182
+ # Per-portal: eject the shell partials and edit them directly
183
+ rails generate pu:eject:shell --dest=admin_portal
184
+ # Or eject the whole layout
185
+ rails generate pu:eject:layout
186
+ ```
187
+
188
+ For programmatic overrides, subclass `Plutonium::UI::Layout::ResourceLayout` and use its render hooks (`render_before_main`, `render_body_scripts`, etc.).
189
+
190
+ → See [Reference › UI › Layouts](/reference/ui/layouts) and [Theming](/guides/theming) for design tokens.
191
+
192
+ ## Tailwind, Stimulus, and assets
193
+
194
+ Plutonium ships with a Tailwind config, design tokens, and a set of Stimulus controllers. To plug into them in your app:
195
+
196
+ ```bash
197
+ rails generate pu:core:assets
198
+ ```
199
+
200
+ This installs the npm packages, creates a `tailwind.config.js` that extends Plutonium's defaults via `plutoniumTailwindConfig.merge`, imports Plutonium's CSS, and registers its Stimulus controllers. After that, you can:
201
+
202
+ - Extend the palette under `theme.extend.colors` (always inside `plutoniumTailwindConfig.merge` — a plain spread drops Plutonium's defaults).
203
+ - Use `.pu-btn`, `.pu-card`, `.pu-input`, `.pu-table`, etc. instead of hand-rolling Tailwind chains.
204
+ - Reference design tokens directly: `bg-[var(--pu-surface)]`, `text-[var(--pu-text-muted)]`, `border-[var(--pu-border)]`. These auto-switch with dark mode.
205
+ - Register your own Stimulus controllers alongside Plutonium's — `registerControllers(application)` is mandatory or the entire interactive layer is dead.
206
+
207
+ → See [Reference › UI › Assets](/reference/ui/assets) for the full toolchain, the `.pu-*` class catalog, and design-token reference.
208
+
209
+ ## ERB views (escape hatch)
210
+
211
+ When the Phlex page class is the wrong tool — you want to keep an existing ERB layout, you're integrating with a designer's HTML, or you just want to surround the generated page with custom markup — drop an ERB view at the controller path:
212
+
213
+ ```
214
+ app/views/posts/show.html.erb
215
+ packages/admin_portal/app/views/admin_portal/posts/show.html.erb
216
+ ```
217
+
218
+ The default page renders the Phlex page class in one line:
219
+
220
+ ```erb
221
+ <%= render current_definition.show_page_class.new %>
222
+ ```
223
+
224
+ Keep that line and wrap it to add chrome without giving up the generated page:
225
+
226
+ ```erb
227
+ <div class="announcement-banner">Special announcement</div>
228
+ <%= render current_definition.show_page_class.new %>
229
+ <%= render partial: "related" %>
230
+ ```
231
+
232
+ Or replace the line entirely for full control. ERB views always win over the Phlex page class when both exist for the same action — reach for this only when Phlex hooks + overrides genuinely can't do the job.
233
+
234
+ ## When to reach for what
235
+
236
+ | You want to… | Use |
237
+ |---|---|
238
+ | Add a banner above the show page | Page hook (`render_before_content`) |
239
+ | Group form fields into sections | Custom `form_template` |
240
+ | Render the index as cards | Custom `Table#view_template` |
241
+ | Reuse a UI block across pages | Custom Phlex component |
242
+ | Recolor without changing structure | Phlexi `Theme` class |
243
+ | Swap the topbar or sidebar | `pu:eject:shell` or custom layout class |
244
+ | Change brand color or radius | Design tokens — see [Theming](/guides/theming) |
245
+ | Add a custom JS interaction | Stimulus controller registered alongside Plutonium's |
246
+
247
+ ## Gotchas
248
+
249
+ - **Don't override `view_template` in pages** when a render hook fits — you lose breadcrumbs, header, and DynaFrame (turbo-frame) behavior.
250
+ - **`render_actions` is mandatory** when you write a custom `form_template` — otherwise the form has no submit button.
251
+ - **Always `registerControllers(application)`** in `app/javascript/controllers/index.js`. Without it, every Plutonium-shipped Stimulus controller is dead (color mode, slim-select, flatpickr, easymde, form pre-submit).
252
+ - **Use `plutoniumTailwindConfig.merge`** when extending the Tailwind theme. A plain object spread drops Plutonium's defaults.
253
+ - **Prefer `.pu-*` classes and `var(--pu-*)` tokens** over hardcoded `gray-X/dark:gray-Y` pairs — they switch with dark mode automatically.
254
+
255
+ ## Related
256
+
257
+ - [Theming](/guides/theming) — design tokens, brand colors.
258
+ - [Reference › UI](/reference/ui/) — the full surface area for every override above.
data/docs/guides/index.md CHANGED
@@ -1,52 +1,49 @@
1
- # Guides
2
-
3
- Task-oriented guides for common Plutonium operations.
4
-
5
- ## Getting Things Done
6
-
7
- These guides show you how to accomplish specific tasks, with complete examples.
8
-
9
- ### Setup & Resources
10
-
11
- - [Adding Resources](./adding-resources) - Create and connect resources to portals
12
- - [Creating Packages](./creating-packages) - Organize code into feature and portal packages
13
-
14
- ### Authentication & Authorization
15
-
16
- - [Authentication](./authentication) - Set up user authentication with Rodauth
17
- - [Authorization](./authorization) - Implement policies for access control
18
-
19
- ### Features
20
-
21
- - [Custom Actions](./custom-actions) - Add interactive actions with Interactions
22
- - [Nested Resources](./nested-resources) - Parent/child resource relationships
23
- - [Multi-tenancy](./multi-tenancy) - Scope data to organizations or accounts
24
- - [Search and Filtering](./search-filtering) - Implement search, filters, and scopes
25
- - [User Invites](./user-invites) - Invitation system for multi-tenant apps
26
-
27
- ### Customization
28
-
29
- - [Theming](./theming) - Customize colors, styles, and branding
30
-
31
- ### Help
32
-
33
- - [Troubleshooting](./troubleshooting) - Common issues and solutions
34
-
35
- ## Finding What You Need
36
-
37
- | I want to... | Guide |
38
- |--------------|-------|
39
- | Add a new model to my app | [Adding Resources](./adding-resources) |
40
- | Protect pages with login | [Authentication](./authentication) |
41
- | Control who can edit what | [Authorization](./authorization) |
42
- | Add a "Publish" button | [Custom Actions](./custom-actions) |
43
- | Show comments under posts | [Nested Resources](./nested-resources) |
44
- | Separate data by company | [Multi-tenancy](./multi-tenancy) |
45
- | Add search to a list | [Search and Filtering](./search-filtering) |
46
- | Invite users to an org | [User Invites](./user-invites) |
47
- | Change the color scheme | [Theming](./theming) |
48
- | Fix a confusing error | [Troubleshooting](./troubleshooting) |
49
-
50
- ## Looking for Reference Docs?
51
-
52
- For complete API documentation, see the [Reference](/reference/) section.
1
+ ---
2
+ layout: page
3
+ sidebar: false
4
+ aside: false
5
+ ---
6
+
7
+ <SectionLanding
8
+ eyebrow="Guides"
9
+ title="How to do the things Plutonium apps do."
10
+ lede="Task-oriented walkthroughs for the parts of the framework you reach for most."
11
+ mode="categorized"
12
+ :rail="[
13
+ { group: 'Setup & Resources', items: [
14
+ { name: 'Adding resources', link: '/plutonium-core/guides/adding-resources' },
15
+ { name: 'Creating packages', link: '/plutonium-core/guides/creating-packages' },
16
+ ]},
17
+ { group: 'Auth', items: [
18
+ { name: 'Authentication', link: '/plutonium-core/guides/authentication' },
19
+ { name: 'Authorization', link: '/plutonium-core/guides/authorization' },
20
+ { name: 'User profile', link: '/plutonium-core/guides/user-profile' },
21
+ { name: 'User invites', link: '/plutonium-core/guides/user-invites' },
22
+ ]},
23
+ { group: 'Features', items: [
24
+ { name: 'Custom actions', link: '/plutonium-core/guides/custom-actions' },
25
+ { name: 'Nested resources', link: '/plutonium-core/guides/nested-resources' },
26
+ { name: 'Multi-tenancy', link: '/plutonium-core/guides/multi-tenancy' },
27
+ { name: 'Search & filtering', link: '/plutonium-core/guides/search-filtering' },
28
+ ]},
29
+ { group: 'Customization', items: [
30
+ { name: 'Customizing the UI', desc: 'A map of the override surface — pages, forms, displays, tables, components, layouts.', link: '/plutonium-core/guides/customizing-ui' },
31
+ { name: 'Theming', desc: 'Design tokens and brand colors.', link: '/plutonium-core/guides/theming' },
32
+ ]},
33
+ { group: 'Quality', items: [
34
+ { name: 'Testing', link: '/plutonium-core/guides/testing' },
35
+ { name: 'Troubleshooting', link: '/plutonium-core/guides/troubleshooting' },
36
+ ]},
37
+ ]"
38
+ :sidebar="[
39
+ { heading: 'New to Plutonium?', items: [
40
+ { label: 'Start with the tutorial', href: '/plutonium-core/getting-started/tutorial/' },
41
+ ]},
42
+ { heading: 'Looking for APIs?', items: [
43
+ { label: 'Browse the reference', href: '/plutonium-core/reference/' },
44
+ ]},
45
+ { heading: 'Need help?', items: [
46
+ { label: 'GitHub Discussions', href: 'https://github.com/radioactive-labs/plutonium-core/discussions' },
47
+ ]},
48
+ ]"
49
+ />