defmodule PetalComponents.Helpers do
@moduledoc """
Module for constructing dynamic class names
"""
@doc """
Builds a class string from a given input list by joining them together
This code was taken from Elixirs `Enum.join/2` function and optimized for
building class name (e.g removing empty strings and joining with " " by default)
"""
def build_class(list, joiner \\ " ")
def build_class([], _joiner), do: ""
def build_class(list, joiner) when is_list(list) do
join_non_empty_list(list, joiner, [])
|> :lists.reverse()
|> IO.iodata_to_binary()
end
# Remove joiner (if present), since our last element was empty and isn't added
defp join_non_empty_list([""], joiner, [joiner | acc]), do: acc
defp join_non_empty_list([nil], joiner, [joiner | acc]), do: acc
defp join_non_empty_list([""], _joiner, acc), do: acc
defp join_non_empty_list([nil], _joiner, acc), do: acc
defp join_non_empty_list([first], _joiner, acc), do: [entry_to_string(first) | acc]
# Don't append empty string to our class list
defp join_non_empty_list(["" | rest], joiner, acc) do
join_non_empty_list(rest, joiner, acc)
end
defp join_non_empty_list([nil | rest], joiner, acc) do
join_non_empty_list(rest, joiner, acc)
end
defp join_non_empty_list([first | rest], joiner, acc) do
join_non_empty_list(rest, joiner, [joiner, entry_to_string(first) | acc])
end
# Trim the input string
defp entry_to_string(entry) when is_binary(entry), do: String.trim(entry)
defp entry_to_string(entry), do: String.trim(String.Chars.to_string(entry))
end