react-native-windows 0.74.4 → 0.74.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/Libraries/Components/TextInput/TextInput.windows.js +6 -2
  2. package/Libraries/Components/View/View.windows.js +3 -0
  3. package/Microsoft.ReactNative/ComponentView.idl +26 -0
  4. package/Microsoft.ReactNative/CompositionComponentView.idl +19 -7
  5. package/Microsoft.ReactNative/CompositionRootView.idl +1 -0
  6. package/Microsoft.ReactNative/CompositionUIService.idl +4 -0
  7. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +2 -1
  8. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +106 -19
  9. package/Microsoft.ReactNative/Fabric/AbiViewProps.h +45 -13
  10. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +83 -12
  11. package/Microsoft.ReactNative/Fabric/ComponentView.h +33 -2
  12. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +28 -64
  13. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +7 -11
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +30 -11
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +4 -0
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp +4 -0
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +12 -0
  18. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.h +4 -0
  19. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService_emptyimpl.cpp +6 -0
  20. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +60 -39
  21. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +19 -6
  22. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -0
  23. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +152 -0
  24. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +85 -0
  25. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +49 -95
  26. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +11 -15
  27. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +16 -31
  28. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +5 -8
  29. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +24 -81
  30. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +4 -13
  31. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +41 -40
  32. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -1
  33. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +53 -68
  34. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +5 -7
  35. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +38 -84
  36. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +6 -10
  37. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +59 -109
  38. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +9 -15
  39. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -0
  40. package/Microsoft.ReactNative/FocusManager.idl +22 -0
  41. package/Microsoft.ReactNative/ViewProps.idl +37 -3
  42. package/Microsoft.ReactNative.Cxx/JSValueComposition.h +4 -0
  43. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  44. package/Shared/Shared.vcxitems +6 -0
  45. package/package.json +1 -1
@@ -1346,9 +1346,13 @@ function InternalTextInput(props: Props): React.Node {
1346
1346
  );
1347
1347
  }
1348
1348
  },
1349
- // TODO: Fix this returning true on null === null, when no input is focused
1350
1349
  isFocused(): boolean {
1351
- return TextInputState.currentlyFocusedInput() === inputRef.current;
1350
+ const currentlyFocusedInput =
1351
+ TextInputState.currentlyFocusedInput();
1352
+ return (
1353
+ currentlyFocusedInput !== null &&
1354
+ currentlyFocusedInput === inputRef.current
1355
+ );
1352
1356
  },
1353
1357
  getNativeRef(): ?React.ElementRef<HostComponent<mixed>> {
1354
1358
  return inputRef.current;
@@ -175,6 +175,9 @@ const View: React.AbstractComponent<
175
175
  // [Windows
176
176
  // $FlowFixMe - children typing
177
177
  const childrenWithImportantForAccessibility = children => {
178
+ if (children == null) {
179
+ return children;
180
+ }
178
181
  const updatedChildren = React.Children.map(children, child => {
179
182
  if (React.isValidElement(child)) {
180
183
  // $FlowFixMe[incompatible-use]
@@ -67,6 +67,26 @@ namespace Microsoft.ReactNative
67
67
  IReactContext ReactContext { get;};
68
68
  };
69
69
 
70
+ [experimental]
71
+ [webhosthidden]
72
+ runtimeclass LosingFocusEventArgs : Microsoft.ReactNative.Composition.Input.RoutedEventArgs {
73
+ Microsoft.ReactNative.ComponentView NewFocusedComponent { get; };
74
+ Microsoft.ReactNative.ComponentView OldFocusedComponent { get; };
75
+
76
+ void TryCancel();
77
+ void TrySetNewFocusedComponent(Microsoft.ReactNative.ComponentView component);
78
+ };
79
+
80
+ [experimental]
81
+ [webhosthidden]
82
+ runtimeclass GettingFocusEventArgs : Microsoft.ReactNative.Composition.Input.RoutedEventArgs {
83
+ Microsoft.ReactNative.ComponentView NewFocusedComponent { get; };
84
+ Microsoft.ReactNative.ComponentView OldFocusedComponent { get; };
85
+
86
+ void TryCancel();
87
+ void TrySetNewFocusedComponent(Microsoft.ReactNative.ComponentView component);
88
+ };
89
+
70
90
  [experimental]
71
91
  [webhosthidden]
72
92
  unsealed runtimeclass ComponentView {
@@ -101,6 +121,12 @@ namespace Microsoft.ReactNative
101
121
  overridable void OnPointerExited(Microsoft.ReactNative.Composition.Input.PointerRoutedEventArgs args);
102
122
  overridable void OnPointerCaptureLost();
103
123
 
124
+ Boolean TryFocus();
125
+
126
+ event Windows.Foundation.EventHandler<LosingFocusEventArgs> LosingFocus;
127
+ event Windows.Foundation.EventHandler<GettingFocusEventArgs> GettingFocus;
128
+ event Windows.Foundation.EventHandler<Microsoft.ReactNative.Composition.Input.RoutedEventArgs> LostFocus;
129
+ event Windows.Foundation.EventHandler<Microsoft.ReactNative.Composition.Input.RoutedEventArgs> GotFocus;
104
130
  };
105
131
 
106
132
  } // namespace Microsoft.ReactNative
@@ -26,6 +26,15 @@ namespace Microsoft.ReactNative.Composition
26
26
  Default = 0x00000007, // ShadowProps | NativeBorder | Background
27
27
  };
28
28
 
29
+ namespace Experimental {
30
+ [webhosthidden]
31
+ [experimental]
32
+ interface IInternalCreateComponentViewArgs
33
+ {
34
+ ICompositionContext CompositionContext { get; };
35
+ }
36
+ }
37
+
29
38
  [experimental]
30
39
  [webhosthidden]
31
40
  runtimeclass CreateCompositionComponentViewArgs : Microsoft.ReactNative.CreateComponentViewArgs {
@@ -39,6 +48,7 @@ namespace Microsoft.ReactNative.Composition
39
48
  ComponentView(CreateCompositionComponentViewArgs args);
40
49
 
41
50
  Microsoft.UI.Composition.Compositor Compositor { get; };
51
+ RootComponentView Root { get; };
42
52
  Theme Theme;
43
53
  overridable void OnThemeChanged();
44
54
  Boolean CapturePointer(Microsoft.ReactNative.Composition.Input.Pointer pointer);
@@ -72,13 +82,14 @@ namespace Microsoft.ReactNative.Composition
72
82
  [experimental]
73
83
  [webhosthidden]
74
84
  [default_interface]
75
- unsealed runtimeclass SwitchComponentView : ComponentView {
85
+ unsealed runtimeclass SwitchComponentView : ViewComponentView {
76
86
  };
77
87
 
78
88
  [experimental]
79
89
  [webhosthidden]
80
90
  [default_interface]
81
91
  unsealed runtimeclass RootComponentView : ViewComponentView {
92
+ Microsoft.ReactNative.ComponentView GetFocusedComponent();
82
93
  };
83
94
 
84
95
  [experimental]
@@ -90,31 +101,32 @@ namespace Microsoft.ReactNative.Composition
90
101
  [experimental]
91
102
  [webhosthidden]
92
103
  [default_interface]
93
- unsealed runtimeclass ActivityIndicatorComponentView : ComponentView {
104
+ unsealed runtimeclass ActivityIndicatorComponentView : ViewComponentView {
94
105
  };
95
106
 
96
107
  [experimental]
97
108
  [webhosthidden]
98
109
  [default_interface]
99
- unsealed runtimeclass WindowsModalHostComponentView : ComponentView {
110
+ unsealed runtimeclass WindowsModalHostComponentView : ViewComponentView {
100
111
  };
101
112
 
102
113
  [experimental]
103
114
  [webhosthidden]
104
115
  [default_interface]
105
- unsealed runtimeclass ImageComponentView : ComponentView {
116
+ unsealed runtimeclass ImageComponentView : ViewComponentView {
117
+ Microsoft.ReactNative.ImageProps ViewProps { get; };
106
118
  };
107
119
 
108
120
  [experimental]
109
121
  [webhosthidden]
110
122
  [default_interface]
111
- unsealed runtimeclass ParagraphComponentView : ComponentView {
123
+ unsealed runtimeclass ParagraphComponentView : ViewComponentView {
112
124
  };
113
125
 
114
126
  [experimental]
115
127
  [webhosthidden]
116
128
  [default_interface]
117
- unsealed runtimeclass ScrollViewComponentView : ComponentView {
129
+ unsealed runtimeclass ScrollViewComponentView : ViewComponentView {
118
130
  };
119
131
 
120
132
  [experimental]
@@ -126,7 +138,7 @@ namespace Microsoft.ReactNative.Composition
126
138
  [experimental]
127
139
  [webhosthidden]
128
140
  [default_interface]
129
- unsealed runtimeclass WindowsTextInputComponentView : ComponentView {
141
+ unsealed runtimeclass WindowsTextInputComponentView : ViewComponentView {
130
142
  };
131
143
 
132
144
  } // namespace Microsoft.ReactNative
@@ -99,6 +99,7 @@ namespace Microsoft.ReactNative
99
99
  Microsoft.ReactNative.Composition.ICustomResourceLoader Resources;
100
100
 
101
101
  Microsoft.ReactNative.Composition.Theme Theme { get; };
102
+ Int64 RootTag { get; };
102
103
 
103
104
  #ifdef USE_WINUI3
104
105
  Microsoft.UI.Content.ContentIsland Island { get; };
@@ -2,6 +2,7 @@
2
2
  // Licensed under the MIT License.
3
3
 
4
4
  import "ReactInstanceSettings.idl";
5
+ import "ComponentView.idl";
5
6
 
6
7
  #include "DocString.h"
7
8
 
@@ -22,5 +23,8 @@ namespace Microsoft.ReactNative.Composition
22
23
  "Gets the Compositor used by this ReactNative instance.")
23
24
  static Microsoft.UI.Composition.Compositor GetCompositor(Microsoft.ReactNative.IReactPropertyBag properties);
24
25
 
26
+ DOC_STRING("Gets the ComponentView from a react tag.")
27
+ static Microsoft.ReactNative.ComponentView ComponentFromReactTag(Microsoft.ReactNative.IReactContext context, Int64 reactTag);
28
+
25
29
  }
26
30
  } // namespace Microsoft.ReactNative.Composition
@@ -99,7 +99,8 @@ facebook::react::Props::Shared AbiViewComponentDescriptor::cloneProps(
99
99
  // auto shadowNodeProps = std::make_shared<ShadowNodeT::Props>(context, rawProps, props);
100
100
  auto shadowNodeProps = std::make_shared<AbiViewProps>(
101
101
  context, props ? static_cast<AbiViewProps const &>(*props) : *ShadowNodeT::defaultSharedProps(), rawProps);
102
- auto viewProps = winrt::make<winrt::Microsoft::ReactNative::implementation::UserViewProps>(shadowNodeProps);
102
+ auto viewProps =
103
+ winrt::make<winrt::Microsoft::ReactNative::implementation::ViewProps>(shadowNodeProps, false /*holdRef*/);
103
104
  auto userProps =
104
105
  winrt::get_self<winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder>(m_builder)
105
106
  ->CreateProps(viewProps);
@@ -7,10 +7,12 @@
7
7
 
8
8
  #include <Fabric/Composition/Theme.h>
9
9
  #include <JSValueReader.h>
10
+ #include <react/renderer/components/image/ImageProps.h>
11
+ #include <winrt/Microsoft.ReactNative.h>
12
+ #include <winrt/Windows.Foundation.h>
10
13
 
11
- #if __has_include("Color.g.cpp")
12
14
  #include "Color.g.cpp"
13
- #endif
15
+ #include "ImageSource.g.cpp"
14
16
 
15
17
  namespace Microsoft::ReactNative {
16
18
 
@@ -21,24 +23,24 @@ AbiViewProps::AbiViewProps(
21
23
  : facebook::react::ViewProps(context, sourceProps, rawProps) {}
22
24
 
23
25
  AbiViewProps::~AbiViewProps() {
24
- if (m_userProps) {
25
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::UserViewProps>(m_userProps)->Disconnect();
26
+ if (m_innerProps) {
27
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ViewProps>(m_innerProps)->Disconnect();
26
28
  }
27
29
  }
28
30
 
29
31
  void AbiViewProps::SetUserProps(
30
- winrt::Microsoft::ReactNative::IComponentProps componentProps,
31
- winrt::Microsoft::ReactNative::ViewProps userProps) noexcept {
32
- m_componentProps = componentProps;
32
+ winrt::Microsoft::ReactNative::IComponentProps userProps,
33
+ winrt::Microsoft::ReactNative::ViewProps innerProps) noexcept {
33
34
  m_userProps = userProps;
35
+ m_innerProps = innerProps;
34
36
  }
35
37
 
36
38
  winrt::Microsoft::ReactNative::IComponentProps AbiViewProps::UserProps() const noexcept {
37
- return m_componentProps;
39
+ return m_userProps;
38
40
  }
39
41
 
40
42
  winrt::Microsoft::ReactNative::ViewProps AbiViewProps::ViewProps() const noexcept {
41
- return m_userProps;
43
+ return m_innerProps;
42
44
  }
43
45
 
44
46
  } // namespace Microsoft::ReactNative
@@ -124,29 +126,114 @@ winrt::Microsoft::ReactNative::Color Color::White() noexcept {
124
126
  return winrt::make<Color>(facebook::react::whiteColor());
125
127
  }
126
128
 
127
- UserViewProps::UserViewProps(std::shared_ptr<::Microsoft::ReactNative::AbiViewProps const> viewProps) noexcept
128
- : m_viewProps(viewProps.get()) {}
129
+ ImageSource::ImageSource(const facebook::react::ImageSource &imageSource) : m_imageSource(imageSource) {}
130
+
131
+ ImageSourceType ImageSource::Type() noexcept {
132
+ static_assert(
133
+ winrt::Microsoft::ReactNative::ImageSourceType::Invalid ==
134
+ static_cast<winrt::Microsoft::ReactNative::ImageSourceType>(facebook::react::ImageSource::Type::Invalid));
135
+ static_assert(
136
+ winrt::Microsoft::ReactNative::ImageSourceType::Remote ==
137
+ static_cast<winrt::Microsoft::ReactNative::ImageSourceType>(facebook::react::ImageSource::Type::Remote));
138
+ static_assert(
139
+ winrt::Microsoft::ReactNative::ImageSourceType::Local ==
140
+ static_cast<winrt::Microsoft::ReactNative::ImageSourceType>(facebook::react::ImageSource::Type::Local));
141
+ return static_cast<winrt::Microsoft::ReactNative::ImageSourceType>(m_imageSource.type);
142
+ }
143
+
144
+ winrt::hstring ImageSource::Uri() noexcept {
145
+ return winrt::to_hstring(m_imageSource.uri);
146
+ }
129
147
 
130
- void UserViewProps::Disconnect() noexcept {
148
+ winrt::hstring ImageSource::Bundle() noexcept {
149
+ return winrt::to_hstring(m_imageSource.bundle);
150
+ }
151
+
152
+ float ImageSource::Scale() noexcept {
153
+ return m_imageSource.scale;
154
+ }
155
+
156
+ winrt::Windows::Foundation::Size ImageSource::Size() noexcept {
157
+ return {m_imageSource.size.width, m_imageSource.size.height};
158
+ }
159
+
160
+ winrt::Microsoft::ReactNative::ImageSource ImageSource::ReadValue(
161
+ const winrt::Microsoft::ReactNative::IJSValueReader &reader) noexcept {
162
+ facebook::react::ImageSource imageSource;
163
+ switch (reader.ValueType()) {
164
+ case JSValueType::String: {
165
+ imageSource.type = facebook::react::ImageSource::Type::Remote;
166
+ imageSource.uri = winrt::to_string(reader.GetString());
167
+ break;
168
+ }
169
+ case JSValueType::Object: {
170
+ imageSource.type = facebook::react::ImageSource::Type::Remote;
171
+
172
+ winrt::hstring propertyName;
173
+ while (reader.GetNextObjectProperty(/*out*/ propertyName)) {
174
+ if (propertyName == L"__packager_asset") {
175
+ imageSource.type = facebook::react::ImageSource::Type::Local;
176
+ } else if (propertyName == L"width") {
177
+ imageSource.size.width = static_cast<float>(reader.GetDouble());
178
+ } else if (propertyName == L"height") {
179
+ imageSource.size.height = static_cast<float>(reader.GetDouble());
180
+ } else if (propertyName == L"scale") {
181
+ imageSource.scale = static_cast<float>(reader.GetDouble());
182
+ } else if (propertyName == L"uri") {
183
+ imageSource.uri = winrt::to_string(reader.GetString());
184
+ } else if (propertyName == L"url") {
185
+ imageSource.uri = winrt::to_string(reader.GetString());
186
+ } else if (propertyName == L"bundle") {
187
+ imageSource.bundle = winrt::to_string(reader.GetString());
188
+ imageSource.type = facebook::react::ImageSource::Type::Local;
189
+ }
190
+ }
191
+ break;
192
+ }
193
+ default: {
194
+ imageSource.type = facebook::react::ImageSource::Type::Invalid;
195
+ break;
196
+ }
197
+ }
198
+ return winrt::make<ImageSource>(imageSource);
199
+ }
200
+
201
+ ViewProps::ViewProps(facebook::react::SharedViewProps props, bool holdRef) noexcept
202
+ : m_props(holdRef ? props : nullptr), m_viewProps(static_cast<const facebook::react::ViewProps *>(props.get())) {}
203
+
204
+ void ViewProps::Disconnect() noexcept {
131
205
  m_viewProps = nullptr;
132
206
  }
133
207
 
134
- float UserViewProps::Opacity() noexcept {
208
+ float ViewProps::Opacity() noexcept {
135
209
  return m_viewProps ? m_viewProps->opacity : 1.0f;
136
210
  }
137
211
 
138
- winrt::Microsoft::ReactNative::Color UserViewProps::BackgroundColor() noexcept {
212
+ winrt::Microsoft::ReactNative::Color ViewProps::BackgroundColor() noexcept {
139
213
  return winrt::make<Color>(m_viewProps ? m_viewProps->backgroundColor : facebook::react::clearColor());
140
214
  }
141
215
 
142
- ViewProps::ViewProps(facebook::react::SharedViewProps props) noexcept : m_props(props) {}
216
+ winrt::hstring ViewProps::TestId() noexcept {
217
+ return m_viewProps ? winrt::to_hstring(m_viewProps->testId) : winrt::hstring{};
218
+ }
143
219
 
144
- float ViewProps::Opacity() noexcept {
145
- return m_props->opacity;
220
+ winrt::hstring ViewProps::AccessibilityLabel() noexcept {
221
+ return m_viewProps ? winrt::to_hstring(m_viewProps->accessibilityLabel) : winrt::hstring{};
146
222
  }
147
223
 
148
- winrt::Microsoft::ReactNative::Color ViewProps::BackgroundColor() noexcept {
149
- return winrt::make<Color>(m_props->backgroundColor);
224
+ ImageProps::ImageProps(facebook::react::SharedViewProps props) noexcept : Super(props) {}
225
+
226
+ winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::ReactNative::ImageSource>
227
+ ImageProps::Sources() noexcept {
228
+ winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::ImageSource> sources{
229
+ winrt::single_threaded_vector<winrt::Microsoft::ReactNative::ImageSource>()};
230
+ const auto imageProps = std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
231
+
232
+ for (const auto &source : imageProps->sources) {
233
+ sources.Append(winrt::make<ImageSource>(source));
234
+ }
235
+
236
+ return sources.GetView();
150
237
  }
151
238
 
152
239
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -4,9 +4,12 @@
4
4
  #pragma once
5
5
 
6
6
  #include "Color.g.h"
7
+ #include "ImageProps.g.h"
8
+ #include "ImageSource.g.h"
7
9
  #include "ViewProps.g.h"
8
10
 
9
11
  #include <react/renderer/components/view/ViewProps.h>
12
+ #include <react/renderer/imagemanager/primitives.h>
10
13
  #include "winrt/Microsoft.ReactNative.Composition.Experimental.h"
11
14
  #include "winrt/Microsoft.ReactNative.h"
12
15
 
@@ -22,14 +25,14 @@ class AbiViewProps final : public facebook::react::ViewProps {
22
25
  ~AbiViewProps();
23
26
 
24
27
  void SetUserProps(
25
- winrt::Microsoft::ReactNative::IComponentProps componentProps,
26
- winrt::Microsoft::ReactNative::ViewProps userProps) noexcept;
28
+ winrt::Microsoft::ReactNative::IComponentProps userProps,
29
+ winrt::Microsoft::ReactNative::ViewProps innerProps) noexcept;
27
30
  winrt::Microsoft::ReactNative::IComponentProps UserProps() const noexcept;
28
31
  winrt::Microsoft::ReactNative::ViewProps ViewProps() const noexcept;
29
32
 
30
33
  private:
31
- winrt::Microsoft::ReactNative::IComponentProps m_componentProps{nullptr};
32
- winrt::Microsoft::ReactNative::ViewProps m_userProps{nullptr};
34
+ winrt::Microsoft::ReactNative::IComponentProps m_userProps{nullptr};
35
+ winrt::Microsoft::ReactNative::ViewProps m_innerProps{nullptr};
33
36
  };
34
37
 
35
38
  } // namespace Microsoft::ReactNative
@@ -60,27 +63,55 @@ struct Color : ColorT<Color, Composition::Experimental::IInternalColor> {
60
63
  facebook::react::SharedColor m_color;
61
64
  };
62
65
 
63
- struct UserViewProps : ViewPropsT<UserViewProps> {
64
- UserViewProps(std::shared_ptr<::Microsoft::ReactNative::AbiViewProps const> viewProps) noexcept;
66
+ struct ImageSource : ImageSourceT<ImageSource> {
67
+ ImageSource(const facebook::react::ImageSource &imageSource);
65
68
 
66
- float Opacity() noexcept;
67
- winrt::Microsoft::ReactNative::Color BackgroundColor() noexcept;
69
+ ImageSourceType Type() noexcept;
70
+ winrt::hstring Uri() noexcept;
71
+ winrt::hstring Bundle() noexcept;
72
+ float Scale() noexcept;
73
+ winrt::Windows::Foundation::Size Size() noexcept;
68
74
 
69
- void Disconnect() noexcept;
75
+ static winrt::Microsoft::ReactNative::ImageSource ReadValue(
76
+ const winrt::Microsoft::ReactNative::IJSValueReader &reader) noexcept;
77
+
78
+ static void WriteValue(
79
+ const winrt::Microsoft::ReactNative::IJSValueWriter &writer,
80
+ const winrt::Microsoft::ReactNative::ImageSource &value) noexcept;
70
81
 
71
82
  private:
72
- // Use a raw pointer here to avoid a ref cycle with AbiViewProps. ~AbiViewProps will clear this pointer
73
- ::Microsoft::ReactNative::AbiViewProps const *m_viewProps{nullptr};
83
+ const facebook::react::ImageSource m_imageSource;
74
84
  };
75
85
 
86
+ /**
87
+ * When providing a external ViewProps object on a normal ComponentView, ViewProps will hold a reference to the internal
88
+ * facebook::react::ViewProps object since the ComponentView could release the object at any time. However, when
89
+ * providing a ViewProps object on a custom ComponentView that has a custom app provided props, the AbiViewProps object
90
+ * will already be holding a reference to this object, so we only hold onto a weak reference.
91
+ */
76
92
  struct ViewProps : ViewPropsT<ViewProps> {
77
- ViewProps(facebook::react::SharedViewProps props) noexcept;
93
+ ViewProps(facebook::react::SharedViewProps props, bool holdRef = true) noexcept;
94
+
95
+ // Notification when the owning AbiViewProps is going away.
96
+ void Disconnect() noexcept;
78
97
 
79
98
  float Opacity() noexcept;
80
99
  winrt::Microsoft::ReactNative::Color BackgroundColor() noexcept;
100
+ winrt::hstring TestId() noexcept;
101
+ winrt::hstring AccessibilityLabel() noexcept;
81
102
 
82
- private:
103
+ protected:
83
104
  facebook::react::SharedViewProps m_props;
105
+
106
+ // Use a raw pointer here to avoid a ref cycle with AbiViewProps. ~AbiViewProps will clear this pointer
107
+ facebook::react::ViewProps const *m_viewProps{nullptr};
108
+ };
109
+
110
+ struct ImageProps : ImagePropsT<ImageProps, ViewProps> {
111
+ using Super = ImagePropsT<ImageProps, ViewProps>;
112
+ ImageProps(facebook::react::SharedViewProps props) noexcept;
113
+
114
+ winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::ReactNative::ImageSource> Sources() noexcept;
84
115
  };
85
116
 
86
117
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -88,5 +119,6 @@ struct ViewProps : ViewPropsT<ViewProps> {
88
119
  namespace winrt::Microsoft::ReactNative::factory_implementation {
89
120
 
90
121
  struct Color : ColorT<Color, implementation::Color> {};
122
+ struct ImageSource : ImageSourceT<ImageSource, implementation::ImageSource> {};
91
123
 
92
124
  } // namespace winrt::Microsoft::ReactNative::factory_implementation
@@ -143,19 +143,16 @@ ComponentView::rootComponentView() noexcept {
143
143
  }
144
144
 
145
145
  void ComponentView::parent(const winrt::Microsoft::ReactNative::ComponentView &parent) noexcept {
146
- if (!parent) {
147
- auto root = rootComponentView();
148
- winrt::Microsoft::ReactNative::ComponentView view{nullptr};
149
- winrt::check_hresult(
150
- QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
151
- if (root && root->GetFocusedComponent() == view) {
152
- root->SetFocusedComponent(nullptr); // TODO need move focus logic - where should focus go?
153
- }
154
- }
155
-
156
146
  if (m_parent != parent) {
147
+ auto oldRootView = rootComponentView();
157
148
  m_rootView = nullptr;
149
+ auto oldParent = m_parent;
158
150
  m_parent = parent;
151
+ if (!parent) {
152
+ if (oldRootView && oldRootView->GetFocusedComponent() == *this) {
153
+ oldRootView->TrySetFocusedComponent(oldParent);
154
+ }
155
+ }
159
156
  if (parent) {
160
157
  theme(winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(parent)->theme());
161
158
  }
@@ -220,9 +217,83 @@ facebook::react::Point ComponentView::getClientOffset() const noexcept {
220
217
  return {};
221
218
  }
222
219
 
223
- void ComponentView::onFocusLost() noexcept {}
220
+ void ComponentView::onLostFocus(
221
+ const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
222
+ m_lostFocusEvent(*this, args);
223
+ if (m_parent) {
224
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onLostFocus(args);
225
+ }
226
+ }
227
+
228
+ void ComponentView::onGotFocus(
229
+ const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
230
+ m_gotFocusEvent(*this, args);
231
+ if (m_parent) {
232
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onGotFocus(args);
233
+ }
234
+ }
235
+
236
+ void ComponentView::onLosingFocus(const winrt::Microsoft::ReactNative::LosingFocusEventArgs &args) noexcept {
237
+ m_losingFocusEvent(*this, args);
238
+ if (m_parent) {
239
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onLosingFocus(args);
240
+ }
241
+ }
242
+
243
+ void ComponentView::onGettingFocus(const winrt::Microsoft::ReactNative::GettingFocusEventArgs &args) noexcept {
244
+ m_gettingFocusEvent(*this, args);
245
+ if (m_parent) {
246
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onGettingFocus(args);
247
+ }
248
+ }
224
249
 
225
- void ComponentView::onFocusGained() noexcept {}
250
+ winrt::event_token ComponentView::LosingFocus(
251
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::LosingFocusEventArgs> const
252
+ &handler) noexcept {
253
+ return m_losingFocusEvent.add(handler);
254
+ }
255
+
256
+ void ComponentView::LosingFocus(winrt::event_token const &token) noexcept {
257
+ m_losingFocusEvent.remove(token);
258
+ }
259
+
260
+ winrt::event_token ComponentView::GettingFocus(
261
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::GettingFocusEventArgs> const
262
+ &handler) noexcept {
263
+ return m_gettingFocusEvent.add(handler);
264
+ }
265
+
266
+ void ComponentView::GettingFocus(winrt::event_token const &token) noexcept {
267
+ m_gettingFocusEvent.remove(token);
268
+ }
269
+
270
+ winrt::event_token ComponentView::LostFocus(
271
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
272
+ &handler) noexcept {
273
+ return m_lostFocusEvent.add(handler);
274
+ }
275
+
276
+ void ComponentView::LostFocus(winrt::event_token const &token) noexcept {
277
+ m_lostFocusEvent.remove(token);
278
+ }
279
+
280
+ winrt::event_token ComponentView::GotFocus(
281
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
282
+ &handler) noexcept {
283
+ return m_gotFocusEvent.add(handler);
284
+ }
285
+
286
+ void ComponentView::GotFocus(winrt::event_token const &token) noexcept {
287
+ m_gotFocusEvent.remove(token);
288
+ }
289
+
290
+ bool ComponentView::TryFocus() noexcept {
291
+ if (auto root = rootComponentView()) {
292
+ return root->TrySetFocusedComponent(*get_strong());
293
+ }
294
+
295
+ return false;
296
+ }
226
297
 
227
298
  void ComponentView::OnPointerEntered(
228
299
  const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept {}
@@ -87,8 +87,29 @@ struct ComponentView : public ComponentViewT<ComponentView> {
87
87
  virtual RECT getClientRect() const noexcept;
88
88
  // The offset from this elements parent to its children (accounts for things like scroll position)
89
89
  virtual facebook::react::Point getClientOffset() const noexcept;
90
- virtual void onFocusLost() noexcept;
91
- virtual void onFocusGained() noexcept;
90
+ virtual void onLosingFocus(const winrt::Microsoft::ReactNative::LosingFocusEventArgs &args) noexcept;
91
+ virtual void onGettingFocus(const winrt::Microsoft::ReactNative::GettingFocusEventArgs &args) noexcept;
92
+ virtual void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
93
+ virtual void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
94
+
95
+ winrt::event_token LosingFocus(
96
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::LosingFocusEventArgs> const
97
+ &handler) noexcept;
98
+ void LosingFocus(winrt::event_token const &token) noexcept;
99
+ winrt::event_token GettingFocus(
100
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::GettingFocusEventArgs> const
101
+ &handler) noexcept;
102
+ void GettingFocus(winrt::event_token const &token) noexcept;
103
+ winrt::event_token LostFocus(
104
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
105
+ &handler) noexcept;
106
+ void LostFocus(winrt::event_token const &token) noexcept;
107
+ winrt::event_token GotFocus(
108
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
109
+ &handler) noexcept;
110
+ void GotFocus(winrt::event_token const &token) noexcept;
111
+
112
+ bool TryFocus() noexcept;
92
113
 
93
114
  virtual bool focusable() const noexcept;
94
115
  virtual facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept;
@@ -158,6 +179,16 @@ struct ComponentView : public ComponentViewT<ComponentView> {
158
179
  winrt::Microsoft::ReactNative::ComponentView m_parent{nullptr};
159
180
  winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::ComponentView> m_children{
160
181
  winrt::single_threaded_vector<winrt::Microsoft::ReactNative::ComponentView>()};
182
+ winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::LosingFocusEventArgs>>
183
+ m_losingFocusEvent;
184
+ winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::GettingFocusEventArgs>>
185
+ m_gettingFocusEvent;
186
+ winrt::event<
187
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs>>
188
+ m_lostFocusEvent;
189
+ winrt::event<
190
+ winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs>>
191
+ m_gotFocusEvent;
161
192
  };
162
193
 
163
194
  // Run fn on all nodes of the component view tree starting from this one until fn returns true