Packages
surface
0.11.2
0.12.3
0.12.2
0.12.1
0.12.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha.0
A component based library for Phoenix LiveView
Current section
Files
Jump to
Current section
Files
lib/surface/compiler/variants.ex
defmodule Surface.Compiler.Variants do
@moduledoc false
@enum_types [:list, :keyword, :map, :mapset]
@choice_types [:string, :atom, :integer]
def generate(specs) do
for spec <- Enum.reverse(specs), css_variant = spec.opts[:css_variant], reduce: {[], []} do
{variants, data_variants} ->
variant_opts = if css_variant == true, do: [], else: css_variant
data_name = normalize_variant_name(spec.name)
assign_ast = {:@, [], [{spec.name, [], nil}]}
{type, all_variants, variants_specs} =
case {spec.type, spec.opts[:values] || spec.opts[:values!]} do
{:boolean, _} ->
true_name = variant_opts[true] || data_name
false_name = variant_opts[false] || "not-#{data_name}"
{:boolean, [true_name, false_name | variants],
[
{:data_present, true_name},
{:data_not_present, false_name}
]}
{type, _} when type in @enum_types ->
has_items_name = variant_opts[:has_items] || "has-#{data_name}"
no_items_name = variant_opts[:no_items] || "no-#{data_name}"
{:enum, [has_items_name, no_items_name | variants],
[
{:data_present, has_items_name},
{:data_not_present, no_items_name}
]}
{type, [_ | _] = values} when type in @choice_types ->
prefix = variant_opts[:prefix] || "#{data_name}-"
{variants_names, variants_specs} =
values
|> Enum.reverse()
|> Enum.reduce({variants, []}, fn value, {variants_names, variants_specs} ->
name = "#{prefix}#{value}"
{[name | variants_names], [{:data_with_value, name, value} | variants_specs]}
end)
{:choice, variants_names, variants_specs}
{_type, _} ->
not_nil_name = variant_opts[:not_nil] || data_name
nil_name = variant_opts[nil] || "no-#{data_name}"
{:other, [not_nil_name, nil_name | variants],
[
{:data_present, not_nil_name},
{:data_not_present, nil_name}
]}
end
{all_variants, [{type, spec.func, spec.name, data_name, assign_ast, variants_specs} | data_variants]}
end
end
def enum_types, do: @enum_types
def choice_types, do: @choice_types
defp normalize_variant_name(name) when is_atom(name) do
name
|> to_string()
|> String.replace(["_", "!", "?"], fn
"_" -> "-"
_ -> ""
end)
end
end