Customization
React Calendar DateTime Picker offers extensive customization options to match your application's design. You can customize themes, colors, icons, labels, and more.
Custom Trigger Elements
Bind the calendar modal to any HTML element instead of just input fields. Use the triggerElement prop to create custom-styled triggers like buttons, divs, or any interactive element. When provided, the default input field will not be rendered.
Type Definition:
triggerElement?: ReactNodeProps:
Custom Div with Icon
Calendar triggered by a beautifully styled div element with icon and gradient
Component
Code
import { DtPicker } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtPicker
triggerElement={
<div
style={{
padding: '14px 20px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
borderRadius: '12px',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
gap: '12px',
minWidth: '240px',
boxShadow: '0 4px 15px rgba(102, 126, 234, 0.4)',
transition: 'all 0.3s ease',
color: 'white',
fontWeight: '500'
}}
onMouseEnter={(e) => {
e.currentTarget.style.transform = 'translateY(-2px)'
e.currentTarget.style.boxShadow = '0 6px 20px rgba(102, 126, 234, 0.5)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.transform = 'translateY(0)'
e.currentTarget.style.boxShadow = '0 4px 15px rgba(102, 126, 234, 0.4)'
}}
>
<span style={{ fontSize: '20px' }}>📅</span>
<span style={{ flex: 1 }}>Select Date</span>
<span style={{ fontSize: '12px', opacity: 0.9 }}>▼</span>
</div>
}
onChange={setDate}
/>
)
}Result
Selected value:
nullCustom Styled Input
Calendar triggered by a custom styled input field that displays the selected date
Component
Code
import { DtPicker, dayToString } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtPicker
calendarSystem="gregorian"
onChange={setDate}
triggerElement={
<input
type="text"
placeholder="Select a date..."
value={date ? dayToString(date, '/') : ''}
readOnly
style={{
padding: '12px 16px',
border: '2px solid #28a745',
borderRadius: '20px',
fontSize: '16px',
width: '280px',
outline: 'none',
backgroundColor: '#f8fff9',
color: '#155724',
fontWeight: '500'
}}
/>
}
/>
)
}Input with Icon Trigger
Calendar triggered by clicking an icon button. Users can type dates directly in the input field, and valid dates are automatically parsed and used as the initial value.
Component
Key Points
- • Editable Input: Users can type dates directly in the input field
- • Automatic Parsing: Uses
parseAndValidateDateto parse and validate date strings in one step - • Date Validation: Validates dates in three steps: 1) Parses the date string format, 2) Checks if the year is within the calendar's year range (Gregorian: 1900 to current year + 30, Jalali: 1300 to current year + 30), 3) Validates the date structure (month and day validity)
- • Year Range Validation: Dates with years outside the calendar's supported range will return an error with code
YEAR_OUT_OF_RANGE - • Icon Trigger: Clicking the icon opens the calendar modal
- • Visual Feedback: Input border color changes based on date validity (green for valid, red for invalid)
- • Two-way Binding: Dates selected from calendar update the input, and typed dates update the calendar
- • Flexible Input: Accepts date strings in formats: "2024/12/25", "2024-12-25", "2024.12.25"
Code
import { DtPicker, parseAndValidateDate } from 'react-calendar-datetime-picker'
import React, { useState, useCallback } from 'react'
import type { Day } from 'react-calendar-datetime-picker'
function InputWithIconTrigger({ onChange, ...props }) {
const [selectedDate, setSelectedDate] = useState<Day | null>(null)
const [inputValue, setInputValue] = useState<string>('')
// Check if input value is valid and get validation result
const validationResult = inputValue
? parseAndValidateDate(inputValue, 'gregorian')
: null
const isValid = validationResult?.success ?? null
const errorMessage = validationResult?.success === false ? validationResult.error?.message : null
// Handle input change - parse and validate
const handleInputChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
setInputValue(value)
// Parse and validate the date string
const validation = parseAndValidateDate(value, 'gregorian')
if (validation.success && validation.data) {
setSelectedDate(validation.data)
onChange?.(validation.data)
}
},
[onChange]
)
// Handle calendar selection
const handleCalendarChange = useCallback(
(date: Day | null, _jsDate: Date | null, formattedString: string | null) => {
setSelectedDate(date)
setInputValue(formattedString || '')
onChange?.(date) //or _jsDate
},
[onChange]
)
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', width: '100%', maxWidth: '300px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', width: '100%' }}>
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
<input
type="text"
placeholder="Type date (YYYY/MM/DD) or click icon"
value={inputValue}
onChange={handleInputChange}
style={{
width: '100%',
minWidth: 0,
padding: '10px 12px',
border: '2px solid',
borderRadius: '6px',
fontSize: '14px',
outline: 'none',
backgroundColor: '#ffffff',
color: '#111827',
borderColor: isValid === true ? '#10b981' : isValid === false ? '#ef4444' : '#d1d5db'
}}
/>
{errorMessage && (
<div style={{ marginTop: '4px', fontSize: '12px', color: '#ef4444', paddingLeft: '4px' }}>
{errorMessage}
</div>
)}
</div>
<div style={{ flexShrink: 0 }}>
<DtPicker
calendarSystem="gregorian"
initValue={selectedDate}
onChange={handleCalendarChange}
triggerElement={
<button
type="button"
style={{
padding: '10px',
border: 'none',
borderRadius: '6px',
backgroundColor: '#3b82f6',
color: 'white',
cursor: 'pointer',
fontSize: '18px',
minWidth: '40px',
height: '40px',
flexShrink: 0
}}
aria-label="Open calendar"
>
📅
</button>
}
/>
</div>
</div>
</div>
)
}React Hook Form Integration
Integrate DtPicker with React Hook Form using the Controller component. The custom trigger element displays the selected date value.
Component
Key Points
- • Use
Controllerto integrate with React Hook Form - • Use
field.valueto get the current form value (no need forwatch) - • Pass
initValue={field.value}to make DtPicker a controlled component - • Call
field.onChangeandfield.onBlurfor proper form validation - • Format the date using
dayToStringin the input value
Code
import { DtPicker, dayToString } from 'react-calendar-datetime-picker'
import { useForm, Controller } from 'react-hook-form'
import React from 'react'
function App() {
const { control, handleSubmit } = useForm({
defaultValues: {
birthDate: null
}
})
const onSubmit = (data) => {
console.log('Form data:', data)
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="birthDate"
control={control}
render={({ field }) => (
<DtPicker
calendarSystem="gregorian"
initValue={field.value}
onChange={(date) => {
field.onChange(date)
field.onBlur() // Trigger validation on change
}}
triggerElement={
<input
type="text"
placeholder="Select your birth date..."
value={field.value ? dayToString(field.value, '/') : ''}
readOnly
style={{
padding: '12px 16px',
border: '2px solid #6366f1',
borderRadius: '8px',
fontSize: '16px',
width: '100%',
outline: 'none',
backgroundColor: '#f8f9ff',
color: '#1e1b4b',
fontWeight: '500'
}}
/>
}
/>
)}
/>
<button type="submit">Submit</button>
</form>
)
}Usage Examples
Basic Button Trigger
import { DtPicker } from 'react-calendar-datetime-picker'
function App() {
return (
<DtPicker
triggerElement={
<button
style={{
padding: '10px 20px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
📅 Select Date
</button>
}
onChange={setDate}
/>
)
}Form Integration
// React Hook Form Integration
import { Controller } from 'react-hook-form'
<Controller
name="birthDate"
control={control}
render={({ field }) => (
<DtPicker
{...field}
triggerElement={
<input
placeholder="Birth date"
style={{
padding: '8px',
border: '1px solid #ccc',
borderRadius: '4px'
}}
/>
}
/>
)}
/>Key Benefits
- • Flexible Design: Use any HTML element as a trigger
- • Backward Compatible: Default input behavior unchanged
- • Accessible: Proper ARIA attributes and keyboard navigation
- • Framework Integration: Works with React Hook Form, Formik, etc.
Themes
The calendar supports light and dark themes, as well as custom themes using CSS variables. The dark prop enables the dark theme for both DtPicker and DtCalendar components.
Type Definition:
dark?: booleanProps:
true, enables the dark theme. Default is false (light theme).Light Theme
Calendar with light theme (default)
Component
Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
dark={false}
showWeekend={true}
todayBtn={true}
onChange={setDate}
/>
)
}Result
Selected value:
nullDark Theme
Calendar with dark theme enabled using the dark prop
Component
Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
dark={true}
showWeekend={true}
todayBtn={true}
onChange={setDate}
/>
)
}Result
Selected value:
nullCSS Variables (Recommended)
The easiest way to customize the calendar appearance is by overriding CSS variables. Apply custom variables using the calenderModalClass prop. This class is applied to the calendar component, allowing you to override any CSS variable.
Type Definition:
calenderModalClass?: stringProps:
Available CSS Variables
Color Variables
| Variable | Light Theme Default | Dark Theme Default | Description |
|---|---|---|---|
| Colors | |||
--calendar-primary | #009a17 | #16a34a | Primary accent color |
--calendar-primary-hover | #008213 | #15803d | Primary color on hover |
--calendar-primary-light | #a0f5ad | #14532d | Light variant of primary color |
--calendar-selected-day | #03bf1f | #16a34a | Selected day color |
--calendar-today | #029418 | #15803d | Today indicator color |
--calendar-selected-range | #a0f5ad | #14532d | Selected date range background |
--calendar-selected-range-color | #008213 | #4ade80 | Selected date range border color |
--calendar-weekends | #990000 | #f87171 | Weekend day text color |
--calendar-danger | #dc3545 | #ef4444 | Danger color |
| Background colors | |||
--calendar-bg | #ffffff | #1f2937 | Calendar background color |
--calendar-bg-hover | #f8f9fa | #374151 | Hover background color |
--calendar-bg-disabled | #e4ebe5 | #374151 | Disabled date background |
--calendar-bg-other-month | #e4ebe5 | #111827 | Other month days background |
--calendar-header-bg | var(--calendar-primary) | #1f2937 | Calendar header background |
| Text colors | |||
--calendar-text | #444 | #f3f4f6 | Primary text color |
--calendar-text-light | #666 | #e5e7eb | Light text color |
--calendar-text-lighter | #aaa | #9ca3af | Lighter text color |
--calendar-text-disabled | #aebfa9 | #6b7280 | Disabled text color |
--calendar-text-header | #ffffff | #ffffff | Header text color |
--calendar-text-day-names | #aaa | #9ca3af | Day names text color |
--calendar-text-other-month | #aebfa9 | #6b7280 | Other month days text color |
--calendar-icon-color | #c9c9c9 | #9ca3af | Icon color |
| Border colors | |||
--calendar-border | #dee2e6 | #374151 | Border color |
--calendar-border-focus | #009a17 | #16a34a | Focus border color |
Other Variables
| Variable | Default Value | Description |
|---|---|---|
| Font sizes | ||
--calendar-header-text-font-size | 18px | Header text font size (month/year buttons and titles) |
--calendar-cell-font-size | 16px | Default grid cell font size |
--calendar-cell-font-size-selected | 18px | Selected cell font size (when enlarged) |
--calendar-month-view-font-size | 14px | Month view default font size |
--calendar-month-view-font-size-selected | 22px | Month view selected font size |
--calendar-year-view-font-size | 14px | Year view default font size |
--calendar-year-view-font-size-selected | 22px | Year view selected font size |
--calendar-footer-btn-font-size | 16px | Footer buttons font size (Today button and preset range buttons) |
| Spacing | ||
--calendar-spacing-xs | 0.25rem | Extra small spacing |
--calendar-spacing-sm | 0.5rem | Small spacing |
--calendar-spacing-md | 1rem | Medium spacing |
--calendar-spacing-lg | 1.5rem | Large spacing |
| Border radius | ||
--calendar-radius-sm | 4px | Small border radius |
--calendar-radius-md | 8px | Medium border radius |
--calendar-radius-lg | 16px | Large border radius |
| Grid cell size | ||
--calendar-cell-size | 44px | Grid cell size - controls calendar grid scaling (calendar width = cell-size × 7). Header and footer remain unchanged. |
| Transitions | ||
--calendar-transition | all 0.2s ease-in-out | Transition timing and easing |
Using calenderModalClass Prop
Tip: This approach applies the class directly to the calendar component, making it cleaner and more direct.
Blue Example
Custom blue theme using CSS variables with calenderModalClass prop
Component
CSS Styles
/* styles.css */
.calendar-blue-theme {
--calendar-bg: #eff6ff;
--calendar-text: #1e40af;
--calendar-text-light: #1e40af;
--calendar-border: #3b82f6;
--calendar-bg-hover: #dbeafe;
--calendar-selected-day: #2563eb;
--calendar-today: #1d4ed8;
--calendar-bg-disabled: #9ca3af;
--calendar-text-disabled: #9ca3af;
--calendar-border-focus: #2563eb;
--calendar-primary: #2563eb;
--calendar-header-bg: #2563eb;
}Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
showWeekend={true}
todayBtn={true}
calenderModalClass="calendar-blue-theme"
onChange={setDate}
/>
)
}Brown Example
Custom brown dark theme using CSS variables with calenderModalClass prop
Component
CSS Styles
/* styles.css */
.react-calendar-datetime-picker.calendar-dark-custom-theme[data-theme='dark'],
.calendar-dark-custom-theme[data-theme='dark'] {
/* Override only background colors - primary colors remain default dark theme green */
/* Using warmer dark brown tones - visually very distinct from default cool gray (#1f2937) */
--calendar-bg: #2c1810;
--calendar-bg-hover: #3d2418;
--calendar-bg-selected: #2c1810;
--calendar-header-bg: #2c1810;
--calendar-border: #4a2e1f;
}Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
dark={true}
showWeekend={true}
todayBtn={true}
calenderModalClass="calendar-dark-custom-theme"
onChange={setDate}
/>
)
}Smaller Calendar Example
Make the calendar grid smaller by reducing the cell size. Header and footer remain unchanged.
Component
CSS Styles
/* styles.css */
.calendar-small-size {
/* Smaller grid cells - calendar width = 35px * 7 = 245px */
--calendar-cell-size: 35px;
--calendar-month-view-font-size: 12px;
--calendar-month-view-font-size-selected: 16px;
--calendar-year-view-font-size: 12px;
--calendar-year-view-font-size-selected: 16px;
}Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
showWeekend={true}
todayBtn={true}
calenderModalClass="calendar-small-size"
onChange={setDate}
/>
)
}Larger Calendar Example
Make the calendar grid larger by increasing the cell size. Header and footer remain unchanged.
Component
CSS Styles
/* styles.css */
.calendar-large-size {
/* Larger grid cells - calendar width = 50px * 7 = 350px */
--calendar-cell-size: 50px;
--calendar-cell-font-size: 16px;
--calendar-cell-font-size-selected: 20px;
}Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
showWeekend={true}
todayBtn={true}
calenderModalClass="calendar-large-size"
onChange={setDate}
/>
)
}Year List Style
Control how the year selection view is displayed. Choose between a grid layout (default) or a vertical list layout.
Grid Layout (Default)
Year selection view displayed in a grid layout. This is the default style.
Component
Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
yearListStyle="grid"
showWeekend={true}
todayBtn={true}
onChange={setDate}
/>
)
}Result
Selected value:
nullList Layout
Year selection view displayed in a vertical list layout. Useful for better scrolling on mobile devices or when you prefer a more compact vertical layout.
Component
Code
import { DtCalendar } from 'react-calendar-datetime-picker'
import React, { useState } from 'react'
function App() {
const [date, setDate] = useState(null)
return (
<DtCalendar
yearListStyle="list"
showWeekend={true}
todayBtn={true}
onChange={setDate}
/>
)
}Result
Selected value:
nullCustom CSS Classes
Override specific calendar elements using the customization prop with the classes property. This allows you to add custom CSS classes to specific calendar components.
Type Definition:
interface CalendarClasses {
header?: string
days?: string
months?: string
years?: string
}
customization?: {
classes?: CalendarClasses
}Properties:
<DtCalendar
calenderModalClass="my-custom-calendar"
// ... other props
/>Available CSS Classes
Calendar Structure
.react-calendar-datetime-picker- Root container.calendar-header- Header section.calendar-days-grid- Days grid container.calendar-months-view- Months selection view.calendar-years-view- Years selection view
Interactive Elements
.calendar-day- Individual day cells.calendar-day--selected- Selected days.calendar-day--today- Today's date.calendar-day--disabled- Disabled days.calendar-nav-button- Navigation buttons
Custom Icons
Customize navigation icons using the customization prop with the icons property. Replace the default chevron icons with your own React components.
Type Definition:
interface CalendarIcons {
next?: React.ComponentType<{ className?: string }>
previous?: React.ComponentType<{ className?: string }>
}
customization?: {
icons?: CalendarIcons
}Properties:
className prop.className prop.Custom Arrow Icons
Calendar with custom arrow navigation icons
Component
Code
import { DtCalendar } from 'react-calendar-datetime-picker'
const CustomPrevIcon = ({ className }) => (
<svg className={className} viewBox="0 0 20 20" fill="currentColor">
<path d="M10 5L5 10L10 15M15 5L10 10L15 15" />
</svg>
)
const CustomNextIcon = ({ className }) => (
<svg className={className} viewBox="0 0 20 20" fill="currentColor">
<path d="M10 5L15 10L10 15M5 5L10 10L5 15" />
</svg>
)
function App() {
const { theme } = useTheme()
return (
<DtCalendar
dark={theme === 'dark'}
customization={{
icons: {
previous: CustomPrevIcon,
next: CustomNextIcon
}
}}
/>
)
}Result
Selected value:
null