-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathhtml.ex
More file actions
70 lines (56 loc) · 1.44 KB
/
html.ex
File metadata and controls
70 lines (56 loc) · 1.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
defmodule React.HTML do
@moduledoc """
Defines macros for creating React HTML elements.
"""
defmacro __using__(_) do
quote do
import React.HTML
end
end
@external_resource tags_path = Path.join([__DIR__, "tags.txt"])
@tags (for line <- File.stream!(tags_path, [], :line) do
line |> String.trim |> String.to_atom
end)
for tag <- @tags do
@doc """
Defines a macro for the html element, #{tag}
"""
defmacro unquote(tag)(attrs, do: inner) do
tag = Atom.to_string(unquote(tag))
{ inner, attributes } = do_tag(inner, attrs)
quote do
React.createElement(unquote(tag), unquote(attributes), unquote(inner))
end
end
defmacro unquote(tag)(attrs \\ []) do
tag = Atom.to_string(unquote(tag))
{ inner, attributes } = Keyword.pop(attrs, :do)
{ inner, attributes } = do_tag(inner, attributes)
quote do
React.createElement(unquote(tag), unquote(attributes), unquote(inner))
end
end
end
defp do_tag(inner, attributes) do
inner = case inner do
{:__block__, _, params} ->
params
nil ->
[]
x ->
[x]
end
attributes = config_to_map(attributes)
{inner, attributes}
end
defp config_to_map(config) do
config = Enum.map(config, fn({key, value}) ->
if is_atom(key) do
{Atom.to_string(key), value}
else
{key, value}
end
end)
{:%{}, [], config}
end
end