Packages
mbta_metro
0.0.8
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.65
0.0.64
0.0.62
0.0.61
0.0.60
0.0.58
0.0.57
0.0.56
0.0.55
0.0.54
0.0.53
0.0.52
0.0.51
0.0.50
0.0.49
0.0.48
0.0.47
0.0.46
0.0.45
0.0.44
0.0.43
0.0.42
0.0.41
0.0.40
0.0.39
0.0.34
0.0.30
0.0.27
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
0.0.1-alpha
A Phoenix LiveView component library
Current section
Files
Jump to
Current section
Files
lib/mbta_metro/components/mode_selector.ex
defmodule MbtaMetro.Components.ModeSelector do
use Phoenix.Component
attr :field, Phoenix.HTML.FormField,
doc: "A form field struct retrieved from the form, for example: @form[:modes_to_show]"
attr :modes, :list,
default: [
{"Subway", :subway},
{"Commuter Rail", :commuter_rail},
{"Bus", :bus},
{"Ferry", :ferry}
],
doc: """
A list of label-value tuples.
"""
@doc """
Select one or more modes of transit in a very visual way.
"""
def mode_selector(assigns) do
assigns =
assigns
|> assign(field: nil, id: assigns.field.id)
|> assign_new(:name, fn -> assigns.field.name <> "[]" end)
|> assign_new(:value, fn -> assigns.field.value end)
~H"""
<div class="flex flex-col gap-1">
<input type="hidden" name={@name} value="" checked={@value == []} />
<label
:for={{mode_name, mode_value} <- @modes}
for={@id <> "_#{mode_value}"}
class="rounded border-solid border-2 border-transparent has-[:checked]:bg-slate-100 has-[:checked]:font-semibold has-[:focus-within]:border-slate-400
py-1 px-2 mb-0 inline-flex items-center gap-2"
>
<div class="relative">
<input
id={@id <> "_#{mode_value}"}
type="checkbox"
class="peer sr-only"
name={@name}
value={mode_value}
checked={if(@value, do: mode_value in @value || "#{mode_value}" in @value)}
/>
<div class="h-8 overflow-hidden rounded-full border-2 border-solid border-slate-200 bg-slate-100 w-14 peer-checked:border-slate-400 peer-checked:bg-slate-300">
</div>
<div class="absolute w-6 h-6 rounded-full shadow-lg shadow-indigo-500/40 left-1 top-1 transition opacity-50 peer-checked:translate-x-full peer-checked:opacity-100">
<%= mode_icon(mode_value) %>
</div>
</div>
<%= mode_name %>
</label>
</div>
"""
end
defp mode_icon(:commuter_rail),
do: get_mode_icon("icon-mode-commuter-rail.svg")
defp mode_icon(:subway),
do: get_mode_icon("icon-mode-subway.svg")
defp mode_icon(:bus),
do: get_mode_icon("icon-mode-bus.svg")
defp mode_icon(:ferry),
do: get_mode_icon("icon-mode-ferry.svg")
defp get_mode_icon(path) do
:mbta_metro
|> Application.app_dir("priv/static/images")
|> Path.join(path)
|> File.read!()
|> Phoenix.HTML.raw()
end
end