Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
49dbc5b
adding stub file, code gen header and cpp implementation
Nov 17, 2025
e1bbddb
Add TurboModule support for Windows DateTimePicker
Nov 17, 2025
2b0019f
adding changes
Nov 17, 2025
bdc50f6
Fix test failures for Windows TurboModule implementation
Nov 17, 2025
6ef5da4
Add Fabric XAML component support for Windows TimePicker
Nov 20, 2025
eacf7b5
adding DateTimePickerWindows.windows.js file
Nov 20, 2025
7ba0c29
adding mounting and unmounting of xaml comeponents
Nov 26, 2025
e8c5182
changing the namespace
Nov 26, 2025
65c12f0
adding demo example
Nov 26, 2025
6c370c9
Convert example Windows app from UWP to pure Win32 C++ application
Dec 15, 2025
ae1cd3f
Remove App.xaml and App.idl files from example Windows project
Dec 15, 2025
b9cd88c
Remove MainPage.idl and MainPage.xaml from example Windows project
Dec 15, 2025
d8092a6
Convert DateTimePickerDemo to proper Win32 application - remove UWP d…
Dec 16, 2025
d5c703b
fixing android build issue
Dec 16, 2025
6c82611
fixing android bundle build issue
Dec 18, 2025
a991a1c
Add RC file with icon resources for Win32 DateTimePickerDemo app
Dec 22, 2025
005dbd2
removing old xaml dependency so that it gets loaded by VS
Dec 22, 2025
9e0b457
adding vccxproj file changes
Dec 22, 2025
057fc23
fixing android , ios build issue
Dec 22, 2025
a4d143c
updating xcode version tyo fix CI builds
Dec 23, 2025
7370f85
updating xcode version tyo fix CI builds 1
Dec 23, 2025
012667b
adding DateTimePicker.package
Dec 23, 2025
2187bb2
addressing first review comments
Dec 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
new_arch_ios_build_only:
executor:
name: rn/macos
xcode_version: '16.2.0'
xcode_version: '15.4.0'
resource_class: macos.m1.medium.gen1
steps:
- checkout
Expand All @@ -52,7 +52,7 @@ jobs:
e2e_release_ios:
executor:
name: rn/macos
xcode_version: '16.2.0'
xcode_version: '15.4.0'
resource_class: macos.m1.medium.gen1
steps:
- checkout
Expand Down
237 changes: 237 additions & 0 deletions docs/windows-xaml-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
# Windows XAML Support for React Native DateTimePicker

## Overview

This document describes the XAML-based implementation for Windows platform using React Native's new architecture (Fabric + TurboModules).

## Implementation Details

### Architecture

The Windows implementation now supports both:
1. **Legacy Architecture**: Using ViewManagers (`DateTimePickerViewManager`, `TimePickerViewManager`)
2. **New Architecture (Fabric + TurboModules)**:
- **Fabric Components**: Using XAML Islands with `CalendarDatePicker` control for declarative UI
- **TurboModules**: Using imperative API similar to Android (`DateTimePickerWindows.open()`)

The implementation automatically selects the appropriate architecture based on the `RNW_NEW_ARCH` compile-time flag.

### Key Components

#### 1. Native Component Spec
- **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

#### 2. TurboModule Specs
- **DatePicker**: `src/specs/NativeModuleDatePickerWindows.js`
- **TimePicker**: `src/specs/NativeModuleTimePickerWindows.js`
- Follow the same pattern as Android TurboModules
- Provide imperative API for opening pickers programmatically

#### 3. Codegen Headers

**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 properties
- `DateTimePickerEventEmitter`: Event handling
- `BaseDateTimePicker<T>`: Base template class for the component view
- `RegisterDateTimePickerNativeComponent<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

#### 4. Fabric Implementation
- **Header**: `windows/DateTimePickerWindows/DateTimePickerFabric.h`
- **Implementation**: `windows/DateTimePickerWindows/DateTimePickerFabric.cpp`
- **Component**: `DateTimePickerComponentView`
- Implements `BaseDateTimePicker<DateTimePickerComponentView>`
- Uses `Microsoft.UI.Xaml.XamlIsland` to host XAML content
- Uses `Microsoft.UI.Xaml.Controls.CalendarDatePicker` as the actual picker control

#### 5. TurboModule Implementations

**DatePicker TurboModule**:
- **Header**: `windows/DateTimePickerWindows/DatePickerModuleWindows.h`
- **Implementation**: `windows/DateTimePickerWindows/DatePickerModuleWindows.cpp`
- Provides imperative `open()` and `dismiss()` methods
- Returns promises with selected date or dismissal action

**TimePicker TurboModule**:
- **Header**: `windows/DateTimePickerWindows/TimePickerModuleWindows.h`
- **Implementation**: `windows/DateTimePickerWindows/TimePickerModuleWindows.cpp`
- Provides imperative `open()` and `dismiss()` methods
- Returns promises with selected time or dismissal action

#### 6. Package Provider
- **File**: `windows/DateTimePickerWindows/ReactPackageProvider.cpp`
- Updated to:
- Register Fabric component when `RNW_NEW_ARCH` is defined
- Register TurboModules using `AddAttributedModules()` for auto-discovery
- Register legacy ViewManagers otherwise

#### 7. JavaScript API
- **File**: `src/DateTimePickerWindows.windows.js`
- Provides `DateTimePickerWindows.open()` and `DateTimePickerWindows.dismiss()` methods
- Similar to `DateTimePickerAndroid` API
- Exported from main `index.js` for easy access

### XAML Integration

The Fabric implementation uses **XAML Islands** to host native XAML controls within the Composition-based Fabric renderer:

```cpp
// 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());
```

### Usage

#### Declarative Component (Fabric)

```javascript
import DateTimePicker from '@react-native-community/datetimepicker';

<DateTimePicker
value={new Date()}
mode="date"
onChange={handleDateChange}
/>
```

#### Imperative API (TurboModules)

```javascript
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();
```

### Supported Properties

**Fabric Component** supports:
- `selectedDate`: Current date (milliseconds timestamp)
- `minimumDate`: Minimum selectable date
- `maximumDate`: Maximum selectable date
- `timeZoneOffsetInSeconds`: Timezone offset for date calculations
- `dayOfWeekFormat`: Format string for day of week display
- `dateFormat`: Format string for date display
- `firstDayOfWeek`: First day of the week (0-6)
- `placeholderText`: Placeholder text when no date is selected
- `accessibilityLabel`: Accessibility label for the control

**TurboModule API** supports:
- All the above properties via the `open()` method parameters
- Returns promises with action results (`dateSetAction`, `dismissedAction`)

### Events

**Fabric Component**:
- `onChange`: Fired when the date changes
- Event payload: `{ newDate: number }` (milliseconds timestamp)

**TurboModule API**:
- Promise-based: Resolves with `{action, timestamp, utcOffset}` for dates
- Or `{action, hour, minute}` for times

### Date/Time Conversion

The implementation includes helper functions to convert between JavaScript timestamps (milliseconds) and Windows `DateTime`:

- `DateTimeFrom(milliseconds, timezoneOffset)`: Converts JS timestamp to Windows DateTime
- `DateTimeToMilliseconds(dateTime, timezoneOffset)`: Converts Windows DateTime to JS timestamp

### Build Configuration

To build with XAML/Fabric/TurboModule support:
1. Ensure `RNW_NEW_ARCH` is defined in your build configuration
2. Include the new Fabric and TurboModule implementation files in your project
3. Link against required XAML libraries

## Comparison with Reference Implementation

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 `XamlIsland` for hosting XAML content
- Implements codegen-based component registration
- Uses `ContentIslandComponentView` initializer 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()`

## Testing

To test the implementation:

**Legacy Architecture**:
```javascript
import DateTimePicker from '@react-native-community/datetimepicker';
// Use as normal component
```

**New Architecture (Fabric Component)**:
1. Build with `RNW_NEW_ARCH` enabled
2. Use the component declaratively as shown above

**New Architecture (TurboModule API)**:
1. Build with `RNW_NEW_ARCH` enabled
2. Use `DateTimePickerWindows.open()` imperatively

## Future Enhancements

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

## References

- [React Native Windows New Architecture](https://microsoft.github.io/react-native-windows/docs/new-architecture)
- [React Native TurboModules](https://reactnative.dev/docs/the-new-architecture/pillars-turbomodules)
- [XAML Islands Overview](https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/xaml-islands)
- [Sample CalendarView PR #15368](https://github.com/microsoft/react-native-windows/pull/15368)
Loading