Packages
corex
0.1.0-beta.4
0.1.2
0.1.1
0.1.0
0.1.0-rc.1
0.1.0-rc.0
0.1.0-beta.5
0.1.0-beta.4
0.1.0-beta.3
0.1.0-beta.2
0.1.0-beta.1
0.1.0-alpha.33
0.1.0-alpha.32
0.1.0-alpha.31
0.1.0-alpha.30
0.1.0-alpha.29
0.1.0-alpha.28
0.1.0-alpha.27
0.1.0-alpha.26
0.1.0-alpha.25
0.1.0-alpha.24
0.1.0-alpha.23
0.1.0-alpha.22
0.1.0-alpha.21
0.1.0-alpha.20
0.1.0-alpha.19
0.1.0-alpha.18
0.1.0-alpha.17
0.1.0-alpha.16
0.1.0-alpha.15
0.1.0-alpha.14
0.1.0-alpha.13
0.1.0-alpha.12
0.1.0-alpha.11
0.1.0-alpha.10
0.1.0-alpha.9
0.1.0-alpha.8
0.1.0-alpha.7
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
Accessible and unstyled UI components library written in Elixir and TypeScript that integrates Zag.js state machines into the Phoenix Framework.
Current section
Files
Jump to
Current section
Files
lib/components/timer/connect.ex
defmodule Corex.Timer.Connect do
@moduledoc false
alias Corex.Selectors
alias Corex.Timer.Anatomy.{
ActionTrigger,
Area,
Control,
Item,
ItemLabel,
Props,
Root,
Segment,
Separator
}
alias Corex.Timer.Translation, as: TimerTranslation
alias Phoenix.LiveView.JS
import Corex.Helpers, only: [get_boolean: 1]
@spec props(Props.t()) :: map()
def props(assigns) do
%{
"id" => assigns.id,
"data-countdown" => get_boolean(assigns.countdown),
"data-start-ms" => to_string(assigns.start_ms),
"data-target-ms" => if(assigns.target_ms, do: to_string(assigns.target_ms), else: nil),
"data-auto-start" => get_boolean(assigns.auto_start),
"data-interval" => to_string(assigns.interval),
"data-on-tick" => assigns.on_tick,
"data-on-tick-client" => assigns.on_tick_client,
"data-on-complete" => assigns.on_complete,
"data-on-complete-client" => assigns.on_complete_client,
"data-dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical"),
"data-collapse-leading-zeros" => collapse_dataset(assigns),
"data-segments" => segments_dataset(assigns),
"data-translation" => translation_json(assigns)
}
end
defp collapse_dataset(%Props{collapse_leading_zeros: false}), do: "false"
defp collapse_dataset(%Props{collapse_leading_zeros: true}), do: "true"
defp collapse_dataset(%Props{segments: segs})
when is_list(segs) and segs != [],
do: "false"
defp collapse_dataset(%Props{countdown: true}), do: "true"
defp collapse_dataset(%Props{}), do: "false"
defp segments_dataset(%Props{segments: list}) when is_list(list) and list != [] do
Enum.map_join(list, ",", &Atom.to_string/1)
end
defp segments_dataset(_), do: nil
defp translation_json(%Props{translation: %TimerTranslation{} = t}) do
t
|> TimerTranslation.to_camel_map()
|> Enum.reject(fn {_, v} -> v in [nil, ""] end)
|> Map.new()
|> then(fn
m when map_size(m) == 0 -> nil
m -> Corex.Json.encode!(m)
end)
end
defp translation_json(_), do: nil
@spec root(Root.t()) :: map()
def root(assigns) do
%{
"data-scope" => "timer",
"data-part" => "root",
"id" => "timer:#{assigns.id}:root",
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical")
}
end
def ignore_root(assigns) do
JS.ignore_attributes(Root.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:root")
)
end
@spec area(Area.t()) :: map()
def area(assigns) do
%{
"data-scope" => "timer",
"data-part" => "area",
"id" => "timer:#{assigns.id}:area",
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical")
}
end
def ignore_area(assigns) do
JS.ignore_attributes(Area.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:area")
)
end
@spec control(Control.t()) :: map()
def control(assigns) do
%{
"data-scope" => "timer",
"data-part" => "control",
"id" => "timer:#{assigns.id}:control",
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical")
}
end
def ignore_control(assigns) do
JS.ignore_attributes(Control.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:control")
)
end
@spec item(Item.t()) :: map()
def item(assigns) do
value = Map.get(assigns, :value, 0)
base = %{
"data-scope" => "timer",
"data-part" => "item",
"data-type" => assigns.type,
"id" => "timer:#{assigns.id}:item:#{assigns.type}",
"style" => "--value:#{value};",
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical")
}
if Map.get(assigns, :hidden, false) do
base
|> Map.put("hidden", "")
|> Map.put("aria-hidden", "true")
else
base
end
end
def ignore_item(assigns) do
JS.ignore_attributes(
Item.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:item:#{assigns.type}")
)
end
@spec segment(Segment.t()) :: map()
def segment(assigns) do
base = %{
"data-timer-segment" => "",
"id" => "timer:#{assigns.id}:segment:#{assigns.type}",
"data-type" => assigns.type
}
if Map.get(assigns, :hidden, false) do
base |> Map.put("hidden", "")
else
base
end
end
def ignore_segment(assigns) do
JS.ignore_attributes(
Segment.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:segment:#{assigns.type}")
)
end
@spec item_label(ItemLabel.t()) :: map()
def item_label(assigns) do
%{
"data-scope" => "timer",
"data-part" => "item-label",
"data-type" => assigns.type,
"id" => "timer:#{assigns.id}:label:#{assigns.type}",
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical")
}
end
def ignore_item_label(assigns) do
JS.ignore_attributes(
ItemLabel.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:label:#{assigns.type}")
)
end
@spec separator(Separator.t()) :: map()
def separator(assigns) do
base = %{
"data-scope" => "timer",
"data-part" => "separator",
"aria-hidden" => "true",
"id" => assigns.id,
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "horizontal")
}
if Map.get(assigns, :hidden, false) do
base |> Map.put("hidden", "")
else
base
end
end
def ignore_separator(assigns) do
JS.ignore_attributes(Separator.ignored_attrs(), to: Selectors.css_id(assigns.id))
end
defp action_label("start"), do: "Start"
defp action_label("pause"), do: "Pause"
defp action_label("resume"), do: "Resume"
defp action_label("reset"), do: "Reset"
defp action_label(_), do: "Timer action"
@spec action_trigger(ActionTrigger.t()) :: map()
def action_trigger(assigns) do
base = %{
"data-scope" => "timer",
"data-part" => "action-trigger",
"data-action" => assigns.action,
"type" => "button",
"aria-label" => action_label(assigns.action),
"id" => "timer:#{assigns.id}:action:#{assigns.action}",
"dir" => Map.get(assigns, :dir),
"data-orientation" => Map.get(assigns, :orientation, "vertical")
}
if assigns.hidden do
Map.put(base, "hidden", "")
else
base
end
end
def ignore_action_trigger(assigns) do
JS.ignore_attributes(
ActionTrigger.ignored_attrs(),
to: Selectors.css_id("timer:#{assigns.id}:action:#{assigns.action}")
)
end
end