Current section

Files

Jump to
moon lib moon components datepicker month.ex
Raw

lib/moon/components/datepicker/month.ex

defmodule Moon.Components.Datepicker.Month do
@moduledoc false
use Moon.StatelessComponent
prop(date, :date, required: true)
prop(start_date, :date)
prop(end_date, :date)
prop(week_starts_on, :integer)
prop(on_click, :event)
def render(assigns) do
~F"""
<div>
<div class="mb-4 text-center">
{Timex.format!(@date, "%B %Y", :strftime)}
</div>
<div class="flex mb-1 text-moon-12 font-semibold text-center text-trunks">
<div :for={ch <- days_letters(@week_starts_on)} class="flex items-center justify-center w-8 h-8">
{ch}
</div>
</div>
<div
class="grid text-moon-12 gap-y-1"
style="grid-template-columns: repeat(7, minmax(2rem, 2rem));"
>
<div :for={_cell <- empty_cells(@date, @week_starts_on)} />
<div
:for={day <- month_days(@date)}
class={"cursor-pointer #{day_container_class(day, @start_date, @end_date, @week_starts_on)}"}
>
<div
class={"border border-transparent hover:border-trunks rounded h-8 w-8 flex items-center justify-center #{day_class(day, @start_date, @end_date)}"}
:on-click={@on_click}
phx-value-date={Timex.format!(day, "%Y-%0m-%0dT%R", :strftime)}
>
{Timex.format!(day, "%-d", :strftime)}
</div>
</div>
</div>
</div>
"""
end
def days_letters(weekstart) do
date = Timex.today()
Timex.Interval.new(
from: Timex.beginning_of_week(date, weekstart),
until: Timex.end_of_week(date, weekstart),
left_open: false,
right_open: false
)
|> Enum.map(fn day ->
Timex.format!(day, "%a", :strftime) |> String.at(0)
end)
end
defp empty_cells(date, weekstart) do
days_count =
date
|> Timex.beginning_of_month()
|> Timex.days_to_beginning_of_week(weekstart)
if days_count == 0, do: [], else: 1..days_count
end
defp month_days(date) do
Timex.Interval.new(
from: Timex.beginning_of_month(date),
until: Timex.end_of_month(date),
left_open: false,
right_open: false
)
end
defp day_container_class(_day, nil, _, _), do: nil
defp day_container_class(day, start_date, nil, _) do
if Timex.to_date(day) == Timex.to_date(start_date) do
"bg-gohan rounded"
end
end
defp day_container_class(day, start_date, end_date, week_starts_on) do
date_day = Timex.to_date(day)
start_day = Timex.to_date(start_date)
end_day = Timex.to_date(end_date)
cond do
date_day == start_day && date_day == end_day ->
nil
date_day == start_day ->
"bg-gohan rounded"
date_day == end_day ->
"bg-gohan rounded"
Timex.between?(day, start_date, end_date) ->
week_start_class(day, week_starts_on)
true ->
nil
end
end
defp week_start_class(day, week_starts_on) do
cond do
Timex.weekday(day) == week_starts_on -> "bg-gohan rounded-l"
Timex.weekday(day) == week_starts_on + 6 -> "bg-gohan rounded-r"
true -> "bg-gohan"
end
end
defp day_class(_day, nil, _), do: nil
defp day_class(day, start_date, end_date) do
if Timex.to_date(day) in [Timex.to_date(start_date), Timex.to_date(end_date)],
do: "bg-piccolo text-goten",
else: nil
end
end