diff --git a/packages/sample-app-fabric/App.tsx b/packages/sample-app-fabric/App.tsx index 125fe1b98eb..26c05e47c37 100644 --- a/packages/sample-app-fabric/App.tsx +++ b/packages/sample-app-fabric/App.tsx @@ -5,7 +5,7 @@ * @format */ -import React from 'react'; +import React, {useState} from 'react'; import type {PropsWithChildren} from 'react'; import { SafeAreaView, @@ -25,6 +25,8 @@ import { ReloadInstructions, } from 'react-native/Libraries/NewAppScreen'; +import {CalendarView} from 'xaml-calendar-view'; + type SectionProps = PropsWithChildren<{ title: string; }>; @@ -62,6 +64,8 @@ function App(): React.JSX.Element { backgroundColor: isDarkMode ? Colors.darker : Colors.lighter, }; + const [selectedDate, setSelectedDate] = useState(true); + return (
- Edit App.tsx to change this - screen and then come back to see your edits. + Edit App.tsx to change this. + I'll try showing a CalendarView here (displayMode=1 for month view).
+ + { + setSelectedDate(e.nativeEvent.startDate); + }} + /> + +
Selected date: {selectedDate}
+
diff --git a/packages/sample-app-fabric/b.cmd b/packages/sample-app-fabric/b.cmd new file mode 100644 index 00000000000..1c73edfcdc7 --- /dev/null +++ b/packages/sample-app-fabric/b.cmd @@ -0,0 +1,14 @@ +setlocal +pushd ..\.. + +call yarn || goto :fail + +popd + +call yarn react-native run-windows --msbuildprops RestoreForceEvaluate=true || goto :fail + +echo Success! +exit /b 0 + +echo FAILED. +exit /b 1 diff --git a/packages/sample-app-fabric/package.json b/packages/sample-app-fabric/package.json index 93723a1cfd8..6a63218b979 100644 --- a/packages/sample-app-fabric/package.json +++ b/packages/sample-app-fabric/package.json @@ -17,7 +17,8 @@ "@typescript-eslint/parser": "^7.1.1", "react": "^19.0.0", "react-native": "0.79.0-nightly-20250303-cee63397b", - "react-native-windows": "^0.0.0-canary.964" + "react-native-windows": "^0.0.0-canary.964", + "xaml-calendar-view": "" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -48,4 +49,4 @@ "engines": { "node": ">=18" } -} +} \ No newline at end of file diff --git a/packages/sample-app-fabric/windows/SampleAppFabric.Package/packages.lock.json b/packages/sample-app-fabric/windows/SampleAppFabric.Package/packages.lock.json index 7d84a365b4f..f7902d3bb09 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric.Package/packages.lock.json +++ b/packages/sample-app-fabric/windows/SampleAppFabric.Package/packages.lock.json @@ -83,6 +83,17 @@ "boost": "[1.83.0, )" } }, + "microsoft.reactnative.xaml": { + "type": "Project", + "dependencies": { + "Common": "[1.0.0, )", + "Folly": "[1.0.0, )", + "Microsoft.ReactNative": "[1.0.0, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "ReactCommon": "[1.0.0, )", + "boost": "[1.83.0, )" + } + }, "reactcommon": { "type": "Project", "dependencies": { @@ -95,6 +106,18 @@ "dependencies": { "Microsoft.JavaScript.Hermes": "[0.0.0-2505.2001-0e4bc3b9, )", "Microsoft.ReactNative": "[1.0.0, )", + "Microsoft.ReactNative.Xaml": "[1.0.0, )", + "Microsoft.VCRTForwarders.140": "[1.0.2-rc, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "XamlCalendarView": "[1.0.0, )", + "boost": "[1.83.0, )" + } + }, + "xamlcalendarview": { + "type": "Project", + "dependencies": { + "Microsoft.ReactNative": "[1.0.0, )", + "Microsoft.ReactNative.Xaml": "[1.0.0, )", "Microsoft.VCRTForwarders.140": "[1.0.2-rc, )", "Microsoft.WindowsAppSDK": "[1.7.250401001, )", "boost": "[1.83.0, )" diff --git a/packages/sample-app-fabric/windows/SampleAppFabric.sln b/packages/sample-app-fabric/windows/SampleAppFabric.sln index 1eabd0cabef..a5cd2bc11e9 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric.sln +++ b/packages/sample-app-fabric/windows/SampleAppFabric.sln @@ -35,6 +35,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\..\..\vnext\Mso\M EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Include", "..\..\..\vnext\include\Include.vcxitems", "{EF074BA1-2D54-4D49-A28E-5E040B47CD2E}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XamlCalendarView", "..\..\..\node_modules\xaml-calendar-view\windows\XamlCalendarView\XamlCalendarView.vcxproj", "{3501592F-3196-4EE1-B4AA-FE4A5F29063B}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\..\..\vnext\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9 @@ -154,6 +156,31 @@ Global {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.ActiveCfg = Release|Win32 {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Build.0 = Release|Win32 {14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Deploy.0 = Release|Win32 + + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x64.ActiveCfg = Debug|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x64.Build.0 = Debug|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x86.ActiveCfg = Debug|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x86.Build.0 = Debug|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|ARM64.Build.0 = Debug|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x64.ActiveCfg = Release|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x64.Build.0 = Release|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x86.ActiveCfg = Release|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x86.Build.0 = Release|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|ARM64.ActiveCfg = Release|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|ARM64.Build.0 = Release|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x64.ActiveCfg = Debug|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x64.Build.0 = Debug|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x86.ActiveCfg = Debug|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x86.Build.0 = Debug|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|ARM64.Build.0 = Debug|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x64.ActiveCfg = Release|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x64.Build.0 = Release|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x86.ActiveCfg = Release|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x86.Build.0 = Release|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|ARM64.ActiveCfg = Release|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|ARM64.Build.0 = Release|ARM64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.cpp b/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.cpp index 5821cfddc55..bc5c9b03d39 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.cpp +++ b/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.cpp @@ -3,12 +3,16 @@ #include "pch.h" #include "AutolinkedNativeModules.g.h" +// Includes from xaml-calendar-view +#include + namespace winrt::Microsoft::ReactNative { void RegisterAutolinkedNativeModulePackages(winrt::Windows::Foundation::Collections::IVector const& packageProviders) { - UNREFERENCED_PARAMETER(packageProviders); + // IReactPackageProviders from xaml-calendar-view + packageProviders.Append(winrt::XamlCalendarView::ReactPackageProvider()); } } diff --git a/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.targets b/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.targets index 6a85ec51cd9..0d854874f0b 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.targets +++ b/packages/sample-app-fabric/windows/SampleAppFabric/AutolinkedNativeModules.g.targets @@ -2,5 +2,9 @@ + + + {3501592F-3196-4EE1-B4AA-FE4A5F29063B} + diff --git a/packages/sample-app-fabric/windows/SampleAppFabric/SampleAppFabric.cpp b/packages/sample-app-fabric/windows/SampleAppFabric/SampleAppFabric.cpp index 2aeaae1397e..211ec1b34e3 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric/SampleAppFabric.cpp +++ b/packages/sample-app-fabric/windows/SampleAppFabric/SampleAppFabric.cpp @@ -8,6 +8,8 @@ #include "NativeModules.h" +#include + // A PackageProvider containing any turbo modules you define within this app project struct CompReactPackageProvider : winrt::implements { @@ -39,6 +41,9 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR RegisterAutolinkedNativeModulePackages(settings.PackageProviders()); // Register any native modules defined within this app project settings.PackageProviders().Append(winrt::make()); + // TODO: Can we make apps register this automatically? (e.g. with autolinking) + // TODO: But ideally we don't load the M.RN.Xaml.dll at all if we're not using Xaml. + settings.PackageProviders().Append(winrt::Microsoft::ReactNative::Xaml::ReactPackageProvider()); #if BUNDLE // Load the JS bundle from a file (not Metro): diff --git a/packages/sample-app-fabric/windows/SampleAppFabric/packages.lock.json b/packages/sample-app-fabric/windows/SampleAppFabric/packages.lock.json index 48426cb9ce0..c1e727c402e 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric/packages.lock.json +++ b/packages/sample-app-fabric/windows/SampleAppFabric/packages.lock.json @@ -93,12 +93,33 @@ "boost": "[1.83.0, )" } }, + "microsoft.reactnative.xaml": { + "type": "Project", + "dependencies": { + "Common": "[1.0.0, )", + "Folly": "[1.0.0, )", + "Microsoft.ReactNative": "[1.0.0, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "ReactCommon": "[1.0.0, )", + "boost": "[1.83.0, )" + } + }, "reactcommon": { "type": "Project", "dependencies": { "Folly": "[1.0.0, )", "boost": "[1.83.0, )" } + }, + "xamlcalendarview": { + "type": "Project", + "dependencies": { + "Microsoft.ReactNative": "[1.0.0, )", + "Microsoft.ReactNative.Xaml": "[1.0.0, )", + "Microsoft.VCRTForwarders.140": "[1.0.2-rc, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "boost": "[1.83.0, )" + } } }, "native,Version=v0.0/win": { diff --git a/packages/sample-app-fabric/windows/SampleAppFabric/pch.h b/packages/sample-app-fabric/windows/SampleAppFabric/pch.h index 364879013f3..0c3c09f6089 100644 --- a/packages/sample-app-fabric/windows/SampleAppFabric/pch.h +++ b/packages/sample-app-fabric/windows/SampleAppFabric/pch.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/packages/xaml-calendar-view/.gitignore b/packages/xaml-calendar-view/.gitignore new file mode 100644 index 00000000000..6ec7c452937 --- /dev/null +++ b/packages/xaml-calendar-view/.gitignore @@ -0,0 +1 @@ +lib-commonjs/ diff --git a/packages/xaml-calendar-view/NuGet.config b/packages/xaml-calendar-view/NuGet.config new file mode 100644 index 00000000000..fe459fedd60 --- /dev/null +++ b/packages/xaml-calendar-view/NuGet.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/xaml-calendar-view/babel.config.js b/packages/xaml-calendar-view/babel.config.js new file mode 100644 index 00000000000..bb24878651d --- /dev/null +++ b/packages/xaml-calendar-view/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['module:@rnw-scripts/babel-react-native-config'], +}; diff --git a/packages/xaml-calendar-view/jest.config.js b/packages/xaml-calendar-view/jest.config.js new file mode 100644 index 00000000000..8eb675e9bc6 --- /dev/null +++ b/packages/xaml-calendar-view/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: 'react-native', +}; diff --git a/packages/xaml-calendar-view/just-task.js b/packages/xaml-calendar-view/just-task.js new file mode 100644 index 00000000000..6627cf0c945 --- /dev/null +++ b/packages/xaml-calendar-view/just-task.js @@ -0,0 +1,51 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * @format + * @ts-check + */ + +const {task, series} = require('just-scripts'); +const fs = require('fs'); +const glob = require('glob'); +const path = require('path'); + +// Use the shared base configuration +require('@rnw-scripts/just-task'); + +// The TS build process will strip all the types from the NativeComponent spec file. Which means that the codegen babel will not correctly generate the JS view config for the component. +// So here we manually run babel, overwriting the tsc output, so that we ship the generated code. +task('codegenNativeComponents', () => { + const babel = require('@babel/core'); + const matches = glob.sync('src/**/*NativeComponent.ts'); + + matches.forEach(matchedPath => { + const relativePath = path.relative( + path.resolve(process.cwd(), 'src'), + matchedPath, + ); + const code = fs.readFileSync(matchedPath).toString(); + const filename = path.resolve(process.cwd(), matchedPath); + + const res = babel.transformSync(code, { + ast: false, + filename, + cwd: process.cwd(), + sourceRoot: process.cwd(), + root: process.cwd(), + babelrc: true, + }); + + const relativeOutputPath = relativePath.replace(/\.ts$/, '.js'); + + fs.writeFileSync( + path.resolve(process.cwd(), 'lib-commonjs', relativeOutputPath), + res?.code, + ); + }); +}); + +task( + 'buildWithCodegetNativeComponents', + series('build', 'codegenNativeComponents'), +); diff --git a/packages/xaml-calendar-view/package.json b/packages/xaml-calendar-view/package.json new file mode 100644 index 00000000000..28d54e20dfd --- /dev/null +++ b/packages/xaml-calendar-view/package.json @@ -0,0 +1,57 @@ +{ + "name": "xaml-calendar-view", + "version": "1.0.0", + "main": "lib-commonjs/index.js", + "types": "lib-commonjs/index.d.ts", + "license": "MIT", + "private": true, + "scripts": { + "build": "rnw-scripts buildWithCodegetNativeComponents", + "lint": "rnw-scripts lint", + "lint:fix": "rnw-scripts lint:fix" + }, + "codegenConfig": { + "name": "CalendarView", + "type": "all", + "jsSrcsDir": "src", + "windows": { + "generators": "componentsWindows", + "namespace": "winrt::XamlCalendarView::Codegen", + "outputDirectory": "windows/XamlCalendarView/codegen" + } + }, + "dependencies": { + "@types/react": "^19.0.0", + "react": "^19.0.0", + "react-native": "0.79.0-nightly-20250123-d1028885e", + "react-native-windows": "^0.0.0-canary.952" + }, + "devDependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/preset-env": "^7.25.3", + "@babel/preset-typescript": "^7.8.3", + "@babel/runtime": "^7.20.0", + "@react-native-community/cli": "15.0.0-alpha.2", + "@react-native/metro-config": "0.79.0-nightly-20250123-d1028885e", + "@rnw-scripts/babel-node-config": "2.3.2", + "@rnw-scripts/babel-react-native-config": "0.0.0", + "@rnw-scripts/eslint-config": "1.2.34", + "@rnw-scripts/just-task": "2.3.51", + "@rnw-scripts/metro-dev-config": "0.0.0", + "@rnw-scripts/ts-config": "2.0.5", + "@rnx-kit/jest-preset": "^0.1.16", + "@types/react": "^19.0.0", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "babel-jest": "^29.6.3", + "eslint": "^8.19.0", + "glob": "^7.1.6", + "just-scripts": "^1.3.3", + "prettier": "2.8.8", + "typescript": "5.0.4" + }, + "engines": { + "node": ">=18" + } +} diff --git a/packages/xaml-calendar-view/src/CalendarView.tsx b/packages/xaml-calendar-view/src/CalendarView.tsx new file mode 100644 index 00000000000..8fe23b958df --- /dev/null +++ b/packages/xaml-calendar-view/src/CalendarView.tsx @@ -0,0 +1,15 @@ + +import * as React from 'react'; +import RawCalendarView from './CalendarViewNativeComponent'; + +import XamlHost from 'react-native-windows/Libraries/Components/Xaml/XamlHost'; + +function CalendarView(props: any) { + return ( + + + + ); +} + +export { CalendarView, RawCalendarView }; diff --git a/packages/xaml-calendar-view/src/CalendarViewNativeComponent.ts b/packages/xaml-calendar-view/src/CalendarViewNativeComponent.ts new file mode 100644 index 00000000000..7aab1a336fc --- /dev/null +++ b/packages/xaml-calendar-view/src/CalendarViewNativeComponent.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + */ + +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import type { ViewProps } from 'react-native'; +import type {DirectEventHandler, Int32} from 'react-native/Libraries/Types/CodegenTypes'; + +type SelectedDatesChangedEvent = Readonly<{ + value: boolean; + startDate: string; +}>; + +export interface CalendarViewProps extends ViewProps { + displayMode : Int32; + onSelectedDatesChanged?: DirectEventHandler; +} + +export default codegenNativeComponent('CalendarView'); diff --git a/packages/xaml-calendar-view/src/index.tsx b/packages/xaml-calendar-view/src/index.tsx new file mode 100644 index 00000000000..5cb606a5706 --- /dev/null +++ b/packages/xaml-calendar-view/src/index.tsx @@ -0,0 +1,2 @@ +import { CalendarView, RawCalendarView} from './CalendarView'; +export { CalendarView, RawCalendarView }; diff --git a/packages/xaml-calendar-view/tsconfig.json b/packages/xaml-calendar-view/tsconfig.json new file mode 100644 index 00000000000..9fe5bc3cf9d --- /dev/null +++ b/packages/xaml-calendar-view/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@rnw-scripts/ts-config", + "include": ["src"], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/packages/xaml-calendar-view/windows/.gitignore b/packages/xaml-calendar-view/windows/.gitignore new file mode 100644 index 00000000000..5bc72a4416d --- /dev/null +++ b/packages/xaml-calendar-view/windows/.gitignore @@ -0,0 +1,41 @@ +*AppPackages* +*BundleArtifacts* + +#OS junk files +[Tt]humbs.db +*.DS_Store + +#Visual Studio files +*.[Oo]bj +*.user +*.aps +*.pch +*.vspscc +*.vssscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.[Cc]ache +*.ilk +*.log +*.lib +*.sbr +*.sdf +*.opensdf +*.opendb +*.unsuccessfulbuild +ipch/ +[Oo]bj/ +[Bb]in +[Dd]ebug*/ +[Rr]elease*/ +Ankh.NoLoad +.vs/ +# Visual C++ cache files + +#Files generated by the VS build +**/Generated Files/** diff --git a/packages/xaml-calendar-view/windows/ExperimentalFeatures.props b/packages/xaml-calendar-view/windows/ExperimentalFeatures.props new file mode 100644 index 00000000000..3153babecb8 --- /dev/null +++ b/packages/xaml-calendar-view/windows/ExperimentalFeatures.props @@ -0,0 +1,33 @@ + + + + + + true + + + false + + true + + + diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView.sln b/packages/xaml-calendar-view/windows/XamlCalendarView.sln new file mode 100644 index 00000000000..cb7fc4ee0b2 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XamlCalendarView", "XamlCalendarView\XamlCalendarView.vcxproj", "{3501592F-3196-4EE1-B4AA-FE4A5F29063B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Debug|ARM64 = Debug|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + Release|ARM64 = Release|ARM64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x64.ActiveCfg = Debug|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x64.Build.0 = Debug|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x64.Deploy.0 = Debug|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x86.ActiveCfg = Debug|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x86.Build.0 = Debug|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|x86.Deploy.0 = Debug|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|ARM64.Build.0 = Debug|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x64.ActiveCfg = Release|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x64.Build.0 = Release|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x64.Deploy.0 = Release|x64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x86.ActiveCfg = Release|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x86.Build.0 = Release|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|x86.Deploy.0 = Release|Win32 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|ARM64.ActiveCfg = Release|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|ARM64.Build.0 = Release|ARM64 + {3501592F-3196-4EE1-B4AA-FE4A5F29063B}.Release|ARM64.Deploy.0 = Release|ARM64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D43FAD39-F619-437D-BB40-04A3982ACB6A} + EndGlobalSection +EndGlobal diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.cpp b/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.cpp new file mode 100644 index 00000000000..e2cff280d6c --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include "ReactPackageProvider.h" +#if __has_include("ReactPackageProvider.g.cpp") +#include "ReactPackageProvider.g.cpp" +#endif + +#include "XamlCalendarView.h" + +using namespace winrt::Microsoft::ReactNative; + +namespace winrt::XamlCalendarView::implementation +{ + +void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept +{ + AddAttributedModules(packageBuilder, true); + RegisterCalendarViewNativeComponent(packageBuilder); + //settings.PackageProviders().Append(winrt::Microsoft::ReactNative::Xaml::ReactPackageProvider()); +} + +} // namespace winrt::XamlCalendarView::implementation diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.h b/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.h new file mode 100644 index 00000000000..7baeecd516c --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.h @@ -0,0 +1,24 @@ +#pragma once + +#include "ReactPackageProvider.g.h" + +using namespace winrt::Microsoft::ReactNative; + +namespace winrt::XamlCalendarView::implementation +{ + +struct ReactPackageProvider : ReactPackageProviderT +{ + ReactPackageProvider() = default; + + void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept; +}; + +} // namespace winrt::XamlCalendarView::implementation + +namespace winrt::XamlCalendarView::factory_implementation +{ + +struct ReactPackageProvider : ReactPackageProviderT {}; + +} // namespace winrt::XamlCalendarView::factory_implementation diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.idl b/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.idl new file mode 100644 index 00000000000..ce11fd77d80 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/ReactPackageProvider.idl @@ -0,0 +1,9 @@ +namespace XamlCalendarView +{ + [webhosthidden] + [default_interface] + runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider + { + ReactPackageProvider(); + }; +} diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.cpp b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.cpp new file mode 100644 index 00000000000..c1b5b954303 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.cpp @@ -0,0 +1,86 @@ +#include "pch.h" + +#include "XamlCalendarView.h" + +#include +#include + +namespace winrt::XamlCalendarView +{ + +struct CalendarView : public winrt::implements, + public Codegen::BaseCalendarView { + + winrt::Microsoft::UI::Xaml::UIElement GetXamlElement() { + if (m_calendarView == nullptr) { + CreateXamlCalendarView(); + } + return m_calendarView; + } + + void UpdateProps( + const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::com_ptr &newProps, + const winrt::com_ptr &oldProps) noexcept override { + Codegen::BaseCalendarView::UpdateProps(view, newProps, oldProps); + + if (m_calendarView && newProps) { + m_calendarView.DisplayMode(static_cast( + newProps->displayMode)); + } + } + + void CreateXamlCalendarView() { + m_calendarView = winrt::Microsoft::UI::Xaml::Controls::CalendarView(); + if (Props()) { + m_calendarView.DisplayMode( + static_cast( + Props()->displayMode)); + } + m_calendarView.SelectedDatesChanged([this](auto &&, auto &&) { + if (auto emitter = EventEmitter()) { + Codegen::CalendarView_OnSelectedDatesChanged args; + auto selectedDates = m_calendarView.SelectedDates(); + if (selectedDates.Size() == 0) { + args.startDate = "(none)"; + } else { + auto firstSelectedDate = selectedDates.GetAt(0); + + auto tt = winrt::clock::to_time_t(firstSelectedDate); + tm local{}; + localtime_s(&local, &tt); + auto timeStr = std::put_time(&local, "%F"); + + std::stringstream ss; + ss << (timeStr._Tptr->tm_year + 1900) << "-" << (timeStr._Tptr->tm_mon + 1) << "-" << timeStr._Tptr->tm_mday; + + args.startDate = ss.str(); + } + emitter->onSelectedDatesChanged(args); + } + }); + } + + + private: + winrt::Microsoft::UI::Xaml::Controls::CalendarView m_calendarView{ nullptr }; +}; + + +// See https://microsoft.github.io/react-native-windows/docs/native-modules for details on writing native modules + +void XamlCalendarView::Initialize(React::ReactContext const &reactContext) noexcept { + m_context = reactContext; +} + +double XamlCalendarView::multiply(double a, double b) noexcept { + return a * b; +} + +void RegisterCalendarViewNativeComponent( + winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept { + Codegen::RegisterCalendarViewNativeComponent(packageBuilder, {}); +} + + +} // namespace winrt::XamlCalendarView diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.def b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.def new file mode 100644 index 00000000000..24e7c1235c3 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.h b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.h new file mode 100644 index 00000000000..2f57b16c4ff --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.h @@ -0,0 +1,37 @@ +#pragma once + +#include "pch.h" +#include "resource.h" + +#if __has_include("codegen/NativeXamlCalendarViewDataTypes.g.h") + #include "codegen/NativeXamlCalendarViewDataTypes.g.h" +#endif + +#include "codegen/react/components/CalendarView/CalendarView.g.h" + +#include "NativeModules.h" + +namespace winrt::XamlCalendarView +{ + +REACT_MODULE(XamlCalendarView) +struct XamlCalendarView +{ + //using ModuleSpec = XamlCalendarViewCodegen::XamlCalendarViewSpec; + + REACT_INIT(Initialize) + void Initialize(React::ReactContext const &reactContext) noexcept; + + REACT_SYNC_METHOD(multiply) + double multiply(double a, double b) noexcept; + +private: + React::ReactContext m_context; +}; + +void RegisterCalendarViewNativeComponent( + winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept; + +} // namespace winrt::XamlCalendarView + + diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.rc b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.rc new file mode 100644 index 00000000000..3212c105fce Binary files /dev/null and b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.rc differ diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.vcxproj b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.vcxproj new file mode 100644 index 00000000000..0d6a8c26676 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.vcxproj @@ -0,0 +1,140 @@ + + + + + + true + true + {3501592F-3196-4EE1-B4AA-FE4A5F29063B} + XamlCalendarView + Win32Proj + XamlCalendarView + 10.0 + en-US + 17.0 + false + + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ + false + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + DynamicLibrary + Unicode + v143 + false + + + true + + + false + true + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + true + %(AdditionalOptions) /bigobj + 4453;28204 + _WINRT_DLL;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + stdcpp20 + + + shell32.lib;user32.lib;windowsapp.lib;%(AdditionalDependenices) + Console + true + XamlCalendarView.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + ReactPackageProvider.idl + + + + + + + + + Create + + + ReactPackageProvider.idl + + + + + + + + + + + + + + + + + + This project references targets in your node_modules\react-native-windows folder. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.vcxproj.filters b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.vcxproj.filters new file mode 100644 index 00000000000..c14f7bdb9af --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/XamlCalendarView.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/codegen/.clang-format b/packages/xaml-calendar-view/windows/XamlCalendarView/codegen/.clang-format new file mode 100644 index 00000000000..a43d914ec38 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/codegen/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: false \ No newline at end of file diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/codegen/react/components/CalendarView/CalendarView.g.h b/packages/xaml-calendar-view/windows/XamlCalendarView/codegen/react/components/CalendarView/CalendarView.g.h new file mode 100644 index 00000000000..e09befdfeb9 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/codegen/react/components/CalendarView/CalendarView.g.h @@ -0,0 +1,217 @@ + +/* + * This file is auto-generated from CalendarViewNativeComponent spec file in flow / TypeScript. + */ +// clang-format off +#pragma once + +#include + +#ifdef RNW_NEW_ARCH +#include + +#include +#include +#endif // #ifdef RNW_NEW_ARCH + +#ifdef RNW_NEW_ARCH + +namespace winrt::XamlCalendarView::Codegen { + +REACT_STRUCT(CalendarViewProps) +struct CalendarViewProps : winrt::implements { + CalendarViewProps(winrt::Microsoft::ReactNative::ViewProps props, const winrt::Microsoft::ReactNative::IComponentProps& cloneFrom) + : ViewProps(props) + { + if (cloneFrom) { + auto cloneFromProps = cloneFrom.as(); + displayMode = cloneFromProps->displayMode; + } + } + + void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept { + winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this); + } + + REACT_FIELD(displayMode) + int32_t displayMode{}; + + const winrt::Microsoft::ReactNative::ViewProps ViewProps; +}; + +REACT_STRUCT(CalendarView_OnSelectedDatesChanged) +struct CalendarView_OnSelectedDatesChanged { + REACT_FIELD(value) + bool value{}; + + REACT_FIELD(startDate) + std::string startDate; +}; + +struct CalendarViewEventEmitter { + CalendarViewEventEmitter(const winrt::Microsoft::ReactNative::EventEmitter &eventEmitter) + : m_eventEmitter(eventEmitter) {} + + using OnSelectedDatesChanged = CalendarView_OnSelectedDatesChanged; + + void onSelectedDatesChanged(OnSelectedDatesChanged &value) const { + m_eventEmitter.DispatchEvent(L"selectedDatesChanged", [value](const winrt::Microsoft::ReactNative::IJSValueWriter writer) { + winrt::Microsoft::ReactNative::WriteValue(writer, value); + }); + } + + private: + winrt::Microsoft::ReactNative::EventEmitter m_eventEmitter{nullptr}; +}; + +template +struct BaseCalendarView { + + virtual void UpdateProps( + const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::com_ptr &newProps, + const winrt::com_ptr &/*oldProps*/) noexcept { + m_props = newProps; + } + + // UpdateLayoutMetrics will only be called if this method is overridden + virtual void UpdateLayoutMetrics( + const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::LayoutMetrics &/*newLayoutMetrics*/, + const winrt::Microsoft::ReactNative::LayoutMetrics &/*oldLayoutMetrics*/) noexcept { + } + + // UpdateState will only be called if this method is overridden + virtual void UpdateState( + const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::IComponentState &/*newState*/) noexcept { + } + + virtual void UpdateEventEmitter(const std::shared_ptr &eventEmitter) noexcept { + m_eventEmitter = eventEmitter; + } + + // MountChildComponentView will only be called if this method is overridden + virtual void MountChildComponentView(const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &/*args*/) noexcept { + } + + // UnmountChildComponentView will only be called if this method is overridden + virtual void UnmountChildComponentView(const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &/*args*/) noexcept { + } + + // Initialize will only be called if this method is overridden + virtual void Initialize(const winrt::Microsoft::ReactNative::ComponentView &/*view*/) noexcept { + } + + // CreateVisual will only be called if this method is overridden + virtual winrt::Microsoft::UI::Composition::Visual CreateVisual(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { + return view.as().Compositor().CreateSpriteVisual(); + } + + // FinalizeUpdate will only be called if this method is overridden + virtual void FinalizeUpdate(const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + winrt::Microsoft::ReactNative::ComponentViewUpdateMask /*mask*/) noexcept { + } + + + + const std::shared_ptr& EventEmitter() const { return m_eventEmitter; } + const winrt::com_ptr& Props() const { return m_props; } + +private: + winrt::com_ptr m_props; + std::shared_ptr m_eventEmitter; +}; + +template +void RegisterCalendarViewNativeComponent( + winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder, + std::function builderCallback) noexcept { + packageBuilder.as().AddViewComponent( + L"CalendarView", [builderCallback](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept { + auto compBuilder = builder.as(); + + builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props, + const winrt::Microsoft::ReactNative::IComponentProps& cloneFrom) noexcept { + return winrt::make(props, cloneFrom); + }); + + builder.SetUpdatePropsHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::IComponentProps &newProps, + const winrt::Microsoft::ReactNative::IComponentProps &oldProps) noexcept { + auto userData = view.UserData().as(); + userData->UpdateProps(view, newProps ? newProps.as() : nullptr, oldProps ? oldProps.as() : nullptr); + }); + + compBuilder.SetUpdateLayoutMetricsHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::LayoutMetrics &newLayoutMetrics, + const winrt::Microsoft::ReactNative::LayoutMetrics &oldLayoutMetrics) noexcept { + auto userData = view.UserData().as(); + userData->UpdateLayoutMetrics(view, newLayoutMetrics, oldLayoutMetrics); + }); + + builder.SetUpdateEventEmitterHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::EventEmitter &eventEmitter) noexcept { + auto userData = view.UserData().as(); + userData->UpdateEventEmitter(std::make_shared(eventEmitter)); + }); + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::FinalizeUpdate != &BaseCalendarView::FinalizeUpdate) { + builder.SetFinalizeUpdateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + winrt::Microsoft::ReactNative::ComponentViewUpdateMask mask) noexcept { + auto userData = view.UserData().as(); + userData->FinalizeUpdate(view, mask); + }); + } + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UpdateState != &BaseCalendarView::UpdateState) { + builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept { + auto userData = view.UserData().as(); + userData->UpdateState(view, newState); + }); + } + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::MountChildComponentView != &BaseCalendarView::MountChildComponentView) { + builder.SetMountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept { + auto userData = view.UserData().as(); + return userData->MountChildComponentView(view, args); + }); + } + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UnmountChildComponentView != &BaseCalendarView::UnmountChildComponentView) { + builder.SetUnmountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept { + auto userData = view.UserData().as(); + return userData->UnmountChildComponentView(view, args); + }); + } + + compBuilder.SetViewComponentViewInitializer([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { + auto userData = winrt::make_self(); + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::Initialize != &BaseCalendarView::Initialize) { + userData->Initialize(view); + } + view.UserData(*userData); + }); + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::CreateVisual != &BaseCalendarView::CreateVisual) { + compBuilder.SetCreateVisualHandler([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { + auto userData = view.UserData().as(); + return userData->CreateVisual(view); + }); + } + + // Allow app to further customize the builder + if (builderCallback) { + builderCallback(compBuilder); + } + }); +} + +} // namespace winrt::XamlCalendarView::Codegen + +#endif // #ifdef RNW_NEW_ARCH diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/packages.lock.json b/packages/xaml-calendar-view/windows/XamlCalendarView/packages.lock.json new file mode 100644 index 00000000000..52c6e386192 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/packages.lock.json @@ -0,0 +1,115 @@ +{ + "version": 1, + "dependencies": { + "native,Version=v0.0": { + "boost": { + "type": "Direct", + "requested": "[1.83.0, )", + "resolved": "1.83.0", + "contentHash": "cy53VNMzysEMvhBixDe8ujPk67Fcj3v6FPHQnH91NYJNLHpc6jxa2xq9ruCaaJjE4M3YrGSHDi4uUSTGBWw6EQ==" + }, + "Microsoft.VCRTForwarders.140": { + "type": "Direct", + "requested": "[1.0.2-rc, )", + "resolved": "1.0.2-rc", + "contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ==" + }, + "Microsoft.Windows.CppWinRT": { + "type": "Direct", + "requested": "[2.0.230706.1, )", + "resolved": "2.0.230706.1", + "contentHash": "l0D7oCw/5X+xIKHqZTi62TtV+1qeSz7KVluNFdrJ9hXsst4ghvqQ/Yhura7JqRdZWBXAuDS0G0KwALptdoxweQ==" + }, + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.7.250401001, )", + "resolved": "1.7.250401001", + "contentHash": "kPsJ2LZoo3Xs/6FtIWMZRGnQ2ZMx9zDa0ZpqRGz1qwZr0gwwlXZJTmngaA1Ym2AHmIa05NtX2jEE2He8CzfhTg==", + "dependencies": { + "Microsoft.Web.WebView2": "1.0.2903.40", + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.756" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "AT3HlgTjsqHnWpBHSNeR0KxbLZD7bztlZVj7I8vgeYG9SYqbeFGh0TM/KVtC6fg53nrWHl3VfZFvb5BiQFcY6Q==" + }, + "Microsoft.JavaScript.Hermes": { + "type": "Transitive", + "resolved": "0.0.0-2505.2001-0e4bc3b9", + "contentHash": "VNSUBgaGzJ/KkK3Br0b9FORkCgKqke54hi48vG42xRACIlxN+uLFMz0hRo+KHogz+Fsn+ltXicGwQsDVpmaCMg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "1.1.1", + "Microsoft.SourceLink.Common": "1.1.1" + } + }, + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.2903.40", + "contentHash": "THrzYAnJgE3+cNH+9Epr44XjoZoRELdVpXlWGPs6K9C9G6TqyDfVCeVAR/Er8ljLitIUX5gaSkPsy9wRhD1sgQ==" + }, + "Microsoft.Windows.SDK.BuildTools": { + "type": "Transitive", + "resolved": "10.0.22621.756", + "contentHash": "7ZL2sFSioYm1Ry067Kw1hg0SCcW5kuVezC2SwjGbcPE61Nn+gTbH86T73G3LcEOVj0S3IZzNuE/29gZvOLS7VA==" + }, + "common": { + "type": "Project", + "dependencies": { + "boost": "[1.83.0, )" + } + }, + "fmt": { + "type": "Project" + }, + "folly": { + "type": "Project", + "dependencies": { + "boost": "[1.83.0, )", + "fmt": "[1.0.0, )" + } + }, + "microsoft.reactnative": { + "type": "Project", + "dependencies": { + "Common": "[1.0.0, )", + "Folly": "[1.0.0, )", + "Microsoft.JavaScript.Hermes": "[0.0.0-2505.2001-0e4bc3b9, )", + "Microsoft.SourceLink.GitHub": "[1.1.1, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "ReactCommon": "[1.0.0, )", + "boost": "[1.83.0, )" + } + }, + "microsoft.reactnative.xaml": { + "type": "Project", + "dependencies": { + "Common": "[1.0.0, )", + "Folly": "[1.0.0, )", + "Microsoft.ReactNative": "[1.0.0, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "ReactCommon": "[1.0.0, )", + "boost": "[1.83.0, )" + } + }, + "reactcommon": { + "type": "Project", + "dependencies": { + "Folly": "[1.0.0, )", + "boost": "[1.83.0, )" + } + } + } + } +} \ No newline at end of file diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/pch.cpp b/packages/xaml-calendar-view/windows/XamlCalendarView/pch.cpp new file mode 100644 index 00000000000..1d9f38c57d6 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/pch.h b/packages/xaml-calendar-view/windows/XamlCalendarView/pch.h new file mode 100644 index 00000000000..61d356df65a --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/pch.h @@ -0,0 +1,30 @@ +// pch.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define NOMINMAX 1 +#define WIN32_LEAN_AND_MEAN 1 +#define WINRT_LEAN_AND_MEAN 1 + +// Windows Header Files +#include +#undef GetCurrentTime +#include + +// WinRT Header Files +#include +#include +#include + +// C RunTime Header Files +#include +#include +#include +#include + +// Reference additional headers your project requires here diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/resource.h b/packages/xaml-calendar-view/windows/XamlCalendarView/resource.h new file mode 100644 index 00000000000..c8bbf48db31 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/resource.h @@ -0,0 +1,5 @@ +// +// Microsoft Visual C++ generated include file. +// Used by XamlCalendarView.rc + +#pragma once diff --git a/packages/xaml-calendar-view/windows/XamlCalendarView/targetver.h b/packages/xaml-calendar-view/windows/XamlCalendarView/targetver.h new file mode 100644 index 00000000000..87c0086de75 --- /dev/null +++ b/packages/xaml-calendar-view/windows/XamlCalendarView/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/vnext/ExperimentalFeatures.props b/vnext/ExperimentalFeatures.props index f305876cfb9..cc658d2cced 100644 --- a/vnext/ExperimentalFeatures.props +++ b/vnext/ExperimentalFeatures.props @@ -9,6 +9,11 @@ true true + + true + true + true + false diff --git a/vnext/Microsoft.ReactNative.Xaml.sln b/vnext/Microsoft.ReactNative.Xaml.sln new file mode 100644 index 00000000000..9e3cae992db --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35913.81 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Xaml", "Microsoft.ReactNative.Xaml\Microsoft.ReactNative.Xaml.vcxproj", "{E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|ARM64.Build.0 = Debug|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x64.ActiveCfg = Debug|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x64.Build.0 = Debug|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x86.ActiveCfg = Debug|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Debug|x86.Build.0 = Debug|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|ARM64.ActiveCfg = Release|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|ARM64.Build.0 = Release|ARM64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x64.ActiveCfg = Release|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x64.Build.0 = Release|x64 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x86.ActiveCfg = Release|Win32 + {E5D1B5D2-0E6A-4011-8BCD-08968256DCBD}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3B36CAF0-BCD9-42C7-B311-05FDDCCEC9D4} + EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{e5d1b5d2-0e6a-4011-8bcd-08968256dcbd}*SharedItemsImports = 4 + EndGlobalSection +EndGlobal diff --git a/vnext/Microsoft.ReactNative.Xaml/App.idl b/vnext/Microsoft.ReactNative.Xaml/App.idl new file mode 100644 index 00000000000..1e889e85a2b --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/App.idl @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.ReactNative.Xaml +{ + [webhosthidden][default_interface] runtimeclass XamlApplication : Microsoft.UI.Xaml.Application, + Microsoft.UI.Xaml.Markup.IXamlMetadataProvider + { + XamlApplication(); + + static void EnsureCreated(); + + static XamlApplication Current { + get; + }; + + void AddMetadataProvider(Microsoft.UI.Xaml.Markup.IXamlMetadataProvider otherProvider); + } +} diff --git a/vnext/Microsoft.ReactNative.Xaml/App.xaml b/vnext/Microsoft.ReactNative.Xaml/App.xaml new file mode 100644 index 00000000000..49d60714075 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/App.xaml @@ -0,0 +1,6 @@ + + diff --git a/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.def b/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.def new file mode 100644 index 00000000000..24e7c1235c3 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.vcxproj b/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.vcxproj new file mode 100644 index 00000000000..b12f7a1e40b --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.vcxproj @@ -0,0 +1,177 @@ + + + + + true + true + true + {e5d1b5d2-0e6a-4011-8bcd-08968256dcbd} + Microsoft.ReactNative.Xaml + Microsoft.ReactNative.Xaml + en-US + 16.0 + false + Windows Store + 10.0 + 10.0.22621.0 + 10.0.17763.0 + true + true + + + + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + DynamicLibrary + v143 + Unicode + false + true + + + true + true + + + false + true + false + + + + + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + true + Microsoft.ReactNative.Xaml.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + ReactPackageProvider.idl + + + + + Create + + + ReactPackageProvider.idl + + + + + + + + + + + Code + + + + + + + + + + + + {fca38f3c-7c73-4c47-be4e-32f77fa8538d} + + + {a990658c-ce31-4bcc-976f-0fc6b1af693d} + + + {a9d95a91-4db7-4f72-beb6-fe8a5c89bfbd} + + + {f7d32bd0-2749-483e-9a0d-1635ef7e3136} + + + + + + + + + + + + + + + diff --git a/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.vcxproj.filters b/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.vcxproj.filters new file mode 100644 index 00000000000..24eec322ed6 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/Microsoft.ReactNative.Xaml.vcxproj.filters @@ -0,0 +1,31 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vnext/Microsoft.ReactNative.Xaml/PropertySheet.props b/vnext/Microsoft.ReactNative.Xaml/PropertySheet.props new file mode 100644 index 00000000000..5b718b12519 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/PropertySheet.props @@ -0,0 +1,17 @@ + + + + + + normal + + + + + + $(CppWinRTVerbosity) + + + \ No newline at end of file diff --git a/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.cpp b/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.cpp new file mode 100644 index 00000000000..e020bc2191e --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.cpp @@ -0,0 +1,14 @@ +#include "pch.h" +#include "ReactPackageProvider.h" +#include "ReactPackageProvider.g.cpp" +#include "ModuleRegistration.h" + +#include "XamlHost.h" + +namespace winrt::Microsoft::ReactNative::Xaml::implementation { +void ReactPackageProvider::CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) { + AddAttributedModules(packageBuilder, true); + + RegisterXamlHostComponentView(packageBuilder); +} +} // namespace winrt::Microsoft::ReactNative::Xaml::implementation diff --git a/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.h b/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.h new file mode 100644 index 00000000000..bf39097efbb --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.h @@ -0,0 +1,13 @@ +#pragma once +#include "ReactPackageProvider.g.h" + +namespace winrt::Microsoft::ReactNative::Xaml::implementation { +struct ReactPackageProvider : ReactPackageProviderT { + ReactPackageProvider() = default; + + void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder); +}; +} // namespace winrt::Microsoft::ReactNative::Xaml::implementation +namespace winrt::Microsoft::ReactNative::Xaml::factory_implementation { +struct ReactPackageProvider : ReactPackageProviderT {}; +} // namespace winrt::Microsoft::ReactNative::Xaml::factory_implementation diff --git a/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.idl b/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.idl new file mode 100644 index 00000000000..5029dc3f768 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/ReactPackageProvider.idl @@ -0,0 +1,16 @@ +namespace Microsoft.ReactNative.Xaml +{ + [webhosthidden] + [default_interface] + runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider + { + ReactPackageProvider(); + }; + + [webhosthidden] + interface IXamlControl + { + Microsoft.UI.Xaml.UIElement GetXamlElement(); + } + +} diff --git a/vnext/Microsoft.ReactNative.Xaml/XamlApplication.cpp b/vnext/Microsoft.ReactNative.Xaml/XamlApplication.cpp new file mode 100644 index 00000000000..1203a92acbe --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/XamlApplication.cpp @@ -0,0 +1,78 @@ +#include "pch.h" + +#include "XamlApplication.h" + +#include "XamlApplication.g.cpp" + +#include "winrt/Microsoft.UI.Xaml.XamlTypeInfo.h" + +namespace winrt::Microsoft::ReactNative::Xaml::implementation { + +using namespace ::winrt::Microsoft::UI::Xaml; +using namespace ::winrt::Microsoft::UI::Xaml::Markup; +using namespace ::winrt::Windows::UI::Xaml::Interop; + +XamlApplication::XamlApplication() { + s_current = *this; + + // TODO: It's probably not a good idea to only load the controls pri file, there are other ones too. + auto resourceManager = + winrt::Microsoft::Windows::ApplicationModel::Resources::ResourceManager(L"Microsoft.UI.Xaml.Controls.pri"); + + this->ResourceManagerRequested([resourceManager](auto &&, ResourceManagerRequestedEventArgs args) { + args.CustomResourceManager(resourceManager); + }); + winrt::Microsoft::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread(); + + m_providers.push_back( + winrt::make_self() + .as()); // Default generated provider + m_providers.push_back(winrt::Microsoft::UI::Xaml::XamlTypeInfo::XamlControlsXamlMetaDataProvider()); + + auto winUIResources = winrt::Microsoft::UI::Xaml::Controls::XamlControlsResources(); + Resources().MergedDictionaries().Append(winUIResources); +} + +XamlApplication::~XamlApplication() { + s_current = nullptr; +} + +IXamlType XamlApplication::GetXamlType(TypeName const &type) { + for (auto &&provider : m_providers) { + if (auto result = provider.GetXamlType(type)) { + return result; + } + } + return nullptr; +} + +IXamlType XamlApplication::GetXamlType(::winrt::hstring const &fullName) { + for (auto &&provider : m_providers) { + if (auto result = provider.GetXamlType(fullName)) { + return result; + } + } + + return nullptr; +} + +::winrt::com_array<::winrt::Microsoft::UI::Xaml::Markup::XmlnsDefinition> XamlApplication::GetXmlnsDefinitions() { + std::vector<::winrt::Microsoft::UI::Xaml::Markup::XmlnsDefinition> allDefinitions; + for (const auto &provider : m_providers) { + auto definitionsCurrentProvider = provider.GetXmlnsDefinitions(); + for (const auto &definition : definitionsCurrentProvider) { + allDefinitions.insert(allDefinitions.begin(), definition); + } + } + return winrt::com_array<::winrt::Microsoft::UI::Xaml::Markup::XmlnsDefinition>( + allDefinitions.begin(), allDefinitions.end()); +} + +void XamlApplication::AddMetadataProvider( + winrt::Microsoft::UI::Xaml::Markup::IXamlMetadataProvider const &otherProvider) { + m_providers.push_back(otherProvider); +} + +winrt::Microsoft::ReactNative::Xaml::XamlApplication XamlApplication::s_current{nullptr}; + +} // namespace winrt::Microsoft::ReactNative::Xaml::implementation diff --git a/vnext/Microsoft.ReactNative.Xaml/XamlApplication.h b/vnext/Microsoft.ReactNative.Xaml/XamlApplication.h new file mode 100644 index 00000000000..4018e1f3a04 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/XamlApplication.h @@ -0,0 +1,46 @@ +#pragma once +#include "XamlApplication.g.h" + +#include "winrt/Microsoft.UI.Xaml.Hosting.h" +#include "winrt/Microsoft.UI.Xaml.Interop.h" +#include "winrt/Microsoft.UI.Xaml.Markup.h" +#include "winrt/Microsoft.UI.Xaml.h" + +#include "winrt/Windows.UI.Xaml.Interop.h" + +#include "XamlMetaDataProvider.h" + +namespace winrt::Microsoft::ReactNative::Xaml::implementation { +struct XamlApplication : XamlApplicationT { + using IXamlType = ::winrt::Microsoft::UI::Xaml::Markup::IXamlType; + + XamlApplication(); + ~XamlApplication(); + + static void EnsureCreated() { + if (Current() == nullptr) { + // Create this type + winrt::make(); + } + } + + static winrt::Microsoft::ReactNative::Xaml::XamlApplication Current() { + return s_current; + } + + IXamlType GetXamlType(::winrt::Windows::UI::Xaml::Interop::TypeName const &type); + + IXamlType GetXamlType(::winrt::hstring const &fullName); + + ::winrt::com_array<::winrt::Microsoft::UI::Xaml::Markup::XmlnsDefinition> GetXmlnsDefinitions(); + + void AddMetadataProvider(winrt::Microsoft::UI::Xaml::Markup::IXamlMetadataProvider const &otherProvider); + + private: + static winrt::Microsoft::ReactNative::Xaml::XamlApplication s_current; + std::vector m_providers; +}; +} // namespace winrt::Microsoft::ReactNative::Xaml::implementation +namespace winrt::Microsoft::ReactNative::Xaml::factory_implementation { +struct XamlApplication : XamlApplicationT {}; +} // namespace winrt::Microsoft::ReactNative::Xaml::factory_implementation diff --git a/vnext/Microsoft.ReactNative.Xaml/XamlHost.cpp b/vnext/Microsoft.ReactNative.Xaml/XamlHost.cpp new file mode 100644 index 00000000000..38a430d59aa --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/XamlHost.cpp @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "pch.h" + +#include "XamlApplication.h" +#include "XamlHost.h" + +#if defined(RNW_NEW_ARCH) + +#include "..\codegen\react\components\rnwcore\XamlHost.g.h" + +namespace winrt::Microsoft::ReactNative::Xaml { + +struct XamlHostComponentView : public winrt::implements, + ::Microsoft::ReactNativeSpecs::BaseXamlHost { + void InitializeContentIsland( + const winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView &islandView) noexcept { + winrt::Microsoft::ReactNative::Xaml::implementation::XamlApplication::EnsureCreated(); + + m_xamlIsland = winrt::Microsoft::UI::Xaml::XamlIsland{}; + + auto grid = winrt::Microsoft::UI::Xaml::Controls::Grid{}; + auto button = winrt::Microsoft::UI::Xaml::Controls::Button{}; + button.Content(winrt::box_value(L"(This is placeholder content for the XamlHost.)")); + grid.Children().Append(button); + m_xamlIsland.Content(grid); + + // m_xamlIsland.Content(m_XamlHost); + islandView.Connect(m_xamlIsland.ContentIsland()); + } + + void MountChildComponentView( + const winrt::Microsoft::ReactNative::ComponentView & /*view*/, + const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept override { + // Add the xaml child to the m_xamlIsland here. + auto childXamlControl = args.Child().UserData().as(); + if (childXamlControl) { + auto xamlElement = childXamlControl.GetXamlElement(); + m_xamlIsland.Content(xamlElement); + } + } + + void UnmountChildComponentView( + const winrt::Microsoft::ReactNative::ComponentView & /*view*/, + const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &) noexcept override { + m_xamlIsland.Content(nullptr); + } + + private: + winrt::Microsoft::UI::Xaml::XamlIsland m_xamlIsland{nullptr}; +}; + +} // namespace winrt::Microsoft::ReactNative::Xaml + +void RegisterXamlHostComponentView(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) { + ::Microsoft::ReactNativeSpecs::RegisterXamlHostNativeComponent< + winrt::Microsoft::ReactNative::Xaml::XamlHostComponentView>( + packageBuilder, + [](const winrt::Microsoft::ReactNative::Composition::IReactCompositionViewComponentBuilder &builder) { + builder.SetContentIslandComponentViewInitializer( + [](const winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView &islandView) noexcept { + auto userData = winrt::make_self(); + userData->InitializeContentIsland(islandView); + islandView.UserData(*userData); + }); + }); +} + +#endif // defined(RNW_NEW_ARCH) && defined(USE_EXPERIMENTAL_WINUI3) diff --git a/vnext/Microsoft.ReactNative.Xaml/XamlHost.h b/vnext/Microsoft.ReactNative.Xaml/XamlHost.h new file mode 100644 index 00000000000..50717a3f53e --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/XamlHost.h @@ -0,0 +1,9 @@ +#pragma once + +#if defined(RNW_NEW_ARCH) + +void RegisterXamlHostComponentView(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder); + +void RegisterXamlControl(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder); + +#endif // defined(RNW_NEW_ARCH) && defined(USE_EXPERIMENTAL_WINUI3) diff --git a/vnext/Microsoft.ReactNative.Xaml/packages.newarch.lock.json b/vnext/Microsoft.ReactNative.Xaml/packages.newarch.lock.json new file mode 100644 index 00000000000..5729b8a31dd --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/packages.newarch.lock.json @@ -0,0 +1,98 @@ +{ + "version": 1, + "dependencies": { + "native,Version=v0.0": { + "boost": { + "type": "Direct", + "requested": "[1.83.0, )", + "resolved": "1.83.0", + "contentHash": "cy53VNMzysEMvhBixDe8ujPk67Fcj3v6FPHQnH91NYJNLHpc6jxa2xq9ruCaaJjE4M3YrGSHDi4uUSTGBWw6EQ==" + }, + "Microsoft.Windows.CppWinRT": { + "type": "Direct", + "requested": "[2.0.230706.1, )", + "resolved": "2.0.230706.1", + "contentHash": "l0D7oCw/5X+xIKHqZTi62TtV+1qeSz7KVluNFdrJ9hXsst4ghvqQ/Yhura7JqRdZWBXAuDS0G0KwALptdoxweQ==" + }, + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.7.250401001, )", + "resolved": "1.7.250401001", + "contentHash": "kPsJ2LZoo3Xs/6FtIWMZRGnQ2ZMx9zDa0ZpqRGz1qwZr0gwwlXZJTmngaA1Ym2AHmIa05NtX2jEE2He8CzfhTg==", + "dependencies": { + "Microsoft.Web.WebView2": "1.0.2903.40", + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.756" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "AT3HlgTjsqHnWpBHSNeR0KxbLZD7bztlZVj7I8vgeYG9SYqbeFGh0TM/KVtC6fg53nrWHl3VfZFvb5BiQFcY6Q==" + }, + "Microsoft.JavaScript.Hermes": { + "type": "Transitive", + "resolved": "0.0.0-2505.2001-0e4bc3b9", + "contentHash": "VNSUBgaGzJ/KkK3Br0b9FORkCgKqke54hi48vG42xRACIlxN+uLFMz0hRo+KHogz+Fsn+ltXicGwQsDVpmaCMg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "1.1.1", + "Microsoft.SourceLink.Common": "1.1.1" + } + }, + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.2903.40", + "contentHash": "THrzYAnJgE3+cNH+9Epr44XjoZoRELdVpXlWGPs6K9C9G6TqyDfVCeVAR/Er8ljLitIUX5gaSkPsy9wRhD1sgQ==" + }, + "Microsoft.Windows.SDK.BuildTools": { + "type": "Transitive", + "resolved": "10.0.22621.756", + "contentHash": "7ZL2sFSioYm1Ry067Kw1hg0SCcW5kuVezC2SwjGbcPE61Nn+gTbH86T73G3LcEOVj0S3IZzNuE/29gZvOLS7VA==" + }, + "common": { + "type": "Project", + "dependencies": { + "boost": "[1.83.0, )" + } + }, + "fmt": { + "type": "Project" + }, + "folly": { + "type": "Project", + "dependencies": { + "boost": "[1.83.0, )", + "fmt": "[1.0.0, )" + } + }, + "microsoft.reactnative": { + "type": "Project", + "dependencies": { + "Common": "[1.0.0, )", + "Folly": "[1.0.0, )", + "Microsoft.JavaScript.Hermes": "[0.0.0-2505.2001-0e4bc3b9, )", + "Microsoft.SourceLink.GitHub": "[1.1.1, )", + "Microsoft.WindowsAppSDK": "[1.7.250401001, )", + "ReactCommon": "[1.0.0, )", + "boost": "[1.83.0, )" + } + }, + "reactcommon": { + "type": "Project", + "dependencies": { + "Folly": "[1.0.0, )", + "boost": "[1.83.0, )" + } + } + } + } +} \ No newline at end of file diff --git a/vnext/Microsoft.ReactNative.Xaml/pch.cpp b/vnext/Microsoft.ReactNative.Xaml/pch.cpp new file mode 100644 index 00000000000..1d9f38c57d6 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/vnext/Microsoft.ReactNative.Xaml/pch.h b/vnext/Microsoft.ReactNative.Xaml/pch.h new file mode 100644 index 00000000000..cccf869f820 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/pch.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include +#include + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include diff --git a/vnext/Microsoft.ReactNative.Xaml/resource.h b/vnext/Microsoft.ReactNative.Xaml/resource.h new file mode 100644 index 00000000000..5c610888ab7 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Xaml/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Resource.rc +// +#define IDD_DIALOG1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp index 57aa7d14656..b3a26693c66 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp @@ -178,14 +178,17 @@ ContentIslandComponentView::~ContentIslandComponentView() noexcept { void ContentIslandComponentView::MountChildComponentView( const winrt::Microsoft::ReactNative::ComponentView &childComponentView, uint32_t index) noexcept { - assert(false); + // I assume this is here b/c it doesn't make sense for a Island CV to have children. + // XamlHost does have children, but the children will represent Xaml elements and + // don't participate direction in RN's rendering. + // assert(false); base_type::MountChildComponentView(childComponentView, index); } void ContentIslandComponentView::UnmountChildComponentView( const winrt::Microsoft::ReactNative::ComponentView &childComponentView, uint32_t index) noexcept { - assert(false); + // assert(false); base_type::UnmountChildComponentView(childComponentView, index); } diff --git a/vnext/PropertySheets/External/Microsoft.ReactNative.Cpp.ProjectReferences.props b/vnext/PropertySheets/External/Microsoft.ReactNative.Cpp.ProjectReferences.props index 1f58b7e950a..b255f226e74 100644 --- a/vnext/PropertySheets/External/Microsoft.ReactNative.Cpp.ProjectReferences.props +++ b/vnext/PropertySheets/External/Microsoft.ReactNative.Cpp.ProjectReferences.props @@ -18,5 +18,13 @@ Microsoft.ReactNative false + + + + {e5d1b5d2-0e6a-4011-8bcd-08968256dcbd} + Microsoft.ReactNative.Xaml + false + + diff --git a/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h b/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h index 45b7b5ea904..f3d7509b0e9 100644 --- a/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h +++ b/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h @@ -23,6 +23,7 @@ using DebuggingOverlayComponentDescriptor = ConcreteComponentDescriptor; using SwitchComponentDescriptor = ConcreteComponentDescriptor; using UnimplementedNativeViewComponentDescriptor = ConcreteComponentDescriptor; +using XamlHostComponentDescriptor = ConcreteComponentDescriptor; void rnwcore_registerComponentDescriptorsFromCodegen( std::shared_ptr registry); diff --git a/vnext/codegen/react/components/rnwcore/EventEmitters.cpp b/vnext/codegen/react/components/rnwcore/EventEmitters.cpp index adcd150d680..b78a6087acf 100644 --- a/vnext/codegen/react/components/rnwcore/EventEmitters.cpp +++ b/vnext/codegen/react/components/rnwcore/EventEmitters.cpp @@ -129,4 +129,5 @@ void SwitchEventEmitter::onChange(OnChange $event) const { } + } // namespace facebook::react diff --git a/vnext/codegen/react/components/rnwcore/EventEmitters.h b/vnext/codegen/react/components/rnwcore/EventEmitters.h index 0c3bce4a218..ccac8315736 100644 --- a/vnext/codegen/react/components/rnwcore/EventEmitters.h +++ b/vnext/codegen/react/components/rnwcore/EventEmitters.h @@ -165,5 +165,12 @@ class UnimplementedNativeViewEventEmitter : public ViewEventEmitter { +}; +class XamlHostEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + + }; } // namespace facebook::react diff --git a/vnext/codegen/react/components/rnwcore/Props.cpp b/vnext/codegen/react/components/rnwcore/Props.cpp index 3d33bfb0980..9e1ca41bd42 100644 --- a/vnext/codegen/react/components/rnwcore/Props.cpp +++ b/vnext/codegen/react/components/rnwcore/Props.cpp @@ -153,5 +153,12 @@ UnimplementedNativeViewProps::UnimplementedNativeViewProps( name(convertRawProp(context, rawProps, "name", sourceProps.name, {""})) {} +XamlHostProps::XamlHostProps( + const PropsParserContext &context, + const XamlHostProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), + + label(convertRawProp(context, rawProps, "label", sourceProps.label, {})) + {} } // namespace facebook::react diff --git a/vnext/codegen/react/components/rnwcore/Props.h b/vnext/codegen/react/components/rnwcore/Props.h index 397bc1706cb..5805acbd7d5 100644 --- a/vnext/codegen/react/components/rnwcore/Props.h +++ b/vnext/codegen/react/components/rnwcore/Props.h @@ -395,4 +395,14 @@ class UnimplementedNativeViewProps final : public ViewProps { std::string name{""}; }; +class XamlHostProps final : public ViewProps { + public: + XamlHostProps() = default; + XamlHostProps(const PropsParserContext& context, const XamlHostProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + std::string label{}; +}; + } // namespace facebook::react diff --git a/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp b/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp index dccefb1d478..627e9a2d3fe 100644 --- a/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp +++ b/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp @@ -19,5 +19,6 @@ extern const char DebuggingOverlayComponentName[] = "DebuggingOverlay"; extern const char PullToRefreshViewComponentName[] = "PullToRefreshView"; extern const char SwitchComponentName[] = "Switch"; extern const char UnimplementedNativeViewComponentName[] = "UnimplementedNativeView"; +extern const char XamlHostComponentName[] = "XamlHost"; } // namespace facebook::react diff --git a/vnext/codegen/react/components/rnwcore/ShadowNodes.h b/vnext/codegen/react/components/rnwcore/ShadowNodes.h index 2c7c94720cf..9b45530d5ad 100644 --- a/vnext/codegen/react/components/rnwcore/ShadowNodes.h +++ b/vnext/codegen/react/components/rnwcore/ShadowNodes.h @@ -95,4 +95,15 @@ using UnimplementedNativeViewShadowNode = ConcreteViewShadowNode< UnimplementedNativeViewEventEmitter, UnimplementedNativeViewState>; +JSI_EXPORT extern const char XamlHostComponentName[]; + +/* + * `ShadowNode` for component. + */ +using XamlHostShadowNode = ConcreteViewShadowNode< + XamlHostComponentName, + XamlHostProps, + XamlHostEventEmitter, + XamlHostState>; + } // namespace facebook::react diff --git a/vnext/codegen/react/components/rnwcore/States.h b/vnext/codegen/react/components/rnwcore/States.h index df8b9e54057..efc143b39cc 100644 --- a/vnext/codegen/react/components/rnwcore/States.h +++ b/vnext/codegen/react/components/rnwcore/States.h @@ -98,4 +98,16 @@ class UnimplementedNativeViewState { #endif }; +class XamlHostState { +public: + XamlHostState() = default; + +#ifdef ANDROID + XamlHostState(XamlHostState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; +#endif +}; + } // namespace facebook::react \ No newline at end of file diff --git a/vnext/codegen/react/components/rnwcore/XamlHost.g.h b/vnext/codegen/react/components/rnwcore/XamlHost.g.h new file mode 100644 index 00000000000..26bd059c3c3 --- /dev/null +++ b/vnext/codegen/react/components/rnwcore/XamlHost.g.h @@ -0,0 +1,200 @@ + +/* + * This file is auto-generated from XamlHostNativeComponent spec file in flow / TypeScript. + */ +// clang-format off +#pragma once + +#include + +#ifdef RNW_NEW_ARCH +#include + +#include +#include +#endif // #ifdef RNW_NEW_ARCH + +#ifdef RNW_NEW_ARCH + +namespace Microsoft::ReactNativeSpecs { + +REACT_STRUCT(XamlHostProps) +struct XamlHostProps : winrt::implements { + XamlHostProps(winrt::Microsoft::ReactNative::ViewProps props, const winrt::Microsoft::ReactNative::IComponentProps& cloneFrom) + : ViewProps(props) + { + if (cloneFrom) { + auto cloneFromProps = cloneFrom.as(); + label = cloneFromProps->label; + } + } + + void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept { + winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this); + } + + REACT_FIELD(label) + std::optional label; + + const winrt::Microsoft::ReactNative::ViewProps ViewProps; +}; + +struct XamlHostEventEmitter { + XamlHostEventEmitter(const winrt::Microsoft::ReactNative::EventEmitter &eventEmitter) + : m_eventEmitter(eventEmitter) {} + + private: + winrt::Microsoft::ReactNative::EventEmitter m_eventEmitter{nullptr}; +}; + +template +struct BaseXamlHost { + + virtual void UpdateProps( + const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::com_ptr &newProps, + const winrt::com_ptr &/*oldProps*/) noexcept { + m_props = newProps; + } + + // UpdateLayoutMetrics will only be called if this method is overridden + virtual void UpdateLayoutMetrics( + const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::LayoutMetrics &/*newLayoutMetrics*/, + const winrt::Microsoft::ReactNative::LayoutMetrics &/*oldLayoutMetrics*/) noexcept { + } + + // UpdateState will only be called if this method is overridden + virtual void UpdateState( + const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::IComponentState &/*newState*/) noexcept { + } + + virtual void UpdateEventEmitter(const std::shared_ptr &eventEmitter) noexcept { + m_eventEmitter = eventEmitter; + } + + // MountChildComponentView will only be called if this method is overridden + virtual void MountChildComponentView(const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &/*args*/) noexcept { + } + + // UnmountChildComponentView will only be called if this method is overridden + virtual void UnmountChildComponentView(const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &/*args*/) noexcept { + } + + // Initialize will only be called if this method is overridden + virtual void Initialize(const winrt::Microsoft::ReactNative::ComponentView &/*view*/) noexcept { + } + + // CreateVisual will only be called if this method is overridden + virtual winrt::Microsoft::UI::Composition::Visual CreateVisual(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { + return view.as().Compositor().CreateSpriteVisual(); + } + + // FinalizeUpdate will only be called if this method is overridden + virtual void FinalizeUpdate(const winrt::Microsoft::ReactNative::ComponentView &/*view*/, + winrt::Microsoft::ReactNative::ComponentViewUpdateMask /*mask*/) noexcept { + } + + + + const std::shared_ptr& EventEmitter() const { return m_eventEmitter; } + const winrt::com_ptr& Props() const { return m_props; } + +private: + winrt::com_ptr m_props; + std::shared_ptr m_eventEmitter; +}; + +template +void RegisterXamlHostNativeComponent( + winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder, + std::function builderCallback) noexcept { + packageBuilder.as().AddViewComponent( + L"XamlHost", [builderCallback](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept { + auto compBuilder = builder.as(); + + builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props, + const winrt::Microsoft::ReactNative::IComponentProps& cloneFrom) noexcept { + return winrt::make(props, cloneFrom); + }); + + builder.SetUpdatePropsHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::IComponentProps &newProps, + const winrt::Microsoft::ReactNative::IComponentProps &oldProps) noexcept { + auto userData = view.UserData().as(); + userData->UpdateProps(view, newProps ? newProps.as() : nullptr, oldProps ? oldProps.as() : nullptr); + }); + + compBuilder.SetUpdateLayoutMetricsHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::LayoutMetrics &newLayoutMetrics, + const winrt::Microsoft::ReactNative::LayoutMetrics &oldLayoutMetrics) noexcept { + auto userData = view.UserData().as(); + userData->UpdateLayoutMetrics(view, newLayoutMetrics, oldLayoutMetrics); + }); + + builder.SetUpdateEventEmitterHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::EventEmitter &eventEmitter) noexcept { + auto userData = view.UserData().as(); + userData->UpdateEventEmitter(std::make_shared(eventEmitter)); + }); + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::FinalizeUpdate != &BaseXamlHost::FinalizeUpdate) { + builder.SetFinalizeUpdateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + winrt::Microsoft::ReactNative::ComponentViewUpdateMask mask) noexcept { + auto userData = view.UserData().as(); + userData->FinalizeUpdate(view, mask); + }); + } + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UpdateState != &BaseXamlHost::UpdateState) { + builder.SetUpdateStateHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept { + auto userData = view.UserData().as(); + userData->UpdateState(view, newState); + }); + } + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::MountChildComponentView != &BaseXamlHost::MountChildComponentView) { + builder.SetMountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept { + auto userData = view.UserData().as(); + return userData->MountChildComponentView(view, args); + }); + } + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::UnmountChildComponentView != &BaseXamlHost::UnmountChildComponentView) { + builder.SetUnmountChildComponentViewHandler([](const winrt::Microsoft::ReactNative::ComponentView &view, + const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept { + auto userData = view.UserData().as(); + return userData->UnmountChildComponentView(view, args); + }); + } + + compBuilder.SetViewComponentViewInitializer([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { + auto userData = winrt::make_self(); + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::Initialize != &BaseXamlHost::Initialize) { + userData->Initialize(view); + } + view.UserData(*userData); + }); + + if CONSTEXPR_SUPPORTED_ON_VIRTUAL_FN_ADDRESS (&TUserData::CreateVisual != &BaseXamlHost::CreateVisual) { + compBuilder.SetCreateVisualHandler([](const winrt::Microsoft::ReactNative::ComponentView &view) noexcept { + auto userData = view.UserData().as(); + return userData->CreateVisual(view); + }); + } + + // Allow app to further customize the builder + if (builderCallback) { + builderCallback(compBuilder); + } + }); +} + +} // namespace Microsoft::ReactNativeSpecs + +#endif // #ifdef RNW_NEW_ARCH diff --git a/vnext/src-win/Libraries/Components/Xaml/XamlHost.d.ts b/vnext/src-win/Libraries/Components/Xaml/XamlHost.d.ts new file mode 100644 index 00000000000..a69cfafe0be --- /dev/null +++ b/vnext/src-win/Libraries/Components/Xaml/XamlHost.d.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * @format + * @flow + */ +/// +import type {ViewProps} from 'react-native'; +export interface XamlHostProps extends ViewProps { + label: string; +} +declare const _default: import('react-native/Libraries/Utilities/codegenNativeComponent').NativeComponentType; +export default _default; diff --git a/vnext/src-win/Libraries/Components/Xaml/XamlHost.windows.js b/vnext/src-win/Libraries/Components/Xaml/XamlHost.windows.js new file mode 100644 index 00000000000..f3b49f6bc78 --- /dev/null +++ b/vnext/src-win/Libraries/Components/Xaml/XamlHost.windows.js @@ -0,0 +1,7 @@ +/** + * @format + * @flow + */ + +import XamlHost from '../../../src/private/specs/components/Xaml/XamlHostNativeComponent'; +export default XamlHost; diff --git a/vnext/src-win/Libraries/platform-types.d.ts b/vnext/src-win/Libraries/platform-types.d.ts index c201a5c88c1..6d379587659 100644 --- a/vnext/src-win/Libraries/platform-types.d.ts +++ b/vnext/src-win/Libraries/platform-types.d.ts @@ -17,3 +17,4 @@ export const ViewWindows = View; import type {View} from './Components/View/View'; export type ViewWindows = View; export * from './AppTheme/AppThemeTypes'; +export * from '../src/private/specs/components/Xaml/XamlHostTypes'; diff --git a/vnext/src-win/index.windows.js b/vnext/src-win/index.windows.js index 43bcc600df9..9af8e7439a2 100644 --- a/vnext/src-win/index.windows.js +++ b/vnext/src-win/index.windows.js @@ -42,6 +42,7 @@ import typeof SafeAreaView from './Libraries/Components/SafeAreaView/SafeAreaVie import typeof ScrollView from './Libraries/Components/ScrollView/ScrollView'; import typeof StatusBar from './Libraries/Components/StatusBar/StatusBar'; import typeof Switch from './Libraries/Components/Switch/Switch'; +import typeof XamlHost from './Libraries/Components/Xaml/XamlHost'; import typeof InputAccessoryView from './Libraries/Components/TextInput/InputAccessoryView'; import typeof TextInput from './Libraries/Components/TextInput/TextInput'; import typeof ToastAndroid from './Libraries/Components/ToastAndroid/ToastAndroid'; @@ -186,6 +187,9 @@ module.exports = { get Switch(): Switch { return require('./Libraries/Components/Switch/Switch').default; }, + get XamlHost(): XamlHost { + return require('./Libraries/Components/Xaml/XamlHost').default; + }, get Text(): Text { return require('./Libraries/Text/Text').default; }, diff --git a/vnext/src-win/src/private/specs/components/Xaml/XamlHostNativeComponent.js b/vnext/src-win/src/private/specs/components/Xaml/XamlHostNativeComponent.js new file mode 100644 index 00000000000..4cf39730380 --- /dev/null +++ b/vnext/src-win/src/private/specs/components/Xaml/XamlHostNativeComponent.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * @format + * @flow + */ + +'use strict'; + +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; + +type XamlHostProps = $ReadOnly<{| + ...ViewProps, + + // Props + label?: string, +|}>; + +export default codegenNativeComponent('XamlHost'); diff --git a/yarn.lock b/yarn.lock index 30b99d76022..fe89dcc4faf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2139,6 +2139,11 @@ resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.11.0.tgz#4587fbce6a382adedad74311e96ee10bb2b2d63a" integrity sha512-QuZU6gbxmOID5zZgd/H90NgBnbJ3VV6qVzp6c7/dDrmWdX8S0X5YFYgDcQFjE3dRen9wB9FWnj2VVdPU64adSg== +"@react-native/assets-registry@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.79.0-nightly-20250123-d1028885e.tgz#27842aea1210494ffe6d1f204db9ae11b4bf5e83" + integrity sha512-NaZg/UFnmXdXsNyoKkGxZ7zJQ852fKdzlakMKBjw4hQ1/e9OntFMrfLbDtpXel3pwSUXqzO0UIlPA0i7XADtcg== + "@react-native/assets-registry@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.79.0-nightly-20250303-cee63397b.tgz#1d5f66cc3618c81219728bfc38da1a6e9d44982a" @@ -2149,6 +2154,14 @@ resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ== +"@react-native/babel-plugin-codegen@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.0-nightly-20250123-d1028885e.tgz#a33c521722a641812357f0445539fe00a08a89a3" + integrity sha512-UXUgArUtGEbnptllVkUcwCkRxGSZxTSmd1TFfh+JRKUqIFEaZ/AJaNv1JJCecgnhc+Tx3ZkMVk0HDS/TAYrPkA== + dependencies: + "@babel/traverse" "^7.25.3" + "@react-native/codegen" "0.79.0-nightly-20250123-d1028885e" + "@react-native/babel-plugin-codegen@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.0-nightly-20250303-cee63397b.tgz#e00dce8bdd920c6fc159746a45073f5230a82157" @@ -2157,6 +2170,57 @@ "@babel/traverse" "^7.25.3" "@react-native/codegen" "0.79.0-nightly-20250303-cee63397b" +"@react-native/babel-preset@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.0-nightly-20250123-d1028885e.tgz#fd1b3b1ef836b1ae3498b341d7ebeb559b3d6dfc" + integrity sha512-x1cvlM9E3n14r30ROAoIICHpLJlNVeAAVcf9SLp2LC91UwcxtSlu5OfMIuOQBhS0lAq1ORH5BP2ALK7B9e08Ow== + dependencies: + "@babel/core" "^7.25.2" + "@babel/plugin-proposal-export-default-from" "^7.24.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-default-from" "^7.24.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.24.7" + "@babel/plugin-transform-async-generator-functions" "^7.25.4" + "@babel/plugin-transform-async-to-generator" "^7.24.7" + "@babel/plugin-transform-block-scoping" "^7.25.0" + "@babel/plugin-transform-class-properties" "^7.25.4" + "@babel/plugin-transform-classes" "^7.25.4" + "@babel/plugin-transform-computed-properties" "^7.24.7" + "@babel/plugin-transform-destructuring" "^7.24.8" + "@babel/plugin-transform-flow-strip-types" "^7.25.2" + "@babel/plugin-transform-for-of" "^7.24.7" + "@babel/plugin-transform-function-name" "^7.25.1" + "@babel/plugin-transform-literals" "^7.25.2" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" + "@babel/plugin-transform-modules-commonjs" "^7.24.8" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" + "@babel/plugin-transform-numeric-separator" "^7.24.7" + "@babel/plugin-transform-object-rest-spread" "^7.24.7" + "@babel/plugin-transform-optional-catch-binding" "^7.24.7" + "@babel/plugin-transform-optional-chaining" "^7.24.8" + "@babel/plugin-transform-parameters" "^7.24.7" + "@babel/plugin-transform-private-methods" "^7.24.7" + "@babel/plugin-transform-private-property-in-object" "^7.24.7" + "@babel/plugin-transform-react-display-name" "^7.24.7" + "@babel/plugin-transform-react-jsx" "^7.25.2" + "@babel/plugin-transform-react-jsx-self" "^7.24.7" + "@babel/plugin-transform-react-jsx-source" "^7.24.7" + "@babel/plugin-transform-regenerator" "^7.24.7" + "@babel/plugin-transform-runtime" "^7.24.7" + "@babel/plugin-transform-shorthand-properties" "^7.24.7" + "@babel/plugin-transform-spread" "^7.24.7" + "@babel/plugin-transform-sticky-regex" "^7.24.7" + "@babel/plugin-transform-typescript" "^7.25.2" + "@babel/plugin-transform-unicode-regex" "^7.24.7" + "@babel/template" "^7.25.0" + "@react-native/babel-plugin-codegen" "0.79.0-nightly-20250123-d1028885e" + babel-plugin-syntax-hermes-parser "0.25.1" + babel-plugin-transform-flow-enums "^0.0.2" + react-refresh "^0.14.0" + "@react-native/babel-preset@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.0-nightly-20250303-cee63397b.tgz#cbe7d5d192f6f0e77488fa7a70b9860dd5a86966" @@ -2208,6 +2272,19 @@ babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" +"@react-native/codegen@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.79.0-nightly-20250123-d1028885e.tgz#48b966e2aec0ed1d12fd40166c780457e82eb9b5" + integrity sha512-ttKR4I3qOZApmiGmOWyF7EkQzP5JCOQAO3y99LCBS/hMNZMMBxe2dV9BO8MdKBPSunYn50P53BgLkOHRYIi7Vg== + dependencies: + "@babel/parser" "^7.25.3" + glob "^7.1.1" + hermes-parser "0.25.1" + invariant "^2.2.4" + jscodeshift "^17.0.0" + nullthrows "^1.1.1" + yargs "^17.6.2" + "@react-native/codegen@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.79.0-nightly-20250303-cee63397b.tgz#14e2ef8ca15c7d917a650583b234748e3ab5f38d" @@ -2221,6 +2298,22 @@ nullthrows "^1.1.1" yargs "^17.6.2" +"@react-native/community-cli-plugin@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.0-nightly-20250123-d1028885e.tgz#7cfadc81c68f5ac4006fb3a02b388452ce68df36" + integrity sha512-vJB9IwXrmI/jMIQttw/kvMpPLasp0kS1TUUK+4gVmXz6qgf4CcX4ABtys9fGVpLRc20yalPWB4jpcN8OcrtbyQ== + dependencies: + "@react-native/dev-middleware" "0.79.0-nightly-20250123-d1028885e" + "@react-native/metro-babel-transformer" "0.79.0-nightly-20250123-d1028885e" + chalk "^4.0.0" + debug "^2.2.0" + invariant "^2.2.4" + metro "^0.81.0" + metro-config "^0.81.0" + metro-core "^0.81.0" + readline "^1.3.0" + semver "^7.1.3" + "@react-native/community-cli-plugin@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.0-nightly-20250303-cee63397b.tgz#74bb4ad8f4c0dfc85fd1a4aafc0637055ca7a37f" @@ -2235,11 +2328,33 @@ metro-core "^0.81.0" semver "^7.1.3" +"@react-native/debugger-frontend@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.79.0-nightly-20250123-d1028885e.tgz#1e6e1fd661d3ae5db8711f54ab985d26acaddcfe" + integrity sha512-TqzdEZMCGd6fV1pXfFj6RlpRWGmkOq1ZhillAuHxpjCaIc5AtKMYQnS5fwd3B0bicmbf0T2f35Vqxrxp4Jbh6Q== + "@react-native/debugger-frontend@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.79.0-nightly-20250303-cee63397b.tgz#11946f4790cdfff351e1aed3dc956006f0881fb2" integrity sha512-hHFJpRuCoVGzvlJxBdZFl6SKdG1GCwQY+hlxyWs60+DW9hwDmWE+rz9WBU9+6zw5pnmKTEpd/zZWz3MrTWWkUA== +"@react-native/dev-middleware@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.79.0-nightly-20250123-d1028885e.tgz#9c2cd8da7586cfa9baa5574eec6ab7e2643a102a" + integrity sha512-UWBdJaKIgaxiKNRmVCVfkxvNS5hPQY/BUyrUmJ0LrmEwJoFRkMk6rkHT/sYPRCVANHJAmrHbc+L2go5k40TKKQ== + dependencies: + "@isaacs/ttlcache" "^1.4.1" + "@react-native/debugger-frontend" "0.79.0-nightly-20250123-d1028885e" + chrome-launcher "^0.15.2" + chromium-edge-launcher "^0.2.0" + connect "^3.6.5" + debug "^2.2.0" + nullthrows "^1.1.1" + open "^7.0.3" + selfsigned "^2.4.1" + serve-static "^1.16.2" + ws "^6.2.3" + "@react-native/dev-middleware@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.79.0-nightly-20250303-cee63397b.tgz#7fd19b43d316184c3d28955cf55cdc99242c220f" @@ -2280,16 +2395,36 @@ resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.79.0-nightly-20250123-d1028885e.tgz#7983608a83b724ab2f31d2e84e67fb5f9a7ad3b1" integrity sha512-vYrjxRh3wvL9MmmmsO52keyONK8O7CqayB1gvgSf/EeptcnnCpd0YdJ06NU54aB3zh6p+k4vkxHliNFqpBTFBg== +"@react-native/gradle-plugin@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.79.0-nightly-20250123-d1028885e.tgz#290df4b33dd0ea25c1c36c824a018d0f8c9b3367" + integrity sha512-ZKQYCjYAHWhaawiirLvQpOyAiYVwTa6eZlvXZ1Mee32kGPP4TYMw4mgrFmP6SKySEI1/4pPCLK77I7eukOIVow== + "@react-native/gradle-plugin@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.79.0-nightly-20250303-cee63397b.tgz#90b61e57a79007bcce5bf58d64f1b7a724489379" integrity sha512-Fw5RsMDDODT4YUtxt53ytTpgfBPhDD/lehRhYVyO4Ud6bN6oUiS8lBdZWKo/7B3mwDh9OEt0ppeBOYTZwirRZA== +"@react-native/js-polyfills@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.79.0-nightly-20250123-d1028885e.tgz#93f36db2f1fc8a0e2fd692108623bc9a141cd1c9" + integrity sha512-kfsivK3v0SogoURYxUs80Cam+7kPpeQSkOdfWUj8gVdde8dA3XAwb78zn1NLUMCl+6nGwWzZ94/y7OZF7Z0EwA== + "@react-native/js-polyfills@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.79.0-nightly-20250303-cee63397b.tgz#20f5b19d244185686262153d0bc93f327f84c9d7" integrity sha512-uPQt+6fE39CpOksFfQIj+suThswQxxLJUf2aaJHZvvTClbXqVrFhjGoCADZ+XSIqrbIK1MIsYA6kCtMCuGmSgA== +"@react-native/metro-babel-transformer@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.79.0-nightly-20250123-d1028885e.tgz#45d06b98331c86086e9b659dcfc9c2b53e481e27" + integrity sha512-l89671iQtDc+UsbQYpbhC4jguBfVk1+Y9lb1qPTIzb2oRKZB+p4HCsazvrrNZ0GX/iuadUL4YLZnboVEng8kFQ== + dependencies: + "@babel/core" "^7.25.2" + "@react-native/babel-preset" "0.79.0-nightly-20250123-d1028885e" + hermes-parser "0.25.1" + nullthrows "^1.1.1" + "@react-native/metro-babel-transformer@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.79.0-nightly-20250303-cee63397b.tgz#4f345cf45fbf86e71de30ee7fa3e59cc30d7cc6d" @@ -2300,6 +2435,16 @@ hermes-parser "0.25.1" nullthrows "^1.1.1" +"@react-native/metro-config@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/metro-config/-/metro-config-0.79.0-nightly-20250123-d1028885e.tgz#0767c94a9f6b7cc23bf924e9e40863373b025c70" + integrity sha512-8YeySMhvRXWroqB1n49WMBXbqX/m4x910VOa7xmAczyzG90VcUI+vORkUk4ZmY3nufVKkDs0a0Y9wOmu0d3xEQ== + dependencies: + "@react-native/js-polyfills" "0.79.0-nightly-20250123-d1028885e" + "@react-native/metro-babel-transformer" "0.79.0-nightly-20250123-d1028885e" + metro-config "^0.81.0" + metro-runtime "^0.81.0" + "@react-native/metro-config@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/metro-config/-/metro-config-0.79.0-nightly-20250303-cee63397b.tgz#5f709afb51fa2732dac79288a28c0ce35fab3729" @@ -2310,6 +2455,11 @@ metro-config "^0.81.0" metro-runtime "^0.81.0" +"@react-native/normalize-colors@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.79.0-nightly-20250123-d1028885e.tgz#c2f5f3790cea75c4452d7171c503a57cbb329947" + integrity sha512-DUN8UAD+YDL8Jdqi5BIvnnzv5tKNkbc7+Om+l0fKvYkGiOWdw9jAyQPFejNPLBc9sUSG5aBbRcN0qL6kIIkpZw== + "@react-native/normalize-colors@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.79.0-nightly-20250303-cee63397b.tgz#39ab0aae6aa677d9bedbfd63696a20d2e591f622" @@ -2322,6 +2472,14 @@ dependencies: nullthrows "^1.1.1" +"@react-native/virtualized-lists@0.79.0-nightly-20250123-d1028885e": + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.79.0-nightly-20250123-d1028885e.tgz#50e6840c0f9f93547ce94b470efa75bca21cd3a1" + integrity sha512-nhEiOU3tlK5xtaQNgp/Twus2xGgFw6XSsf/29YvUoi2xq6gdG+Xt5vfdu/qq2wrNa50bjSkV9+BjH12kPWDUkg== + dependencies: + invariant "^2.2.4" + nullthrows "^1.1.1" + "@react-native/virtualized-lists@0.79.0-nightly-20250303-cee63397b": version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.79.0-nightly-20250303-cee63397b.tgz#9831d218b32908af6f7284bdd299dcfeb12d61ac" @@ -2330,6 +2488,32 @@ invariant "^2.2.4" nullthrows "^1.1.1" +"@rnw-scripts/eslint-config@1.2.34": + version "1.2.34" + resolved "https://registry.yarnpkg.com/@rnw-scripts/eslint-config/-/eslint-config-1.2.34.tgz#c76ddf984e55fd1a2609bfbe6dece5ea017d8336" + integrity sha512-G4WoBojT6EX/mca0cWLXSWVU/gXSVm/3/NlLlMCSFJ/O6EklVv/wFtzepHL45XWYiHiG/ng+wSy9VVgjONfsmw== + dependencies: + "@babel/core" "^7.25.2" + "@babel/eslint-parser" "^7.25.1" + "@microsoft/eslint-plugin-sdl" "^0.2.0" + "@react-native/eslint-config" "0.79.0-nightly-20250123-d1028885e" + eslint-config-prettier "^8.5.0" + eslint-plugin-ft-flow "^2.0.1" + hermes-eslint "0.23.1" + +"@rnw-scripts/just-task@2.3.51": + version "2.3.51" + resolved "https://registry.yarnpkg.com/@rnw-scripts/just-task/-/just-task-2.3.51.tgz#675a169f08042559c5b1758e159153ff3d9b0904" + integrity sha512-xV+tJZkL+1L7HdcTAD20VNPjpuDArdEc/xIchp9em0UxV7MyDfwgOwxVb7Uh+ZKhyz/86+nTQo0NtuiQvHAt5w== + dependencies: + "@octokit/rest" "^18.5.3" + "@rnw-scripts/jest-e2e-config" "1.4.11" + "@rnw-scripts/jest-unittest-config" "1.5.11" + depcheck "^1.4.1" + find-up "^4.1.0" + glob "^7.1.6" + just-scripts "^1.3.3" + "@rnx-kit/align-deps@^2.5.0": version "2.5.5" resolved "https://registry.yarnpkg.com/@rnx-kit/align-deps/-/align-deps-2.5.5.tgz#708b4fd65941699e1ef33c728d34bc568e648b73" @@ -2771,6 +2955,13 @@ "@types/node" "*" form-data "^4.0.0" +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + "@types/node@*": version "22.9.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.0.tgz#b7f16e5c3384788542c72dc3d561a7ceae2c0365" @@ -7591,7 +7782,7 @@ jest-each@^29.7.0: jest-util "^29.7.0" pretty-format "^29.7.0" -jest-environment-node@^29.7.0: +jest-environment-node@^29.6.3, jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== @@ -9133,6 +9324,11 @@ node-fetch@^2.2.0, node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -9995,7 +10191,7 @@ react-clone-referenced-element@^1.0.1: resolved "https://registry.yarnpkg.com/react-clone-referenced-element/-/react-clone-referenced-element-1.1.1.tgz#8d76727dc0459788e461741e804a512d20757381" integrity sha512-LZBPvQV8W0B5dFzXFu+D3Tpil8YHS8tO00iFsfXcTLdtpuH7XyvaHqHcoz4hd4uNPQCZ30fceh+s7mLznzMXvg== -react-devtools-core@^6.1.1: +react-devtools-core@^6.0.1, react-devtools-core@^6.1.1: version "6.1.2" resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-6.1.2.tgz#bf4030c4012be8a9201dc1f8a36238c9a5078c98" integrity sha512-ldFwzufLletzCikNJVYaxlxMLu7swJ3T2VrGfzXlMsVhZhPDKXA38DEROidaYZVgMAmQnIjymrmqto5pyfrwPA== @@ -10030,6 +10226,48 @@ react-native-xaml@^0.0.78: dependencies: "@types/react" "*" +react-native@0.79.0-nightly-20250123-d1028885e: + version "0.79.0-nightly-20250123-d1028885e" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.79.0-nightly-20250123-d1028885e.tgz#22848dd2b2afb9fd90cae8916fd07fb47b4e06ff" + integrity sha512-4uVCYZvHWimD0kX8tskSoMOsahfn9o4WhMMjKWyw0V02OxJ8pWhhgZucy+itHc0YWC/tNb9g2aX3EXTpnuqAVA== + dependencies: + "@jest/create-cache-key-function" "^29.6.3" + "@react-native/assets-registry" "0.79.0-nightly-20250123-d1028885e" + "@react-native/codegen" "0.79.0-nightly-20250123-d1028885e" + "@react-native/community-cli-plugin" "0.79.0-nightly-20250123-d1028885e" + "@react-native/gradle-plugin" "0.79.0-nightly-20250123-d1028885e" + "@react-native/js-polyfills" "0.79.0-nightly-20250123-d1028885e" + "@react-native/normalize-colors" "0.79.0-nightly-20250123-d1028885e" + "@react-native/virtualized-lists" "0.79.0-nightly-20250123-d1028885e" + abort-controller "^3.0.0" + anser "^1.4.9" + ansi-regex "^5.0.0" + babel-jest "^29.7.0" + babel-plugin-syntax-hermes-parser "0.25.1" + base64-js "^1.5.1" + chalk "^4.0.0" + commander "^12.0.0" + event-target-shim "^5.0.1" + flow-enums-runtime "^0.0.6" + glob "^7.1.1" + invariant "^2.2.4" + jest-environment-node "^29.6.3" + memoize-one "^5.0.0" + metro-runtime "^0.81.0" + metro-source-map "^0.81.0" + nullthrows "^1.1.1" + pretty-format "^29.7.0" + promise "^8.3.0" + react-devtools-core "^6.0.1" + react-refresh "^0.14.0" + regenerator-runtime "^0.13.2" + scheduler "0.25.0" + semver "^7.1.3" + stacktrace-parser "^0.1.10" + whatwg-fetch "^3.0.0" + ws "^6.2.3" + yargs "^17.6.2" + react-native@0.79.0-nightly-20250303-cee63397b: version "0.79.0-nightly-20250303-cee63397b" resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.79.0-nightly-20250303-cee63397b.tgz#7ca4ee8e894ca3fa3f6d733cdf1bf35346b0c66f" @@ -10566,6 +10804,14 @@ screenshot-desktop@^1.12.2: dependencies: temp "^0.9.4" +selfsigned@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"