react-native-windows 0.74.4 → 0.74.5

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 (37) 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/CompositionComponentView.idl +17 -7
  4. package/Microsoft.ReactNative/CompositionRootView.idl +1 -0
  5. package/Microsoft.ReactNative/CompositionUIService.idl +4 -0
  6. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +2 -1
  7. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +106 -19
  8. package/Microsoft.ReactNative/Fabric/AbiViewProps.h +45 -13
  9. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +28 -64
  10. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +7 -11
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +4 -0
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +2 -0
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp +4 -0
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +12 -0
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.h +4 -0
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService_emptyimpl.cpp +6 -0
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +27 -16
  18. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +13 -4
  19. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -0
  20. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +49 -95
  21. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +11 -15
  22. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +16 -31
  23. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +5 -8
  24. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +24 -81
  25. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +4 -13
  26. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +1 -0
  27. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +53 -68
  28. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +5 -7
  29. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +38 -84
  30. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +6 -10
  31. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +52 -104
  32. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +7 -13
  33. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -0
  34. package/Microsoft.ReactNative/ViewProps.idl +37 -3
  35. package/Microsoft.ReactNative.Cxx/JSValueComposition.h +4 -0
  36. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  37. package/package.json +1 -1
@@ -18,4 +18,10 @@ winrt::Microsoft::UI::Composition::Compositor CompositionUIService::GetComposito
18
18
  return nullptr;
19
19
  }
20
20
 
21
+ winrt::Microsoft::ReactNative::ComponentView CompositionUIService::ComponentFromReactTag(
22
+ const winrt::Microsoft::ReactNative::IReactContext &,
23
+ int64_t) noexcept {
24
+ return nullptr;
25
+ }
26
+
21
27
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -134,7 +134,8 @@ winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext Co
134
134
  void ComponentView::updateProps(
135
135
  facebook::react::Props::Shared const &props,
136
136
  facebook::react::Props::Shared const &oldProps) noexcept {
137
- const auto &oldViewProps = *viewProps();
137
+ const auto &oldViewProps =
138
+ oldProps ? (*std::static_pointer_cast<const facebook::react::ViewProps>(oldProps)) : (*viewProps());
138
139
  const auto &newViewProps = *std::static_pointer_cast<const facebook::react::ViewProps>(props);
139
140
 
140
141
  if ((m_flags & ComponentViewFeatures::Background) == ComponentViewFeatures::Background) {
@@ -1455,6 +1456,7 @@ std::string ComponentView::DefaultHelpText() const noexcept {
1455
1456
  ViewComponentView::ViewComponentView(
1456
1457
  const winrt::Microsoft::ReactNative::Composition::CreateCompositionComponentViewArgs &args)
1457
1458
  : ViewComponentView(
1459
+ ViewComponentView::defaultProps(),
1458
1460
  winrt::get_self<
1459
1461
  winrt::Microsoft::ReactNative::Composition::implementation::CreateCompositionComponentViewArgs>(args)
1460
1462
  ->CompositionContext(),
@@ -1463,16 +1465,20 @@ ViewComponentView::ViewComponentView(
1463
1465
  args.Features(),
1464
1466
  true) {}
1465
1467
 
1468
+ facebook::react::SharedViewProps ViewComponentView::defaultProps() noexcept {
1469
+ static auto const defaultViewProps = std::make_shared<facebook::react::ViewProps const>();
1470
+ return defaultViewProps;
1471
+ }
1472
+
1466
1473
  ViewComponentView::ViewComponentView(
1474
+ const facebook::react::SharedViewProps &defaultProps,
1467
1475
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
1468
1476
  facebook::react::Tag tag,
1469
1477
  winrt::Microsoft::ReactNative::ReactContext const &reactContext,
1470
1478
  ComponentViewFeatures flags,
1471
1479
  bool customComponent)
1472
- : base_type(compContext, tag, reactContext, flags, customComponent) {
1473
- static auto const defaultProps = std::make_shared<facebook::react::ViewProps const>();
1474
- m_props = defaultProps;
1475
- }
1480
+ : base_type(compContext, tag, reactContext, flags, customComponent),
1481
+ m_props(defaultProps ? defaultProps : ViewComponentView::defaultProps()) {}
1476
1482
 
1477
1483
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ViewComponentView::createVisual() noexcept {
1478
1484
  return m_compContext.CreateSpriteVisual();
@@ -1507,7 +1513,8 @@ winrt::Microsoft::ReactNative::ComponentView ViewComponentView::Create(
1507
1513
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
1508
1514
  facebook::react::Tag tag,
1509
1515
  winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept {
1510
- return winrt::make<ViewComponentView>(compContext, tag, reactContext, ComponentViewFeatures::Default, false);
1516
+ return winrt::make<ViewComponentView>(
1517
+ ViewComponentView::defaultProps(), compContext, tag, reactContext, ComponentViewFeatures::Default, false);
1511
1518
  }
1512
1519
 
1513
1520
  void ViewComponentView::MountChildComponentView(
@@ -1521,7 +1528,7 @@ void ViewComponentView::MountChildComponentView(
1521
1528
  // TODO if we get mixed children of composition and non-composition ComponentViews the indexes will get mixed up
1522
1529
  // We could offset the index based on non-composition children in m_children
1523
1530
  if (auto compositionChild = childComponentView.try_as<ComponentView>()) {
1524
- m_visual.InsertAt(compositionChild->OuterVisual(), index);
1531
+ Visual().InsertAt(compositionChild->OuterVisual(), index);
1525
1532
  }
1526
1533
  }
1527
1534
 
@@ -1532,27 +1539,27 @@ void ViewComponentView::UnmountChildComponentView(
1532
1539
 
1533
1540
  indexOffsetForBorder(index);
1534
1541
  if (auto compositionChild = childComponentView.try_as<ComponentView>()) {
1535
- m_visual.Remove(compositionChild->OuterVisual());
1542
+ Visual().Remove(compositionChild->OuterVisual());
1536
1543
  }
1537
1544
  }
1538
1545
 
1539
1546
  void ViewComponentView::updateProps(
1540
1547
  facebook::react::Props::Shared const &props,
1541
1548
  facebook::react::Props::Shared const &oldProps) noexcept {
1542
- const auto &oldViewProps = *std::static_pointer_cast<const facebook::react::ViewProps>(m_props);
1549
+ const auto &oldViewProps = *std::static_pointer_cast<const facebook::react::ViewProps>(oldProps ? oldProps : m_props);
1543
1550
  const auto &newViewProps = *std::static_pointer_cast<const facebook::react::ViewProps>(props);
1544
1551
 
1545
1552
  ensureVisual();
1546
1553
  if (oldViewProps.opacity != newViewProps.opacity) {
1547
- m_visual.Opacity(newViewProps.opacity);
1554
+ Visual().Opacity(newViewProps.opacity);
1548
1555
  }
1549
1556
  if (oldViewProps.testId != newViewProps.testId) {
1550
- m_visual.Comment(winrt::to_hstring(newViewProps.testId));
1557
+ Visual().Comment(winrt::to_hstring(newViewProps.testId));
1551
1558
  }
1552
1559
 
1553
1560
  // update BaseComponentView props
1554
1561
  updateAccessibilityProps(oldViewProps, newViewProps);
1555
- updateTransformProps(oldViewProps, newViewProps, m_visual);
1562
+ updateTransformProps(oldViewProps, newViewProps, Visual());
1556
1563
  base_type::updateProps(props, oldProps);
1557
1564
 
1558
1565
  m_props = std::static_pointer_cast<facebook::react::ViewProps const>(props);
@@ -1571,7 +1578,7 @@ facebook::react::Tag ViewComponentView::hitTest(
1571
1578
  bool ignorePointerEvents) const noexcept {
1572
1579
  facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
1573
1580
 
1574
- facebook::react::Tag targetTag;
1581
+ facebook::react::Tag targetTag = -1;
1575
1582
 
1576
1583
  if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1577
1584
  m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) &&
@@ -1637,7 +1644,7 @@ void ViewComponentView::OnKeyDown(
1637
1644
  (source.GetKeyState(winrt::Windows::System::VirtualKey::RightWindows) !=
1638
1645
  winrt::Windows::UI::Core::CoreVirtualKeyStates::None);
1639
1646
 
1640
- if (args.OriginalSource() == Tag()) {
1647
+ if (args.OriginalSource() == Tag() && !args.Handled()) {
1641
1648
  facebook::react::KeyEvent event;
1642
1649
  event.shiftKey = fShift;
1643
1650
  event.ctrlKey = fCtrl;
@@ -1712,16 +1719,20 @@ void ViewComponentView::updateLayoutMetrics(
1712
1719
  }
1713
1720
 
1714
1721
  void ViewComponentView::UpdateLayoutMetrics(const LayoutMetrics &metrics, const LayoutMetrics &oldMetrics) noexcept {
1715
- m_visual.Size({metrics.Frame.Width * metrics.PointScaleFactor, metrics.Frame.Height * metrics.PointScaleFactor});
1722
+ Visual().Size({metrics.Frame.Width * metrics.PointScaleFactor, metrics.Frame.Height * metrics.PointScaleFactor});
1716
1723
  }
1717
1724
 
1718
1725
  void ViewComponentView::prepareForRecycle() noexcept {}
1719
1726
 
1720
- facebook::react::SharedViewProps ViewComponentView::viewProps() noexcept {
1727
+ const facebook::react::SharedViewProps &ViewComponentView::viewProps() const noexcept {
1721
1728
  return m_props;
1722
1729
  }
1723
1730
 
1724
1731
  winrt::Microsoft::ReactNative::ViewProps ViewComponentView::ViewProps() noexcept {
1732
+ return ViewPropsInner();
1733
+ }
1734
+
1735
+ winrt::Microsoft::ReactNative::ViewProps ViewComponentView::ViewPropsInner() noexcept {
1725
1736
  // If we have AbiViewProps, then we dont need to new up a props wrapper
1726
1737
  if (m_customComponent) {
1727
1738
  const auto &abiViewProps = *std::static_pointer_cast<const ::Microsoft::ReactNative::AbiViewProps>(m_props);
@@ -23,7 +23,8 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
23
23
  struct CreateCompositionComponentViewArgs
24
24
  : public CreateCompositionComponentViewArgsT<
25
25
  CreateCompositionComponentViewArgs,
26
- winrt::Microsoft::ReactNative::implementation::CreateComponentViewArgs> {
26
+ winrt::Microsoft::ReactNative::implementation::CreateComponentViewArgs,
27
+ winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCreateComponentViewArgs> {
27
28
  CreateCompositionComponentViewArgs(
28
29
  const winrt::Microsoft::ReactNative::IReactContext &reactContext,
29
30
  facebook::react::Tag tag,
@@ -63,8 +64,10 @@ struct ComponentView
63
64
  void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
64
65
  override;
65
66
  facebook::react::Props::Shared props() noexcept override;
66
- virtual facebook::react::SharedViewProps viewProps() noexcept {
67
- return nullptr;
67
+ virtual const facebook::react::SharedViewProps &viewProps() const noexcept {
68
+ static facebook::react::SharedViewProps emptyProps;
69
+ assert(false);
70
+ return emptyProps;
68
71
  };
69
72
  void Theme(const winrt::Microsoft::ReactNative::Composition::Theme &theme) noexcept;
70
73
  winrt::Microsoft::ReactNative::Composition::Theme Theme() const noexcept;
@@ -195,7 +198,7 @@ struct ViewComponentView : public ViewComponentViewT<ViewComponentView, Componen
195
198
  const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
196
199
  std::string DefaultControlType() const noexcept override;
197
200
 
198
- facebook::react::SharedViewProps viewProps() noexcept override;
201
+ const facebook::react::SharedViewProps &viewProps() const noexcept override;
199
202
  winrt::Microsoft::ReactNative::ViewProps ViewProps() noexcept;
200
203
 
201
204
  facebook::react::Tag hitTest(
@@ -207,7 +210,10 @@ struct ViewComponentView : public ViewComponentViewT<ViewComponentView, Componen
207
210
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept override;
208
211
  void ensureVisual() noexcept;
209
212
 
213
+ static facebook::react::SharedViewProps defaultProps() noexcept;
214
+
210
215
  ViewComponentView(
216
+ const facebook::react::SharedViewProps &defaultProps,
211
217
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
212
218
  facebook::react::Tag tag,
213
219
  winrt::Microsoft::ReactNative::ReactContext const &reactContext,
@@ -220,6 +226,9 @@ struct ViewComponentView : public ViewComponentViewT<ViewComponentView, Componen
220
226
  virtual winrt::Microsoft::UI::Composition::Visual CreateVisual() noexcept;
221
227
  virtual void UpdateLayoutMetrics(const LayoutMetrics &metrics, const LayoutMetrics &oldMetrics) noexcept;
222
228
 
229
+ protected:
230
+ virtual winrt::Microsoft::ReactNative::ViewProps ViewPropsInner() noexcept;
231
+
223
232
  private:
224
233
  facebook::react::SharedViewProps m_props;
225
234
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_visual{nullptr};
@@ -15,6 +15,7 @@ DebuggingOverlayComponentView::DebuggingOverlayComponentView(
15
15
  facebook::react::Tag tag,
16
16
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
17
17
  : base_type(
18
+ {}, // default ViewProps
18
19
  compContext,
19
20
  tag,
20
21
  reactContext,
@@ -14,6 +14,7 @@
14
14
  #include <react/renderer/components/image/ImageEventEmitter.h>
15
15
 
16
16
  #include <AutoDraw.h>
17
+ #include <Fabric/AbiViewProps.h>
17
18
  #include <Fabric/FabricUIManagerModule.h>
18
19
  #include <Utils/ImageUtils.h>
19
20
  #include <shcore.h>
@@ -48,19 +49,22 @@ void ImageComponentView::WindowsImageResponseObserver::didReceiveFailure() const
48
49
  m_image->didReceiveFailureFromObserver();
49
50
  }
50
51
 
52
+ facebook::react::SharedViewProps ImageComponentView::defaultProps() noexcept {
53
+ static auto const defaultProps = std::make_shared<facebook::react::ImageProps const>();
54
+ return defaultProps;
55
+ }
56
+
51
57
  ImageComponentView::ImageComponentView(
52
58
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
53
59
  facebook::react::Tag tag,
54
60
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
55
61
  : Super(
62
+ ImageComponentView::defaultProps(),
56
63
  compContext,
57
64
  tag,
58
65
  reactContext,
59
66
  ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
60
- false) {
61
- static auto const defaultProps = std::make_shared<facebook::react::ImageProps const>();
62
- m_props = defaultProps;
63
- }
67
+ false) {}
64
68
 
65
69
  void ImageComponentView::MountChildComponentView(
66
70
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
@@ -111,32 +115,24 @@ void ImageComponentView::didReceiveFailureFromObserver() noexcept {
111
115
  }
112
116
  }
113
117
 
118
+ const facebook::react::ImageProps &ImageComponentView::imageProps() const noexcept {
119
+ return *std::static_pointer_cast<const facebook::react::ImageProps>(viewProps());
120
+ }
121
+
114
122
  void ImageComponentView::updateProps(
115
123
  facebook::react::Props::Shared const &props,
116
124
  facebook::react::Props::Shared const &oldProps) noexcept {
117
- const auto &oldImageProps = *std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
125
+ const auto &oldImageProps =
126
+ *std::static_pointer_cast<const facebook::react::ImageProps>(oldProps ? oldProps : viewProps());
118
127
  const auto &newImageProps = *std::static_pointer_cast<const facebook::react::ImageProps>(props);
119
128
 
120
- ensureVisual();
121
-
122
- // update BaseComponentView props
123
- updateTransformProps(oldImageProps, newImageProps, m_visual);
124
- Super::updateProps(props, oldProps);
125
-
126
129
  if (oldImageProps.backgroundColor != newImageProps.backgroundColor ||
127
130
  oldImageProps.blurRadius != newImageProps.blurRadius || oldImageProps.tintColor != newImageProps.tintColor ||
128
131
  oldImageProps.resizeMode != newImageProps.resizeMode) {
129
132
  m_drawingSurface = nullptr; // TODO don't need to recreate the surface just to redraw...
130
133
  }
131
134
 
132
- if (oldImageProps.opacity != newImageProps.opacity) {
133
- m_visual.Opacity(newImageProps.opacity);
134
- }
135
- if (oldImageProps.testId != newImageProps.testId) {
136
- m_visual.Comment(winrt::to_hstring(newImageProps.testId));
137
- }
138
-
139
- m_props = std::static_pointer_cast<facebook::react::ImageProps const>(props);
135
+ Super::updateProps(props, oldProps);
140
136
  }
141
137
 
142
138
  void ImageComponentView::updateState(
@@ -182,19 +178,22 @@ void ImageComponentView::setStateAndResubscribeImageResponseObserver(
182
178
  }
183
179
  }
184
180
 
185
- void ImageComponentView::updateLayoutMetrics(
186
- facebook::react::LayoutMetrics const &layoutMetrics,
187
- facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
188
- // Set Position & Size Properties
181
+ winrt::Microsoft::ReactNative::ImageProps ImageComponentView::ImageProps() noexcept {
182
+ // We do not currently support custom ImageComponentView's
183
+ // If we did we would need to create a AbiImageProps and possibly return them here
184
+ assert(!m_customComponent);
185
+ return winrt::make<winrt::Microsoft::ReactNative::implementation::ImageProps>(viewProps());
186
+ }
189
187
 
190
- if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
191
- OuterVisual().IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
192
- }
188
+ winrt::Microsoft::ReactNative::ImageProps ImageComponentView::ViewProps() noexcept {
189
+ return ViewPropsInner().as<winrt::Microsoft::ReactNative::ImageProps>();
190
+ }
193
191
 
194
- Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
195
- m_visual.Size(
196
- {layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
197
- layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
192
+ winrt::Microsoft::ReactNative::ViewProps ImageComponentView::ViewPropsInner() noexcept {
193
+ // We do not currently support custom ImageComponentView's
194
+ // If we did we would need to create a AbiImageProps and possibly return them here
195
+ assert(!m_customComponent);
196
+ return winrt::make<winrt::Microsoft::ReactNative::implementation::ImageProps>(viewProps());
198
197
  }
199
198
 
200
199
  void ImageComponentView::OnRenderingDeviceLost() noexcept {
@@ -203,7 +202,7 @@ void ImageComponentView::OnRenderingDeviceLost() noexcept {
203
202
  }
204
203
 
205
204
  bool ImageComponentView::themeEffectsImage() const noexcept {
206
- return m_props->backgroundColor || isColorMeaningful(m_props->tintColor);
205
+ return viewProps()->backgroundColor || isColorMeaningful(imageProps().tintColor);
207
206
  }
208
207
 
209
208
  void ImageComponentView::onThemeChanged() noexcept {
@@ -218,7 +217,7 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
218
217
  assert(m_reactContext.UIDispatcher().HasThreadAccess());
219
218
 
220
219
  if (!m_imageResponseImage) {
221
- m_visual.Brush(nullptr);
220
+ Visual().as<Experimental::ISpriteVisual>().Brush(nullptr);
222
221
  return;
223
222
  }
224
223
 
@@ -230,18 +229,18 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
230
229
  if (!m_drawingSurface && m_imageResponseImage->m_wicbmp) {
231
230
  winrt::Windows::Foundation::Size drawingSurfaceSize{static_cast<float>(width), static_cast<float>(height)};
232
231
 
233
- const auto imageProps = std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
232
+ const auto &imgProps = imageProps();
234
233
  const auto frame{m_layoutMetrics.getContentFrame().size};
235
234
 
236
- if (imageProps->resizeMode == facebook::react::ImageResizeMode::Repeat) {
235
+ if (imgProps.resizeMode == facebook::react::ImageResizeMode::Repeat) {
237
236
  drawingSurfaceSize = {
238
237
  frame.width * m_layoutMetrics.pointScaleFactor, frame.height * m_layoutMetrics.pointScaleFactor};
239
- } else if (imageProps->blurRadius > 0) {
238
+ } else if (imgProps.blurRadius > 0) {
240
239
  // https://learn.microsoft.com/en-us/windows/win32/direct2d/gaussian-blur#output-bitmap
241
240
  // The following equation that can be used to compute the output bitmap:
242
241
  // Output bitmap growth (X and Y) = (StandardDeviation(DIPs)*3 + StandardDeviation(DIPs)*3)*((User DPI)/96)
243
242
  // Where StandardDeviation(DIPs)*3 is equivalent to the blur radius.
244
- const auto bmpGrowth{imageProps->blurRadius * 2 * m_layoutMetrics.pointScaleFactor};
243
+ const auto bmpGrowth{imgProps.blurRadius * 2 * m_layoutMetrics.pointScaleFactor};
245
244
  drawingSurfaceSize = {drawingSurfaceSize.Width + bmpGrowth, drawingSurfaceSize.Height + bmpGrowth};
246
245
  }
247
246
 
@@ -252,7 +251,7 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
252
251
 
253
252
  DrawImage();
254
253
 
255
- switch (imageProps->resizeMode) {
254
+ switch (imgProps.resizeMode) {
256
255
  case facebook::react::ImageResizeMode::Stretch:
257
256
  m_drawingSurface.Stretch(winrt::Microsoft::ReactNative::Composition::Experimental::CompositionStretch::Fill);
258
257
  break;
@@ -281,9 +280,10 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
281
280
  assert(false);
282
281
  }
283
282
 
284
- m_visual.Brush(m_drawingSurface);
283
+ Visual().as<Experimental::ISpriteVisual>().Brush(m_drawingSurface);
285
284
  } else if (m_imageResponseImage->m_brushFactory) {
286
- m_visual.Brush(m_imageResponseImage->m_brushFactory(m_reactContext.Handle(), m_compContext));
285
+ Visual().as<Experimental::ISpriteVisual>().Brush(
286
+ m_imageResponseImage->m_brushFactory(m_reactContext.Handle(), m_compContext));
287
287
  }
288
288
  }
289
289
 
@@ -310,15 +310,15 @@ void ImageComponentView::DrawImage() noexcept {
310
310
  d2dDeviceContext->CreateBitmapFromWicBitmap(m_imageResponseImage->m_wicbmp.get(), nullptr, bitmap.put()));
311
311
 
312
312
  d2dDeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f));
313
- if (m_props->backgroundColor) {
314
- d2dDeviceContext->Clear(theme()->D2DColor(*m_props->backgroundColor));
313
+ if (viewProps()->backgroundColor) {
314
+ d2dDeviceContext->Clear(theme()->D2DColor(*viewProps()->backgroundColor));
315
315
  }
316
316
 
317
- const auto imageProps = std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
317
+ const auto &imgProps = imageProps();
318
318
 
319
319
  bool useEffects{
320
- imageProps->blurRadius > 0 || isColorMeaningful(imageProps->tintColor) ||
321
- imageProps->resizeMode == facebook::react::ImageResizeMode::Repeat};
320
+ imgProps.blurRadius > 0 || isColorMeaningful(imgProps.tintColor) ||
321
+ imgProps.resizeMode == facebook::react::ImageResizeMode::Repeat};
322
322
 
323
323
  if (useEffects) {
324
324
  winrt::com_ptr<ID2D1Effect> bitmapEffects;
@@ -326,23 +326,22 @@ void ImageComponentView::DrawImage() noexcept {
326
326
  winrt::check_hresult(
327
327
  bitmapEffects->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_imageResponseImage->m_wicbmp.get()));
328
328
 
329
- if (imageProps->blurRadius > 0) {
329
+ if (imgProps.blurRadius > 0) {
330
330
  winrt::com_ptr<ID2D1Effect> gaussianBlurEffect;
331
331
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1GaussianBlur, gaussianBlurEffect.put()));
332
332
  // https://learn.microsoft.com/en-us/windows/win32/direct2d/gaussian-blur#effect-properties
333
333
  // You can compute the blur radius of the kernel by multiplying the standard deviation by 3 (radius multiplier).
334
334
  constexpr float radiusMultiplier = 3;
335
335
  winrt::check_hresult(gaussianBlurEffect->SetValue(
336
- D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, (imageProps->blurRadius) / radiusMultiplier));
336
+ D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, (imgProps.blurRadius) / radiusMultiplier));
337
337
  gaussianBlurEffect->SetInputEffect(0, bitmapEffects.get());
338
338
  bitmapEffects.copy_from(gaussianBlurEffect.get());
339
339
  }
340
340
 
341
- if (isColorMeaningful(imageProps->tintColor)) {
341
+ if (isColorMeaningful(imgProps.tintColor)) {
342
342
  winrt::com_ptr<ID2D1Effect> tintColorEffect;
343
343
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1Flood, tintColorEffect.put()));
344
- winrt::check_hresult(
345
- tintColorEffect->SetValue(D2D1_FLOOD_PROP_COLOR, theme()->D2DColor(*imageProps->tintColor)));
344
+ winrt::check_hresult(tintColorEffect->SetValue(D2D1_FLOOD_PROP_COLOR, theme()->D2DColor(*imgProps.tintColor)));
346
345
 
347
346
  winrt::com_ptr<ID2D1Effect> compositeEffect;
348
347
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1Composite, compositeEffect.put()));
@@ -353,7 +352,7 @@ void ImageComponentView::DrawImage() noexcept {
353
352
  bitmapEffects.copy_from(compositeEffect.get());
354
353
  }
355
354
 
356
- if (imageProps->resizeMode == facebook::react::ImageResizeMode::Repeat) {
355
+ if (imgProps.resizeMode == facebook::react::ImageResizeMode::Repeat) {
357
356
  winrt::com_ptr<ID2D1Effect> borderEffect;
358
357
  winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1Border, borderEffect.put()));
359
358
  winrt::check_hresult(borderEffect->SetValue(D2D1_BORDER_PROP_EDGE_MODE_X, D2D1_BORDER_EDGE_MODE_WRAP));
@@ -386,51 +385,6 @@ void ImageComponentView::DrawImage() noexcept {
386
385
  }
387
386
  }
388
387
 
389
- void ImageComponentView::prepareForRecycle() noexcept {}
390
-
391
- facebook::react::SharedViewProps ImageComponentView::viewProps() noexcept {
392
- return m_props;
393
- }
394
-
395
- facebook::react::Tag ImageComponentView::hitTest(
396
- facebook::react::Point pt,
397
- facebook::react::Point &localPt,
398
- bool ignorePointerEvents) const noexcept {
399
- facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
400
-
401
- facebook::react::Tag targetTag;
402
-
403
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
404
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) &&
405
- anyHitTestHelper(targetTag, ptLocal, localPt))
406
- return targetTag;
407
-
408
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
409
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
410
- ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
411
- ptLocal.y <= m_layoutMetrics.frame.size.height) {
412
- localPt = ptLocal;
413
- return Tag();
414
- }
415
-
416
- return -1;
417
- }
418
-
419
- void ImageComponentView::ensureVisual() noexcept {
420
- if (!m_visual) {
421
- m_visual = m_compContext.CreateSpriteVisual();
422
- OuterVisual().InsertAt(m_visual, 0);
423
- }
424
- }
425
-
426
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ImageComponentView::Visual() const noexcept {
427
- return m_visual;
428
- }
429
-
430
- bool ImageComponentView::focusable() const noexcept {
431
- return m_props->focusable;
432
- }
433
-
434
388
  std::string ImageComponentView::DefaultControlType() const noexcept {
435
389
  return "image";
436
390
  }
@@ -29,8 +29,8 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
29
29
 
30
30
  struct WindowsImageResponseObserver;
31
31
 
32
- struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentView> {
33
- using Super = ImageComponentViewT<ImageComponentView, ComponentView>;
32
+ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ViewComponentView> {
33
+ using Super = ImageComponentViewT<ImageComponentView, ViewComponentView>;
34
34
 
35
35
  [[nodiscard]] static winrt::Microsoft::ReactNative::ComponentView Create(
36
36
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
@@ -47,25 +47,25 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
47
47
  override;
48
48
  void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
49
49
  override;
50
- void updateLayoutMetrics(
51
- facebook::react::LayoutMetrics const &layoutMetrics,
52
- facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
53
- void prepareForRecycle() noexcept override;
54
- facebook::react::SharedViewProps viewProps() noexcept override;
55
50
  void OnRenderingDeviceLost() noexcept override;
56
51
  void onThemeChanged() noexcept override;
57
52
 
58
- facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
59
- const noexcept override;
60
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept override;
61
- bool focusable() const noexcept override;
62
53
  virtual std::string DefaultControlType() const noexcept;
54
+ static facebook::react::SharedViewProps defaultProps() noexcept;
63
55
 
64
56
  ImageComponentView(
65
57
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
66
58
  facebook::react::Tag tag,
67
59
  winrt::Microsoft::ReactNative::ReactContext const &reactContext);
68
60
 
61
+ const facebook::react::ImageProps &imageProps() const noexcept;
62
+ // TODO try to change to ViewProps
63
+ winrt::Microsoft::ReactNative::ImageProps ImageProps() noexcept;
64
+ winrt::Microsoft::ReactNative::ImageProps ViewProps() noexcept;
65
+
66
+ protected:
67
+ winrt::Microsoft::ReactNative::ViewProps ViewPropsInner() noexcept override;
68
+
69
69
  private:
70
70
  struct WindowsImageResponseObserver : facebook::react::ImageResponseObserver {
71
71
  public:
@@ -78,7 +78,6 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
78
78
  winrt::com_ptr<ImageComponentView> m_image;
79
79
  };
80
80
 
81
- void ensureVisual() noexcept;
82
81
  void ensureDrawingSurface() noexcept;
83
82
  void DrawImage() noexcept;
84
83
 
@@ -90,9 +89,6 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
90
89
  facebook::react::ImageShadowNode::ConcreteState::Shared const &state) noexcept;
91
90
  bool themeEffectsImage() const noexcept;
92
91
 
93
- std::shared_ptr<const facebook::react::ImageProps> m_props;
94
-
95
- winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_visual{nullptr};
96
92
  winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface;
97
93
  std::shared_ptr<ImageResponseImage> m_imageResponseImage;
98
94
  std::shared_ptr<WindowsImageResponseObserver> m_imageResponseObserver;
@@ -23,14 +23,13 @@ WindowsModalHostComponentView::WindowsModalHostComponentView(
23
23
  facebook::react::Tag tag,
24
24
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
25
25
  : Super(
26
+ WindowsModalHostComponentView::defaultProps(),
26
27
  compContext,
27
28
  tag,
28
29
  reactContext,
29
30
  ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
30
31
  false) {
31
- m_props = std::make_shared<facebook::react::ModalHostViewProps const>();
32
32
  m_context = reactContext; // save context
33
- m_visual = compContext.CreateSpriteVisual();
34
33
  }
35
34
 
36
35
  winrt::Microsoft::ReactNative::ComponentView WindowsModalHostComponentView::Create(
@@ -201,7 +200,8 @@ void WindowsModalHostComponentView::HandleCommand(
201
200
  void WindowsModalHostComponentView::updateProps(
202
201
  facebook::react::Props::Shared const &props,
203
202
  facebook::react::Props::Shared const &oldProps) noexcept {
204
- const auto &oldModalProps = *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(m_props);
203
+ const auto &oldModalProps =
204
+ *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(oldProps ? oldProps : viewProps());
205
205
  const auto &newModalProps = *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(props);
206
206
 
207
207
  // currently Modal only gets Destroyed by closing the window
@@ -210,20 +210,15 @@ void WindowsModalHostComponentView::updateProps(
210
210
  ShowOnUIThread();
211
211
  }
212
212
 
213
- // update BaseComponentView props
214
- updateTransformProps(oldModalProps, newModalProps, m_visual);
215
- Super::updateProps(props, oldProps);
216
- m_props = std::static_pointer_cast<facebook::react::ModalHostViewProps const>(props);
213
+ base_type::updateProps(props, oldProps);
217
214
  }
218
215
 
219
216
  void WindowsModalHostComponentView::updateLayoutMetrics(
220
217
  facebook::react::LayoutMetrics const &layoutMetrics,
221
218
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
222
- if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
223
- OuterVisual().IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
224
- }
219
+ Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
225
220
 
226
- // Temparary placeholder for Modal, draws on main hwnd
221
+ // Temporary placeholder for Modal, draws on main hwnd
227
222
  if (m_layoutMetrics.frame.size != layoutMetrics.frame.size ||
228
223
  m_layoutMetrics.pointScaleFactor != layoutMetrics.pointScaleFactor || m_layoutMetrics.frame.size.width == 0) {
229
224
  // Always make visual a min size, so that even if its laid out at zero size, its clear an unimplemented view was
@@ -241,9 +236,9 @@ void WindowsModalHostComponentView::updateLayoutMetrics(
241
236
  drawingSurface.HorizontalAlignmentRatio(0.f);
242
237
  drawingSurface.VerticalAlignmentRatio(0.f);
243
238
  drawingSurface.Stretch(winrt::Microsoft::ReactNative::Composition::Experimental::CompositionStretch::None);
244
- m_visual.Brush(drawingSurface);
245
- m_visual.Size(surfaceSize);
246
- m_visual.Offset({
239
+ Visual().as<Experimental::ISpriteVisual>().Brush(drawingSurface);
240
+ Visual().Size(surfaceSize);
241
+ Visual().Offset({
247
242
  layoutMetrics.frame.origin.x * layoutMetrics.pointScaleFactor,
248
243
  layoutMetrics.frame.origin.y * layoutMetrics.pointScaleFactor,
249
244
  0.0f,
@@ -290,28 +285,18 @@ void WindowsModalHostComponentView::updateLayoutMetrics(
290
285
  }
291
286
  }
292
287
  }
293
-
294
- Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
295
288
  }
296
289
 
297
290
  void WindowsModalHostComponentView::updateState(
298
291
  facebook::react::State::Shared const &state,
299
292
  facebook::react::State::Shared const &oldState) noexcept {}
300
293
 
301
- void WindowsModalHostComponentView::prepareForRecycle() noexcept {}
302
-
303
- facebook::react::SharedViewProps WindowsModalHostComponentView::viewProps() noexcept {
304
- return m_props;
305
- }
306
-
307
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual WindowsModalHostComponentView::Visual()
308
- const noexcept {
309
- return m_visual;
294
+ facebook::react::SharedViewProps WindowsModalHostComponentView::defaultProps() noexcept {
295
+ static auto const defaultProps = std::make_shared<facebook::react::ModalHostViewProps const>();
296
+ return defaultProps;
310
297
  }
311
-
312
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual WindowsModalHostComponentView::OuterVisual()
313
- const noexcept {
314
- return m_visual;
298
+ const facebook::react::ModalHostViewProps &WindowsModalHostComponentView::modalHostViewProps() const noexcept {
299
+ return *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(viewProps());
315
300
  }
316
301
 
317
302
  facebook::react::Tag WindowsModalHostComponentView::hitTest(
@@ -320,8 +305,8 @@ facebook::react::Tag WindowsModalHostComponentView::hitTest(
320
305
  bool ignorePointerEvents) const noexcept {
321
306
  facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
322
307
 
323
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
324
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
308
+ if ((ignorePointerEvents || viewProps()->pointerEvents == facebook::react::PointerEventsMode::Auto ||
309
+ viewProps()->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
325
310
  ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
326
311
  ptLocal.y <= m_layoutMetrics.frame.size.height) {
327
312
  localPt = ptLocal;