Calendar
Interactive calendar component for date selection with month/year navigation
You are reading the v1 docs. v2 renamed several props and replaced GeckoUIPortal with GeckoUIProvider. Read this page in v2.
Live examples are only rendered in the v2 docs.
Calendar
An interactive calendar component for selecting dates. Features month/year navigation, three view modes (day/month/year), and programmatic control via ref.
Installation
import { Calendar } from '@geckoui/geckoui';Basic Usage
'use client';
import { useState } from 'react';
import { Calendar } from '@geckoui/geckoui';
function Example() {
const [selectedDate, setSelectedDate] = useState<string | undefined>();
return (
<div className="space-y-4">
<Calendar selectedDate={selectedDate} onSelectDate={setSelectedDate} />
{selectedDate && <p className="text-sm text-gray-600">Selected: {selectedDate}</p>}
</div>
);
}Props API
Single Mode Props
| Prop | Type | Default | Description |
|---|---|---|---|
mode | 'single' | 'single' | Selection mode for single date |
selectedDate | string | null | undefined | - | Currently selected date in YYYY-MM-DD format |
onSelectDate | (date: string) => void | - | Callback when date is selected |
Range Mode Props
| Prop | Type | Default | Description |
|---|---|---|---|
mode | 'range' | - | Selection mode for date range |
selectedRange | DateRange | - | Selected date range with from and to |
onSelectRange | (range: DateRange | null) => void | - | Callback when range is selected |
Common Props
| Prop | Type | Default | Description |
|---|---|---|---|
calendarRef | React.Ref<CalendarRef> | - | Ref for programmatic control |
className | string | - | Additional CSS classes |
style | React.CSSProperties | - | Inline styles |
disableDate | (date: string) => boolean | - | Callback to determine if a date should be disabled |
renderDayCell | (props: DayCellRenderProps) => ReactNode | - | Custom renderer for day cells |
DateRange Type
interface DateRange {
from: string | null; // ISO format: 'YYYY-MM-DD'
to?: string | null; // ISO format: 'YYYY-MM-DD'
}DayCellRenderProps Type
interface DayCellRenderProps {
day: number;
month: number;
year: number;
date: string; // 'YYYY-MM-DD' format
isDisabled: boolean;
isSelected: boolean;
isFocusedMonth: boolean; // true if the day is in the current month being viewed
}Date Format
All dates must be in ISO format: YYYY-MM-DD
// ✅ Correct
selectedDate="2024-12-25"
selectedDate="2024-01-01"
// ❌ Incorrect
selectedDate="12/25/2024"
selectedDate="25-12-2024"The component validates the date format and logs an error if invalid.
Examples
With Default Date
Pre-select a date when the calendar loads:
const [selectedDate, setSelectedDate] = useState<string | undefined>('2024-06-15');
<Calendar selectedDate={selectedDate} onSelectDate={setSelectedDate} />Use Cases:
- Highlight today's date
- Mark important dates (holidays, events)
- Show reference dates while selecting
Programmatic Control
Navigate to specific months/years using calendarRef:
'use client';
import { useState, useRef } from 'react';
import { Calendar, Button } from '@geckoui/geckoui';
import type { CalendarRef } from '@geckoui/geckoui';
function Example() {
const [selectedDate, setSelectedDate] = useState<string | undefined>();
const calendarRef = useRef<CalendarRef>(null);
const jumpToDate = (month: number, year: number) => {
calendarRef.current?.moveTo(month, year);
};
return (
<div className="space-y-4">
<div className="flex gap-2">
<Button size="sm" variant="outlined" onClick={() => jumpToDate(1, 2025)}>
January 2025
</Button>
<Button size="sm" variant="outlined" onClick={() => jumpToDate(7, 2024)}>
July 2024
</Button>
<Button size="sm" variant="outlined" onClick={() => jumpToDate(12, 2023)}>
December 2023
</Button>
</div>
<Calendar
selectedDate={selectedDate}
onSelectDate={setSelectedDate}
calendarRef={calendarRef}
/>
</div>
);
}CalendarRef API
interface CalendarRef {
moveTo: (month: number, year: number) => void;
}Parameters:
month: 1-12 (January = 1, December = 12)year: Full year (e.g., 2024, 2025)
Behavior:
- Switches view to Day mode
- Displays the specified month/year
- Does NOT select a date (only navigates)
Range Mode
Use mode="range" to enable date range selection with a dual-month calendar display.
'use client';
import { useState } from 'react';
import { Calendar } from '@geckoui/geckoui';
import type { DateRange } from '@geckoui/geckoui';
function Example() {
const [selectedRange, setSelectedRange] = useState<DateRange | undefined>();
return (
<Calendar
mode="range"
selectedRange={selectedRange}
onSelectRange={(range) => setSelectedRange(range ?? undefined)}
/>
);
}Single Month Display
<Calendar
mode="range"
selectedRange={selectedRange}
onSelectRange={(range) => setSelectedRange(range ?? undefined)}
/>Disable Dates
Use disableDate to prevent selection of specific dates. The callback receives a date string in YYYY-MM-DD format and returns true to disable the date.
'use client';
import { useState } from 'react';
import { Calendar } from '@geckoui/geckoui';
function Example() {
const [selectedDate, setSelectedDate] = useState<string | undefined>();
const disableDate = (date: string) => {
const dayOfWeek = new Date(date).getDay();
return dayOfWeek === 0 || dayOfWeek === 6; // Disable weekends
};
return (
<Calendar
selectedDate={selectedDate}
onSelectDate={setSelectedDate}
disableDate={disableDate}
/>
);
}Common Use Cases:
- Disable weekends
- Disable past dates
- Disable holidays or specific dates
- Disable dates outside a valid range
Custom Day Rendering
Use renderDayCell to customize how each day cell is displayed. This allows adding custom styling, indicators, or content to specific dates.
'use client';
import { useState } from 'react';
import { Calendar } from '@geckoui/geckoui';
import type { DayCellRenderProps } from '@geckoui/geckoui';
function Example() {
const [selectedDate, setSelectedDate] = useState<string | undefined>();
const hasEvent = (date: string) => {
const today = new Date();
return today.getDate() === new Date(date).getDate();
};
return (
<div className="space-y-4">
<Calendar
selectedDate={selectedDate}
onSelectDate={setSelectedDate}
renderDayCell={({ day, date }) => (
<>
<span>{day}</span>
{hasEvent(date) && (
<span className="absolute top-1 right-1 w-1.5 h-1.5 bg-red-500 rounded-full" />
)}
</>
)}
/>
{selectedDate && <p className="text-sm text-gray-600">Selected: {selectedDate}</p>}
</div>
);
}Common Use Cases:
- Add event indicators or dots
- Show custom styling for holidays
- Display additional information on hover
- Highlight specific date ranges
Styling
The component uses base class names with data-* attributes for states:
Main Container:
GeckoUICalendar- Main containerGeckoUICalendar[data-calendars="2"]- Dual calendar modeGeckoUICalendar[data-mode]- Current view mode (day,month,year)GeckoUICalendar[data-selection]- Selection mode (single,range)GeckoUICalendar__dual- Dual calendar wrapperGeckoUICalendar__dual[data-position="first"]/GeckoUICalendar__dual[data-position="second"]- First/second calendar
Header:
GeckoUICalendar__header- Header containerGeckoUICalendar__header__title- Month/year titleGeckoUICalendar__header__title[data-clickable]- Clickable title stateGeckoUICalendar__header__arrow-button- Navigation arrow buttonsGeckoUICalendar__header__arrow-left-icon/GeckoUICalendar__header__arrow-right-icon- Arrow icons
Year Picker:
GeckoUICalendar__year-picker- Year picker gridGeckoUICalendar__year-picker__button- Year buttonGeckoUICalendar__year-picker__button[data-selected]- Selected yearGeckoUICalendar__year-picker__button[data-prev-next]- Previous/next year buttons
Month Picker:
GeckoUICalendar__month-picker- Month picker gridGeckoUICalendar__month-picker__button- Month buttonGeckoUICalendar__month-picker__button[data-selected]- Selected month
Day Picker:
GeckoUICalendar__day-picker-weekdays- Weekday header rowGeckoUICalendar__day-picker- Day picker gridGeckoUICalendar__day-picker__button- Day buttonGeckoUICalendar__day-picker__button[data-today]- Today's dateGeckoUICalendar__day-picker__button[data-selected]- Selected dateGeckoUICalendar__day-picker__button[data-disabled]- Disabled dateGeckoUICalendar__day-picker__button[data-active-month]- Dates in current month (absent for outside dates)GeckoUICalendar__day-picker__button[data-in-range]- Date within selected rangeGeckoUICalendar__day-picker__button[data-range-start]- Range start dateGeckoUICalendar__day-picker__button[data-range-end]- Range end dateGeckoUICalendar__day-picker__button[data-hover-preview]- Hover preview for range selectionGeckoUICalendar__day-picker__button[data-hover-preview-start]/GeckoUICalendar__day-picker__button[data-hover-preview-end]- Hover preview boundaries
Accessibility
- Semantic HTML with proper table structure for day grid
- Keyboard navigation with arrow keys
- Tab to focus navigation buttons
- Enter/Space to select dates
- Screen reader announcements for date selection
- ARIA labels for navigation controls
Best Practices
- Always use ISO format: Use YYYY-MM-DD for all date values
- Validate dates: Check date ranges and constraints in onSelectDate
- Clear selection: Provide a way to clear the selected date
- Form integration: Disable submit until date is selected
- Error handling: Show validation errors near the calendar
- Responsive design: Calendar adapts to container width
Related Components
- DateInput - Input field with calendar popup
- DateRangeInput - Input for selecting date ranges
- RHFDateInput - React Hook Form integrated date input