Packages
moon
2.89.0
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
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