# Date picker

> A date picker lets users pick a date from a calendar instead of typing it, for booking forms, deadlines and other date fields.

Let users pick a date from a calendar with the Litepicker plugin, as a plain input, an icon input, or an inline calendar.

Source: https://docs.tabler.io/ui/plugins/date-picker

---

## Overview

The date picker is a normal text input with the [Litepicker](https://litepicker.com/) plugin attached. Litepicker opens a calendar when the field is focused and writes the picked date back into the input, so the field still works in a form like any other text field.

```html
<input type="text" class="form-control" id="datepicker-overview" placeholder="Select a date" />
```

## Installation

Install Litepicker with npm:

```shell
npm install litepicker
yarn add litepicker
pnpm install litepicker
bun install litepicker
```

Or include it from a CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.0/dist/libs/litepicker/dist/litepicker.js"></script>
```

Tabler restyles the calendar to match the rest of the interface. Those styles live in the vendors plugin, so include `tabler-vendors.css` as well:

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.5.0/dist/css/tabler-vendors.min.css" />
```

## Usage

### Basic input

Add a text input with the `form-control` class, then attach Litepicker to it with its `element` option.

```html
<input type="text" class="form-control" id="datepicker-basic" placeholder="Select a date" />
```

```js
const picker = new Litepicker({
  element: document.getElementById('datepicker-basic'),
});
```

### Icon input

Wrap the field in `.input-icon` and add a calendar icon, so users can see what the field is for at a glance. Use `.input-icon-addon` after the input to place the icon on the right, or before it to place the icon on the left.

```html
<div class="input-icon">
  <input type="text" class="form-control" id="datepicker-icon" placeholder="Select a date" />
  <span class="input-icon-addon">
    <!-- Download SVG icon from http://tabler.io/icons/icon/calendar -->
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
      <path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12" />
      <path d="M16 3v4" />
      <path d="M8 3v4" />
      <path d="M4 11h16" />
      <path d="M11 15h1" />
      <path d="M12 15v3" />
    </svg>
  </span>
</div>
```

```html
<div class="input-icon">
  <span class="input-icon-addon">
    <!-- Download SVG icon from http://tabler.io/icons/icon/calendar -->
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
      <path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12" />
      <path d="M16 3v4" />
      <path d="M8 3v4" />
      <path d="M4 11h16" />
      <path d="M11 15h1" />
      <path d="M12 15v3" />
    </svg>
  </span>
  <input type="text" class="form-control" id="datepicker-icon-prepend" placeholder="Select a date" />
</div>
```

### Inline calendar

Give Litepicker an empty `div` instead of an input, and pass `inlineMode: true`. The calendar then renders directly on the page instead of opening in a popover. Use this when the date is the main thing on the screen, for example a booking or availability page.

```html
<div class="datepicker-inline" id="datepicker-inline"></div>
```

```js
const picker = new Litepicker({
  element: document.getElementById('datepicker-inline'),
  inlineMode: true,
});
```

## JavaScript

### Custom navigation icons

Litepicker's default previous/next month buttons are plain arrows. Tabler replaces them with [Tabler Icons](/icons) chevrons through the `buttonText` option, which accepts HTML for each button.

```js
const picker = new Litepicker({
  element: document.getElementById('datepicker-basic'),
  buttonText: {
    previousMonth: '<svg class="icon" ...><!-- chevron-left --></svg>',
    nextMonth: '<svg class="icon" ...><!-- chevron-right --></svg>',
  },
});
```

Litepicker uses `buttonText` as the buttons' `innerHTML`, and the icon SVGs are `aria-hidden`, so the generated buttons have no accessible name on their own. Litepicker also re-renders these buttons on every open and every month change, so re-apply the labels on each `render` event instead of once at init:

```js
picker.on('render', () => {
  picker.ui?.querySelector('.button-previous-month')?.setAttribute('aria-label', 'Previous month');
  picker.ui?.querySelector('.button-next-month')?.setAttribute('aria-label', 'Next month');
});
```

### Common options

These are the options you will need most often. Litepicker has more, and they are listed in its [documentation](https://litepicker.com/#option).

| Option | What it does |
| --- | --- |
| `element` | The input or element Litepicker attaches to. |
| `inlineMode` | Renders the calendar on the page instead of in a popover. |
| `singleMode` | `true` picks one date; `false` picks a date range. |
| `format` | Format of the date shown in the field, for example `YYYY-MM-DD`. |
| `minDate` / `maxDate` | Limits the range of selectable dates. |
| `lockDays` | List of dates users cannot pick. |
| `numberOfColumns` / `numberOfMonths` | Shows more than one month at a time. |
| `buttonText` | HTML for the previous/next month and other buttons. |

## Accessibility

- Always add a `<label>` linked to the input with `for` and `id`. The calendar icon alone does not say what the field is for.
- Litepicker's month-navigation buttons carry no accessible name on their own - set `aria-label` on the `render` event, as shown above.
- Keep the typed value working. Users can type a date directly into the input; the picker is a shortcut, not the only way to set the value.
- The picker can be operated with the keyboard: focus the input to open it, use arrow keys to move between days, and <kbd>Enter</kbd> to pick a date.

<script>{`
window.addEventListener('load', function () {
	if (typeof Litepicker === 'undefined') return;

	function initPicker(el, options) {
		if (!el) return;
		var picker = new Litepicker(Object.assign({ element: el }, options));
		picker.on('render', function () {
			var prev = picker.ui && picker.ui.querySelector('.button-previous-month');
			var next = picker.ui && picker.ui.querySelector('.button-next-month');
			if (prev) prev.setAttribute('aria-label', 'Previous month');
			if (next) next.setAttribute('aria-label', 'Next month');
		});
		return picker;
	}

	initPicker(document.getElementById('datepicker-overview'));
	initPicker(document.getElementById('datepicker-basic'));
	initPicker(document.getElementById('datepicker-icon'));
	initPicker(document.getElementById('datepicker-icon-prepend'));
	initPicker(document.getElementById('datepicker-inline'), { inlineMode: true });
});
`}</script>
