Design system Inputs

Date picker

One calendar component with two variants: a one-month single-date picker and a two-month date-range picker.

.mk-daterange.mk-calpop

Overview

Date picker is one field with two deliberate variants. Single date opens one month and commits one day. Date range opens two adjacent months on desktop, then keeps the first press as the start and the second as the end. Both variants use the same field face, calendar cells, keyboard behaviour, and viewport-clamped popover.

Date range Choose the start and end of one continuous interval.

Usage

  • Choose dates from a calendarUse the picker when weekday, month, or surrounding dates help the user find the intended answer more reliably than typing it.
  • Match the calendar to the valueSingle date commits one day from one month. Date range exposes adjacent months and commits one continuous start-to-end interval.
  • Keep the stored value explicitThe field displays the committed date or interval after the calendar closes; temporary calendar focus is not a selected value.

Anatomy

Field

1
23
  1. 1Field face. The standard 44px control boundary. Open warms the border and adds the focus outline.
  2. 2Calendar icon. The 16px registry mark announces a picker rather than free text.
  3. 3Value seat. One date or one complete range in tabular numerals. Before selection it carries a clear prompt.

Calendar structure

The Date range variant is used here because it exposes both month-navigation edges and the complete two-month reading order.

125
3 4
  1. 1Previous month. Moves the visible pair back by one month.
  2. 2Month heading. Names the month and year above its own grid.
  3. 3Weekday headings. Monday-first labels establish the seven columns.
  4. 4Day grid. Every date owns one equal target; padding cells are silent and inert.
  5. 5Next month. Moves the visible pair forward by one month.

Range selection

The interval has three roles. Start and end are explicit dates; the connected wash between them communicates continuity without turning every day into another endpoint.

123
  1. 1Range start. The first press becomes a solid accent endpoint.
  2. 2In-range span. Adjacent square cells join into one uninterrupted wash.
  3. 3Range end. The second press closes the interval with the same endpoint face.

Variants

Single dateOne month; one press commits and closes.
Date rangeTwo months on desktop; start, connected span, and end.
  • Month count follows the jobSingle date remains one month on desktop. Date range uses two months where space permits and one below 720px.
  • The field face stays sharedVariant changes the selection model and calendar width, not the trigger's component family.

States

Field states

StateSpecimenWhat changes
EmptyThe prompt names the date's job; the field never goes blank.
ChosenSingle shows one date; range shows both endpoints in the same seat.
HoverThe border warms to the accent hairline.
Keyboard focusThe standard 2px camel outline appears at 2px offset.
Openaria-expanded="true" combines the warm border with the focus outline.

Day states

StateSpecimenWhat changes
RestA bare number inside the complete cell target.
HoverThe sunken surface fills the cell.
Keyboard focusThe inset camel outline follows keyboard focus.
Selected dateSolid accent and contrast ink identify the committed day or endpoint.
In rangeSquare adjacent washes read as one continuous interval.

Do and don't

Do

Name what the date or range is for and keep the calendar affordance visible.

Don't

Split one interval into two unrelated free-text fields that can disagree.

Copy

  • Single date14 Nov; add the year only when the current context makes it ambiguous.
  • Date range27 Nov – 4 Dec; one en dash joins the endpoints.
  • The prompt names the jobChoose travel dates or Choose start date, not the implementation phrase “select date range”.

Accessibility

  • A button, then a gridThe field exposes aria-expanded; the popover is a keyboard-walkable date grid.
  • The value reads back completelySingle announces one date. Range announces both endpoints in order.
  • Escape closes, focus returnsThe field that opened the calendar receives focus again.
  • Endpoints do not rely on colour aloneThe field text carries the committed date or range after selection.

When to reach for something else

  • A date transcribed from a documentUse a date input when typing is faster than finding.
  • A timeUse the time picker. The calendar owns days, not clock values.

Markup

<button class="mk-daterange" type="button">
  <svg data-mk-icon="calendar" aria-hidden="true"></svg>
  <span class="mk-daterange-label">Choose date</span>
</button>

<script>
  window.mkDateRange(singleButton, { mode: 'single' });
  window.mkDateRange(rangeButton, { mode: 'range' });
</script>