slotify 0.0.1.alpha.0 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b774ed1d3d704f77cbeebc55d117488eb70f52c1a00527dda727d6cb9100d72
4
- data.tar.gz: b8c6ce6b033715c768315671e6d3547925943825a100f5ea67e11d7df7b81ba6
3
+ metadata.gz: c0623930b397a09cafd4f47da222d46595e013da9987ee1491be5c501689e095
4
+ data.tar.gz: 29f4f8d8427932b1bf85ed6205262e2dbe8196281951bec74042b2f35967928c
5
5
  SHA512:
6
- metadata.gz: ad4a579d74c471684a40b0d60cd8362325cb529d13a362c73d23f5aa67f7383d8d4c9853ebe3e9e4120a31126c4a0069688c924a38ceb8ae0d857e0ba3935b59
7
- data.tar.gz: c64f9c44d9880d0488acac9bcc0a4882780b1517024ac86c3b73177f287817bf70ea52d036b74516c0e3f7a4681453acdfccda46b1d9b98ca80f011a09857ebf
6
+ metadata.gz: b14613a0d5522daf91565b60860c24df657a67807751034aab3a91d70888edeb0bcf381120e958fd42d9cf04290cc7b65964b913ea6a66339d6e375922109608
7
+ data.tar.gz: 754d99784a31195603eaa9a4c9e91dc4cf4575e7987f181163ff6062251cfe50c7af5ff75f2133f552d7b57aaedc327e43c5d0fe74253964528503ea7fa54404
data/README.md CHANGED
@@ -1,36 +1,39 @@
1
1
  <img src=".github/assets/slotify_wordmark.svg" width="200">
2
2
 
3
- #### Superpowered slots for ActionView partials
3
+ <p><a href="https://rubygems.org/gems/slotify"><img src="https://img.shields.io/gem/v/slotify" alt="Gem version"></a>
4
+ <a href="https://github.com/allmarkedup/slotify/actions/workflows/ci.yml"><img src="https://github.com/allmarkedup/slotify/actions/workflows/ci.yml/badge.svg" alt="CI status"></a></p>
4
5
 
5
- ----------
6
+ ## Superpowered slots for ActionView partials
6
7
 
7
- ## Overview
8
-
9
- Slotify adds an unobtrusive but powerful **content slot API** to ActionView partials.
8
+ Slotify adds an unobtrusive (but powerful!) **content slot API** to ActionView partials.
10
9
 
11
10
  Slots are a convenient way to pass blocks of content in to a partial without having to resort to ugly `<% capture do ... end %>` workarounds or unscoped (global) `<% content_for :foo %>` declarations.
12
11
 
13
- Slotified partials are **a great tool for building components** in a Rails app if you want to stay close to _The Rails Way™️_ or just want to avoid the additional overhead and learning curve of libraries like [ViewComponent](https://viewcomponent.org/) or [Phlex](https://www.phlex.fun/).
12
+ Slotified partials are a great way to build components in a Rails app without the additional overhead and learning curve of libraries like [ViewComponent](https://viewcomponent.org/) or [Phlex](https://www.phlex.fun/).
13
+
14
+ > [!CAUTION]
15
+ > Slotify is still in a early stage of development.
16
+ The documentation is still quite sparse and the API could change at any point prior to a `v1.0` release.
14
17
 
15
18
  ###
16
19
 
17
20
  ## Slotify basics
18
21
 
19
- Slotify slots are defined using a [strict locals](https://guides.rubyonrails.org/action_view_overview.html#strict-locals)-style magic comment at the top of partial templates ([more details here](#defining-slots)).
22
+ Slotify slots are defined using a **[strict locals](https://guides.rubyonrails.org/action_view_overview.html#strict-locals)-style magic comment** at the top of **partial templates** ([more details here](#defining-slots)).
20
23
 
21
24
  ```erb
22
- <%# slots: (slot_name: "default value", optional_slot_name: nil, required_slot_name:) -%>
25
+ <%# slots: (title:, body: nil, theme: "default") -%>
23
26
  ```
24
27
 
25
- Slot content is accessed via standard local variables within the partial. So a simple slot-enabled `article` partial template might look something like this:
28
+ Slot content is accessed via **standard local variables** within the partial. So a simple, slot-enabled `article` partial template might look something like this:
26
29
 
27
30
  ```erb
28
31
  <!-- _article.html.erb -->
29
32
 
30
- <%# slots: (heading: "Default title", body: nil) -%>
33
+ <%# slots: (title: "Default title", body: nil) -%>
31
34
 
32
35
  <article>
33
- <h1><%= heading %></h1>
36
+ <h1><%= title %></h1>
34
37
  <% if body.present? %>
35
38
  <div>
36
39
  <%= body %>
@@ -40,17 +43,15 @@ Slot content is accessed via standard local variables within the partial. So a s
40
43
  ```
41
44
 
42
45
  > [!NOTE]
43
- > _The above code should feel familiar if you have used partials in the past. This is just regular partial syntax but with `slots` defined instead of `locals` (don't worry - you can still define locals too!)._
46
+ > _The above should feel familiar to anyone who has partials (and strict locals) in the past. This is just regular partial syntax but with `slots` defined instead of `locals` (don't worry - you can still define locals too!)._
44
47
 
45
- When the partial is rendered, a special `partial` object is yielded as an argument to the block. Slot content is set by calling the appropriate `.with_<slot_name>` methods on this partial object.
48
+ When the partial is rendered, a special `partial` object is yielded as an argument to the block. Slot content is set by calling the appropriate `#with_<slot_name>` methods on this partial object.
46
49
 
47
- For example, here our `article` partial is being rendered with content for the `heading` and `body` slots that were defined above:
50
+ For example, here our `article` partial is being rendered with content for the `title` and `body` slots that were defined above:
48
51
 
49
52
  ```erb
50
- <!-- index.html.erb -->
51
-
52
53
  <%= render "article" do |partial| %>
53
- <% partial.with_heading "This is a title" %>
54
+ <% partial.with_title "This is a title" %>
54
55
  <% partial.with_body do %>
55
56
  <p>You can use <%= tag.strong "markup" %> within slot content blocks without
56
57
  having to worry about marking the output as <code>html_safe</code> later.</p>
@@ -61,82 +62,10 @@ For example, here our `article` partial is being rendered with content for the `
61
62
  > [!NOTE]
62
63
  > _If you've ever used [ViewComponent](https://viewcomponent.org) then the above code should also feel quite familiar to you - it's pretty much the same syntax used to provide content to [component slots](https://viewcomponent.org/guide/slots.html)._
63
64
 
64
- The example above just scratches the surface of what Slotify slots can do.
65
-
66
- You can [jump to a more full-featured example here](#full-example) or read on to learn more...
67
-
68
- ## Single vs multiple value slots
69
-
70
- > _Docs coming soon..._
71
-
72
- ## Slot arguments and options
73
-
74
- > _Docs coming soon..._
75
-
76
- ## Using helpers with slots
77
-
78
- > _Docs coming soon..._
79
-
80
- ## Rendering slot contents
81
-
82
- > _Docs coming soon..._
83
-
84
- <a name="defining-slots" id="defining-slots"></a>
85
- ## Defining slots
65
+ But this example just scratches the surface of what Slotify slots can do. Have a look at the more full-featured example below or jump to [the usage information](#usage).
86
66
 
87
- Slots are defined using a [strict locals](https://guides.rubyonrails.org/action_view_overview.html#strict-locals)-style magic comment at the top of the partial template. The `slots:` signature uses the same syntax as standard Ruby method signatures.
88
-
89
- > _Docs coming soon..._
90
-
91
- ### Required slots
92
-
93
- > _Docs coming soon..._
94
-
95
- ### Optional slots
96
-
97
- > _Docs coming soon..._
98
-
99
- ### Setting default values
100
-
101
- > _Docs coming soon..._
102
-
103
- ### Using alongside strict locals
104
-
105
- > _Docs coming soon..._
106
-
107
- ## Slotify API
108
-
109
- > _Docs coming soon..._
110
-
111
- ## Installation
112
-
113
- Add the following to your Rails app Gemfile:
114
-
115
- ```rb
116
- gem "slotify"
117
- ```
118
-
119
- And then run `bundle install`. You are good to go!
120
-
121
- ## Requirements
122
-
123
- * `Rails 7.1+`
124
- * `Ruby 3.1+`
125
-
126
- ## Credits
127
-
128
- Slotify was inspired by the excellent [nice_partials gem](https://github.com/bullet-train-co/nice_partials) as well as ViewComponent's [slots implementation](https://viewcomponent.org/guide/slots.html).
129
-
130
- `nice_partials` provides very similar functionality to Slotify but takes a slightly different approach/style. So if you are not convinced by Slotify then definitely [check it out](https://github.com/bullet-train-co/nice_partials)!
131
-
132
- <br>
133
-
134
- ---
135
-
136
- <br>
137
- <a name="full-example" id="full-example"></a>
138
-
139
- ## A more full-featured example
67
+ <details>
68
+ <summary><h4>More full-featured example</h4></summary>
140
69
 
141
70
  ```erb
142
71
  <!-- views/_example.html.erb -->
@@ -149,7 +78,7 @@ Slotify was inspired by the excellent [nice_partials gem](https://github.com/bul
149
78
  <%= title %>
150
79
  </h1>
151
80
 
152
- <p>Example link: <%= partial.link_to website_link, data: {controller: "external-link"} %></p>
81
+ <p>Example link: <%= link_to website_link, data: {controller: "external-link"} %></p>
153
82
 
154
83
  <%= render lists, title: "Default title" %>
155
84
 
@@ -175,7 +104,7 @@ Slotify was inspired by the excellent [nice_partials gem](https://github.com/bul
175
104
 
176
105
  <% if items.any? %>
177
106
  <%= tag.ul class: "list" do %>
178
- <%= partial.li items, class: "list-item" %>
107
+ <%= content_tag :li, items, class: "list-item" %>
179
108
  <% end %>
180
109
  <% end %>
181
110
  ```
@@ -206,4 +135,427 @@ Slotify was inspired by the excellent [nice_partials gem](https://github.com/bul
206
135
  <% end %>
207
136
  ```
208
137
 
138
+ </details>
139
+
140
+ ---
141
+
142
+ ## Usage
143
+
144
+ <a name="defining-slots" id="defining-slots"></a>
145
+ ### Defining slots
146
+
147
+ Slots are defined using a [strict locals](https://guides.rubyonrails.org/action_view_overview.html#strict-locals)-style magic comment at the top of the partial template. The `slots:` signature uses the same syntax as standard Ruby method signatures:
148
+
149
+ ```erb
150
+ <%# slots: (title:, body: "No content available", author: nil) -%>
151
+ ```
152
+
153
+ #### Required slots
154
+
155
+ Required slots are defined without a default value.
156
+ If no content is provided for a required slot then a `StrictSlotsError` exception will be raised.
157
+
158
+ ```erb
159
+ <!-- _required.html.erb -->
160
+
161
+ <%# slots: (title:) -%>
162
+ <h1><%= title %></h1>
163
+ ```
164
+
165
+ ```erb
166
+ <%= render "required" do |partial| %>
167
+ <!-- ❌ raises an error, no content set for the `title` slot -->
168
+ <% end %>
169
+ ```
170
+
171
+ #### Optional slots
172
+
173
+ If a default value is set then the slot becomes _optional_. If no content is provided when rendering the partial then
174
+ the default value will be used instead.
175
+
176
+ ```erb
177
+ <%# slots: (title: "Default title", author: nil) -%>
178
+ ```
179
+
180
+ ### Using alongside strict locals
181
+
182
+ Strict locals can be defined in 'slotified' partial templates in the same way as usual,
183
+ either above or below the `slots` definition.
184
+
185
+ ```erb
186
+ <!-- _article.html.erb -->
187
+
188
+ <%# locals: (title:) -%>
189
+ <%# slots: (body: "No content available") -%>
190
+
191
+ <article>
192
+ <h1><%= title %></h1>
193
+ <div><%= body %></div>
194
+ </article>
195
+ ```
196
+
197
+ Locals are provided when rendering the partial in the usual way.
198
+
199
+ ```erb
200
+ <%= render "article", title: "Article title here" do |partial| %>
201
+ <% partial.with_body do %>
202
+ <p>Body content here...</p>
203
+ <% end %>
204
+ <% end %>
205
+ ```
206
+
207
+ ### Setting slot values
208
+
209
+ Content is passed into slots using dynamically generated `partial#with_<slot_name>` writer methods.
210
+
211
+ Content can be provided as either the **first argument** or **as a block** when calling these methods at render time.
212
+ The following two examples are equivalent:
213
+
214
+ ```erb
215
+ <%= render "example" do |partial| %>
216
+ <% partial.with_title "Title passed as argument" %>
217
+ <% end %>
218
+ ```
219
+
220
+ ```erb
221
+ <%= render "example" do |partial| %>
222
+ <% partial.with_title do %>
223
+ Title passed as block content
224
+ <% end %>
225
+ <% end %>
226
+ ```
227
+
228
+ > [!TIP]
229
+ > Block content is generally better suited for longer-form content containing HTML tags because it will not need to be marked
230
+ as `html_safe` when used in the partial template.
231
+
232
+ The content will be available as a local variable in the partial template whichever way it is provided.
233
+
234
+ ```erb
235
+ <%# slots: (title:) -%>
236
+ <h1><%= title %></h1>
237
+ ```
238
+
239
+ ### Slot options
240
+
241
+ The slot value writer methods also accept optional arbitrary keyword arguments.
242
+ These can then be accessed in the partial template via the `.options` method on the slot variable.
243
+
244
+ ```erb
245
+ <%= render "example" do |partial| %>
246
+ <% partial.with_title "The title", class: "color-hotpink", data: {controller: "fancy-title"} %>
247
+ <% end %>
248
+ ```
249
+
250
+ ```erb
251
+ <%# slots: (title:) -%>
252
+
253
+ <%= title.options.keys %> <!-- [:class, :data] -->
254
+ <%= title %> <!-- The title -->
255
+ ```
256
+
257
+ Slot options can be useful for providing tag attributes when rendering slot content or rendering variants
258
+ of a slot based on an option value.
259
+
260
+ When rendered as a string the options are passed through the Rails `tag.attributes` helper to generate an HTML tag attributes string:
261
+
262
+ ```erb
263
+ <h1 <%= title.options %>><%= title %></h1>
264
+ <!-- <h1 class="color-hotpink" data-controller="fancy-title">The title</h1> -->
265
+ ```
266
+
267
+ ### Slot types
268
+
269
+ There are two types of slots.
270
+
271
+ * **Single-value** slots can only be called **once** and return **a single value**.
272
+ * **Multiple-value** slots can be called **many times** and return **an array of values**.
273
+
274
+ #### Single-value slots
275
+
276
+ Single-value slots are defined using a **singlular** slot name:
277
+
278
+ ```erb
279
+ <%# slots: (item: nil) -%>
280
+ ```
281
+
282
+ Single-value slots can be called once (at most)
283
+ and their corresponding template variable represents a single value:
284
+
285
+ ```erb
286
+ <%= render "example" do |partial| %>
287
+ <% partial.with_item "Item one" %>
288
+ <% end %>
289
+ ```
290
+
291
+ ```erb
292
+ <%# slots: (item: nil) -%>
293
+ <div>
294
+ <%= item %> <!-- "Item one" -->
295
+ </div>
296
+ ```
297
+
298
+ > [!WARNING]
299
+ > Calling a single-value slot more than once when rendering a partial will raise an error:
300
+ >
301
+ > ```erb
302
+ > <%= render "example" do |partial| %>
303
+ > <% partial.with_item "Item one" %>
304
+ > <% partial.with_item "Item two" %> # ❌ raises an error!
305
+ > <% end %>
306
+ > ```
307
+
308
+ #### Multiple-value slots
309
+
310
+ Multiple-value slots are defined using a **plural** slot name:
311
+
312
+ ```erb
313
+ <%# slots: (items: nil) -%>
314
+ ```
315
+
316
+ Multiple-value slots can be called as many times as needed
317
+ and their corresponding template variable represents an array of values.
318
+
319
+ The slot writer methods for multiple-value slots use the **singluar form** of the slot name (e.g. `#with_item` for the `items` slot).
320
+
321
+ ```erb
322
+ <%= render "example" do |partial| %>
323
+ <% partial.with_item "Item one" %>
324
+ <% partial.with_item "Item two" %>
325
+ <% partial.with_item "Item three" %>
326
+ <% end %>
327
+ ```
328
+
329
+ ```erb
330
+ <%# slots: (items: nil) -%>
331
+
332
+ <%= items %> <!-- ["Item one", "Item two", "Item three"] -->
333
+
334
+ <ul>
335
+ <% items.each do |item| %>
336
+ <li>
337
+ <% item %>
338
+ </li>
339
+ <% end %>
340
+ </ul>
341
+ ```
342
+
343
+ ### Using slots with helpers
344
+
345
+ > _Docs coming soon..._
346
+
347
+ ```erb
348
+ <% partial.with_title "The title", class: "color-hotpink" %>
349
+ <% partial.with_website_link "Example website", "https://example.com", data: {controller: "external-link"} %>
350
+
351
+ <% partial.with_item "Item one" %>
352
+ <% partial.with_item "Item two", class: "highlight" %>
353
+ ```
354
+
355
+ ```erb
356
+ <%= content_tag :h1, title %> <!-- <h1 class="color-hotpink">The title</h1> -->
357
+ <%= content_tag :h1, title, class: "example-title" %> <!-- <h1 class="example-title color-hotpink">The title</h1> -->
358
+
359
+ <%= link_to website_link %> <!-- <a href="https://example.com" data-controller="external-link">Example website</a> -->
360
+
361
+ <%= content_tag :li, items %> <!-- <li>Item one</li><li class="highlight">Item two</li> -->
362
+ <%= content_tag :li, items, class: "item" %> <!-- <li class="item">Item one</li><li class="item highlight">Item two</li> -->
363
+ ```
364
+
365
+ ### Rendering slots
366
+
367
+ > _Docs coming soon..._
368
+
369
+ ### Slot values API
370
+
371
+ **Singlular slot value variables** in partial templates are actually instances of `Slotity::Value`.
372
+ These value objects are automatically stringified so in most cases you will not even be aware of this and they can just be treated as regular string variables.
373
+
374
+
375
+
376
+ ```erb
377
+ <%= render "example" do |partial| %>
378
+ <% partial.with_title class: "color-hotpink" do %>
379
+ The title
380
+ <% end %>
381
+ <% end %>
382
+ ```
383
+
384
+ ```erb
385
+ <% title.is_a?(Slotify::Value) %> <!-- true -->
386
+ <% items.is_a?(Slotify::ValueCollection) %> <!-- true -->
387
+
388
+ <%= title %> <!-- "The title" -->
389
+ <% title.content %> <!-- "The title" -->
390
+
391
+ <% title.options %> <!-- { class: "color-hotpink" } (hash of any options provided when calling the `.with_title` slot value writer method) -->
392
+ <%= title.options %> <!-- "class='color-hotpink'" (string generated by passing the options hash through the Rails `tag.attributes` helper) -->
393
+ ```
394
+
395
+ **Plural slot value variables** in partial templates are instances of the enumerable `Slotify::ValueCollection` class, with all items instances of `Slotity::Value`.
396
+
397
+ ```erb
398
+ <%= render "example" do |partial| %>
399
+ <% partial.with_item "Item one" %>
400
+ <% partial.with_item "Item two", class: "current" %>
401
+ <% end %>
402
+ ```
403
+
404
+ ```erb
405
+ <% items.is_a?(Slotify::ValueCollection) %> <!-- true -->
209
406
 
407
+ <% items.each do |item| %>
408
+ <li <%= item.options %>><%= item %></li>
409
+ <% end %>
410
+ <!-- <li>Item one</li> <li class="current">Item two</li> -->
411
+
412
+ <%= items %> <!-- "Item one Item two" -->
413
+ ```
414
+
415
+ #### `Slotity::Value`
416
+
417
+ The following methods are available on `Slotity::Value` instances:
418
+
419
+ **`.content`**
420
+
421
+ Returns the slot content string that was provided as the first argument or as the block when calling the slot writer method.
422
+
423
+ **`.options`**
424
+
425
+ Returns a `Slotify::ValueOptions` instance that can be treated like a `Hash`. Calling `.slice` or `.except` on this will return another `Slotify::ValueOptions` instance.
426
+
427
+ When converted to a string either explicitly (via `.to_s`) or implicitly (by outputting the value template using ERB `<%= %>` expression tags) the stringified value is generated by passing the options hash through the Rails `tag.attributes` helper.
428
+
429
+ **`.with_default_options(default_options)`**
430
+
431
+ Merges the options set when calling the slot value writer method with the `default_options` hash provided and returns a new `Slotity::Value` instance with the merged options set.
432
+
433
+ ```erb
434
+ <% title_with_default_opts = title.with_default_options(class: "size-lg", aria: {level: 1}) %> <!-- apply default options -->
435
+
436
+ <% title_with_default_opts.options %> <!-- { class: "size-lg color-hotpink", aria: {level: 1} } -->
437
+ <%= title_with_default_opts.options %> <!-- "class='size-lg color-hotpink' aria-level='1'" -->
438
+ ```
439
+
440
+ ## Slotify vs alternatives
441
+
442
+ #### `nice_partials`
443
+
444
+ Slotify was very much inspired by the [Nice Partials gem](https://github.com/bullet-train-co/nice_partials) and both provide similar functionality.
445
+ However there are a number of key differences:
446
+
447
+ * Slotify requires the explicit definition of slots using 'strict locals'-style comments;
448
+ Nice partials slots are implicitly defined when rendering the partial.
449
+ * Slotify slot values are available as local variables;
450
+ with Nice partials slot values are accessed via methods on the `partial` variable.
451
+ * Slotify has the concept (and enforces the use) of single-value vs. multiple-value slots.
452
+ * Slotify slot content and options are transparently expanded and merged into defaults when using with helpers like `content_tag` and `link_to`.
453
+ * Slotify slot values are `renderable` objects
454
+
455
+ You might choose slotify if you prefer a stricter, 'Rails-native'-feeling slots implementation, and Nice Partials if you want more render-time flexibility and a clearer
456
+ separation of 'nice partial' functionality from ActionView-provided locals etc.
457
+
458
+ #### `view_component`
459
+
460
+ Both [ViewComponent](https://viewcomponent.org/) and Slotify provide a 'slots' API for content blocks.
461
+ Slotify's slot writer syntax (i.e. `.with_<slot_name>` methods) and the concept of single-value (`renders_one`) vs multiple-value (`renders_many`) slots
462
+ are both modelled on ViewComponent's slots implementation.
463
+
464
+ However apart from that they are quite different. Slotify adds functionality to regular ActionView partials whereas ViewComponent provides a complete standalone component system.
465
+
466
+ Each ViewComponent has an associated class which can be used to extract and encapsulate view logic.
467
+ Slotify doesn't have an analagous concept, any view-specific logic will by default live in the partial template (as per standard partial rendering patterns).
468
+
469
+ You might choose Slotify if you want a more 'component-y' API but you don't want the overhead or learning curve associated with a tool that sits somewhat adjacent to the standard Rails way of doing things.
470
+ But if you have components with a lot of view logic or want a more formalised component format then ViewComponent is likely a better fit for your project.
471
+
472
+ ## Installation
473
+
474
+ Add the following to your Rails app Gemfile:
475
+
476
+ ```rb
477
+ gem "slotify"
478
+ ```
479
+
480
+ And then run `bundle install`. You are good to go!
481
+
482
+ ## Requirements
483
+
484
+ * `Rails 7.1+`
485
+ * `Ruby 3.1+`
486
+
487
+ ## Credits
488
+
489
+ Slotify was inspired by the excellent [nice_partials gem](https://github.com/bullet-train-co/nice_partials) as well as ViewComponent's [slots implementation](https://viewcomponent.org/guide/slots.html).
490
+
491
+ `nice_partials` provides very similar functionality to Slotify but takes a slightly different approach/style. So if you are not convinced by Slotify then definitely [check it out](https://github.com/bullet-train-co/nice_partials)!
492
+
493
+ ## Benchmarks
494
+
495
+ Slotify is still in the early stages of development and no attempt has yet been made to optimise rendering performance.
496
+
497
+ Below are some initial (crude) benchmarking comparisons with other similar gems.
498
+
499
+ > [!TIP]
500
+ > Benchmarks can be run using the `bin/benchmarks` command from the repository root.
501
+
502
+ ```
503
+ ✨🦄 ACTION_VIEW 🦄✨
504
+
505
+ ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23]
506
+ Warming up --------------------------------------
507
+ no slots 12.997k i/100ms
508
+ slots 10.891k i/100ms
509
+ Calculating -------------------------------------
510
+ no slots 125.622k (± 5.4%) i/s (7.96 μs/i) - 1.261M in 10.072521s
511
+ slots 108.468k (± 3.3%) i/s (9.22 μs/i) - 1.089M in 10.053026s
512
+
513
+ Comparison:
514
+ no slots: 125621.9 i/s
515
+ slots: 108467.5 i/s - 1.16x slower
516
+
517
+
518
+ ✨🦄 NICE_PARTIALS 🦄✨
519
+
520
+ ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23]
521
+ Warming up --------------------------------------
522
+ no slots 11.822k i/100ms
523
+ slots 4.204k i/100ms
524
+ Calculating -------------------------------------
525
+ no slots 114.190k (± 4.7%) i/s (8.76 μs/i) - 1.147M in 10.069870s
526
+ slots 41.138k (± 4.3%) i/s (24.31 μs/i) - 411.992k in 10.039730s
527
+
528
+ Comparison:
529
+ no slots: 114190.2 i/s
530
+ slots: 41137.9 i/s - 2.78x slower
531
+
532
+
533
+ ✨🦄 VIEW_COMPONENT 🦄✨
534
+
535
+ ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23]
536
+ Warming up --------------------------------------
537
+ no slots 20.329k i/100ms
538
+ slots 7.409k i/100ms
539
+ Calculating -------------------------------------
540
+ no slots 196.288k (± 4.7%) i/s (5.09 μs/i) - 1.972M in 10.073103s
541
+ slots 71.311k (± 5.0%) i/s (14.02 μs/i) - 718.673k in 10.108426s
542
+
543
+ Comparison:
544
+ no slots: 196287.6 i/s
545
+ slots: 71310.5 i/s - 2.75x slower
546
+
547
+
548
+ ✨🦄 SLOTIFY 🦄✨
549
+
550
+ ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23]
551
+ Warming up --------------------------------------
552
+ no slots 10.883k i/100ms
553
+ slots 77.000 i/100ms
554
+ Calculating -------------------------------------
555
+ no slots 110.153k (± 4.8%) i/s (9.08 μs/i) - 1.099M in 10.009002s
556
+ slots 789.118 (± 4.1%) i/s (1.27 ms/i) - 7.931k in 10.071749s
557
+
558
+ Comparison:
559
+ no slots: 110152.8 i/s
560
+ slots: 789.1 i/s - 139.59x slower
561
+ ```
@@ -0,0 +1,18 @@
1
+ module Slotify
2
+ module InflectionHelper
3
+ extend ActiveSupport::Concern
4
+
5
+ def singular?(str)
6
+ str = str.to_s
7
+ str.singularize == str && str.pluralize != str
8
+ end
9
+
10
+ def singularize(sym)
11
+ sym.to_s.singularize.to_sym
12
+ end
13
+
14
+ def plural?(str)
15
+ !singular?(str)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module Slotify
2
+ module SlotCompatability
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def make_compatible_with_slots(*method_names)
7
+ proxy = Module.new
8
+ method_names.each do |name|
9
+ proxy.define_method(name) do |*args, **kwargs, &block|
10
+ return super(*args, **kwargs, &block) if args.none?
11
+
12
+ results = MethodArgsResolver.call(args, kwargs, block) { super(*_1, **_2, &_3) }
13
+ results.reduce(ActiveSupport::SafeBuffer.new) { _1 << _2 }
14
+ end
15
+ end
16
+ prepend proxy
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/slotify/error.rb CHANGED
@@ -2,16 +2,13 @@ module Slotify
2
2
  class UnknownSlotError < NameError
3
3
  end
4
4
 
5
- class MissingRequiredSlotError < ArgumentError
5
+ class SlotsDefinedError < RuntimeError
6
6
  end
7
7
 
8
- class MultipleSlotEntriesError < ArgumentError
9
- end
10
-
11
- class SlotsAccessError < RuntimeError
8
+ class UndefinedSlotError < StandardError
12
9
  end
13
10
 
14
- class UndefinedSlotError < StandardError
11
+ class MultipleSlotEntriesError < ArgumentError
15
12
  end
16
13
 
17
14
  class SlotArgumentError < ArgumentError
@@ -19,4 +16,7 @@ module Slotify
19
16
 
20
17
  class StrictSlotsError < ArgumentError
21
18
  end
19
+
20
+ class ReservedSlotNameError < ArgumentError
21
+ end
22
22
  end