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.
<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.
<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.
<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.
<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.
Value: none
<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.
<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.
<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
| Name | Type | Default | Description |
|---|---|---|---|
value | BsDateValue | null | ISO date, or an array of them with multiple and range. Supports [(value)]. |
selectionMode | 'single' | 'multiple' | 'range' | 'single' | How dates are selected. |
min | string | null | null | Earliest selectable date, as YYYY-MM-DD. |
max | string | null | null | Latest selectable date, as YYYY-MM-DD. |
dateDisabled | ((iso: string) => boolean) | null | null | Returns true for dates that can’t be selected. |
firstWeekday | number | 1 | First day of the week: 0 for Sunday, 1 for Monday. |
monthsCount | number | 1 | Number of months shown side by side. |
locale | string | undefined | undefined | Locale for dates and month and day names. Defaults to the browser’s. |
colorMode | 'light' | 'dark' | null | null | Forces a color mode for the calendar. |
dateFormat | Intl.DateTimeFormatOptions | ((date, locale) => string) | null | null | How dates are shown. Inputs show ISO dates by default, buttons the locale’s medium date. |
placement | BsPlacement | 'bottom-start' | Where the calendar opens. |
calendarLabel | string | 'Choose date' | Accessible name of the calendar popup. |
open | boolean | false | Opens the calendar. |
disabled | boolean | false | Disables the control. Forms also disable it through the form control. |
Outputs
| Name | Type | Description |
|---|---|---|
valueChange | BsDateValue | Emits the value when the user picks or types dates. |
openChange | boolean | Emits when the calendar opens or closes. |
Methods
| Name | Type | Description |
|---|---|---|
show() / hide() / toggle() | void | Opens or closes the calendar. |
focusCalendar() | void | Opens the calendar and moves focus into it. |
isOpen | Signal<boolean> | Whether the calendar is open. |
display | Signal<string> | The selected dates as text. |
BsDatepickerDisplay
Selector: [bsDatepickerDisplay]
BsCalendar
Selector: [bsCalendar] · Exported as: bsCalendar
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
value | BsDateValue | null | ISO date, or an array of them with multiple and range. Supports [(value)]. |
selectionMode | 'single' | 'multiple' | 'range' | 'single' | How dates are selected. |
min | string | null | null | Earliest selectable date, as YYYY-MM-DD. |
max | string | null | null | Latest selectable date, as YYYY-MM-DD. |
dateDisabled | ((iso: string) => boolean) | null | null | Returns true for dates that can’t be selected. |
firstWeekday | number | 1 | First day of the week: 0 for Sunday, 1 for Monday. |
monthsCount | number | 1 | Number of months shown side by side. |
locale | string | undefined | undefined | Locale for dates and month and day names. Defaults to the browser’s. |
colorMode | 'light' | 'dark' | null | null | Forces a color mode for the calendar. |
prevLabel | string | 'Previous month' | Accessible name of the previous month button. |
nextLabel | string | 'Next month' | Accessible name of the next month button. |
hideOutsideDays | boolean | false | Hides the neighboring months’ days. Always hidden with several months. |
disabled | boolean | false | Disables the control. Forms also disable it through the form control. |
Outputs
| Name | Type | Description |
|---|---|---|
valueChange | BsDateValue | Emits the value when the user picks a date. |
selectionComplete | BsDateValue | Emits when a date, or a range’s end date, is picked. |
Methods
| Name | Type | Description |
|---|---|---|
focus() | void | Moves focus to the selected date or today. |
isDateDisabled(iso) | boolean | Whether a date is outside min and max or disabled. |