compony 0.11.8 → 0.11.9

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/.yardopts +36 -1
  3. data/CHANGELOG.md +31 -0
  4. data/CLAUDE.md +85 -0
  5. data/Gemfile.lock +1 -1
  6. data/README.md +13 -3
  7. data/VERSION +1 -1
  8. data/compony.gemspec +3 -3
  9. data/doc/ComponentGenerator.html +1 -1
  10. data/doc/Components.html +1 -1
  11. data/doc/ComponentsGenerator.html +1 -1
  12. data/doc/Compony/Component.html +54 -54
  13. data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
  14. data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
  15. data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +109 -70
  16. data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +64 -28
  17. data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
  18. data/doc/Compony/ComponentMixins/Default.html +1 -1
  19. data/doc/Compony/ComponentMixins/Resourceful.html +213 -74
  20. data/doc/Compony/ComponentMixins.html +1 -1
  21. data/doc/Compony/Components/Buttons/CssButton.html +1 -1
  22. data/doc/Compony/Components/Buttons/Link.html +1 -1
  23. data/doc/Compony/Components/Buttons.html +1 -1
  24. data/doc/Compony/Components/Destroy.html +83 -29
  25. data/doc/Compony/Components/Edit.html +110 -38
  26. data/doc/Compony/Components/Form.html +551 -208
  27. data/doc/Compony/Components/Index.html +1 -1
  28. data/doc/Compony/Components/List.html +3 -3
  29. data/doc/Compony/Components/New.html +110 -38
  30. data/doc/Compony/Components/Show.html +1 -1
  31. data/doc/Compony/Components/WithForm.html +194 -47
  32. data/doc/Compony/Components.html +1 -1
  33. data/doc/Compony/ControllerMixin.html +1 -1
  34. data/doc/Compony/Engine.html +1 -1
  35. data/doc/Compony/Intent.html +2 -2
  36. data/doc/Compony/ManageIntentsDsl.html +1 -1
  37. data/doc/Compony/MethodAccessibleHash.html +1 -1
  38. data/doc/Compony/ModelFields/Anchormodel.html +1 -1
  39. data/doc/Compony/ModelFields/Association.html +1 -1
  40. data/doc/Compony/ModelFields/Attachment.html +1 -1
  41. data/doc/Compony/ModelFields/Base.html +1 -1
  42. data/doc/Compony/ModelFields/Boolean.html +1 -1
  43. data/doc/Compony/ModelFields/Color.html +1 -1
  44. data/doc/Compony/ModelFields/Currency.html +1 -1
  45. data/doc/Compony/ModelFields/Date.html +1 -1
  46. data/doc/Compony/ModelFields/Datetime.html +1 -1
  47. data/doc/Compony/ModelFields/Decimal.html +1 -1
  48. data/doc/Compony/ModelFields/Email.html +1 -1
  49. data/doc/Compony/ModelFields/Float.html +1 -1
  50. data/doc/Compony/ModelFields/Integer.html +1 -1
  51. data/doc/Compony/ModelFields/Percentage.html +1 -1
  52. data/doc/Compony/ModelFields/Phone.html +1 -1
  53. data/doc/Compony/ModelFields/RichText.html +1 -1
  54. data/doc/Compony/ModelFields/String.html +1 -1
  55. data/doc/Compony/ModelFields/Text.html +1 -1
  56. data/doc/Compony/ModelFields/Time.html +1 -1
  57. data/doc/Compony/ModelFields/Url.html +1 -1
  58. data/doc/Compony/ModelFields.html +1 -1
  59. data/doc/Compony/ModelMixin.html +1 -1
  60. data/doc/Compony/NaturalOrdering.html +1 -1
  61. data/doc/Compony/RequestContext.html +1 -1
  62. data/doc/Compony/Version.html +1 -1
  63. data/doc/Compony/ViewHelpers.html +1 -1
  64. data/doc/Compony/VirtualModel.html +1 -1
  65. data/doc/Compony.html +1 -1
  66. data/doc/ComponyController.html +1 -1
  67. data/doc/_index.html +97 -1
  68. data/doc/file.CHANGELOG.html +758 -0
  69. data/doc/file.README.html +25 -4
  70. data/doc/file.basic_component.html +314 -0
  71. data/doc/file.cookbook.html +189 -0
  72. data/doc/file.destroy.html +105 -0
  73. data/doc/file.dsl_reference.html +672 -0
  74. data/doc/file.edit.html +109 -0
  75. data/doc/file.example.html +291 -0
  76. data/doc/file.example_advanced.html +257 -0
  77. data/doc/file.feasibility.html +115 -0
  78. data/doc/file.form.html +195 -0
  79. data/doc/file.generators.html +89 -0
  80. data/doc/file.glossary.html +217 -0
  81. data/doc/file.gotchas.html +222 -0
  82. data/doc/file.index.html +135 -0
  83. data/doc/file.inheritance.html +136 -0
  84. data/doc/file.installation.html +115 -0
  85. data/doc/file.integrations.html +218 -0
  86. data/doc/file.intents.html +265 -0
  87. data/doc/file.internal_datastructures.html +129 -0
  88. data/doc/file.list.html +253 -0
  89. data/doc/file.maintaining.html +127 -0
  90. data/doc/file.model_fields.html +137 -0
  91. data/doc/file.nesting.html +237 -0
  92. data/doc/file.new.html +109 -0
  93. data/doc/file.ownership.html +98 -0
  94. data/doc/file.patterns.html +669 -0
  95. data/doc/file.pre_built_components.html +99 -0
  96. data/doc/file.resourceful.html +181 -0
  97. data/doc/file.show.html +158 -0
  98. data/doc/file.standalone.html +233 -0
  99. data/doc/file.virtual_models.html +117 -0
  100. data/doc/file.with_form.html +157 -0
  101. data/doc/file_list.html +160 -0
  102. data/doc/guide/cookbook.md +41 -0
  103. data/doc/guide/dsl_reference.md +155 -0
  104. data/doc/guide/example_advanced.md +209 -0
  105. data/doc/guide/generators.md +1 -1
  106. data/doc/guide/glossary.md +42 -0
  107. data/doc/guide/gotchas.md +125 -0
  108. data/doc/guide/maintaining.md +64 -0
  109. data/doc/guide/patterns.md +681 -0
  110. data/doc/guide/pre_built_components/edit.md +1 -1
  111. data/doc/guide/pre_built_components/index.md +64 -1
  112. data/doc/guide/pre_built_components/list.md +111 -7
  113. data/doc/guide/pre_built_components/show.md +57 -2
  114. data/doc/guide/pre_built_components/with_form.md +56 -9
  115. data/doc/guide/pre_built_components.md +7 -2
  116. data/doc/guide/standalone.md +16 -1
  117. data/doc/index.html +25 -4
  118. data/doc/integrations.md +61 -0
  119. data/doc/llms.txt +62 -0
  120. data/doc/top-level-namespace.html +1 -1
  121. data/lib/compony/component.rb +8 -3
  122. data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +32 -15
  123. data/lib/compony/component_mixins/default/standalone/verb_dsl.rb +11 -3
  124. data/lib/compony/component_mixins/resourceful.rb +30 -16
  125. data/lib/compony/components/destroy.rb +21 -1
  126. data/lib/compony/components/edit.rb +25 -1
  127. data/lib/compony/components/form.rb +63 -21
  128. data/lib/compony/components/list.rb +1 -1
  129. data/lib/compony/components/new.rb +25 -1
  130. data/lib/compony/components/with_form.rb +20 -5
  131. data/lib/compony/intent.rb +1 -1
  132. metadata +43 -1
@@ -0,0 +1,672 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ File: dsl_reference
8
+
9
+ &mdash; Documentation by YARD 0.9.34
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
16
+
17
+ <script type="text/javascript">
18
+ pathId = "dsl_reference";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="file_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+ <span class="title">File: dsl_reference</span>
41
+
42
+ </div>
43
+
44
+ <div id="search">
45
+
46
+ <a class="full_list_link" id="class_list_link"
47
+ href="class_list.html">
48
+
49
+ <svg width="24" height="24">
50
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
51
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
52
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
53
+ </svg>
54
+ </a>
55
+
56
+ </div>
57
+ <div class="clear"></div>
58
+ </div>
59
+
60
+ <div id="content"><div id='filecontents'>
61
+ <p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
62
+
63
+ <h1 id="label-DSL+reference">DSL reference</h1>
64
+
65
+ <p>Flat lookup of every Compony DSL method, its calling context, signature, and a one-line description. This page is generated from <code># DSL method</code> markers in the source — when in doubt the Ruby source under <code>lib/compony/</code> is authoritative. “Context” says where the call is legal.</p>
66
+
67
+ <p>Contexts:</p>
68
+ <ul><li>
69
+ <p><strong>class</strong> — directly in the component class body.</p>
70
+ </li><li>
71
+ <p><strong>setup</strong> — inside <code>setup do ... end</code>.</p>
72
+ </li><li>
73
+ <p><strong>standalone</strong> — inside <code>standalone do ... end</code>.</p>
74
+ </li><li>
75
+ <p><strong>verb</strong> — inside <code>verb :x do ... end</code>.</p>
76
+ </li><li>
77
+ <p><strong>form_fields</strong> — inside a Form component’s <code>form_fields do ... end</code>.</p>
78
+ </li><li>
79
+ <p><strong>content</strong> — inside a <code>content do ... end</code> block (a RequestContext).</p>
80
+ </li><li>
81
+ <p><strong>model</strong> — in an <code>ActiveRecord</code>/model class that <code>include</code>s the model mixin.</p>
82
+ </li></ul>
83
+
84
+ <h2 id="label-Component+definition">Component definition</h2>
85
+
86
+ <table role="table">
87
+ <thead>
88
+ <tr>
89
+ <th>Method</th>
90
+ <th>Context</th>
91
+ <th>Signature</th>
92
+ <th>Description</th>
93
+ </tr>
94
+ </thead>
95
+ <tbody>
96
+ <tr>
97
+ <td>‘setup`</td>
98
+ <td>class</td>
99
+ <td>‘setup { block }`</td>
100
+ <td>Main config block. Runs at end of init; parent runs before child.</td>
101
+ </tr>
102
+ <tr>
103
+ <td>‘label`</td>
104
+ <td>setup</td>
105
+ <td>‘label(:short/:long/:all) { |model| … }`</td>
106
+ <td>Component title + link/button text. Resourceful comps take 1 block arg.</td>
107
+ </tr>
108
+ <tr>
109
+ <td>‘color`</td>
110
+ <td>setup</td>
111
+ <td>‘color { ’#AA0000’ }‘</td>
112
+ <td>Component color (not used by Compony itself).</td>
113
+ </tr>
114
+ <tr>
115
+ <td>‘icon`</td>
116
+ <td>setup</td>
117
+ <td>‘icon { %i[fa-solid circle] }`</td>
118
+ <td>Component icon (not used by Compony itself).</td>
119
+ </tr>
120
+ <tr>
121
+ <td>‘content`</td>
122
+ <td>setup</td>
123
+ <td>‘content(name = :main, before: nil, hidden: false) { block }`</td>
124
+ <td>Define/replace a named view block (Dyny). ‘hidden: true` = don’t auto-render. Non-obvious use: hidden ‘:main` + `:wrapper` chrome → [patterns §1](/doc/guide/patterns.md#1-the-app-base-component-layer).</td>
125
+ </tr>
126
+ <tr>
127
+ <td>‘content`</td>
128
+ <td>content</td>
129
+ <td>‘content(:name)`</td>
130
+ <td>Render another content block of the <strong>same</strong> component (nesting). [patterns §1](/doc/guide/patterns.md#1-the-app-base-component-layer).</td>
131
+ </tr>
132
+ <tr>
133
+ <td>‘remove_content`</td>
134
+ <td>setup</td>
135
+ <td>‘remove_content(:name)`</td>
136
+ <td>Remove an inherited content block (returns false if absent).</td>
137
+ </tr>
138
+ <tr>
139
+ <td>‘remove_content!`</td>
140
+ <td>setup</td>
141
+ <td>‘remove_content!(:name)`</td>
142
+ <td>Same, raises if the block was not found.</td>
143
+ </tr>
144
+ <tr>
145
+ <td>‘before_render`</td>
146
+ <td>setup</td>
147
+ <td>‘before_render(name = :main, before: nil) { block }`</td>
148
+ <td>Pre-content hook. If it sets a response body (e.g. redirect), content is skipped. Non-obvious uses: verb-independent guard → [patterns §8](/doc/guide/patterns.md#8-lifecycle-hooks-for-derived-data); wizard step nav → [patterns §16](/doc/guide/patterns.md#16-multi-step-wizard-across-components).</td>
149
+ </tr>
150
+ <tr>
151
+ <td>‘exposed_intents`</td>
152
+ <td>setup</td>
153
+ <td>‘exposed_intents { add …; remove … }`</td>
154
+ <td>Declare intents the layout/parent renders. See ‘add`/`remove`, and the toolbar pattern → [patterns §9](/doc/guide/patterns.md#9-exposed-intents-as-the-action-toolbar).</td>
155
+ </tr>
156
+ <tr>
157
+ <td>‘path`</td>
158
+ <td>setup</td>
159
+ <td>‘path { |model, *args, standalone_name:, **kw| … }`</td>
160
+ <td>Override path generation for this component (advanced). Runs outside the request context — build URLs via ‘Rails.application.routes.url_helpers`. Non-obvious use: mint a signed token into the URL → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links); see also [standalone.md](/doc/guide/standalone.md#customizing-path-generation).</td>
161
+ </tr>
162
+ </tbody>
163
+ </table>
164
+
165
+ <p><code>exposed_intents</code> DSL (inside its block):</p>
166
+
167
+ <table role="table">
168
+ <thead>
169
+ <tr>
170
+ <th>Method</th>
171
+ <th>Signature</th>
172
+ <th>Description</th>
173
+ </tr>
174
+ </thead>
175
+ <tbody>
176
+ <tr>
177
+ <td>‘add`</td>
178
+ <td>‘add(comp, model_or_family, before: nil, **intent_opts)`</td>
179
+ <td>Add/replace an exposed intent (keyed by intent name).</td>
180
+ </tr>
181
+ <tr>
182
+ <td>‘remove`</td>
183
+ <td>‘remove(:intent_name)`</td>
184
+ <td>Remove a previously added exposed intent.</td>
185
+ </tr>
186
+ </tbody>
187
+ </table>
188
+
189
+ <h2 id="label-Standalone+-28routing-29">Standalone (routing)</h2>
190
+
191
+ <table role="table">
192
+ <thead>
193
+ <tr>
194
+ <th>Method</th>
195
+ <th>Context</th>
196
+ <th>Signature</th>
197
+ <th>Description</th>
198
+ </tr>
199
+ </thead>
200
+ <tbody>
201
+ <tr>
202
+ <td>‘standalone`</td>
203
+ <td>setup</td>
204
+ <td>‘standalone(name = nil, path:, constraints: nil, scope: nil, scope_args: {}) { … }`</td>
205
+ <td>Generate a Rails route. Non-obvious use: a <strong>named</strong> extra ‘standalone` for an ajax companion endpoint of the same screen → [patterns §17](/doc/guide/patterns.md#17-inline-patch-without-a-form-reorder–quick-toggle).</td>
206
+ </tr>
207
+ <tr>
208
+ <td>‘verb`</td>
209
+ <td>standalone</td>
210
+ <td>‘verb(:get/:post/:patch/:put/:delete/…) { … }`</td>
211
+ <td>Config one HTTP verb. Up to once per verb per standalone.</td>
212
+ </tr>
213
+ <tr>
214
+ <td>‘skip_authentication!`</td>
215
+ <td>standalone</td>
216
+ <td>‘skip_authentication!`</td>
217
+ <td>Disable app authentication for this standalone (still need ‘authorize`). Non-obvious use: token-gated auth-less links → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links).</td>
218
+ </tr>
219
+ <tr>
220
+ <td>‘skip_forgery_protection!`</td>
221
+ <td>standalone</td>
222
+ <td>‘skip_forgery_protection!`</td>
223
+ <td>Disable CSRF for this standalone’s action. Non-obvious use: inbound webhooks → [patterns §13](/doc/guide/patterns.md#13-public-endpoints–webhooks).</td>
224
+ </tr>
225
+ <tr>
226
+ <td>‘layout`</td>
227
+ <td>standalone</td>
228
+ <td>‘layout(’layouts/backend’)‘</td>
229
+ <td>Rails layout for this standalone. Defaults to ‘layouts/application`. Centralize in the base layer → [patterns §1](/doc/guide/patterns.md#1-the-app-base-component-layer).</td>
230
+ </tr>
231
+ <tr>
232
+ <td>‘authorize`</td>
233
+ <td>verb</td>
234
+ <td>‘authorize { can?(:read, @data) }`</td>
235
+ <td><strong>Mandatory.</strong> Truthy = access; falsy → ‘CanCan::AccessDenied`. Non-obvious use: validate a signed token → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links).</td>
236
+ </tr>
237
+ <tr>
238
+ <td>‘respond`</td>
239
+ <td>verb</td>
240
+ <td>‘respond(format = nil) { … }`</td>
241
+ <td>Override the controller response (e.g. send_data, render json, redirect). Overriding ‘nil` format **skips `authorize`** — re-check yourself. Non-obvious uses: CSV/PDF export → [patterns §10](/doc/guide/patterns.md#10-csv–pdf-via-respond-format); ajax-only PATCH → [patterns §17](/doc/guide/patterns.md#17-inline-patch-without-a-form-reorder–quick-toggle).</td>
242
+ </tr>
243
+ </tbody>
244
+ </table>
245
+
246
+ <h2 id="label-Resourceful+lifecycle+hooks">Resourceful lifecycle hooks</h2>
247
+
248
+ <p>Available in <strong>setup</strong> (global, all verbs) on resourceful components; the same names also work inside a <strong>verb</strong> block to override for one path+verb.</p>
249
+
250
+ <table role="table">
251
+ <thead>
252
+ <tr>
253
+ <th>Method</th>
254
+ <th>Signature</th>
255
+ <th>Description</th>
256
+ </tr>
257
+ </thead>
258
+ <tbody>
259
+ <tr>
260
+ <td>‘data_class`</td>
261
+ <td>‘data_class(NewClass = nil)`</td>
262
+ <td>Set/get the model class. Defaults to family name singularized+constantized. Non-obvious use: point at a ‘VirtualModel` → [patterns §12](/doc/guide/patterns.md#12-virtual-model-for-non-persistent–upload-forms).</td>
263
+ </tr>
264
+ <tr>
265
+ <td>‘load_data`</td>
266
+ <td>‘load_data { @data = … }`</td>
267
+ <td>Override record loading. Default: ‘<a href=":id">data_class.find(params</a>)`. Runs before `authorize`. Non-obvious uses: Index scope → [patterns §3](/doc/guide/patterns.md#3-index–load_data-scope–nested-list); load+dup for clone → [patterns §11](/doc/guide/patterns.md#11-non-crud-job-dispatch-toggles-clone).</td>
268
+ </tr>
269
+ <tr>
270
+ <td>‘after_load_data`</td>
271
+ <td>‘after_load_data { … }`</td>
272
+ <td>Runs after ‘load_data`, before `authorize`. Refine an AR relation here.</td>
273
+ </tr>
274
+ <tr>
275
+ <td>‘assign_attributes`</td>
276
+ <td>‘assign_attributes { … }`</td>
277
+ <td>Assign validated params onto ‘@data`. Pre-built forms supply a default.</td>
278
+ </tr>
279
+ <tr>
280
+ <td>‘after_assign_attributes`</td>
281
+ <td>‘after_assign_attributes { … }`</td>
282
+ <td>After ‘assign_attributes`, before `store_data`. Prefill/derive fields here → [patterns §8](/doc/guide/patterns.md#8-lifecycle-hooks-for-derived-data); seed from a token → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links).</td>
283
+ </tr>
284
+ <tr>
285
+ <td>‘store_data`</td>
286
+ <td>‘store_data { @data.save }`</td>
287
+ <td>Persist ‘@data`. Override for virtual models / uploads → [patterns §12](/doc/guide/patterns.md#12-virtual-model-for-non-persistent–upload-forms), or to enqueue work / multi-record txn → [patterns §11](/doc/guide/patterns.md#11-non-crud-job-dispatch-toggles-clone).</td>
288
+ </tr>
289
+ </tbody>
290
+ </table>
291
+
292
+ <h2 id="label-Form+component+DSL">Form component DSL</h2>
293
+
294
+ <p><code>class Components::X::Form &lt; Compony::Components::Form</code></p>
295
+
296
+ <table role="table">
297
+ <thead>
298
+ <tr>
299
+ <th>Method</th>
300
+ <th>Context</th>
301
+ <th>Signature</th>
302
+ <th>Description</th>
303
+ </tr>
304
+ </thead>
305
+ <tbody>
306
+ <tr>
307
+ <td>‘form_fields`</td>
308
+ <td>setup</td>
309
+ <td>‘form_fields { … }`</td>
310
+ <td><strong>Mandatory.</strong> Block holding the form inputs (Dyny + ‘field`/`f`).</td>
311
+ </tr>
312
+ <tr>
313
+ <td>‘field`</td>
314
+ <td>form_fields</td>
315
+ <td>‘field(:name, multilang: false, **simple_form_opts)`</td>
316
+ <td>Render a simple_form input inferred from the model field. ‘as:`/`hidden:` supported.</td>
317
+ </tr>
318
+ <tr>
319
+ <td>‘pw_field`</td>
320
+ <td>form_fields</td>
321
+ <td>‘pw_field(:password, **opts)`</td>
322
+ <td>Password input; checks ‘:set_password` ability.</td>
323
+ </tr>
324
+ <tr>
325
+ <td>‘f`</td>
326
+ <td>form_fields</td>
327
+ <td>‘f`</td>
328
+ <td>The underlying ‘simple_form` builder (for `f.rich_text_area` etc.).</td>
329
+ </tr>
330
+ <tr>
331
+ <td>‘collect`</td>
332
+ <td>form_fields</td>
333
+ <td>‘collect(…)`</td>
334
+ <td>Wrap a collection in Rails-compatible format (Anchormodel helper).</td>
335
+ </tr>
336
+ <tr>
337
+ <td>‘schema_field`</td>
338
+ <td>setup</td>
339
+ <td>‘schema_field(:name, multilang: false)`</td>
340
+ <td>Whitelist one field in the Schemacop param schema. For associations use the **association name**, not ‘_id`.</td>
341
+ </tr>
342
+ <tr>
343
+ <td>‘schema_fields`</td>
344
+ <td>setup</td>
345
+ <td>‘schema_fields(:a, :b, …)`</td>
346
+ <td>Mass ‘schema_field`.</td>
347
+ </tr>
348
+ <tr>
349
+ <td>‘schema_pw_field`</td>
350
+ <td>setup</td>
351
+ <td>‘schema_pw_field(:password)`</td>
352
+ <td>Whitelist a password param (checks ‘:set_password`).</td>
353
+ </tr>
354
+ <tr>
355
+ <td>‘schema_line`</td>
356
+ <td>setup</td>
357
+ <td>‘schema_line { str? :foo }`</td>
358
+ <td>Add a raw Schemacop3 line (nested attrs, custom shapes) → [patterns §5](/doc/guide/patterns.md#5-custom-form–schemacop-kept-in-sync).</td>
359
+ </tr>
360
+ <tr>
361
+ <td>‘schema`</td>
362
+ <td>setup</td>
363
+ <td>‘schema(:wrapper_key) { … }`</td>
364
+ <td>Replace the whole schema + wrapper key (fully manual).</td>
365
+ </tr>
366
+ <tr>
367
+ <td>‘form_params`</td>
368
+ <td>setup</td>
369
+ <td>‘form_params(**opts)`</td>
370
+ <td>Extra kwargs passed to ‘simple_form_for`.</td>
371
+ </tr>
372
+ <tr>
373
+ <td>‘disable!`</td>
374
+ <td>setup</td>
375
+ <td>‘disable!`</td>
376
+ <td>Render all inputs disabled.</td>
377
+ </tr>
378
+ <tr>
379
+ <td>‘skip_autofocus`</td>
380
+ <td>setup</td>
381
+ <td>‘skip_autofocus`</td>
382
+ <td>Don’t autofocus the first field.</td>
383
+ </tr>
384
+ </tbody>
385
+ </table>
386
+
387
+ <p>WithForm / New / Edit wiring (in the New/Edit component’s <code>setup</code>):</p>
388
+
389
+ <table role="table">
390
+ <thead>
391
+ <tr>
392
+ <th>Method</th>
393
+ <th>Signature</th>
394
+ <th>Description</th>
395
+ </tr>
396
+ </thead>
397
+ <tbody>
398
+ <tr>
399
+ <td>‘submit_verb`</td>
400
+ <td>‘submit_verb(:patch)`</td>
401
+ <td>HTTP verb the form submits with (‘:post` for New, `:patch` for Edit).</td>
402
+ </tr>
403
+ <tr>
404
+ <td>‘form_comp_class`</td>
405
+ <td>‘form_comp_class(Components::X::MyForm)`</td>
406
+ <td>Use a custom Form component instead of ‘Components::&lt;Family&gt;::Form`. Non-obvious uses: non-default form → [patterns §5](/doc/guide/patterns.md#5-custom-form–schemacop-kept-in-sync); token-gated signup → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links).</td>
407
+ </tr>
408
+ <tr>
409
+ <td>‘form_cancancan_action`</td>
410
+ <td>‘form_cancancan_action(:edit)`</td>
411
+ <td>CanCanCan action used for per-field ‘permitted_attributes`. Pass `nil` to disable per-field auth (e.g. token-gated forms → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links)).</td>
412
+ </tr>
413
+ <tr>
414
+ <td>‘submit_path`</td>
415
+ <td>‘submit_path { Compony.path(…) }`</td>
416
+ <td>Override where the form POSTs/PATCHes to. Non-obvious use: carry a token through submit → [patterns §18](/doc/guide/patterns.md#18-signed-token-capability-links-auth-less-onboarding–magic-links).</td>
417
+ </tr>
418
+ <tr>
419
+ <td>‘on_created` / `on_updated`</td>
420
+ <td>‘on_created { … }`</td>
421
+ <td>Post-save, pre-respond hook (success).</td>
422
+ </tr>
423
+ <tr>
424
+ <td>‘on_created_respond` / `on_updated_respond`</td>
425
+ <td>‘… { … }`</td>
426
+ <td>Override the success response (default: flash + redirect).</td>
427
+ </tr>
428
+ <tr>
429
+ <td>‘on_created_redirect_path` / `on_updated_redirect_path`</td>
430
+ <td>‘… { path }`</td>
431
+ <td>Override the success redirect target. Non-obvious use: chain wizard steps → [patterns §16](/doc/guide/patterns.md#16-multi-step-wizard-across-components).</td>
432
+ </tr>
433
+ <tr>
434
+ <td>‘on_create_failed_respond` / `on_update_failed`</td>
435
+ <td>‘… { … }`</td>
436
+ <td>Override the validation-failure response.</td>
437
+ </tr>
438
+ <tr>
439
+ <td>‘on_destroyed` / `on_destroyed_respond` / `on_destroyed_redirect_path`</td>
440
+ <td>‘… { … }`</td>
441
+ <td>Destroy component equivalents.</td>
442
+ </tr>
443
+ </tbody>
444
+ </table>
445
+
446
+ <h2 id="label-List+-2F+Index+component+DSL">List / Index component DSL</h2>
447
+
448
+ <p><code>Compony::Components::List</code> (nest in Index or owner Show); <code>Compony::Components::Index</code>.</p>
449
+
450
+ <table role="table">
451
+ <thead>
452
+ <tr>
453
+ <th>Method</th>
454
+ <th>Context</th>
455
+ <th>Signature</th>
456
+ <th>Description</th>
457
+ </tr>
458
+ </thead>
459
+ <tbody>
460
+ <tr>
461
+ <td>‘column`</td>
462
+ <td>setup</td>
463
+ <td>‘column(:name, label: nil, class: nil, link_opts: {}) { |record| … }`</td>
464
+ <td>Add/define a column; block renders the cell.</td>
465
+ </tr>
466
+ <tr>
467
+ <td>‘columns`</td>
468
+ <td>setup</td>
469
+ <td>‘columns(:a, :b, as_title: false)`</td>
470
+ <td>Add several field-based columns. ‘as_title: true` = card title on mobile.</td>
471
+ </tr>
472
+ <tr>
473
+ <td>‘filter`</td>
474
+ <td>setup</td>
475
+ <td>‘filter(:name, label: nil) { |f| … }`</td>
476
+ <td>Add/define a filter; block customizes the input.</td>
477
+ </tr>
478
+ <tr>
479
+ <td>‘filters`</td>
480
+ <td>setup</td>
481
+ <td>‘filters(:a, :b)`</td>
482
+ <td>Add several filters.</td>
483
+ </tr>
484
+ <tr>
485
+ <td>‘sort`</td>
486
+ <td>setup</td>
487
+ <td>‘sort(:name, label: nil)`</td>
488
+ <td>Add a sort option.</td>
489
+ </tr>
490
+ <tr>
491
+ <td>‘sorts`</td>
492
+ <td>setup</td>
493
+ <td>‘sorts(:a, :b)`</td>
494
+ <td>Add several sort options.</td>
495
+ </tr>
496
+ <tr>
497
+ <td>‘default_sorting`</td>
498
+ <td>setup</td>
499
+ <td>‘default_sorting(’id desc’)‘</td>
500
+ <td>Default Ransack sort string.</td>
501
+ </tr>
502
+ <tr>
503
+ <td>‘row_intents`</td>
504
+ <td>setup</td>
505
+ <td>‘row_intents(**opts) { add/remove }`</td>
506
+ <td>Per-row action buttons (intent DSL) → [patterns §4](/doc/guide/patterns.md#4-list-customization).</td>
507
+ </tr>
508
+ <tr>
509
+ <td>‘pagination`</td>
510
+ <td>setup</td>
511
+ <td>‘pagination(false)`</td>
512
+ <td>Enable/disable pagination (caution: loads all rows).</td>
513
+ </tr>
514
+ <tr>
515
+ <td>‘results_per_page`</td>
516
+ <td>setup</td>
517
+ <td>‘results_per_page(20)`</td>
518
+ <td>Rows per page when paginating.</td>
519
+ </tr>
520
+ <tr>
521
+ <td>‘filtering`</td>
522
+ <td>setup</td>
523
+ <td>‘filtering(false)`</td>
524
+ <td>Enable/disable filtering entirely.</td>
525
+ </tr>
526
+ <tr>
527
+ <td>‘sorting`</td>
528
+ <td>setup</td>
529
+ <td>‘sorting(false)`</td>
530
+ <td>Enable/disable both sorting links and in-filter sorting.</td>
531
+ </tr>
532
+ <tr>
533
+ <td>‘sorting_in_filter` / `sorting_links`</td>
534
+ <td>setup</td>
535
+ <td>‘sorting_links(false)`</td>
536
+ <td>Toggle one sorting UI independently.</td>
537
+ </tr>
538
+ <tr>
539
+ <td>‘filter_label_class` / `filter_input_class` / `filter_select_class`</td>
540
+ <td>setup</td>
541
+ <td>‘filter_input_class(’…‘)`</td>
542
+ <td>CSS classes for filter form elements.</td>
543
+ </tr>
544
+ <tr>
545
+ <td>‘skip_column`</td>
546
+ <td>setup</td>
547
+ <td>‘skip_column(:name)`</td>
548
+ <td>Remove an inherited column (Show/List).</td>
549
+ </tr>
550
+ </tbody>
551
+ </table>
552
+
553
+ <p>Many of these also accept <code>skip_*</code> kwargs on the constructor when the List is nested via <code>render_sub_comp</code> (e.g. <code>render_sub_comp(:list, coll, skip_pagination: true)</code>).</p>
554
+
555
+ <h2 id="label-Model+mixin+-28in+your+ApplicationRecord+models-29">Model mixin (in your <code>ApplicationRecord</code> models)</h2>
556
+
557
+ <table role="table">
558
+ <thead>
559
+ <tr>
560
+ <th>Method</th>
561
+ <th>Context</th>
562
+ <th>Signature</th>
563
+ <th>Description</th>
564
+ </tr>
565
+ </thead>
566
+ <tbody>
567
+ <tr>
568
+ <td>‘field`</td>
569
+ <td>model (class)</td>
570
+ <td>‘field(:name, :type, multilang: false, **attrs)`</td>
571
+ <td>Declare a UI-relevant attribute + its type/formatting.</td>
572
+ </tr>
573
+ <tr>
574
+ <td>‘prevent`</td>
575
+ <td>model (class)</td>
576
+ <td>‘prevent(:destroy, ’msg’) { condition }‘</td>
577
+ <td>Feasibility: block returns truthy → action prevented (buttons disabled).</td>
578
+ </tr>
579
+ <tr>
580
+ <td>‘owned_by`</td>
581
+ <td>model (class)</td>
582
+ <td>‘owned_by(:invoice)`</td>
583
+ <td>Mark this model as owned by another; adjusts redirects/top actions.</td>
584
+ </tr>
585
+ <tr>
586
+ <td>‘skip_autodetect_feasibilities`</td>
587
+ <td>model (class)</td>
588
+ <td>‘skip_autodetect_feasibilities`</td>
589
+ <td>Don’t auto-derive ‘:destroy` preventions from `dependent:` associations.</td>
590
+ </tr>
591
+ <tr>
592
+ <td>‘feasible?`</td>
593
+ <td>model (instance)</td>
594
+ <td>‘record.feasible?(:destroy)`</td>
595
+ <td>True if no prevention blocks the action.</td>
596
+ </tr>
597
+ <tr>
598
+ <td>‘feasibility_messages`</td>
599
+ <td>model (instance)</td>
600
+ <td>‘record.feasibility_messages(:destroy)`</td>
601
+ <td>Array of reasons (like ‘errors`).</td>
602
+ </tr>
603
+ <tr>
604
+ <td>‘full_feasibility_messages`</td>
605
+ <td>model (instance)</td>
606
+ <td>‘record.full_feasibility_messages(:destroy)`</td>
607
+ <td>Joined human string (like ‘full_messages`).</td>
608
+ </tr>
609
+ </tbody>
610
+ </table>
611
+
612
+ <p><code>label</code> is not a DSL method but <strong>every Compony model must implement <code>def label</code></strong> (or have a <code>label</code> column) — used for titles and link text.</p>
613
+
614
+ <h2 id="label-Intent+-2F+navigation+helpers">Intent / navigation helpers</h2>
615
+
616
+ <p>Used from <code>content</code> blocks or controllers — see <a href="/doc/guide/intents_md.html">intents.md</a>.</p>
617
+
618
+ <table role="table">
619
+ <thead>
620
+ <tr>
621
+ <th>Method</th>
622
+ <th>Context</th>
623
+ <th>Signature</th>
624
+ <th>Description</th>
625
+ </tr>
626
+ </thead>
627
+ <tbody>
628
+ <tr>
629
+ <td>‘Compony.intent`</td>
630
+ <td>anywhere</td>
631
+ <td>‘Compony.intent(:show, model, **opts)`</td>
632
+ <td>Build an ‘Intent`.</td>
633
+ </tr>
634
+ <tr>
635
+ <td>‘Compony.path`</td>
636
+ <td>anywhere</td>
637
+ <td>‘Compony.path(:index, :users, **opts)`</td>
638
+ <td>Rails path string (redirects).</td>
639
+ </tr>
640
+ <tr>
641
+ <td>‘render_intent`</td>
642
+ <td>content</td>
643
+ <td>‘render_intent(:edit, model, style:, label:, button:)`</td>
644
+ <td>Render a link/button to a component. Wrap in ‘concat`.</td>
645
+ </tr>
646
+ <tr>
647
+ <td>‘render_sub_comp`</td>
648
+ <td>content</td>
649
+ <td>‘render_sub_comp(:list, @data.quotes, **opts)`</td>
650
+ <td>Instantiate + nest another component. Wrap in ‘concat`.</td>
651
+ </tr>
652
+ <tr>
653
+ <td>‘Compony.comp_class_for`</td>
654
+ <td>anywhere</td>
655
+ <td>‘Compony.comp_class_for(:show, family)`</td>
656
+ <td>Comp class or ‘nil`.</td>
657
+ </tr>
658
+ </tbody>
659
+ </table>
660
+
661
+ <p><a href="/README_md.html#guide--documentation">Guide index</a></p>
662
+ </div></div>
663
+
664
+ <div id="footer">
665
+ Generated on Mon May 18 13:55:34 2026 by
666
+ <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
667
+ 0.9.34 (ruby-3.3.5).
668
+ </div>
669
+
670
+ </div>
671
+ </body>
672
+ </html>