LineaUI.Components.DatePicker (linea_ui v0.3.0)

Copy Markdown View Source

LineOne's date pickers (flatpickr's calendar in LineOne's skin): one date, several dates or a range, with limits, disabled days, a custom text format, a time row, and a calendar that pops under the input or stays inline.

<.date_picker field={@form[:due_on]} placeholder="Choose date..." />
<.date_picker name="trip" mode="range" value={{~D[2026-10-10], ~D[2026-10-20]}} />
<.date_picker name="days" mode="multiple" disabled_weekdays={[0, 6]} week_start={1} />
<.datetime_picker field={@form[:starts_at]} min_time="16:00" max_time="22:00" />
<.date_picker name="due" display_format="M j, Y" show_icon={false} placeholder="Due date" />

The input shows the date in display_format (flatpickr tokens: Y-m-d, F j, Y, H:i...); the form gets ISO text through hidden inputs named like the field: 2026-10-23 (one date), 2026-10-23 16:30 (date and time), and name[] per date for multiple and range (with an empty name[] first so an empty choice still reaches the server). A pick fires a bubbling input event, so phx-change runs; the server re-rendering the same value changes nothing, a different value replaces the one in the browser.

The calendar is an overlay: LineaUI.open/close/toggle("id") work on it, and date_picker_clear/1 empties it.

A range in two fields

A range can submit its two ends as two fields instead of name[]: give start_field and end_field (or start_name and end_name) and the form gets start=2026-10-01 and end=2026-10-31 (empty text for an end not picked yet). presets adds quick choices under the calendar, computed on the server from today:

<.date_picker
  start_field={@form[:from]}
  end_field={@form[:to]}
  locale="pt_BR"
  week_start={1}
  placeholder="Período"
  presets={[
    {"Hoje", "today"},
    {"Últimos 7 dias", "last_7_days"},
    {"Este mês", "this_month"},
    {"Mês passado", "last_month"}
  ]}
/>

locale="pt_BR" names the months and weekdays in Portuguese, shows dd/mm/aaaa and joins a range with "até"; months, weekdays, display_format and range_separator still override it one by one.

Summary

Functions

Renders a date input with its calendar.

A %JS{} that empties the picker with id, for a clear button.

The {first, last} days of a named period around today, the way date_picker/1's presets compute them. week_start is the first day of a week, 0 = Sunday. The this_* and last_* periods are whole weeks, months and years; last_7_days and last_30_days end today.

Renders a date and time input: the calendar with flatpickr's hour and minute row.

Functions

date_picker(assigns)

Renders a date input with its calendar.

<.date_picker id="due" name="due" label="Due" min={Date.utc_today()} />
<.date_picker id="when" name="when" placeholder="Choose date">
  <:trailing>
    <.button phx-click={LineaUI.toggle("when")}>…</.button>
    <.button phx-click={date_picker_clear("when")}>×</.button>
  </:trailing>
</.date_picker>

Events: on_change is pushed with %{"id" => id, "value" => value} after each pick, where value is the ISO text (or a list of them for multiple and range), to target or to the LiveView/LiveComponent the picker is in.

A preset is {label, key} with a key of date_range_preset/3 ("today", "yesterday", "last_7_days", "last_30_days", "this_week", "last_week", "this_month", "last_month", "this_year", "last_year"), {label, {from, to}} or %{label: label, from: from, to: to} with Dates or ISO text. Picking one sets the range (or, in single mode, its first day), fires phx-change and on_change, and closes the calendar; the preset matching the current choice is highlighted.

Attributes

  • id (:string) - Defaults to the field id, or a generated one.
  • name (:string) - Defaults to the field name.
  • value (:any) - A Date, ISO text, a list of them, {from, to} or a Date.Range.
  • field (Phoenix.HTML.FormField) - Defaults to nil.
  • label (:string) - Defaults to nil.
  • help (:string) - Defaults to nil.
  • errors (:list) - Defaults to [].
  • placeholder (:string) - Defaults to nil.
  • mode (:string) - Set to range by start_field/end_field and start_name/end_name. Defaults to "single". Must be one of "single", "multiple", or "range".
  • start_field (Phoenix.HTML.FormField) - The field the first day of a range goes to; with end_field. Defaults to nil.
  • end_field (Phoenix.HTML.FormField) - The field the last day of a range goes to; with start_field. Defaults to nil.
  • start_name (:string) - The input name of the first day of a range (without fields); with end_name. Defaults to nil.
  • end_name (:string) - The input name of the last day of a range. Defaults to nil.
  • presets (:list) - Quick choices under the calendar: {label, key}, {label, {from, to}} or %{label:, from:, to:}. Defaults to [].
  • locale (:string) - Month and weekday names, the default display_format and the range separator. Defaults to "en". Must be one of "en", or "pt_BR".
  • range_separator (:string) - The text between the two days of a range; " to " (en) or " até " (pt_BR). Defaults to nil.
  • min (:any) - The first day that can be picked (Date or ISO text). Defaults to nil.
  • max (:any) - The last day that can be picked. Defaults to nil.
  • disabled_dates (:list) - Days that cannot be picked. Defaults to [].
  • disabled_weekdays (:list) - Weekdays that cannot be picked, 0 = Sunday. Defaults to [].
  • week_start (:integer) - The first column of the calendar, 0 = Sunday. Defaults to 0.
  • display_format (:string) - The text of the input in flatpickr tokens; Y-m-d by default. M j, Y reads Oct 23, 2026, D, M j reads Fri, Oct 23, F j, Y reads October 23, 2026. Only the shown text changes: the form still gets ISO. Defaults to nil.
  • months (:list) - The twelve month names, for another language. Defaults to nil.
  • weekdays (:list) - The seven weekday names from Sunday; the calendar shows their first three letters. Defaults to nil.
  • today (:any) - The day marked as today; the server's UTC day by default. Defaults to nil.
  • inline (:boolean) - The calendar always shows, under the input. Defaults to false.
  • show_icon (:boolean) - The calendar icon inside the input; false leaves a bare input (and drops the left padding). Defaults to true.
  • disabled (:boolean) - Defaults to false.
  • on_change (:string) - Defaults to nil.
  • target (:any) - Defaults to nil.
  • class (:any) - Classes of the input. Defaults to nil.
  • Global attributes are accepted.

Slots

  • icon - Replaces the calendar icon.
  • trailing - Buttons joined to the right of the input (LineOne's External Elements); the icon is then left out.

date_picker_clear(js \\ %JS{}, id)

@spec date_picker_clear(Phoenix.LiveView.JS.t(), String.t()) ::
  Phoenix.LiveView.JS.t()

A %JS{} that empties the picker with id, for a clear button.

<.button phx-click={date_picker_clear("when")}>Clear</.button>

date_range_preset(key, today, week_start \\ 0)

@spec date_range_preset(String.t(), Date.t(), 0..6) :: {Date.t(), Date.t()}

The {first, last} days of a named period around today, the way date_picker/1's presets compute them. week_start is the first day of a week, 0 = Sunday. The this_* and last_* periods are whole weeks, months and years; last_7_days and last_30_days end today.

iex> LineaUI.Components.DatePicker.date_range_preset("last_month", ~D[2026-10-24])
{~D[2026-09-01], ~D[2026-09-30]}

iex> LineaUI.Components.DatePicker.date_range_preset("this_week", ~D[2026-10-24], 1)
{~D[2026-10-19], ~D[2026-10-25]}

datetime_picker(assigns)

Renders a date and time input: the calendar with flatpickr's hour and minute row.

<.datetime_picker name="meeting" placeholder="Choose datetime..." min_time="16:00" max_time="22:00" />

Takes every attr of date_picker/1 (in single mode) and the time attrs below. The form gets 2026-10-23 16:30.

Attributes

  • id (:string) - Defaults to the field id, or a generated one.
  • name (:string) - Defaults to the field name.
  • value (:any) - A NaiveDateTime, DateTime or "2026-10-23 16:30".
  • field (Phoenix.HTML.FormField) - Defaults to nil.
  • label (:string) - Defaults to nil.
  • help (:string) - Defaults to nil.
  • errors (:list) - Defaults to [].
  • placeholder (:string) - Defaults to nil.
  • min (:any) - Defaults to nil.
  • max (:any) - Defaults to nil.
  • disabled_dates (:list) - Defaults to [].
  • disabled_weekdays (:list) - Defaults to [].
  • week_start (:integer) - Defaults to 0.
  • display_format (:string) - Y-m-d H:i by default. Defaults to nil.
  • locale (:string) - Month and weekday names and the default display_format (d/m/Y H:i in pt_BR). Defaults to "en". Must be one of "en", or "pt_BR".
  • months (:list) - Defaults to nil.
  • weekdays (:list) - Defaults to nil.
  • today (:any) - Defaults to nil.
  • inline (:boolean) - Defaults to false.
  • show_icon (:boolean) - Defaults to true.
  • time_24hr (:boolean) - Hours 0-23 instead of 1-12 with AM/PM. Defaults to false.
  • min_time (:string) - The earliest time, "HH:MM". Defaults to nil.
  • max_time (:string) - The latest time, "HH:MM". Defaults to nil.
  • minute_step (:integer) - Defaults to 5.
  • hour_step (:integer) - Defaults to 1.
  • default_hour (:integer) - The hour a first pick starts at. Defaults to 12.
  • disabled (:boolean) - Defaults to false.
  • on_change (:string) - Defaults to nil.
  • target (:any) - Defaults to nil.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • icon
  • trailing