# DatePicker

> Date selection in a monthly calendar, with an optional allowed range and the chosen day returned.

Source: https://crossfly.dev/docs/ui/widgets/datepicker — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# DatePicker

`DatePicker` selects a **date** in a monthly calendar, with navigation by month, by year and quick month/year selection grids. It follows the picker pattern: it returns the value via `getAnswer()` consumed by `show(onAnswer)` on close (see [`Picker`](/docs/ui/widgets/picker)).

> 🟡 · **Package:** `dev.crossfly.ui.picker` · **Extends:** `Picker` · **Style:** `DatePickerStyle`

## When to use
- Collect a date (birthday, scheduling, due date) with a calendar UI.

## When NOT to use
- Collect a time → use [`TimePicker`](/docs/ui/widgets/timepicker).

## Appearance
A card with a title bar, a month row (`< Name >`), a year row (`< 2026 >`) and a 6×7 grid of day cells. It sizes at ~90% of `Screen.minSize`.

## Complete example (copy, paste and run)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button abrir = new Button("Escolher data");
      abrir.onAction(c ->
      {
         DatePicker dp = new DatePicker().title("Data de nascimento");
         dp.show(answer -> Hint.show("Data: " + (String) answer, 2000));
      });
      add(LAY_AUTO, abrir);
   }
}
```

> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

## Basic usage
```java
DatePicker dp = new DatePicker();
dp.show(answer -> campoData.setText((String) answer));
```

## Constructors
| Constructor | Description |
|---|---|
| `DatePicker()` | No parameters; starts at today's date. |

## Properties and customization (fluent)
| Method | Type | Default | What it does |
|---|---|---|---|
| `setDate(int year, int month, int day)` | year, **0-based** month, 1-based day | today | Pre-selects the date. |
| `title(String)` | `String` | `"Date Picker"` | Title bar text. |
| `yearRange(int before, int after)` | `int`, `int` | 30, 10 | Years before/after for the year grid. |
| `style(DatePickerStyle)` | style | skin | Custom style. |
| `getSelectedDay()` | `int` | — | Selected day (1-based). |
| `getDisplayYear()` / `getDisplayMonth()` | `int` | — | Displayed year / month (0-based month). |

## Callbacks and events
| Callback | When it fires |
|---|---|
| `onSelect(Action)` | on tapping a day (receives the `DatePicker` itself). |
| `show(onAnswer)` | on close, delivers the date `String` (if confirmed). |

`getAnswer()` returns the date in the format of `DateTimeUtils.formatDate` — **the order (DMY/MDY/YMD) and the separator depend on `LocaleFormats`**, it is not a fixed `dd/MM/yyyy`.

## States
- Navigating between months resets `selectedDay` to `-1` (no day marked until the user chooses).
- Per-state styles: today, selected, other month, normal (via `DatePickerStyle`).

### Birthday
```java
DatePicker dp = new DatePicker()
   .title("Data de nascimento")
   .yearRange(100, 0)     // up to 100 years ago, none in the future
   .setDate(2000, 0, 1);  // 01/Jan/2000 (month 0-based!)

dp.onSelect(p ->
{
   DatePicker d = (DatePicker) p;
   Debug.log("dia=" + d.getSelectedDay() + " mes=" + (d.getDisplayMonth() + 1));
});

dp.show(answer ->
{
   String data = (String) answer; // e.g.: "01/01/2000" per LocaleFormats
   campoData.setText(data);
});
```

## Best practices
- Remember that **`month` is 0-based** in `setDate`.
- To localize month/day names, reassign the public constants `MONTH_NAMES`/`MONTH_SHORT`.

## Common mistakes
- **Passing a 1-based month in `setDate`** — January is `0`.
- **Expecting a fixed format** — the output follows `LocaleFormats.dateFormat`/`dateSeparator`.
- **`yearRange` as a selection clamp** — it only limits year *navigation*; any day of the displayed month is selectable.

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Pattern base: [`Picker`](/docs/ui/widgets/picker)
- Related components: [`TimePicker`](/docs/ui/widgets/timepicker)
