Skip to content

Commit

Permalink
Remove deprecated slot :args option and directive
Browse files Browse the repository at this point in the history
  • Loading branch information
msaraiva committed Sep 18, 2024
1 parent b1318ec commit 4e8cc9f
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 172 deletions.
37 changes: 1 addition & 36 deletions lib/surface/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -395,42 +395,7 @@ defmodule Surface.API do
end

defp get_valid_opts(:slot, _type, _opts) do
[:required, :arg, :args, :as, :generator_prop]
end

defp validate_opt_ast!(:slot, :args, args_ast, caller) do
Enum.each(args_ast, fn
{name, {:^, _, [{generator, _, context}]}} when context in [Elixir, nil] ->
message = """
The API for generators has changed. Use `generator_prop: :#{generator}` instead of `args: [#{name}: ^#{generator}]`.
Example:
prop #{generator}, :generator, root: true
slot default, generator_prop: :#{generator}
...
{#for #{name} <- @#{generator}}
<#slot generator_value={#{name}} />
{/for}
"""

IOHelper.compile_error(message, caller.file, caller.line)

_ ->
nil
end)

message = """
option :args has been deprecated. Use :arg instead.
Example:
slot default, arg: %{name: :string, age: :number}
"""

IOHelper.warn(message, caller)
[:required, :arg, :as, :generator_prop]
end

defp validate_opt_ast!(_func, _key, value, _caller) do
Expand Down
25 changes: 6 additions & 19 deletions lib/surface/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ defmodule Surface.Compiler do
Surface.Directive.For
]

@valid_slot_props [:root, "for", "name", "index", "generator_value", ":args", "context_put"]
@valid_slot_props [:root, "for", "name", "index", "generator_value", "context_put"]

@directive_prefixes [":", "s-"]

Expand Down Expand Up @@ -609,24 +609,11 @@ defmodule Surface.Compiler do
slot.name == name || (Keyword.has_key?(slot.opts, :as) and slot.opts[:as] == name)
end)

if has_attribute?(attributes, ":args") do
Surface.IOHelper.warn(
"directive :args has been deprecated. Use the root prop instead.",
meta.caller,
meta.line
)
end

arg =
cond do
has_root? ->
render_slot_args.argument

has_attribute?(attributes, ":args") ->
attribute_value_as_ast(attributes, ":args", :let_arg, %Surface.AST.Literal{value: nil}, compile_meta)

true ->
nil
if has_root? do
render_slot_args.argument
else
nil
end

if slot do
Expand Down Expand Up @@ -1611,7 +1598,7 @@ defmodule Surface.Compiler do
message = """
invalid #{type} `#{name}` for <#slot>.
Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:args`, `:if` and `:for`.
Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:if` and `:for`.
"""

IOHelper.compile_error(message, file, line)
Expand Down
2 changes: 1 addition & 1 deletion test/surface/api_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ defmodule Surface.APITest do

test "validate unknown options" do
code = "slot cols, a: 1"
message = ~r/unknown option :a. Available options: \[:required, :arg, :args, :as, :generator_prop\]/
message = ~r/unknown option :a. Available options: \[:required, :arg, :as, :generator_prop\]/

assert_raise(CompileError, message, fn ->
eval(code)
Expand Down
118 changes: 2 additions & 116 deletions test/surface/integrations/slot_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,7 @@ defmodule Surface.SlotSyncTest do
message = ~r"""
code:10: invalid directive `:attrs` for <#slot>.
Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:args`, `:if` and `:for`.
Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:if` and `:for`.
"""

assert_raise(CompileError, message, fn ->
Expand Down Expand Up @@ -1567,7 +1567,7 @@ defmodule Surface.SlotSyncTest do
message = ~r"""
code:11: invalid attribute `let` for <#slot>.
Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:args`, `:if` and `:for`.
Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:if` and `:for`.
"""

assert_raise(CompileError, message, fn ->
Expand Down Expand Up @@ -1672,120 +1672,6 @@ defmodule Surface.SlotSyncTest do
"""
end

test "outputs compile warning when using deprecated args option" do
component_code = """
defmodule UsingDeprecatedArgsOption do
use Surface.Component
slot default, args: [:info]
def render(assigns) do
~F"\""
<span class="fancy-column">
<#slot {@default, info: "this is a test"} />
</span>
"\""
end
end
"""

output =
capture_io(:standard_error, fn ->
{{:module, _, _, _}, _} = Code.eval_string(component_code, [], %{__ENV__ | file: "code.exs", line: 1})
end)

assert output =~ "option :args has been deprecated. Use :arg instead."
end

test "outputs compile warning when using deprecated :args directive" do
component_code = """
defmodule UsingDeprecatedArgsDirective do
use Surface.Component
slot default, args: [:info]
def render(assigns) do
~F"\""
<#slot :args={arg: "slot argument"} />
"\""
end
end
"""

component_output =
capture_io(:standard_error, fn ->
{{:module, _, _, _}, _} = Code.eval_string(component_code, [], %{__ENV__ | file: "component.exs", line: 1})

code =
quote do
~F"""
<Surface.SlotSyncTest.UsingDeprecatedArgsDirective :let={arg: arg}>
{arg}
</Surface.SlotSyncTest.UsingDeprecatedArgsDirective>
"""
end

usage_output =
capture_io(:standard_error, fn ->
module = compile_surface(code)

html =
module.render(%{__context__: %{}})
|> Phoenix.HTML.Safe.to_iodata()
|> IO.iodata_to_binary()

assert html == """
slot argument
"""
end)

assert usage_output == ""
end)

assert component_output =~ "directive :args has been deprecated. Use the root prop instead.\n component.exs:8"
end

test "outputs compile warning when using deprecated :args generator option" do
component_code = """
defmodule UsingDeprecatedGenerator do
use Surface.Component
prop items, :list, root: true
slot default, args: [item: ^items]
def render(assigns) do
~F"\""
{#for item <- @items}
<#slot :args={item: item} />
{/for}
"\""
end
end
"""

message = """
component.exs:5: The API for generators has changed. Use `generator_prop: :items` instead of `args: [item: ^items]`.
Example:
prop items, :generator, root: true
slot default, generator_prop: :items
...
{#for item <- @items}
<#slot generator_value={item} />
{/for}
"""

assert_raise(CompileError, message, fn ->
{{:module, _, _, _}, _} = Code.eval_string(component_code, [], %{__ENV__ | file: "component.exs", line: 1})
end)
end

test "outputs compile warning when adding arg attribute to the default slot in a slotable component" do
component_code = """
defmodule ColumnWithRenderAndSlotArg do
Expand Down

0 comments on commit 4e8cc9f

Please sign in to comment.