This document describes the XAML-based implementation for Windows platform using React Native's new architecture (Fabric + TurboModules).
The Windows implementation now supports both:
- Legacy Architecture: Using ViewManagers (
DateTimePickerViewManager,TimePickerViewManager) - New Architecture (Fabric + TurboModules):
- Fabric Components: Using XAML Islands with
CalendarDatePickercontrol for declarative UI - TurboModules: Using imperative API similar to Android (
DateTimePickerWindows.open())
- Fabric Components: Using XAML Islands with
The implementation automatically selects the appropriate architecture based on the RNW_NEW_ARCH compile-time flag.
- File:
src/specs/DateTimePickerNativeComponent.js(existing cross-platform spec) - Defines the component interface using React Native's codegen
- Specifies props and events for the component
- DatePicker:
src/specs/NativeModuleDatePickerWindows.js - TimePicker:
src/specs/NativeModuleTimePickerWindows.js - Follow the same pattern as Android TurboModules
- Provide imperative API for opening pickers programmatically
Fabric Component (New Architecture):
- File:
windows/DateTimePickerWindows/codegen/react/components/DateTimePicker/DateTimePicker.g.h - Auto-generated-style header following React Native Windows codegen patterns
- Defines:
DateTimePickerProps: Component propertiesDateTimePickerEventEmitter: Event handlingBaseDateTimePicker<T>: Base template class for the component viewRegisterDateTimePickerNativeComponent<T>: Registration helper
TurboModules (New Architecture):
- File:
windows/DateTimePickerWindows/NativeModulesWindows.g.h - Defines specs for both DatePicker and TimePicker TurboModules
- Includes parameter structs and result structs
- Follows React Native TurboModule patterns
- Header:
windows/DateTimePickerWindows/DateTimePickerFabric.h - Implementation:
windows/DateTimePickerWindows/DateTimePickerFabric.cpp - Component:
DateTimePickerComponentView- Implements
BaseDateTimePicker<DateTimePickerComponentView> - Uses
Microsoft.UI.Xaml.XamlIslandto host XAML content - Uses
Microsoft.UI.Xaml.Controls.CalendarDatePickeras the actual picker control
- Implements
DatePicker TurboModule:
- Header:
windows/DateTimePickerWindows/DatePickerModuleWindows.h - Implementation:
windows/DateTimePickerWindows/DatePickerModuleWindows.cpp - Provides imperative
open()anddismiss()methods - Returns promises with selected date or dismissal action
TimePicker TurboModule:
- Header:
windows/DateTimePickerWindows/TimePickerModuleWindows.h - Implementation:
windows/DateTimePickerWindows/TimePickerModuleWindows.cpp - Provides imperative
open()anddismiss()methods - Returns promises with selected time or dismissal action
- File:
windows/DateTimePickerWindows/ReactPackageProvider.cpp - Updated to:
- Register Fabric component when
RNW_NEW_ARCHis defined - Register TurboModules using
AddAttributedModules()for auto-discovery - Register legacy ViewManagers otherwise
- Register Fabric component when
- File:
src/DateTimePickerWindows.windows.js - Provides
DateTimePickerWindows.open()andDateTimePickerWindows.dismiss()methods - Similar to
DateTimePickerAndroidAPI - Exported from main
index.jsfor easy access
The Fabric implementation uses XAML Islands to host native XAML controls within the Composition-based Fabric renderer:
// Initialize XAML Application
winrt::Microsoft::ReactNative::Xaml::implementation::XamlApplication::EnsureCreated();
// Create XamlIsland
m_xamlIsland = winrt::Microsoft::UI::Xaml::XamlIsland{};
// Create and set XAML control
m_calendarDatePicker = winrt::Microsoft::UI::Xaml::Controls::CalendarDatePicker{};
m_xamlIsland.Content(m_calendarDatePicker);
// Connect to Fabric's ContentIsland
islandView.Connect(m_xamlIsland.ContentIsland());import DateTimePicker from '@react-native-community/datetimepicker';
<DateTimePicker
value={new Date()}
mode="date"
onChange={handleDateChange}
/>import {DateTimePickerWindows} from '@react-native-community/datetimepicker';
// Open date picker
DateTimePickerWindows.open({
value: new Date(),
mode: 'date',
minimumDate: new Date(2020, 0, 1),
maximumDate: new Date(2025, 11, 31),
onChange: (event, date) => {
if (event.type === 'set') {
console.log('Selected date:', date);
}
},
onError: (error) => {
console.error('Picker error:', error);
}
});
// Dismiss picker
DateTimePickerWindows.dismiss();Fabric Component supports:
selectedDate: Current date (milliseconds timestamp)minimumDate: Minimum selectable datemaximumDate: Maximum selectable datetimeZoneOffsetInSeconds: Timezone offset for date calculationsdayOfWeekFormat: Format string for day of week displaydateFormat: Format string for date displayfirstDayOfWeek: First day of the week (0-6)placeholderText: Placeholder text when no date is selectedaccessibilityLabel: Accessibility label for the control
TurboModule API supports:
- All the above properties via the
open()method parameters - Returns promises with action results (
dateSetAction,dismissedAction)
Fabric Component:
onChange: Fired when the date changes- Event payload:
{ newDate: number }(milliseconds timestamp)
- Event payload:
TurboModule API:
- Promise-based: Resolves with
{action, timestamp, utcOffset}for dates - Or
{action, hour, minute}for times
The implementation includes helper functions to convert between JavaScript timestamps (milliseconds) and Windows DateTime:
DateTimeFrom(milliseconds, timezoneOffset): Converts JS timestamp to Windows DateTimeDateTimeToMilliseconds(dateTime, timezoneOffset): Converts Windows DateTime to JS timestamp
To build with XAML/Fabric/TurboModule support:
- Ensure
RNW_NEW_ARCHis defined in your build configuration - Include the new Fabric and TurboModule implementation files in your project
- Link against required XAML libraries
This implementation follows the pattern established in the xaml-calendar-view sample from the React Native Windows repository (PR #15368), but extends it with TurboModules:
Similarities:
- Uses
XamlIslandfor hosting XAML content - Implements codegen-based component registration
- Uses
ContentIslandComponentViewinitializer pattern - Follows the
BaseXXXX<T>template pattern
Extensions:
- TurboModule Support: Added imperative API similar to Android
- Promise-based API: Modern async/await pattern for picker operations
- Comprehensive property set: Supports all date/time picker scenarios
- Dual architecture: Works with both legacy and new architecture
Differences from Android:
- Windows uses XAML Islands instead of native Android dialogs
- Different property names for some platform-specific features
- Windows TurboModules registered via
AddAttributedModules()
To test the implementation:
Legacy Architecture:
import DateTimePicker from '@react-native-community/datetimepicker';
// Use as normal componentNew Architecture (Fabric Component):
- Build with
RNW_NEW_ARCHenabled - Use the component declaratively as shown above
New Architecture (TurboModule API):
- Build with
RNW_NEW_ARCHenabled - Use
DateTimePickerWindows.open()imperatively
Potential improvements:
- Implement ContentDialog/Flyout for better picker presentation
- Add support for date range pickers
- Implement state management for complex scenarios
- Add more XAML-specific styling properties
- Performance optimizations for rapid prop updates
- Custom themes and styling support