Packages

An utility module to concatenate strings fragments, filtering falsey values. Inspired to https://github.com/lukeed/clsx, it is useful to produce class names for components that depend on component attributes.

Current section

Files

Jump to
ex_clsx lib ex_clsx.ex
Raw

lib/ex_clsx.ex

defmodule ExClsx do
@moduledoc """
An utility module to concatenate strings fragments, filtering falsey values.
Inspired to https://github.com/lukeed/clsx, it is useful to produce class names for components that depend on component attributes.
"""
defguard is_falsey(term) when term in [false, nil, 0, ""]
defp clsx_item(item) when is_falsey(item), do: []
defp clsx_item(item) when is_map(item) do
item
|> Map.reject(fn {_key, value} -> is_falsey(value) end)
|> Map.keys()
|> Enum.map(fn
class when is_atom(class) -> Atom.to_string(class)
class -> class
end)
end
defp clsx_item(item) when is_list(item), do: Enum.filter(item, &is_falsey/1)
defp clsx_item(item), do: ["#{item}"]
@doc """
Resolves a class names from a list of fragments. Supports string, maps and boolean values. Falsey values are automatically discarded.
## Examples
iex> ExClsx.clsx(["hello", "world"])
"hello world"
iex> ExClsx.clsx(["hello", false, 0, nil, "world"])
"hello world"
iex> ExClsx.clsx(["please", %{ keep: true, discard: false }])
"please keep"
iex> ExClsx.clsx(["please", %{ "keep" => true, "discard" => false }])
"please keep"
"""
def clsx(items) do
items
|> Enum.map(&clsx_item/1)
|> List.flatten()
|> Enum.join(" ")
end
end