phlex-slotable 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1aa68f30783948c69ae6e3a9018e3e0fe828b8d1e3392208bbd926dead27761
4
- data.tar.gz: f60047a296679c099258024d72e23d13a252bd4f5fd38576769716218785d962
3
+ metadata.gz: '09e928c0d1e4cec5220e01d3e6b06ebc5fef4b50ed8f43bdf3634e89f91d201f'
4
+ data.tar.gz: 726cadd0901159f4cdb083d80300658b44b00da06515946f38fc3701b2ea019b
5
5
  SHA512:
6
- metadata.gz: cf5b19581bab8cb2ba50e91e44f9489b40cbdae7c0873310a98637be51cbac6212e8621a95f67bd8d5d1ad1286533b66023847c4ac4eacbe2a7f867635b2bfaa
7
- data.tar.gz: d1e6a2cb591541105802d4338b857baf99ef5817aacbdd644f5a6ad3e77a4ac60669c8b5f0d9f7bdae63565e05f6fe7cbe6852e29aac88aa31366def63a5ac01
6
+ metadata.gz: 42f10716289705dd92edc63b31637781f490eb02348a6f17911229a5798a31e7a7bc905c990c6b3770cbf5b1bd31110279c509649ac25f16c1b449bc757a4cdf
7
+ data.tar.gz: 9c050854b88de83f4a4edbbf2ea8c05cf34938d89c5bb0a8b9c4a056c84363c93582091afa3b6f2a91f393dffcf262a6f8f81a936d229c4edfff2ad779724533
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2024-02-13
4
+
5
+ - Allow view slots using string as class name
6
+
7
+ *stephannv*
8
+
9
+ - Allow lambda slots
10
+
11
+ *stephannv*
12
+
3
13
  ## [0.1.0] - 2024-02-12
14
+ - Add single and multi slots
15
+
16
+ *stephannv*
17
+
18
+ - Add generic slots
19
+
20
+ *stephannv*
21
+
22
+ - Add view slots
4
23
 
5
- - Initial release
24
+ *stephannv*
data/README.md CHANGED
@@ -1,25 +1,28 @@
1
+ > [!WARNING]
2
+ > Please note that Phlex::Slotable is currently under development and may undergo changes to its API before reaching the stable release (1.0.0). As a result, there may be breaking changes that affect its usage.
3
+
1
4
  # Phlex::Slotable
2
5
 
3
- Phlex::Slotable enables slots feature to Phlex views. Inspired by ViewComponent.
6
+ Phlex::Slotable enables slots feature to [Phlex](https://www.phlex.fun/) views. Inspired by ViewComponent.
4
7
 
5
8
  ## Installation
6
9
 
7
10
  Install the gem and add to the application's Gemfile by executing:
8
11
 
9
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
12
+ $ bundle add phlex-slotable
10
13
 
11
14
  If bundler is not being used to manage dependencies, install the gem by executing:
12
15
 
13
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
16
+ $ gem install phlex-slotable
14
17
 
15
18
  ## Usage
16
19
 
17
20
  #### Basic
18
21
 
19
- Include `Phlex::Slotable` to your Phlex view and use `slot` class method to define slots.
22
+ To incorportate slots into your Phlex views, include `Phlex::Slotable` and utilize `slot` class method to define them.
20
23
 
21
- - `slot :slot_name` defines a single slot that will be rendered at most once per component
22
- - `slot :slot_name, many: true` defines a slot that can be rendered multiple times per component
24
+ - `slot :slot_name` declaration establishes a single slot intended for rendering once within a view
25
+ - `slot :slot_name, many: true` denotes a slot capable of being rendered multiple times within a view
23
26
 
24
27
  ```ruby
25
28
  class BlogComponent < Phlex::HTML
@@ -32,9 +35,9 @@ class BlogComponent < Phlex::HTML
32
35
  end
33
36
  ```
34
37
 
35
- To render a single slot, render `{slot_name}_slot`, eg. `render header_slot`.
38
+ To render a single slot, utilize the `{slot_name}_slot` method. For example, you can render the `header_slot` using `render header_slot`.
36
39
 
37
- To render a multi slot, iterate over `{slot_name}_slots` and render each element, eg. `post_slots.each { |s| render s }`
40
+ For multi-slot rendering, iterate over the `{slot_name}_slots` collection and and render each slot individually, eg. `post_slots.each { |s| render s }`.
38
41
 
39
42
  ```ruby
40
43
  class BlogComponent < Phlex::HTML
@@ -44,11 +47,11 @@ class BlogComponent < Phlex::HTML
44
47
  slot :post, many: true
45
48
 
46
49
  def template
47
- div id: "header" do
50
+ div id: "header" do
48
51
  render header_slot
49
52
  end
50
53
 
51
- div id: "main" do
54
+ div id: "main" do
52
55
  post_slots.each do |slot|
53
56
  p { render slot }
54
57
  end
@@ -59,7 +62,7 @@ class BlogComponent < Phlex::HTML
59
62
  end
60
63
  ```
61
64
 
62
- To set slot content, you need to use `with_{slot_name}` when rendering the view:
65
+ When setting slot content, ensure to utilize the `with_{slot_name}` method while rendering the view:
63
66
 
64
67
  ```ruby
65
68
  class MyPage < Phlex::HTML
@@ -96,7 +99,7 @@ This will output:
96
99
 
97
100
  #### Predicate methods
98
101
 
99
- You can check if a slot has been passed to the component using `{slot_name}_slot?` when it is a single slot, or `{slot_name}_slots?` when it is a multi slot.
102
+ You can verify whether a slot has been provided to the view using `{slot_name}_slot?` for single slots or `{slot_name}_slots?` when for multi-slots.
100
103
 
101
104
  ```ruby
102
105
  class BlogComponent < Phlex::HTML
@@ -106,13 +109,13 @@ class BlogComponent < Phlex::HTML
106
109
  slot :post, many: true
107
110
 
108
111
  def template
109
- if header_slot?
112
+ if header_slot?
110
113
  div id: "header" do
111
114
  render header_slot
112
115
  end
113
116
  end
114
117
 
115
- div id: "main" do
118
+ div id: "main" do
116
119
  if post_slots?
117
120
  post_slots.each do |slot|
118
121
  p { render slot }
@@ -129,11 +132,11 @@ end
129
132
 
130
133
  #### View slot
131
134
 
132
- Slots can render other views, you just need to pass the view class name to `slot` method.
135
+ Slots have the capability to render other views, Simply pass the view class name to the `slot` method.
133
136
 
134
137
  ```ruby
135
138
  class HeaderComponent < Phlex::HTML
136
- def initialize(size:)
139
+ def initialize(size:)
137
140
  @size = size
138
141
  end
139
142
 
@@ -143,7 +146,7 @@ class HeaderComponent < Phlex::HTML
143
146
  end
144
147
 
145
148
  class PostComponent < Phlex::HTML
146
- def initialize(featured:)
149
+ def initialize(featured:)
147
150
  @featured = featured
148
151
  end
149
152
 
@@ -159,13 +162,13 @@ class BlogComponent < Phlex::HTML
159
162
  slot :post, PostComponent, many: true
160
163
 
161
164
  def template
162
- if header_slot?
165
+ if header_slot?
163
166
  div id: "header" do
164
167
  render header_slot
165
168
  end
166
169
  end
167
170
 
168
- div id: "main" do
171
+ div id: "main" do
169
172
  if post_slots?
170
173
  post_slots.each { render slot }
171
174
 
@@ -207,11 +210,73 @@ The output:
207
210
  </div>
208
211
  ```
209
212
 
210
- ## Roadmap
213
+ You can pass the class name as a string for cases where the class isn't evaluated yet, such as with inner classes. For example:
214
+ ```ruby
215
+ class BlogComponent < Phlex::HTML
216
+ include Phlex::Slotable
217
+
218
+ # This will not work
219
+ slot :header, HeaderComponent # uninitialized constant BlogComponent::HeaderComponent
220
+ # You should do this
221
+ slot :header, "HeaderComponent"
222
+
223
+ private
224
+
225
+ class HeaderComponent < Phlex::HTML
226
+ # ...
227
+ end
228
+ end
229
+ ```
230
+
231
+ #### Lambda slots
232
+ Lambda slots are valuable when you prefer not to create another component for straightforward structures or when you need to render another view with specific parameters
233
+ ```ruby
234
+
235
+ class BlogComponent < Phlex::HTML
236
+ include Phlex::Slotable
237
+
238
+ slot :header, ->(size:, &content) { render HeaderComponent.new(size: size, color: "blue"), &content }
239
+ slot :post, ->(featured:, &content) { span(class: featured ? "featured" : nil, &content) }, many: true
240
+ end
241
+
242
+ class MyPage < Phlex::HTML
243
+ def template
244
+ render BlogComponent.new do |blog|
245
+ blog.with_header(size: :lg) { "Hello World!" }
246
+
247
+ blog.with_post(featured: true) { "Post A" }
248
+ blog.with_post { "Post B" }
249
+ blog.with_post { "Post C" }
250
+ end
251
+ end
252
+ end
253
+ ```
254
+
255
+ You can access the internal view state within lambda slots.For example:
256
+ ```ruby
257
+ class BlogComponent < Phlex::HTML
258
+ include Phlex::Slotable
259
+
260
+ slot :header, ->(size:, &content) { render HeaderComponent.new(size: size, color: @header_color), &content }
211
261
 
212
- [] Accepts Strings as view class name
213
- [] Allow lambda slots
214
- [] Allow polymorphic slots
262
+ def initialize(header_color:)
263
+ @header_color = header_color
264
+ end
265
+ end
266
+
267
+ class MyPage < Phlex::HTML
268
+ def template
269
+ render BlogComponent.new(header_color: "red") do |blog|
270
+ blog.with_header(size: :lg) { "Hello World!" }
271
+ end
272
+ end
273
+ end
274
+ ```
275
+
276
+ ## Roadmap
277
+ - ✅ ~~Accept Strings as view class name~~
278
+ - ✅ ~~Allow lambda slots~~
279
+ - 🕐 Allow polymorphic slots
215
280
 
216
281
  ## Development
217
282
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlex
4
4
  module Slotable
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -12,6 +12,11 @@ module Phlex
12
12
  def slot(slot_name, callable = nil, many: false)
13
13
  include Phlex::DeferredRender
14
14
 
15
+ if callable.is_a?(Proc)
16
+ define_method :"__call_#{slot_name}__", &callable
17
+ private :"__call_#{slot_name}__"
18
+ end
19
+
15
20
  if many
16
21
  define_method :"with_#{slot_name}" do |*args, **kwargs, &block|
17
22
  instance_variable_set(:"@#{slot_name}_slots", []) unless instance_variable_defined?(:"@#{slot_name}_slots")
@@ -19,6 +24,10 @@ module Phlex
19
24
  value = case callable
20
25
  when nil
21
26
  block
27
+ when String
28
+ self.class.const_get(callable).new(*args, **kwargs, &block)
29
+ when Proc
30
+ -> { self.class.instance_method(:"__call_#{slot_name}__").bind_call(self, *args, **kwargs, &block) }
22
31
  else
23
32
  callable.new(*args, **kwargs, &block)
24
33
  end
@@ -40,6 +49,10 @@ module Phlex
40
49
  value = case callable
41
50
  when nil
42
51
  block
52
+ when String
53
+ self.class.const_get(callable).new(*args, **kwargs, &block)
54
+ when Proc
55
+ -> { self.class.instance_method(:"__call_#{slot_name}__").bind_call(self, *args, **kwargs, &block) }
43
56
  else
44
57
  callable.new(*args, **kwargs, &block)
45
58
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlex-slotable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - stephann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-12 00:00:00.000000000 Z
11
+ date: 2024-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex