Pathfinderby Commenda
Components

Date picker

Segmented dates, ranges, and months with a matching calendar.

Installation

Import the component in your screen:

Example.tsx
import { DatePicker } from '@commenda/pathfinder/date-picker';

Load the stylesheet once in your app root, after host styles:

Example.tsx
import '@commenda/pathfinder/styles.css';

Pathfinder ships precompiled CSS; no Tailwind setup is required. In Next.js App Router, put interactive state and callbacks in a client component. See installation for the workspace setup.

API reference

PropTypeBehavior
modeConditional"single"|"range"|"month"'single'; discriminates value and constraints
valueConditionalstring | null | ObjectView fieldsSingle YYYY-MM-DD, month YYYY-MM, range { start, end } of date strings/null
defaultValuestring | null | ObjectView fieldsSingle YYYY-MM-DD, month YYYY-MM, range { start, end } of date strings/null
onValueChangeConditional| ((value: string | null) => void) | ((value: DateRange) => void)Controlled mode requires it. Receives valid values, explicit clears, or partial ranges
format"us"|"in"|"iso"'iso'; MM/DD/YYYY, DD/MM/YYYY, YYYY-MM-DD
calendarConfigfalse | ObjectView fieldsCalendar enabled, Sunday first; false is typed-only
constraintConfigObjectView fields · 2 shapesSingle/range date constraints; month mode uses isMonthUnavailable and month strings
presetConfigObjectView fieldsRange-only; presets obey the same constraints
clearConfigObjectView fieldsOptional clear action
namestringSingle/month submit one ISO value; range submits name.start and name.end
formstringSingle/month submit one ISO value; range submits name.start and name.end
labelConditionalstringVisible field label. Supply an accessible name when it is omitted.
hideLabelbooleanVisually hide the label while preserving its accessible name.
aria-labelConditionalstringDefines a string value that labels the current element.
requiredConditionalbooleanMark the field as required. See validation guidance for the component.
labelConfigObjectView fields · 2 shapesChoose either optionalLabel or help, never both. never excludes the other field.
descriptionstringSupporting guidance associated with the field.
errorConfigObjectView fieldsValidation message and when it becomes visible.
disableConfigDisableConfigView fieldsDisabled state with an optional explanation.
idstringStable HTML identifier for the component.
classNamestringAdditional classes for the component root.
readOnlybooleanAllow reading the current value without editing it.
onBlurFocusEventHandler<HTMLDivElement>Called when focus leaves the component.
onFocusFocusEventHandler<HTMLDivElement>Called when focus enters the component.
valueObject fields
FieldTypeRequirement
startstring | nullRequired
endstring | nullRequired
defaultValueObject fields
FieldTypeRequirement
startstring | nullRequired
endstring | nullRequired
calendarConfigObject fields
FieldTypeRequirement
weekStartsOn0 | 1Optional
constraintConfigObject fields

Choose one of these 2 shapes. Do not combine fields excluded by the selected shape.

Option 1

FieldTypeRequirement
minstringOptional
maxstringOptional
isDateUnavailable((date: string) => boolean)Optional

Option 2

FieldTypeRequirement
minstringOptional
maxstringOptional
isMonthUnavailable((month: string) => boolean)Optional
presetConfigObject fields
FieldTypeRequirement
itemsreadonly { id: string; label: string; value: DateRange; }[]Required
clearConfigObject fields
FieldTypeRequirement
labelstringOptional
labelConfigObject fields

Choose one of these 2 shapes. Do not combine fields excluded by the selected shape.

Option 1

FieldTypeRequirement
optionalLabelstringRequired

Do not supply: help.

Option 2

FieldTypeRequirement
helpstringRequired

Do not supply: optionalLabel.

errorConfigObject fields
FieldTypeRequirement
messagestringRequired
reveal"after-blur" | "immediate"Optional
disableConfigObject fields
FieldTypeRequirement
isDisabledbooleanRequired
reasonstringOptional

Shared presentation and readOnly follow Input. Refs and native form behavior differ because this is a composite editor. Set valid ISO strings in controlled props; invalid or incomplete drafts remain in the editor and block native form submission. They never silently revert on blur. A changed external value replaces the draft; form reset restores uncontrolled defaults and clears draft edits.

Typing and calendar selection

The parent field is the Kakashi-derived DateField: type or adjust its day, month, and year segments directly. The calendar icon opens the matching day, range, or month picker. Choosing a date updates those same segments and the same ISO value; neither interaction owns a second date state. Invalid drafts stay visible until corrected.

Range and presets

Click a day to start a new range; the calendar stays open while you choose its end. The second click completes the range, including a same-day range, and closes the calendar. Choosing an earlier second day orders the two dates chronologically. End must be on or after start. A range cannot cross an unavailable date. Wide screens show two months; narrow screens show one navigable month. For large selectable periods, provide practical application min/max bounds so predicate checks stay inexpensive.

Month

Typed-only

Type DD/MM/YYYY. Arrow keys navigate and adjust segments.

Each segment has an accessible name. Arrow keys move between or adjust segments. Dates are calendar strings; do not convert through new Date('YYYY-MM-DD').toISOString() in application adapters.

Constraints

October only; the 15th is unavailable. Typed dates use the same constraints.

States

Choose a filing date.

Read composite field rules.

Design rules

The calendar follows Calendar, day cells, and month cells.

  • The typed block follows Kakashi DateField spacing: 40px minimum height, 8px horizontal padding, 24px-tall segments, 40px year and 28px month/day widths, 2px gaps, and 2px separator padding. This user-requested spacing overrides Figma's compact 28px field. The 16px calendar icon sits in a 24px action target.
  • The floating card has a 10px radius, pearl-300 hairline, menu shadow, and 12px calendar padding.
  • Navigation is 24px; weekday labels are 24px tall; days are 32px square with 2px between weeks. Month options are 72 × 32px.
  • Selected dates and range ends use blue-700. Interior dates form a continuous blue-100 band. Today has a 4px dot. Presets show a check when their range matches.
  • Outside days and weekday labels use pearl-800 for readable contrast, a deliberate adjustment from Figma's lighter colors.
  • At narrow widths the range calendar shows one month and puts supplied presets above the calendar. Preset dates and labels remain application-owned.

Reference rules

Figma guidance and reviewed implementation decisions for this component. Rule IDs remain stable for source comments and AI references.

Dates

  • DATE-001: Single, range, month, and typed-only use Kakashi DateField spacing per the user override: minimum height 40px, horizontal inset 8px, fixed 40px year and 28px month/day segments, 24px segment height, 2px segment gaps and separator padding. Locale segment order is explicit through format; default is ISO.

  • DATE-002: Calendar 190:587, day cell 188:33, and month cell 188:50: offset 4px, radius 10, pearl-300 hairline, 12px padding, 24px navigation and weekday row, 32px days with 2px week gaps, 72 × 32px month options. Sunday first; selected blue-700, continuous blue-100 range band, 4px today dot, unavailable dates disabled and muted. These exact cell frames supersede the older page note about strikethrough. Supplied presets have a divided sidebar and selection check; narrow screens place presets above one month. Weekday/outside text is strengthened to pearl-800 for contrast.

  • DATE-003: Private DateField derives from Kakashi's editing/navigation engine, with Pathfinder tokens and no private workspace runtime imports. Keep incomplete/invalid drafts visible; never replace them with the old committed value on blur.

  • DATE-004: ISO date-only strings, no UTC conversion. Typed input, calendar, and presets use identical constraints. Typed ranges reject reversed dates and ranges crossing unavailable days. Calendar selection uses two clicks: the first starts a new range and keeps the popup open; the second completes it (including the same day). Month mode uses month predicates.

  • DATE-005: calendarConfig={false} removes the icon/popover. Composite refs target the group. Native forms submit ISO values; invalid drafts cannot submit an older saved value.

  • DATE-006: First calendar click starts a fresh range and keeps the popup open. Second click completes it, including a same-day range. Display a prompt for the pending end date. Selected days retain their blue fill on hover.

Explicit differences and boundaries

  • Editors: Select and DatePicker retain their existing control heights; they are not pixel-identical to compact picker drawings. Text/number editors use the compact geometry. Async save errors remain visibly actionable with retry.

Shared rules

Labels activate the first input; every date segment has its own accessible label. Descriptions, disabled reasons, and validation messages stay associated with the field. Error icons center on the first 18px text line, including wrapped messages. Controlled values require callbacks; uncontrolled form resets restore defaults. Public props expose application values, never private primitive or calendar objects. Styles ship precompiled for React 18/19 and Next.js consumers.

Date segments use native text selection as their single editing highlight. Focusing a segment selects its text for replacement; the field retains its own outer focus or validation border.

On this page