Date Selector
Standalone calendar selector used by DateInput and custom date-picking popovers.
Overview
DateSelector is the standalone calendar component behind DateInput.
Use it when:
- you need a custom trigger instead of the standard
DateInputfield shell - the date picker lives inside an existing
Popover - the calendar is part of a richer scheduling or range-selection layout
For normal field-based date picking, prefer DateInput.
For more specialized scheduling UIs, DateSelector is not always the right abstraction. MeetingScheduler.tsx is the important counterexample: it uses raw DayPicker because the calendar is tightly coupled to a timezone-aware timeslot column and a two-pane booking workflow.
Basic Usage
<DateSelector
selected={selectedDate}
onSelect={setSelectedDate}
/>Inside A Custom Popover
<Popover>
<Popover.Button>Choose Date</Popover.Button>
<Popover.Panel className="w-64">
<DateSelector
selected={startDate ? new Date(startDate) : undefined}
direction="future"
onSelect={setStartDate}
/>
</Popover.Panel>
</Popover>This is the pattern used in scheduling and campaign-send flows.
When DateSelector Is Not Enough
Use DateSelector when you need a standalone calendar selection surface.
Do not force it into workflow UIs that need deeper calendar behavior such as:
- a calendar plus available-timeslot column
- timezone-aware meeting scheduling
- a multi-step booking flow with the calendar as only one part of the interaction
MeetingScheduler.tsx is the clearest example of this boundary. That component drops down to raw DayPicker instead of DateSelector because the scheduling experience is more specialized than a normal reusable calendar selector.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
selected | Date | — | Currently selected date. |
onSelect | (date: Date) => void | — | Called when a date is selected. |
direction | 'future' | 'past' | 'both' | 'both' | Restricts which dates are selectable. |
disabled | boolean | — | Disables selection entirely. |
className | string | — | Additional classes passed to the calendar root. |
Direction Rules
futuredisables past dates except todaypastdisables future dates except todaybothallows all dates
Brand Dashboard Usage
| Pattern | Path | Notes |
|---|---|---|
| Calendar event date picker | fsai/apps/brand-dashboard/src/pages/Home/Calendar/CalendarEventInformation/CalendarEventForm.tsx | Custom date-selection surface in a richer form. |
| Rich scheduling counterexample | fsai/packages/shared-ui/src/components/MeetingScheduler/MeetingScheduler.tsx | Important example of when to bypass DateSelector and use raw calendar composition instead. |
| Scheduled send date | fsai/apps/brand-dashboard/src/pages/EmailBuilder/BulkSendDrawer/BulkSendDrawer.tsx | DateSelector inside a custom popover. |
| Campaign send scheduling | fsai/apps/brand-dashboard/src/pages/Workflows/CampaignSendDrawer/CampaignSendDrawer.tsx | Future-only selection inside custom trigger UI. |
| Shared portal field rendering | fsai/packages/shared-ui/src/modules/applicantPortal/components/PortalFormField/PortalFormField.components.tsx | Standalone selector used outside DateInput. |
Guidelines
- Do use
DateSelectorwhen the calendar needs custom trigger or placement behavior - Do use
DateInputfor ordinary field-style date picking - Do use
directionto express allowed date ranges clearly - Do look at
MeetingScheduler.tsxwhen the UX needs a richer calendar-plus-timeslot workflow thanDateSelectoris meant to provide - Don't rebuild a calendar popover from scratch when
DateSelectoralready fits