Components

Date range picker

A .ds-input that opens a flat .ds-daterange__popover laying two .ds-calendar month grids side by side. Click to set the start, click again for the end — the span fills with a soft accent and the endpoints fill with ink. Reuses the .ds-calendar* look from the date picker. No radius, no shadow.

Two-month range

The open .ds-daterange__popover: a .ds-calendar__head with the prev / next steppers, then .ds-daterange__months holding two borderless .ds-calendar grids. The endpoints carry .is-range-start / .is-range-end (ink fill); the days between carry .is-in-range (a var(--ds-accent-bg) band). Here the range runs June 12 → July 3, 2026.

Open range popover
<div class="ds-daterange__popover" role="dialog" aria-label="Choose date range">
  <div class="ds-calendar__head">
    <button class="ds-button ds-button--icon ds-button--sm" aria-label="Previous month">…</button>
    <button class="ds-button ds-button--icon ds-button--sm" aria-label="Next month">…</button>
  </div>
  <div class="ds-daterange__months">
    <div class="ds-calendar" role="grid" aria-label="June 2026">
      <div class="ds-calendar__head"><div class="ds-calendar__label">June 2026</div></div>
      <div class="ds-calendar__grid">
        <div class="ds-calendar__weekday">Su</div> … <div class="ds-calendar__weekday">Sa</div>
        <button class="ds-calendar__day">11</button>
        <button class="ds-calendar__day is-range-start" aria-pressed="true">12</button>
        <button class="ds-calendar__day is-in-range">13</button> …
      </div>
    </div>
    <div class="ds-calendar" role="grid" aria-label="July 2026">
      …
      <button class="ds-calendar__day is-in-range">2</button>
      <button class="ds-calendar__day is-range-end" aria-pressed="true">3</button> …
    </div>
  </div>
</div>

Field

In a form the popover hangs off a read-only .ds-input inside a .ds-daterange anchor. The input shows the selected range as start — end; the React component opens and positions the popover for you.

Closed input
<div class="ds-daterange">
  <input class="ds-input" type="text" readonly
         value="2026-06-12 — 2026-07-03"
         aria-haspopup="dialog" aria-expanded="false">
  <!-- .ds-daterange__popover (hidden until open) -->
</div>

React

The DateRangePicker renders the .ds-input and two-month popover, computes both grids with pure JS date math, and selects a range: the first click sets the start, the next sets the end (swapping if it precedes the start), and a third click starts over. Hover previews the in-progress range. Works controlled (value/onChange) or uncontrolled (defaultValue); value is { start, end } with Dates or ISO strings.

<DateRangePicker>
import { DateRangePicker } from "@diametral/design-system/react";

<DateRangePicker
  defaultValue={{ start: "2026-06-12", end: "2026-07-03" }}
  min="2026-01-01"
  max="2026-12-31"
  onChange={(range, iso) => console.log(iso.start, iso.end, range)}
/>