Skip to content

Commit a18e6fe

Browse files
authored
feat: allow component to declare let! parameter (#245)
This allows the user to declare a let parameter for the default slot without manually defining the `slot :inner_lock, let!: foo do` slot in the component body. Closes #239
1 parent 39fceeb commit a18e6fe

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

lib/temple/ast/components.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ defmodule Temple.Ast.Components do
5353
{nil, {nil, %{}}}
5454
end
5555

56+
{default_slot_parameter, arguments} = Keyword.pop(arguments || [], :let!)
57+
5658
children =
5759
if default_slot == nil do
5860
[]
@@ -61,6 +63,7 @@ defmodule Temple.Ast.Components do
6163
Temple.Ast.new(
6264
Temple.Ast.Slottable,
6365
name: :inner_block,
66+
parameter: default_slot_parameter,
6467
content: Temple.Parser.parse(default_slot)
6568
)
6669
]

test/support/components.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ defmodule Temple.Support.Components do
1818
end
1919
end
2020

21+
def default_slot_with_parameter(assigns) do
22+
temple do
23+
div do
24+
slot @inner_block, %{name: "jimbo"}
25+
end
26+
end
27+
end
28+
2129
def named_slot(assigns) do
2230
temple do
2331
div do

test/temple/ast/components_test.exs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,5 +216,49 @@ defmodule Temple.Ast.ComponentsTest do
216216
]
217217
} = ast
218218
end
219+
220+
test "can use let! with default slot without manually declaring it", %{func: func} do
221+
raw_ast =
222+
quote do
223+
c unquote(func), let!: %{form: form}, foo: :bar do
224+
"in the #{form} inner block"
225+
end
226+
end
227+
228+
ast = Components.run(raw_ast)
229+
230+
assert %Components{
231+
function: ^func,
232+
arguments: [foo: :bar],
233+
slots: [
234+
%Slottable{
235+
name: :inner_block,
236+
content: [
237+
%Temple.Ast.Default{
238+
elixir_ast:
239+
{:<<>>,
240+
[
241+
end_of_expression: [newlines: 1, line: 224, column: 41],
242+
delimiter: "\""
243+
],
244+
[
245+
"in the ",
246+
{:"::", [],
247+
[
248+
{{:., [], [Kernel, :to_string]},
249+
[from_interpolation: true, closing: [line: 224, column: 27]],
250+
[{:form, [], Temple.Ast.ComponentsTest}]},
251+
{:binary, [], Temple.Ast.ComponentsTest}
252+
]},
253+
" inner block"
254+
]}
255+
}
256+
],
257+
parameter: {:%{}, _, [form: _]},
258+
attributes: []
259+
}
260+
]
261+
} = ast
262+
end
219263
end
220264
end

test/temple/renderer_test.exs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,38 @@ defmodule Temple.RendererTest do
408408
assert_html expected, result
409409
end
410410

411+
test "component with a default slot let! parameter" do
412+
assigns = %{label: "i'm a slot attribute"}
413+
414+
result =
415+
Renderer.compile do
416+
div do
417+
c &default_slot_with_parameter/1, let!: %{name: name} do
418+
p do
419+
"#{name} comes from the component"
420+
end
421+
end
422+
end
423+
end
424+
425+
# heex
426+
expected = """
427+
<div>
428+
<div>
429+
<p>
430+
jimbo comes from the component
431+
</p>
432+
433+
</div>
434+
435+
436+
</div>
437+
438+
"""
439+
440+
assert_html expected, result
441+
end
442+
411443
test "component with a named slot" do
412444
assigns = %{label: "i'm a slot attribute"}
413445

0 commit comments

Comments
 (0)