Skip to main content

Datepicker

A calendar and date picker popup, opened from an input or a button, with range selection, multiple months and more.

Bootstrap’s datepicker docs describe the markup and CSS.

Overview

Add bsDatepicker to a text input. The calendar opens below it on focus or click, and closes after you pick a date, on Escape, on a click outside, or when focus leaves it. ↓ moves focus into the calendar. The value is an ISO date (YYYY-MM-DD), which the input shows and accepts when typed. Unlike Bootstrap’s datepicker, the calendar is rendered by Angular, with no Vanilla Calendar Pro dependency.

Value: none

<label bsFormLabel for="datepicker1">Datepicker</label>
<input
  type="text"
  bsFormControl
  bsDatepicker
  id="datepicker1"
  class="w-12"
  autocomplete="off"
  placeholder="Choose date…"
  [formControl]="date" />
<p class="mt-3 mb-0 fg-3">Value: {{ date.value ?? 'none' }}</p>

With form field

Use a form field for a label, description and validation feedback.

We’ll send a reminder the day before.
HTML
<div bsFormField>
  <label bsFormLabel>Datepicker field</label>
  <input
    type="text"
    bsFormControl
    bsDatepicker
    class="w-12"
    autocomplete="off"
    placeholder="Choose date…" />
  <small bsFormText>We’ll send a reminder the day before.</small>
</div>

With icon

Put the input in a form adorn for a calendar icon. The calendar lines up with the adorn.

HTML
<label bsFormLabel for="datepickerIcon">Select date</label>
<label bsFormAdorn class="w-12">
  <span bsFormAdornIcon>
    <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
      <path
        d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-5 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z" />
      <path
        d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z" />
    </svg>
  </span>
  <input
    type="text"
    class="form-ghost"
    bsDatepicker
    id="datepickerIcon"
    autocomplete="off"
    placeholder="Choose date…" />
</label>

Min and max dates

Restrict the selectable dates with min and max, or with a dateDisabled function, such as one that disables weekends.

<div class="d-flex flex-wrap gap-3">
  <div>
    <label bsFormLabel for="datepickerMinMax">Event date (2026 only)</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerMinMax"
      class="w-12"
      autocomplete="off"
      min="2026-01-01"
      max="2026-12-31"
      placeholder="Select a date in 2026" />
  </div>
  <div>
    <label bsFormLabel for="datepickerWeekdays">Weekday</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerWeekdays"
      class="w-12"
      autocomplete="off"
      placeholder="Mon to Fri"
      [dateDisabled]="weekend" />
  </div>
</div>

Multiple dates

Set selectionMode="multiple" to pick several dates. The value is an array, and the calendar stays open while you pick.

<label bsFormLabel for="datepickerMultiple">Select multiple dates</label>
<input
  type="text"
  bsFormControl
  bsDatepicker
  id="datepickerMultiple"
  autocomplete="off"
  selectionMode="multiple"
  placeholder="Select dates…"
  [(value)]="dates" />

Date range

Set selectionMode="range" to pick a start and an end date, and monthsCount to show months side by side. The calendar closes once both dates are picked.

<label bsFormLabel for="datepickerRange">Select date range</label>
<input
  type="text"
  bsFormControl
  bsDatepicker
  id="datepickerRange"
  autocomplete="off"
  selectionMode="range"
  monthsCount="2"
  placeholder="Select start and end dates…"
  [(value)]="stay" />

First day of week

Weeks start on Monday. Set firstWeekday to 0 to start on Sunday. Set locale for month and day names in another language.

HTML
<div class="d-flex flex-wrap gap-3">
  <div>
    <label bsFormLabel for="datepickerSunday">Week starts on Sunday</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerSunday"
      class="w-12"
      autocomplete="off"
      firstWeekday="0"
      locale="en-US"
      placeholder="Select a date" />
  </div>
  <div>
    <label bsFormLabel for="datepickerFrench">In French</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerFrench"
      class="w-12"
      autocomplete="off"
      locale="fr-FR"
      placeholder="Choisir une date"
      calendarLabel="Choisir une date" />
  </div>
</div>

Placement

Set placement to open the calendar elsewhere. It flips when there isn’t room.

HTML
<div class="d-flex flex-wrap gap-3">
  <div>
    <label bsFormLabel for="datepickerStart">Start aligned</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerStart"
      autocomplete="off"
      placement="bottom-start"
      placeholder="Start" />
  </div>
  <div>
    <label bsFormLabel for="datepickerCenter">Centered</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerCenter"
      autocomplete="off"
      placement="bottom"
      placeholder="Center" />
  </div>
  <div>
    <label bsFormLabel for="datepickerEnd">End aligned</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerEnd"
      autocomplete="off"
      placement="bottom-end"
      placeholder="End" />
  </div>
</div>

Button trigger

Use bsDatepicker on a button, for example for a dashboard date filter. A click opens the calendar and moves focus into it. Put the text in a bsDatepickerDisplay element to keep icons when a date is picked. Buttons show dates in the locale’s medium format; change it with dateFormat.

<div class="d-flex flex-wrap gap-3">
  <button type="button" bsButton="outline" theme="secondary" bsDatepicker [(value)]="date">
    <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
      <path
        d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-5 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z" />
      <path
        d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z" />
    </svg>
    <span bsDatepickerDisplay>Select date</span>
  </button>
  <button
    type="button"
    bsButton="outline"
    theme="secondary"
    bsDatepicker
    selectionMode="range"
    [dateFormat]="short"
    [(value)]="period">
    <svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
      <path
        d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-5 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z" />
      <path
        d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z" />
    </svg>
    <span bsDatepickerDisplay>Last 7 days</span>
  </button>
</div>

Inline mode

Use bsCalendar for an always-visible calendar. It takes the same options and binds to forms the same way.

October2026
MonTueWedThuFriSatSun

Value: none

October2026
MonTueWedThuFriSatSun
November2026
MonTueWedThuFriSatSun
<div class="d-flex flex-wrap gap-5">
  <div>
    <div bsCalendar [(value)]="date"></div>
    <p class="mt-3 mb-0 fg-3">Value: {{ date() ?? 'none' }}</p>
  </div>
  <div bsCalendar selectionMode="range" monthsCount="2" [(value)]="range"></div>
</div>

Dark mode

The calendar is rendered next to its input, so it follows the surrounding color mode. Set colorMode to force one for the calendar only.

HTML
<div class="d-flex flex-wrap gap-3">
  <div data-bs-theme="dark" class="p-3 bg-body fg-body rounded">
    <label bsFormLabel for="datepickerDark">Dark mode datepicker</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerDark"
      autocomplete="off"
      placeholder="Select a date" />
  </div>
  <div class="p-3">
    <label bsFormLabel for="datepickerDarkOnly">Dark calendar only</label>
    <input
      type="text"
      bsFormControl
      bsDatepicker
      id="datepickerDarkOnly"
      autocomplete="off"
      colorMode="dark"
      placeholder="Select a date" />
  </div>
</div>

Accessibility

The trigger has aria-haspopup="dialog" and aria-expanded, and the popup is a labeled dialog. Dates form an ARIA grid with one date in the tab order: ← → move by day, ↑ ↓ by week, Home and End to the start and end of the week, Page Up and Page Down by month, and with Shift by year. Each date is labeled with its full date, today has aria-current="date", and the month heading is announced when it changes.

June2026
MonTueWedThuFriSatSun
HTML
<div bsCalendar locale="en-US" min="2026-06-05" value="2026-06-10"></div>

API

BsDatepicker

Selector: input[bsDatepicker], button[bsDatepicker] · Exported as: bsDatepicker

Inputs

NameTypeDefaultDescription
valueBsDateValuenullISO date, or an array of them with multiple and range. Supports [(value)].
selectionMode'single' | 'multiple' | 'range''single'How dates are selected.
minstring | nullnullEarliest selectable date, as YYYY-MM-DD.
maxstring | nullnullLatest selectable date, as YYYY-MM-DD.
dateDisabled((iso: string) => boolean) | nullnullReturns true for dates that can’t be selected.
firstWeekdaynumber1First day of the week: 0 for Sunday, 1 for Monday.
monthsCountnumber1Number of months shown side by side.
localestring | undefinedundefinedLocale for dates and month and day names. Defaults to the browser’s.
colorMode'light' | 'dark' | nullnullForces a color mode for the calendar.
dateFormatIntl.DateTimeFormatOptions | ((date, locale) => string) | nullnullHow dates are shown. Inputs show ISO dates by default, buttons the locale’s medium date.
placementBsPlacement'bottom-start'Where the calendar opens.
calendarLabelstring'Choose date'Accessible name of the calendar popup.
openbooleanfalseOpens the calendar.
disabledbooleanfalseDisables the control. Forms also disable it through the form control.

Outputs

NameTypeDescription
valueChangeBsDateValueEmits the value when the user picks or types dates.
openChangebooleanEmits when the calendar opens or closes.

Methods

NameTypeDescription
show() / hide() / toggle()voidOpens or closes the calendar.
focusCalendar()voidOpens the calendar and moves focus into it.
isOpenSignal<boolean>Whether the calendar is open.
displaySignal<string>The selected dates as text.

BsDatepickerDisplay

Selector: [bsDatepickerDisplay]

BsCalendar

Selector: [bsCalendar] · Exported as: bsCalendar

Inputs

NameTypeDefaultDescription
valueBsDateValuenullISO date, or an array of them with multiple and range. Supports [(value)].
selectionMode'single' | 'multiple' | 'range''single'How dates are selected.
minstring | nullnullEarliest selectable date, as YYYY-MM-DD.
maxstring | nullnullLatest selectable date, as YYYY-MM-DD.
dateDisabled((iso: string) => boolean) | nullnullReturns true for dates that can’t be selected.
firstWeekdaynumber1First day of the week: 0 for Sunday, 1 for Monday.
monthsCountnumber1Number of months shown side by side.
localestring | undefinedundefinedLocale for dates and month and day names. Defaults to the browser’s.
colorMode'light' | 'dark' | nullnullForces a color mode for the calendar.
prevLabelstring'Previous month'Accessible name of the previous month button.
nextLabelstring'Next month'Accessible name of the next month button.
hideOutsideDaysbooleanfalseHides the neighboring months’ days. Always hidden with several months.
disabledbooleanfalseDisables the control. Forms also disable it through the form control.

Outputs

NameTypeDescription
valueChangeBsDateValueEmits the value when the user picks a date.
selectionCompleteBsDateValueEmits when a date, or a range’s end date, is picked.

Methods

NameTypeDescription
focus()voidMoves focus to the selected date or today.
isDateDisabled(iso)booleanWhether a date is outside min and max or disabled.