# Datepicker

Component of the SBB design system Lyne.

- Package: `@sbb-esta/lyne-elements` (Angular: `@sbb-esta/lyne-angular`)
- Structure: main element with parts; use parts only within the element they belong to
- Categories: Form
- Status: Design guidelines complete

## Links

- Page on digital.sbb.ch: https://digital.sbb.ch/en/design-system/lyne/components/datepicker/
- Storybook: https://lyne-elements.app.sbb.ch/?path=/docs/elements-datepicker--docs
- Angular (`@sbb-esta/lyne-angular`): https://lyne-angular.app.sbb.ch/angular/components/datepicker/overview (API: https://lyne-angular.app.sbb.ch/angular/components/datepicker/api)
- Figma: https://www.figma.com/design/mWknI2rC5DJmOgRO61WKai/Lyne-Components?node-id=7491-25
- GitHub: https://github.com/sbb-design-systems/lyne-components/tree/v5.12.0/src/elements/datepicker

## Elements

- `sbb-datepicker`: A datepicker component that allows users to select a date from a calendar view.
  - `sbb-datepicker-next-day`, only within `sbb-datepicker`: Combined with a `sbb-datepicker`, it can be used to move the date ahead.
  - `sbb-datepicker-previous-day`, only within `sbb-datepicker`: Combined with a `sbb-datepicker`, it can be used to move the date back.
  - `sbb-datepicker-toggle`, only within `sbb-datepicker`: Combined with a `sbb-datepicker`, it can be used to select a date from a `sbb-calendar`.

## Related components

- Similar: [Date-Input](https://digital.sbb.ch/en/design-system/lyne/components/date-input/index.md), [Mini-Calendar](https://digital.sbb.ch/en/design-system/lyne/components/mini-calendar/index.md)

## Overview

### What does the component do?
The datepicker adds a calendar view to a [date input](https://digital.sbb.ch/en/design-system/lyne/components/date-input/). Users select a date in it instead of typing it.

### When should the component be used?
* When users select a date in a calendar, for example a travel date close to today.
* When the weekday or an overview of the month helps with the selection.
* For plain text entry without a calendar, use the date input.

### Rules.
* The datepicker is always used together with a date input in a [form field](https://digital.sbb.ch/en/design-system/lyne/components/form-field/). A toggle opens the calendar.
* For quick browsing, buttons for the previous and next day can be added. They are disabled automatically at the earliest and latest date.
* Where useful, a default value is set, e.g. today's date.
* If only a certain period is permitted, the earliest and latest date are defined on the date input. The calendar adopts them.
* The two-month view suits longer periods, for example journeys across a month change.

## Implementation (web components)

The `<sbb-datepicker>` is a component which can be used together with
an `<sbb-date-input>` and an `<sbb-datepicker-toggle>` element to attach
a dropdown to select a date from a calendar.

It is also possible to display a two-months view using the `wide` property.

It is recommended to use the datepicker inside an `<sbb-form-field>`, which will
automatically take care of connecting the corresponding components.

To manually connect the components, see the example below:

```html
<sbb-date-input id="datepicker-input"></sbb-date-input>
<sbb-datepicker-toggle input="datepicker-input" datepicker="datepicker"></sbb-datepicker-toggle>
<sbb-datepicker input="datepicker-input" id="datepicker"></sbb-datepicker>
```

### In `<sbb-form-field>`

If the `<sbb-datepicker>` is used within a [sbb-form-field](https://lyne-elements.app.sbb.ch/?path=/docs/elements-form-field--docs)
with an `<sbb-date-input>`, they are automatically linked. This also
applies to the `<sbb-datepicker-previous-day>` and
`<sbb-datepicker-next-day>` components.

```html
<sbb-form-field>
  <sbb-date-input></sbb-date-input>
  <sbb-datepicker></sbb-datepicker>
</sbb-form-field>
```

```html
<!-- Component's usage with all the related components. -->
<sbb-form-field>
  <sbb-datepicker-previous-day></sbb-datepicker-previous-day>
  <sbb-date-input value="2023-01-01" min="2000-01-01" max="2050-12-31"></sbb-date-input>
  <sbb-datepicker-toggle></sbb-datepicker-toggle>
  <sbb-datepicker-next-day></sbb-datepicker-next-day>
  <sbb-datepicker></sbb-datepicker>
</sbb-form-field>
```

### `<sbb-datepicker-previous-day>` & `<sbb-datepicker-next-day>`

The components `<sbb-datepicker-previous-day>` and `<sbb-datepicker-next-day>`
can be used as quick navigation buttons to either decrement or increment
the selected date.

The components can be connected using the `input` id reference attribute or property, similar to the `<sbb-datepicker>` component.

Same as before, it is recommended to use them in an `<sbb-form-field>`,
which will automatically take care of connecting the corresponding
components.

If the two components are used within a [sbb-form-field](https://lyne-elements.app.sbb.ch/?path=/docs/elements-form-field--docs),
they are automatically linked and, depending on the position relative to the
`<sbb-date-input>`, the `<sbb-datepicker-previous-day>` will be projected in the
`prefix` slot (if placed before the `<sbb-date-input>`) or the
`suffix` slot (if placed after the `<sbb-date-input>`) of the `<sbb-form-field>`, whereas the `<sbb-datepicker-next-day>` will be projected in the
`suffix` slot (if placed after the `<sbb-date-input>`) or the
`prefix` slot (if placed before the `<sbb-date-input>`) of the `<sbb-form-field>`.

Both the `<sbb-datepicker-previous-day>` and the `<sbb-datepicker-next-day>`
component have an internal disabled state, which is
synchronized with the `<sbb-date-input>` state:
It is disabled if the date input is disabled or if the selected date is equal
to the input's `min`/`max` attribute/property.

### Custom current date

For testing purposes you might want to set a fixed date as `today`.
This can be achieved by using the underlying date adapter that
the date components use.
By default, the `defaultDateAdapter` is used in the background.
You can e.g. stub the `today()` method and return your fixed date.

```ts
import { defaultDateAdapter } from '@sbb-esta/lyne-elements/datetime.js';
import { stub, type SinonStub } from 'sinon';

// Have defaultDateAdapter.today() return 2022-05-01
todayStub = stub(defaultDateAdapter, 'today').returns(new Date(2022, 4, 1, 0, 0, 0, 0));
// Restore the original method
todayStub.restore();
```

## API (web components)

Full API tables (attributes, events, slots, CSS properties): https://digital.sbb.ch/en/design-system/lyne/components/datepicker/api.md
