How to Use Astryx DateTimeInput and Calendar Components for Date Picking

Astryx provides a composable DateTimeInput component that bundles a text field, pop-over calendar, and time picker into a single accessible interaction, internally leveraging the Calendar component from packages/core/src/Calendar/Calendar.tsx to handle month grids, navigation, and ARIA live announcements.

The facebook/astryx repository delivers robust date-picking primitives through its DateTimeInput and Calendar components. These components manage ISO-8601 datetime strings, support complex constraints like disabled date ranges, and provide full keyboard navigation while maintaining strict accessibility standards.

Component Architecture and Source Files

The DateTimeInput component, implemented in packages/core/src/DateTimeInput/DateTimeInput.tsx, composes the core Calendar component from packages/core/src/Calendar/Calendar.tsx to render the month grid. When a user focuses the date field or clicks the calendar icon, the Calendar pop-over activates, managing navigation via the useGridFocus hook and screen-reader announcements via useAnnounce.

Basic Implementation with DateTimeInput

To implement a standard date and time picker, import DateTimeInput from @astryxdesign/core/DateTimeInput and bind an ISO-8601 string value.

import {DateTimeInput} from '@astryxdesign/core/DateTimeInput';
import {useState} from 'react';

function MeetingScheduler() {
  const [meeting, setMeeting] = useState<ISODateTimeString | undefined>();

  return (
    <DateTimeInput
      label="Meeting date & time"
      description="Select a future date and time for the meeting."
      placeholder="Select a date"
      timePlaceholder="Select a time"
      value={meeting}
      onChange={setMeeting}
      hasClear                // shows a clear (×) button when a value is set
      hourFormat="24h"       // use 24‑hour clock
      timeIncrement={5}      // arrow keys step minutes by 5
      min="2024-01-01T00:00" // earliest selectable datetime
      max="2025-12-31T23:59" // latest selectable datetime
    />
  );
}

Configuring Calendar Display and Constraints

The underlying Calendar component supports multiple display modes and validation constraints through props forwarded from DateTimeInput.

Multi-Month Display

Set numberOfMonths to 2 to display two months side-by-side, useful for range selection or travel booking interfaces.

Date Constraints

Use min and max props to define selectable boundaries, or provide a dateConstraints array with predicate functions to disable specific dates.

// Example with a two‑month calendar and custom date constraints
import {DateTimeInput} from '@astryxdesign/core/DateTimeInput';
import {useState} from 'react';

function WeekendOnlyPicker() {
  const [dateTime, setDateTime] = useState<ISODateTimeString | undefined>();

  // Disable all weekdays – only weekends can be selected
  const weekendOnly = (date: Date) => {
    const day = date.getDay(); // 0 = Sun, 6 = Sat
    return day === 0 || day === 6;
  };

  return (
    <DateTimeInput
      label="Weekend event"
      value={dateTime}
      onChange={setDateTime}
      numberOfMonths={2}       // show two months side‑by‑side
      dateConstraints={[weekendOnly]}
      placeholder="Pick a weekend date"
    />
  );
}

Time Input Configuration

DateTimeInput exposes granular control over time selection through several props. Set hourFormat to '12h' or '24h', enable hasSeconds for second-level precision, and configure timeIncrement to define minute-step intervals for keyboard navigation. The hasClear prop adds a clear button to reset the value.

Handling Async Updates with changeAction

For server-side persistence, use changeAction instead of onChange to handle asynchronous operations. This prop accepts a callback function and works with the isLoading state to indicate pending operations.

// Using async changeAction for optimistic UI updates
import {DateTimeInput} from '@astryxdesign/core/DateTimeInput';
import {useState, useTransition} from 'react';

function OptimisticSave() {
  const [value, setValue] = useState<ISODateTimeString | undefined>();
  const [isPending, startTransition] = useTransition();

  const save = async (newValue: ISODateTimeString | undefined) => {
    await fetch('/api/save', {
      method: 'POST',
      body: JSON.stringify({datetime: newValue}),
    });
  };

  return (
    <DateTimeInput
      label="Save on change"
      value={value}
      onChange={setValue}
      changeAction={newVal => startTransition(() => save(newVal))}
      isLoading={isPending}
    />
  );
}

Accessibility and Keyboard Navigation

The Calendar component implements robust accessibility features through internal hooks. The useGridFocus hook manages keyboard navigation across the month grid using arrow keys, Page Up/Down for month navigation, and Home/End keys. Screen-reader users receive context updates via the useAnnounce hook, which provides live region announcements for month changes and selected dates. These implementations ensure compliance with ARIA guidelines as documented in packages/core/src/Calendar/Calendar.doc.mjs and packages/core/src/DateTimeInput/DateTimeInput.doc.mjs.

Summary

  • DateTimeInput composes Calendar from packages/core/src/Calendar/Calendar.tsx to provide a unified date-time picking interface.
  • Configure display options via numberOfMonths, and restrict selection using min, max, and custom dateConstraints predicates.
  • Control time formatting with hourFormat, hasSeconds, and timeIncrement props.
  • Implement asynchronous saves using changeAction coupled with isLoading state.
  • Accessibility is handled internally via useGridFocus for keyboard navigation and useAnnounce for screen-reader updates.

Frequently Asked Questions

How do I disable specific dates in the Astryx Calendar component?

Pass an array of predicate functions to the dateConstraints prop. Each function receives a JavaScript Date object and returns a boolean indicating whether the date is selectable. For example, to allow only weekends, return true when date.getDay() equals 0 or 6.

What is the difference between onChange and changeAction in DateTimeInput?

The onChange callback executes synchronously when the value updates, suitable for local state management. The changeAction prop accepts an async function for server-side operations, automatically handling loading states and optimistic updates when paired with the isLoading prop.

How do I display two months side by side in the date picker?

Set the numberOfMonths prop to 2. This configuration renders a dual-month view within the Calendar pop-over, allowing users to navigate and select dates across two adjacent months simultaneously.

Can I use the Calendar component independently without the time picker?

Yes. While DateTimeInput provides the combined interface, you can import and use the Calendar component directly from @astryxdesign/core/Calendar for date-only selection scenarios. The component maintains the same constraint and navigation APIs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →