BwDatepicker | bw-datepicker
This component is experimental and it's public api is subject to change
Overview
An inline date / time picker. It renders a month calendar and/or time columns
and reports the selected value as epoch milliseconds. It is fluid — it fills
the width of its container — so it works inline, inside a bw-card, or as the
content of a bw-popover to build a field-style picker with bw-input.
Usage
Basics
bw-datepicker is an inline picker. Choose what it shows with type: a calendar (date), a calendar plus time columns (datetime, the default), or time only (time).
<div class="flex-row gap" style="flex-wrap: wrap; align-items: flex-start;">
<bw-card><bw-datepicker type="date"></bw-datepicker></bw-card>
<bw-card><bw-datepicker type="time"></bw-datepicker></bw-card>
</div>
Reading the value
The selected value is epoch milliseconds. bw-datepicker emits valueChange (and updates its value property) whenever the selection changes.
<div class="flex-column gap">
<bw-card><bw-datepicker id="dpRead" type="datetime"></bw-datepicker></bw-card>
<bw-note id="dpReadOut">Nothing selected yet</bw-note>
</div>
<script>
const dp = document.getElementById('dpRead');
const out = document.getElementById('dpReadOut');
dp.addEventListener('valueChange', e => {
out.textContent = e.detail ? new Date(e.detail).toLocaleString() : 'Nothing selected yet';
});
</script>
Setting an initial value
value is a number, so set it as a property in JavaScript. The picker opens to that date and marks it selected.
<bw-card><bw-datepicker id="dpInit" type="date"></bw-datepicker></bw-card>
<script>
document.getElementById('dpInit').value = Date.now();
</script>
Constraints
Limit the selectable range with min and max (both epoch ms). Days outside the range are disabled.
<bw-card><bw-datepicker id="dpRange" type="date"></bw-datepicker></bw-card>
<script>
const dp = document.getElementById('dpRange');
const now = Date.now();
dp.min = now;
//30 days
dp.max = now + 30 * 24 * 60 * 60 * 1000;
</script>
Disabling specific days
For finer control, pass an isDateDisabled predicate (a property, since it's a function). Return true to disable a day — here, weekends.
<bw-card><bw-datepicker id="dpWeekdays" type="date"></bw-datepicker></bw-card>
<script>
const dp = document.getElementById('dpWeekdays');
dp.isDateDisabled = (date) => {
const day = date.getDay();
return day === 0 || day === 6; // Sun / Sat
};
</script>
Seconds
For time and datetime, set include-seconds to add a seconds column.
<bw-card><bw-datepicker type="time" include-seconds></bw-datepicker></bw-card>
In a Field
bw-datepicker is an inline picker, but the common form pattern is an editable field that also opens a picker. Compose it from a bw-popover (the picker as its content) and a bw-input with the datetime mask as its trigger. The two stay in sync: typing MM/DD/YYYY HH:mm moves the picker, and choosing a day/time in the picker fills the field.
<bw-popover id="dpFieldPop" placement="bottom-start">
<bw-input slot="trigger" id="dpFieldInput" type="datetime" label="Appointment" placeholder="MM/DD/YYYY HH:mm">
<bw-icon slot="start">calendar_month</bw-icon>
</bw-input>
<bw-card>
<bw-datepicker id="dpFieldPicker" type="datetime"></bw-datepicker>
</bw-card>
</bw-popover>
<script>
const picker = document.getElementById('dpFieldPicker');
const input = document.getElementById('dpFieldInput');
const pad = n => String(n).padStart(2, '0');
let syncing = false;
// Picker → field: write the date as the mask's raw digits (MMDDYYYYHHmm).
picker.addEventListener('valueChange', e => {
if (syncing) return;
syncing = true;
const d = e.detail != null ? new Date(e.detail) : null;
input.value = d
? `${pad(d.getMonth() + 1)}${pad(d.getDate())}${d.getFullYear()}${pad(d.getHours())}${pad(d.getMinutes())}`
: '';
syncing = false;
});
// Field → picker: once a full MM/DD/YYYY HH:mm is typed, move the picker.
input.addEventListener('valueChange', e => {
if (syncing) return;
const g = String(e.detail || '').replace(/\D/g, '');
if (g.length !== 12) return;
const date = new Date(+g.slice(4, 8), +g.slice(0, 2) - 1, +g.slice(2, 4), +g.slice(8, 10), +g.slice(10, 12));
if (!isNaN(date)) { syncing = true; picker.value = date.getTime(); syncing = false; }
});
</script>
How it fits together:
type="datetime"on the input applies a datetime mask — the user types digits and the field formats them asMM/DD/YYYY HH:mm. The input'svalueis the raw 12-digit string, which is easy to parse.- A
syncingguard prevents the twovalueChangehandlers from looping when one updates the other. - The picker's
valueis the source of truth (epoch ms). Store or submit that; the field is just a fast text entry path into it. type="datetime"on the picker keeps the popover open so the user can pick the time after the day. For a date-only field, close the popover once a day is chosen:
picker.addEventListener('valueChange', e => {
document.querySelector('bw-popover').open = false; // dismiss after selection
});
Time Zones
By default the picker displays times in the browser's time zone. Set time-zone to an IANA zone to display and select in a fixed zone instead — the emitted value is still epoch milliseconds, only the displayed clock changes.
<bw-card><bw-datepicker id="dpTz" type="datetime" time-zone="Asia/Tokyo"></bw-datepicker></bw-card>
<script>
document.getElementById('dpTz').value = Date.now();
</script>
Properties
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
includeSeconds | include-seconds | Include a seconds column in the time picker (time / datetime). | boolean | false |
isDateDisabled | -- | Predicate to disable individual days — return true to disable the given date. | (date: Date) => boolean | undefined |
max | max | Latest selectable instant (epoch ms). Days after it are disabled. | number | undefined |
min | min | Earliest selectable instant (epoch ms). Days before it are disabled. | number | undefined |
timeZone | time-zone | IANA time zone used for display (e.g. America/New_York). Defaults to the browser zone. | string | undefined |
type | type | Which controls to show: a calendar (date), calendar + time (datetime), or just time (time). | "date" | "datetime" | "time" | 'datetime' |
value | value | The selected value (epoch ms). Mutable and two-way via valueChange. | number | undefined |
Events
| Event | Description | Type |
|---|---|---|
valueChange | Emitted when the selected value changes. Detail is the new value (epoch ms) or undefined. | CustomEvent<number> |
Dependencies
Used by
Depends on
Graph
© 2025 United Systems & Software - All Rights Reserved.