# `Noora.DatePicker`

A date range picker component with preset options and custom selection.

Built on top of Zag.js date picker machine, this component supports:
- Predefined range presets (Last 7 days, Last 30 days, etc.) with DateTime precision
- Custom date range selection via calendar
- Desktop layout (sidebar presets + two-month calendar) and mobile layout (tabs + single-month calendar)
- Light/dark mode theming

## Example

```elixir
<.date_picker
  id="date-range"
  name="date_range"
  on_period_change="date_range_changed"
  selected_preset={@selected_preset}
  period={@date_range_period}
  presets={[
    %{id: "1h", label: "Last 1 hour", period: {1, :hour}},
    %{id: "24h", label: "Last 24 hours", period: {24, :hour}},
    %{id: "7d", label: "Last 7 days", period: {7, :day}},
    %{id: "30d", label: "Last 30 days", period: {30, :day}},
    %{id: "custom", label: "Custom"}
  ]}
>
  <:actions>
    <.button
      label="Cancel"
      variant="secondary"
      phx-click={JS.dispatch("phx:date-picker-cancel", detail: %{id: "date-range"})}
    />
    <.button
      label="Apply"
      phx-click={JS.dispatch("phx:date-picker-apply", detail: %{id: "date-range"})}
    />
  </:actions>
</.date_picker>
```

## Handling period changes

```elixir
def handle_event("date_range_changed", %{"value" => %{"start" => start, "end" => end}, "preset" => preset}, socket) do
  # start and end are ISO8601 DateTime strings
  {:noreply, assign(socket, date_range_period: {start, end})}
end
```

# `date_picker`

## Attributes

* `id` (`:string`) (required) - Unique identifier for the date picker component.
* `label` (`:string`) - Label displayed on the trigger button. Defaults to `"Select date range"`.
* `name` (`:string`) - The name attribute for the hidden input field. Defaults to `nil`.
* `period` (`:any`) - The currently selected range as a tuple {start_datetime, end_datetime}. Both values must be DateTime structs. Defaults to `nil`.
* `presets` (`:list`) (required) - List of preset options. Each preset is a map with :id, :label, and optional :period keys. Period is a tuple of {amount, unit} where unit is :hour, :day, :week, :month, or :year.
* `selected_preset` (`:string`) - The ID of the currently selected preset. Defaults to `nil`.
* `min` (`:any`) - Minimum selectable date (Date, DateTime, or ISO8601 string). Defaults to `nil`.
* `max` (`:any`) - Maximum selectable date (Date, DateTime, or ISO8601 string). Defaults to `nil`.
* `start_of_week` (`:integer`) - The day the week starts on (0 = Sunday, 1 = Monday, etc.). Defaults to `0`.
* `disabled` (`:boolean`) - Whether the date picker is disabled. Defaults to `false`.
* `on_period_change` (`:string`) - Event handler name for when the selected date range changes. Defaults to `nil`.
* `on_cancel` (`:string`) - Event handler name for when the cancel button is clicked. Defaults to `nil`.
* `open` (`:boolean`) - Whether the date picker should be open by default (useful for storybook). Defaults to `false`.
* Global attributes are accepted. Additional HTML attributes.
## Slots

* `actions` - Action buttons for the footer (e.g., Cancel and Apply). Use JS.dispatch("phx:date-picker-cancel", detail: %{id: id}) and JS.dispatch("phx:date-picker-apply", detail: %{id: id}) to trigger the date picker's cancel and apply actions.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
