Only collect slots in the root of a component

slot definitions in a component instance can only exist in the root of
that component, with root being defined as the lexical scoping of the
slot still being the component it's defined in.

Fixes #126
This commit is contained in:
Mitchell Hanberg 2021-05-23 13:53:47 -04:00
parent 978df64ffe
commit 15a999d8f3
3 changed files with 55 additions and 10 deletions

View file

@ -2,7 +2,9 @@
## Main
Nothing Yet
### Bug fixes
- Only collect slots in the root of a component instance #127
## 0.6.0 The LiveView compatibility release!

View file

@ -19,27 +19,31 @@ defmodule Temple.Parser.Components do
{do_and_else, assigns} = Temple.Parser.Utils.consolidate_blocks(do_and_else, args)
{default_slot, named_slots} =
{default_slot, {_, named_slots}} =
if children = do_and_else[:do] do
Macro.postwalk(
Macro.prewalk(
children,
%{},
{component_module, %{}},
fn
{:slot, _, [name | args]} = node, named_slots ->
{:c, _, [name | _]} = node, {_, named_slots} ->
{node, {name, named_slots}}
{:slot, _, [name | args]} = node, {^component_module, named_slots} ->
{assigns, slot} = split_assigns_and_children(args, Macro.escape(%{}))
if is_nil(slot) do
{node, named_slots}
{node, {component_module, named_slots}}
else
{nil, Map.put(named_slots, name, %{assigns: assigns, slot: slot})}
{nil,
{component_module, Map.put(named_slots, name, %{assigns: assigns, slot: slot})}}
end
node, named_slots ->
{node, named_slots}
node, acc ->
{node, acc}
end
)
else
{nil, %{}}
{nil, {nil, %{}}}
end
children =

View file

@ -131,6 +131,45 @@ defmodule Temple.Parser.ComponentsTest do
children: []
} = ast
end
test "slots should only be assigned to the component root" do
raw_ast =
quote do
c Card do
c Card.Footer do
c LinkList, socials: @user.socials do
"hello"
slot :default, %{text: text, url: url} do
a class: "text-blue-500 hover:underline", href: url do
text
end
end
end
end
end
end
ast = Components.run(raw_ast)
assert Kernel.==(ast.slots, [])
assert %Components{
children: [
%Components{
children: [
%Components{
slots: [
%Slottable{
name: :default
}
]
}
]
}
]
} = ast
end
end
describe "Temple.Generator.to_eex/1" do