syncfusion-react-calendars — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited syncfusion-react-calendars (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The Syncfusion React CalendarComponent is a highly customizable calendar UI control that allows users to select single or multiple dates. It supports multiple views (Month, Year, Decade), navigation, week numbers, disabled dates, custom day cell rendering, localization, RTL support, and full accessibility (WCAG 2.2 compliant).
#### Install
npm install @syncfusion/ej2-react-calendars @syncfusion/ej2-base#### Basic Example (App.jsx)
import React, { useState } from 'react';
import { CalendarComponent } from '@syncfusion/ej2-react-calendars';
import '@syncfusion/ej2-base/styles/material3.css';
import '@syncfusion/ej2-calendars/styles/material3.css';
export default function App() {
const [value, setValue] = useState(new Date());
const onChange = (args) => setValue(args.value || args);
return (
<div style={{ padding: 20 }}>
<h3>Select a date</h3>
<CalendarComponent value={value} change={onChange} />
<p>Selected: {value.toDateString()}</p>
</div>
);
}Notes:
change event to sync selected date to React state.value via change event.isMultiSelection={true} with values prop and addDate()/removeDate() methods.ref to call navigateTo(view, date) — both arguments are required (see references/getting-started-react.md).role="region" and a separate aria-live region for announcements — these are not direct Calendar props.weekNumber={true} (the correct prop name).Navigate to the reference that matches your current task:
#### Getting Started 📄 Read: references/getting-started-react.md
#### Date Selection 📄 Read: references/date-selection.md
#### Calendar Views 📄 Read: references/calendar-views.md
#### Styling & Customization 📄 Read: references/styling-customization.md
#### Events & Methods 📄 Read: references/events-methods.md
#### Accessibility & Globalization 📄 Read: references/accessibility-globalization.md
#### API Reference (Quick Lookup) 📄 Read: references/api-reference.md
#### Troubleshooting & Tips
node_modules/@syncfusion/ej2-calendars/styles/ and are loaded before component styles.value prop and change event to keep React state in sync — do not rely on framework-specific bindings.isMultiSelection={true} and use values (not value) for the initial array.navigateTo(view: CalendarView, date: Date).npm install @syncfusion/ej2-react-calendars @syncfusion/ej2-base and confirm package.json.weekNumber={true} (not showWeekNumber).The Syncfusion React DatePickerComponent provides an intuitive input control with a calendar popup for selecting a single date. It features flexible formatting, masked input, min/max date validation, strict mode, multiple input formats, custom day rendering, localization, and seamless integration as a controlled React component.
The DatePicker is a Syncfusion React component for date selection with powerful features:
enableMask for segment-by-segment date entry with maskPlaceholderstrictMode automatic correctionstart and depth propertiesrenderDayCell eventenableRtl), locale-specific formatting, firstDayOfWeekshow(), hide(), focusIn(), focusOut(), navigateTo(), currentView()#### Key Properties
| Property | Type | Default | Description | |
|---|---|---|---|---|
value | Date | null | Selected date | |
min | Date | 1900-01-01 | Minimum selectable date | |
max | Date | 2099-12-31 | Maximum selectable date | |
format | string \ | FormatObject | null | Display format (e.g., "dd/MM/yyyy") |
inputFormats | string[] \ | FormatObject[] | null | Accepted input formats array |
placeholder | string | null | Placeholder text for the input | |
enabled | boolean | true | Enable or disable the component | |
readonly | boolean | false | Readonly state | |
allowEdit | boolean | true | Allow editing the input textbox | |
strictMode | boolean | false | Auto-correct out-of-range dates | |
showClearButton | boolean | true | Show/hide the clear button | |
showTodayButton | boolean | true | Show/hide today button | |
start | CalendarView | Month | Initial view: "Month", "Year", "Decade" | |
depth | CalendarView | Month | Deepest navigation level | |
enableMask | boolean | false | Enable masked date input | |
maskPlaceholder | MaskPlaceholderModel | {...} | Segment placeholders for masked input | |
enableRtl | boolean | false | Right-to-left rendering | |
locale | string | '' | Culture/locale code | |
firstDayOfWeek | number | 0 | First day of week (0=Sunday) | |
weekNumber | boolean | false | Show week numbers | |
weekRule | WeekRule | FirstDay | Rule for first week of year | |
calendarMode | CalendarType | Gregorian | Calendar type (Gregorian or Islamic) | |
dayHeaderFormat | DayHeaderFormats | Short | Day name format in header | |
floatLabelType | FloatLabelType | Never | Floating label behavior | |
fullScreenMode | boolean | false | Full screen popup on mobile | |
openOnFocus | boolean | false | Open popup on input focus | |
serverTimezoneOffset | number | null | Server timezone offset | |
cssClass | string | null | Custom CSS class | |
htmlAttributes | { [key: string]: string } | {} | Additional HTML attributes | |
keyConfigs | { [key: string]: string } | null | Custom key action mappings | |
width | number \ | string | null | Component width |
zIndex | number | 1000 | Popup z-index | |
enablePersistence | boolean | false | Persist state between reloads |
#### Methods
| Method | Returns | Description |
|---|---|---|
show() | void | Opens the calendar popup |
hide() | void | Closes the calendar popup |
focusIn() | void | Sets focus to the component |
focusOut() | void | Removes focus from the component |
navigateTo(view, date) | void | Navigates to a specific view and date |
currentView() | string | Returns the current calendar view name |
getPersistData() | string | Gets persisted state data |
removeDate(dates) | void | Removes date(s) from the values |
destroy() | void | Destroys the component |
#### Events
| Event | Args Type | Description | |
|---|---|---|---|
change | ChangedEventArgs | Fires when the selected date changes | |
focus | FocusEventArgs | Fires when input gains focus | |
blur | BlurEventArgs | Fires when input loses focus | |
open | PreventableEventArgs \ | PopupObjectArgs | Fires when the popup opens |
close | PreventableEventArgs \ | PopupObjectArgs | Fires when the popup closes |
cleared | ClearedEventArgs | Fires when value is cleared | |
created | Object | Fires when component is created | |
destroyed | Object | Fires when component is destroyed | |
navigated | NavigatedEventArgs | Fires when calendar view is navigated | |
renderDayCell | RenderDayCellEventArgs | Fires when each day cell is rendered |
When the user needs help with DatePicker, guide them to the appropriate reference:
#### Getting Started 📄 Read: references/getting-started.md
#### Date Formats & Input 📄 Read: references/date-formats-and-input.md
#### Date Range & Validation 📄 Read: references/date-range-and-validation.md
#### Date Views & Navigation 📄 Read: references/date-views-and-navigation.md
#### Customization & Styling 📄 Read: references/customization-and-styling.md
#### Globalization & Localization 📄 Read: references/globalization-and-localization.md
#### Accessibility & Keyboard Navigation 📄 Read: references/accessibility-and-keyboard.md
#### Date Masking & Advanced Validation 📄 Read: references/date-masking-and-strict-mode.md
enableMask property for structured segment-by-segment date inputmaskPlaceholder for custom segment placeholder textstrictMode property behavior and enforcementHere's a minimal working example to get started:
import React, { useState } from 'react';
import { DatePickerComponent } from '@syncfusion/ej2-react-calendars';
import '@syncfusion/ej2-base/styles/material3.css';
import '@syncfusion/ej2-buttons/styles/material3.css';
import '@syncfusion/ej2-inputs/styles/material3.css';
import '@syncfusion/ej2-popups/styles/material3.css';
import '@syncfusion/ej2-react-calendars/styles/material3.css';
export default function App() {
const [selectedDate, setSelectedDate] = useState(new Date());
return (
<div style={{ padding: '20px' }}>
<h3>Select a Date</h3>
<DatePickerComponent
value={selectedDate}
change={(e) => setSelectedDate(e.value)}
placeholder="Enter date"
/>
<p>Selected: {selectedDate?.toDateString()}</p>
</div>
);
}Key points:
DatePickerComponent from @syncfusion/ej2-react-calendarsvalue prop for the current date (can be null or Date object)change event (not onChange) to update React state — this is the Syncfusion event name#### 1. Date Range Picker (Min/Max Dates)
<DatePickerComponent
value={new Date()}
min={new Date(2026, 0, 1)}
max={new Date(2026, 11, 31)}
placeholder="Select a date in 2026"
/>#### 2. Custom Date Format
<DatePickerComponent
value={new Date()}
format="dd/MM/yyyy"
placeholder="DD/MM/YYYY"
/>#### 3. Multiple Accepted Input Formats
<DatePickerComponent
value={new Date()}
format="yyyy-MM-dd"
inputFormats={['dd/MM/yyyy', 'yyyy-MM-dd', 'yyyyMMdd']}
placeholder="Enter date (dd/MM/yyyy or yyyy-MM-dd)"
/>#### 4. Year/Decade View for Birth Date Selection
<DatePickerComponent
value={new Date()}
start="Decade"
depth="Year"
placeholder="Select year"
/>#### 5. Disable Weekends
<DatePickerComponent
value={new Date()}
renderDayCell={(args) => {
if ((args.date.getDay()) === 0 || (args.date.getDay()) === 6) {
args.isDisabled = true;
}
}}
placeholder="Weekdays only"
/>#### 6. Controlled Component in React Form
const [date, setDate] = useState(null);
<DatePickerComponent
value={date}
change={(e) => setDate(e.value)}
format="yyyy-MM-dd"
strictMode={true}
placeholder="Enter date"
/>#### 7. German Culture with RTL Support
<DatePickerComponent
locale="de"
enableRtl={false}
firstDayOfWeek={1}
value={new Date()}
placeholder="Datum eingeben"
/>#### 8. Masked Date Input
<DatePickerComponent
enableMask={true}
format="MM/dd/yyyy"
maskPlaceholder={{ day: 'DD', month: 'MM', year: 'YYYY' }}
placeholder="Select a date"
/>#### 9. Programmatic Control
import { useRef } from 'react';
const datePickerRef = useRef(null);
// Open calendar
datePickerRef.current.show();
// Close calendar
datePickerRef.current.hide();
// Focus
datePickerRef.current.focusIn();
// Get current view
const view = datePickerRef.current.currentView(); // "Month" | "Year" | "Decade"
// Navigate to specific view
datePickerRef.current.navigateTo('Year', new Date(2026, 0, 1));
<DatePickerComponent ref={datePickerRef} value={new Date()} />#### 10. Handle All Key Events
<DatePickerComponent
value={new Date()}
change={(e) => console.log('Changed:', e.value)}
focus={(e) => console.log('Focused')}
blur={(e) => console.log('Blurred')}
open={(e) => console.log('Opened')}
close={(e) => console.log('Closed')}
cleared={(e) => console.log('Cleared')}
navigated={(e) => console.log('Navigated to view:', e.view)}
renderDayCell={(args) => {
// Disable weekends
if (args.date.getDay() === 0 || args.date.getDay() === 6) {
args.isDisabled = true;
}
}}
/>The Syncfusion React DateRangePickerComponent enables users to select a start and end date range with built-in support for presets, validation, custom formatting, separator configuration, full-screen mobile mode, and advanced range constraints (minDays, maxDays, min, max).
#### Getting Started 📄 Read: references/getting-started.md
#### Date Range Selection 📄 Read: references/date-range-selection.md
#### Date Range Formatting 📄 Read: references/date-range-formatting.md
#### Events and Methods 📄 Read: references/events-and-methods.md
#### Customization and Styling 📄 Read: references/customization-and-styling.md
#### API Reference 📄 Read: references/api-reference.md
#### Advanced Patterns 📄 Read: references/advanced-patterns.md
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
import '@syncfusion/ej2-base/styles/material3.css';
import '@syncfusion/ej2-buttons/styles/material3.css';
import '@syncfusion/ej2-lists/styles/material3.css';
import '@syncfusion/ej2-inputs/styles/material3.css';
import '@syncfusion/ej2-popups/styles/material3.css';
import '@syncfusion/ej2-calendars/styles/material3.css';
function App() {
const [selectedRange, setSelectedRange] = React.useState<[Date, Date] | null>(null);
const handleDateRangeChange = (e: any) => {
setSelectedRange([e.startDate, e.endDate]);
};
return (
<div style={{ padding: '20px' }}>
<h2>Select Date Range</h2>
<DateRangePickerComponent
id="daterangepicker"
placeholder="Select a range"
change={handleDateRangeChange}
/>
{selectedRange && (
<p>
Selected: {selectedRange[0]?.toLocaleDateString()} - {selectedRange[1]?.toLocaleDateString()}
</p>
)}
</div>
);
}
export default App;#### Pattern 1: Date Range with Preset Options
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function ReportingDashboard() {
const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);
const getDateRangePresets = () => {
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
const last7Days = new Date(today);
last7Days.setDate(today.getDate() - 7);
const last30Days = new Date(today);
last30Days.setDate(today.getDate() - 30);
const thisMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const lastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
return [
{ text: 'Today', value: [today, today] },
{ text: 'Yesterday', value: [yesterday, yesterday] },
{ text: 'Last 7 Days', value: [last7Days, today] },
{ text: 'Last 30 Days', value: [last30Days, today] },
{ text: 'This Month', value: [thisMonth, today] },
{ text: 'Last Month', value: [new Date(today.getFullYear(), today.getMonth() - 1, 1), lastMonth] },
];
};
const handlePresetClick = (start: Date, end: Date) => {
setDateRange([start, end]);
};
return (
<div style={{ padding: '20px' }}>
<h3>Analytics Report</h3>
<DateRangePickerComponent
id="daterangepicker"
placeholder="Select report date range"
startDate={dateRange?.[0]}
endDate={dateRange?.[1]}
change={(e: any) => setDateRange([e.startDate, e.endDate])}
/>
<div style={{ marginTop: '15px' }}>
{getDateRangePresets().map((preset) => (
<button
key={preset.text}
onClick={() => handlePresetClick(preset.value[0], preset.value[1])}
style={{ marginRight: '10px', padding: '5px 10px' }}
>
{preset.text}
</button>
))}
</div>
</div>
);
}
export default ReportingDashboard;#### Pattern 2: Date Range with Validation
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';
function BookingForm() {
const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);
const [validationError, setValidationError] = React.useState<string>('');
const minDate = new Date();
const maxDate = new Date();
maxDate.setDate(maxDate.getDate() + 90); // 90 days from now
const handleDateRangeChange = (e: any) => {
setValidationError('');
if (!e.startDate || !e.endDate) {
return;
}
const start = new Date(e.startDate);
const end = new Date(e.endDate);
// Validation checks
if (start > end) {
setValidationError('Start date must be before end date');
return;
}
const daysDifference = (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24);
if (daysDifference > 30) {
setValidationError('Date range cannot exceed 30 days');
return;
}
setDateRange([start, end]);
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (dateRange && !validationError) {
console.log('Booking dates:', {
checkIn: dateRange[0].toLocaleDateString(),
checkOut: dateRange[1].toLocaleDateString(),
});
}
};
return (
<form onSubmit={handleSubmit} style={{ padding: '20px', maxWidth: '500px' }}>
<h3>Book Your Stay</h3>
<label style={{ display: 'block', marginBottom: '8px' }}>
Select Check-in and Check-out Dates (Max 30 days)
</label>
<DateRangePickerComponent
id="daterangepicker"
placeholder="Select check-in and check-out"
min={minDate}
max={maxDate}
startDate={dateRange?.[0]}
endDate={dateRange?.[1]}
change={handleDateRangeChange}
style={{ width: '100%', marginBottom: '8px' }}
/>
{validationError && (
<div style={{ color: 'red', marginBottom: '10px', fontSize: '14px' }}>
⚠️ {validationError}
</div>
)}
<ButtonComponent
type="submit"
isPrimary={true}
disabled={!dateRange || !!validationError}
>
Book Now
</ButtonComponent>
</form>
);
}
export default BookingForm;<!-- Pattern 3 removed: examples using non-API props (e.g., disabledDates) deleted to match authoritative API reference -->
#### Pattern 4: Event Handling and State Management
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function EventTrackingExample() {
const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);
const [eventLog, setEventLog] = React.useState<string[]>([]);
const handleSelect = (e: any) => {
setEventLog(prev => [
...prev,
`Selected: ${e.startDate?.toLocaleDateString()} to ${e.endDate?.toLocaleDateString()}`
]);
};
const handleChange = (e: any) => {
setDateRange([e.startDate, e.endDate]);
setEventLog(prev => [...prev, `Changed: ${new Date().toLocaleTimeString()}`]);
};
const handleOpen = (e: any) => {
setEventLog(prev => [...prev, `Popup opened at ${new Date().toLocaleTimeString()}`]);
};
const handleClose = (e: any) => {
setEventLog(prev => [...prev, `Popup closed at ${new Date().toLocaleTimeString()}`]);
};
const clearLog = () => {
setEventLog([]);
};
return (
<div style={{ padding: '20px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
<div>
<h3>DateRangePicker</h3>
<DateRangePickerComponent
id="daterangepicker"
placeholder="Select date range"
select={handleSelect}
change={handleChange}
open={handleOpen}
close={handleClose}
/>
</div>
<div style={{ padding: '10px', border: '1px solid #ccc', borderRadius: '4px' }}>
<h3>Event Log</h3>
<button
onClick={clearLog}
style={{
padding: '5px 10px',
marginBottom: '10px',
backgroundColor: '#f0f0f0',
border: '1px solid #ccc',
cursor: 'pointer'
}}
>
Clear Log
</button>
<ul style={{ maxHeight: '300px', overflowY: 'auto', margin: 0, paddingLeft: '20px' }}>
{eventLog.map((event, idx) => (
<li key={idx} style={{ marginBottom: '5px', fontSize: '12px' }}>
{event}
</li>
))}
</ul>
</div>
</div>
);
}
export default EventTrackingExample;#### Pattern 5: Custom Date Range Format
import { DateRangePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function DateFormatDemo() {
const [formatType, setFormatType] = React.useState<'short' | 'long' | 'custom'>('short');
const [dateRange, setDateRange] = React.useState<[Date, Date] | null>(null);
const getFormat = () => {
switch (formatType) {
case 'short':
return 'M/d/yyyy';
case 'long':
return 'MMMM d, yyyy';
case 'custom':
return 'dd-MMM-yy';
default:
return 'M/d/yyyy';
}
};
return (
<div style={{ padding: '20px' }}>
<h3>Date Range Format Options</h3>
<div style={{ marginBottom: '15px' }}>
<label style={{ marginRight: '10px' }}>Format Type:</label>
{(['short', 'long', 'custom'] as const).map((format) => (
<label key={format} style={{ marginRight: '15px' }}>
<input
type="radio"
name="format"
value={format}
checked={formatType === format}
onChange={(e) => setFormatType(e.target.value as any)}
/>
{format.charAt(0).toUpperCase() + format.slice(1)}
</label>
))}
</div>
<div style={{ marginBottom: '10px', padding: '10px', backgroundColor: '#f5f5f5' }}>
<strong>Format String:</strong> {getFormat()}
</div>
<DateRangePickerComponent
id="daterangepicker"
placeholder="Select date range"
format={getFormat()}
startDate={dateRange?.[0]}
endDate={dateRange?.[1]}
change={(e: any) => setDateRange([e.startDate, e.endDate])}
/>
{dateRange && (
<div style={{ marginTop: '15px', padding: '10px', backgroundColor: '#e8f5e9' }}>
<p>
<strong>Formatted Output:</strong> {dateRange[0].toLocaleDateString('en-US')} - {dateRange[1].toLocaleDateString('en-US')}
</p>
</div>
)}
</div>
);
}
export default DateFormatDemo;startDate: Type: Date — Default: null — Initial start date of the range.endDate: Type: Date — Default: null — Initial end date of the range.min: Type: Date — Default: new Date(1900, 0, 1) — Minimum selectable date.max: Type: Date — Default: new Date(2099, 11, 31) — Maximum selectable date.value: Type: Date[] | DateRange — Default: null — Gets or sets the start and end date.format: Type: string | RangeFormatObject — Default: null — Date display and input format.placeholder: Type: string — Default: null — Input placeholder text.enabled: Type: boolean — Default: true — Enables or disables the component (use enabled, not disabled).readonly: Type: boolean — Default: false — Read-only state; prevents editing.allowEdit: Type: boolean — Default: true — Allow manual text editing of the input.cssClass: Type: string — Default: '' — Adds a custom CSS class to the root element.floatLabelType: Type: FloatLabelType | string — Default: Never — Float label behavior (Never, Always, Auto).separator: Type: string — Default: '-' — Separator string between start and end date in the input.locale: Type: string — Default: 'en-US' — Locale used for formatting and localization.inputFormats: Type: string[] | RangeFormatObject[] — Default: null — Acceptable input parsing formats.keyConfigs: Type: object — Default: null — Custom keyboard shortcuts mapping.firstDayOfWeek: Type: number — Default: null — First day of week for calendar rendering.dayHeaderFormat: Type: DayHeaderFormats — Default: Short — Day name format in header.start: Type: CalendarView — Default: Month — Initial calendar view when popup opens.depth: Type: CalendarView — Default: Month — Maximum navigation depth for the calendar.weekNumber: Type: boolean — Default: false — Show week numbers in calendar rows.weekRule: Type: WeekRule — Default: FirstDay — Rule that defines first week of the year.minDays: Type: number — Default: null — Minimum allowed span of days in a selection.maxDays: Type: number — Default: null — Maximum allowed span of days in a selection.strictMode: Type: boolean — Default: false — When true, only valid ranges can be entered.showClearButton: Type: boolean — Default: true — Toggle visibility of the clear button.fullScreenMode: Type: boolean — Default: false — Use full-screen popup on mobile.htmlAttributes: Type: { [key: string]: string } — Default: {} — Additional HTML attributes applied to the component element.serverTimezoneOffset: Type: number — Default: null — Server timezone offset in minutes for initial value processing.width: Type: number | string — Default: '' — Width of the component input.zIndex: Type: number — Default: 1000 — z-index for popup element.Next Steps:
The Syncfusion React DateTimePickerComponent combines date and time selection in a single control. It offers calendar + time list popup, customizable time steps, masking, strict validation, timezone handling, format customization, and full keyboard accessibility.
npm install @syncfusion/ej2-react-calendarsindex.css or component CSS):@import '../node_modules/@syncfusion/ej2-base/styles/material3.css';
@import '../node_modules/@syncfusion/ej2-calendars/styles/material3.css';App.tsx):import React, { useState } from 'react';
import { DateTimePickerComponent } from '@syncfusion/ej2-react-calendars';
export default function App() {
const [value, setValue] = useState<Date | null>(new Date());
return (
<div style={{ padding: 20 }}>
<h3>Choose date and time</h3>
<DateTimePickerComponent
value={value}
change={(e) => setValue((e as any).value)}
format="dd/MM/yyyy hh:mm a"
step={15}
placeholder="Select date and time"
/>
<p>Selected: {value ? value.toString() : 'none'}</p>
</div>
);
}value and update on change.min and max for dates, minTime/maxTime for times.enableMask and provide maskPlaceholder.locale or use global culture settings.keyConfigs for custom shortcuts.value, min, max, step, format, enableMask, placeholder, cssClass, locale, readonly, enabled.change, open, close, created, destroyed, navigated, blur, focus, renderDayCell.references/api-reference.md).completion-status.json, or produce publish-ready artifacts.The Syncfusion React TimePickerComponent is a lightweight and feature-rich control for selecting time values. It supports 12/24-hour formats, time stepping, min/max constraints, masked input, localization, full-screen mode, and easy integration into React forms.
#### Getting Started 📄 Read: references/getting-started.md
#### Time Format and Display 📄 Read: references/time-format-and-display.md
#### Time Range and Selection 📄 Read: references/time-range-and-selection.md
#### Events and Methods 📄 Read: references/events-and-methods.md
#### Customization and Styling 📄 Read: references/customization-and-styling.md
#### API Reference 📄 Read: references/api-reference.md
#### Advanced Patterns 📄 Read: references/advanced-patterns.md
import { TimePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
import '@syncfusion/ej2-base/styles/material3.css';
import '@syncfusion/ej2-calendars/styles/material3.css';
function App() {
const [selectedTime, setSelectedTime] = React.useState(new Date('1/1/2018 9:00 AM'));
const handleChange = (e: any) => {
setSelectedTime(e.value);
};
return (
<div style={{ padding: '20px' }}>
<h2>Select Time</h2>
<TimePickerComponent
value={selectedTime}
change={handleChange}
placeholder="Select a time"
/>
<p>Selected: {selectedTime ? selectedTime.toLocaleTimeString() : 'None'}</p>
</div>
);
}
export default App;#### Pattern 1: Time Picker with Min/Max Constraints
import { TimePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function AppointmentScheduler() {
const [appointmentTime, setAppointmentTime] = React.useState(new Date('1/1/2018 9:00 AM'));
const minTime = new Date('1/1/2018 8:00 AM');
const maxTime = new Date('1/1/2018 5:00 PM');
return (
<div>
<h3>Select Appointment Time (8 AM - 5 PM)</h3>
<TimePickerComponent
value={appointmentTime}
min={minTime}
max={maxTime}
step={30}
change={(e: any) => setAppointmentTime(e.value)}
placeholder="Choose time"
/>
</div>
);
}
export default AppointmentScheduler;#### Pattern 2: Form with Time Picker Submission
import { TimePickerComponent } from '@syncfusion/ej2-react-calendars';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import * as React from 'react';
function ScheduleForm() {
const [formData, setFormData] = React.useState({
startTime: new Date('1/1/2018 9:00 AM'),
endTime: new Date('1/1/2018 5:00 PM'),
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log('Schedule data:', {
startTime: formData.startTime?.toLocaleTimeString(),
endTime: formData.endTime?.toLocaleTimeString(),
});
};
return (
<form onSubmit={handleSubmit}>
<h3>Schedule Meeting</h3>
<label>Start Time:</label>
<TimePickerComponent
value={formData.startTime}
change={(e: any) => setFormData(prev => ({ ...prev, startTime: e.value }))}
/>
<label style={{ marginTop: '10px' }}>End Time:</label>
<TimePickerComponent
value={formData.endTime}
min={formData.startTime}
change={(e: any) => setFormData(prev => ({ ...prev, endTime: e.value }))}
/>
<ButtonComponent type="submit" isPrimary={true} style={{ marginTop: '15px' }}>
Schedule
</ButtonComponent>
</form>
);
}
export default ScheduleForm;#### Pattern 3: Time Picker with Custom Format
import { TimePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function TimeFormatDemo() {
const [time12hr, setTime12hr] = React.useState(new Date('1/1/2018 2:30 PM'));
const [time24hr, setTime24hr] = React.useState(new Date('1/1/2018 14:30'));
return (
<div style={{ padding: '20px' }}>
<div>
<h4>12-Hour Format (hh:mm a)</h4>
<TimePickerComponent
value={time12hr}
format="hh:mm a"
change={(e: any) => setTime12hr(e.value)}
/>
<p>Value: {time12hr?.toLocaleTimeString('en-US', { hour12: true })}</p>
</div>
<div style={{ marginTop: '20px' }}>
<h4>24-Hour Format (HH:mm)</h4>
<TimePickerComponent
value={time24hr}
format="HH:mm"
change={(e: any) => setTime24hr(e.value)}
/>
<p>Value: {time24hr?.toLocaleTimeString('en-US', { hour12: false })}</p>
</div>
</div>
);
}
export default TimeFormatDemo;#### Pattern 4: Event Handling and State Management
import { TimePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function EventTrackingExample() {
const [selectedTime, setSelectedTime] = React.useState<Date | null>(null);
const [eventLog, setEventLog] = React.useState<string[]>([]);
const handleChange = (e: any) => {
setSelectedTime(e.value);
setEventLog(prev => [...prev, `Changed: ${e.value?.toLocaleTimeString()}`]);
};
const handleOpen = (e: any) => {
setEventLog(prev => [...prev, 'Popup opened']);
};
const handleClose = (e: any) => {
setEventLog(prev => [...prev, 'Popup closed']);
};
return (
<div style={{ padding: '20px' }}>
<h3>Time Picker with Event Tracking</h3>
<TimePickerComponent
value={selectedTime}
change={handleChange}
open={handleOpen}
close={handleClose}
placeholder="Select time to track events"
/>
<div style={{ marginTop: '20px', padding: '10px', border: '1px solid #ccc' }}>
<h4>Event Log:</h4>
<ul>
{eventLog.map((event, idx) => (
<li key={idx}>{event}</li>
))}
</ul>
</div>
</div>
);
}
export default EventTrackingExample;#### Pattern 5: Masked Time Input
import { TimePickerComponent } from '@syncfusion/ej2-react-calendars';
import * as React from 'react';
function MaskedTimePickerExample() {
const [maskedTime, setMaskedTime] = React.useState(new Date('1/1/2018 10:30 AM'));
return (
<div style={{ padding: '20px' }}>
<h3>Masked Time Input</h3>
<TimePickerComponent
value={maskedTime}
enableMask={true}
format="hh:mm a"
maskPlaceholder={{
hour: 'HH',
minute: 'MM',
second: 'SS',
}}
change={(e: any) => setMaskedTime(e.value)}
placeholder="Enter time (HH:MM AM/PM)"
/>
<p>Masked input helps users enter time in correct format</p>
</div>
);
}
export default MaskedTimePickerExample;| Prop | Type | Default | Purpose |
|---|---|---|---|
value | Date | null | Current selected time value |
format | string | Based on culture | Time display format (e.g., "HH:mm", "hh:mm a") |
min | Date | 00:00 | Minimum selectable time |
max | Date | 00:00 | Maximum selectable time |
step | number | 30 | Time interval in minutes between list items |
enabled | boolean | true | Enable/disable the component |
readonly | boolean | false | Read-only state (no editing) |
placeholder | string | - | Input placeholder text |
openOnFocus | boolean | false | Open popup on input focus |
enableMask | boolean | false | Enable masked input mode |
enableRtl | boolean | false | Enable right-to-left layout |
strictMode | boolean | false | Validate input and restrict to valid times |
showClearButton | boolean | true | Show/hide clear button |
fullScreenMode | boolean | false | Mobile full-screen mode |
cssClass | string | - | Custom CSS class for styling |
floatLabelType | string | Never | Float label position |
allowEdit | boolean | true | Allow manual input editing |
locale | string | 'en-US' | Locale for time formatting |
scrollTo | Date | - | Default scroll position in popup |
width | string/number | - | Component width |
zIndex | number | 1000 | Z-index of popup |
serverTimezoneOffset | number | - | Server timezone offset for processing |
htmlAttributes | object | {} | Custom HTML attributes |
Next Steps:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.