PhiaUi.Components.DatePicker (phia_ui v0.1.17)

Copy Markdown View Source

Date picker component that composes Calendar and a popover-style dropdown.

The date picker is fully server-rendered. The parent LiveView owns all state (open, value, current_month) and handles the events emitted by the trigger button and the embedded calendar. There is no client-side JS hook.

Sub-components

When to use

Use date_picker/1 for any date-selection field in a form or settings panel — booking dates, birth dates, expiry dates, due dates, etc.

Use form_date_picker/1 when the field is part of a Phoenix form backed by an Ecto changeset, so validation errors are automatically displayed.

For selecting a date range (check-in / check-out, report period), use date_range_picker/1 instead.

Standalone example

defmodule MyAppWeb.EventLive do
  use Phoenix.LiveView

  def mount(_params, _session, socket) do
    {:ok, assign(socket,
      picker_open: false,
      selected_date: nil,
      current_month: Date.beginning_of_month(Date.utc_today())
    )}
  end

  def handle_event("toggle-picker", _params, socket) do
    {:noreply, update(socket, :picker_open, &(!&1))}
  end

  def handle_event("date-selected", %{"date" => iso}, socket) do
    date = Date.from_iso8601!(iso)
    {:noreply, assign(socket, selected_date: date, picker_open: false)}
  end

  def handle_event("calendar-prev-month", %{"month" => iso}, socket) do
    {:noreply, assign(socket, current_month: Date.from_iso8601!(iso))}
  end

  def handle_event("calendar-next-month", %{"month" => iso}, socket) do
    {:noreply, assign(socket, current_month: Date.from_iso8601!(iso))}
  end
end

<%!-- Template --%>
<.date_picker
  id="event-date"
  open={@picker_open}
  value={@selected_date}
  current_month={@current_month}
  on_toggle="toggle-picker"
  on_change="date-selected"
  min={Date.utc_today()}
  placeholder="Select event date"
/>

Form-integrated example

<.form for={@form} phx-submit="save_event">
  <.form_date_picker
    id="start-date-picker"
    field={@form[:start_date]}
    open={@picker_open}
    value={@selected_date}
    current_month={@current_month}
    on_toggle="toggle-picker"
    on_change="date-selected"
    placeholder="Pick a start date"
  />
  <.button type="submit">Save</.button>
</.form>

Date format

The :format attribute uses Calendar.strftime/2 directives:

Format stringOutput example
"%d/%m/%Y""25/12/2026"
"%B %d, %Y""December 25, 2026"
"%Y-%m-%d""2026-12-25"

Summary

Functions

Renders a date picker with a trigger button and a calendar dropdown.

Renders a date picker integrated with Phoenix.HTML.FormField.

Functions

date_picker(assigns)

Renders a date picker with a trigger button and a calendar dropdown.

The parent LiveView must handle four events:

  • on_toggle — toggle the popover open/closed
  • on_change — a day was clicked (close the picker and update value)
  • "calendar-prev-month" — navigate to the previous month
  • "calendar-next-month" — navigate to the next month

The calendar dropdown is conditionally rendered with :if={@open}, so it is completely absent from the DOM when closed (no CSS visibility tricks).

Attributes

  • id (:string) (required) - Unique date picker ID — also used as the calendar's id prefix.

  • value (:any) - Selected date (Date.t()) or nil when no date has been chosen. Defaults to nil.

  • current_month (:any) - Currently displayed month (Date.t()). When nil, defaults to the month of :value, or the current month if :value is also nil. Update this in response to calendar-prev-month / calendar-next-month events.

    Defaults to nil.

  • open (:boolean) - Whether the calendar dropdown is currently visible. Controlled by the LiveView. Defaults to false.

  • placeholder (:string) - Trigger button text displayed when no date is selected. Defaults to "Pick a date".

  • format (:string) - Calendar.strftime/2 format string used to display the selected date in the trigger. Defaults to "%d/%m/%Y" (e.g. "25/12/2026").

    Defaults to "%d/%m/%Y".

  • on_toggle (:string) - phx-click event name for the trigger button to toggle the dropdown open/closed. Defaults to "date-picker-toggle".

  • on_change (:string) - phx-click event fired when a day is clicked. Receives %{"date" => "YYYY-MM-DD"}. Defaults to "calendar-change".

  • min (:any) - Minimum selectable date (Date.t()). Passed through to the embedded calendar/1. Defaults to nil.

  • max (:any) - Maximum selectable date (Date.t()). Passed through to the embedded calendar/1. Defaults to nil.

  • disabled_dates (:list) - List of Date.t() values that cannot be selected. Passed through to calendar/1. Defaults to [].

  • class (:string) - Additional CSS classes merged onto the root element. Defaults to nil.

  • Global attributes are accepted. HTML attributes forwarded to the root div element.

form_date_picker(assigns)

Renders a date picker integrated with Phoenix.HTML.FormField.

Renders a <input type="hidden"> bound to field.name with the ISO 8601 date value. This hidden input is what gets submitted with the form so Phoenix changesets receive a string they can cast with cast/3.

Changeset validation errors from field.errors are rendered as destructive text below the picker.

Changeset integration

Cast the hidden input value in your changeset:

def changeset(event, attrs) do
  event
  |> cast(attrs, [:start_date])
  |> validate_required([:start_date])
end

The hidden input sends an ISO 8601 string ("2026-03-15"), which Ecto's Date type will automatically parse during cast/3.

Attributes

  • field (Phoenix.HTML.FormField) (required) - Phoenix.HTML.FormField struct from @form[:field_name]. Provides the id, name, and errors for form integration.

  • id (:string) (required) - Unique date picker ID (separate from field.id which is used for the hidden input).

  • value (:any) - Selected date (Date.t()) or nil. Defaults to nil.

  • current_month (:any) - Currently displayed month (Date.t()). Defaults to nil.

  • open (:boolean) - Whether the popover is open. Defaults to false.

  • placeholder (:string) - Placeholder text. Defaults to "Pick a date".

  • format (:string) - Calendar.strftime/2 format string for displaying the selected date. Defaults to "%d/%m/%Y".

  • on_toggle (:string) - phx-click event name for the trigger button. Defaults to "date-picker-toggle".

  • on_change (:string) - phx-click event name for day clicks in the embedded calendar. Defaults to "calendar-change".

  • class (:string) - Additional CSS classes for the wrapper div. Defaults to nil.