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
@@ -578,19 +578,22 @@ winrt::Microsoft::ReactNative::ComponentView ScrollViewComponentView::Create(
578
578
  return winrt::make<ScrollViewComponentView>(compContext, tag, reactContext);
579
579
  }
580
580
 
581
+ facebook::react::SharedViewProps ScrollViewComponentView::defaultProps() noexcept {
582
+ static auto const defaultViewProps = std::make_shared<facebook::react::ScrollViewProps const>();
583
+ return defaultViewProps;
584
+ }
585
+
581
586
  ScrollViewComponentView::ScrollViewComponentView(
582
587
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
583
588
  facebook::react::Tag tag,
584
589
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
585
590
  : Super(
591
+ ScrollViewComponentView::defaultProps(),
586
592
  compContext,
587
593
  tag,
588
594
  reactContext,
589
595
  ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
590
596
  false) {
591
- static auto const defaultProps = std::make_shared<facebook::react::ScrollViewProps const>();
592
- m_props = defaultProps;
593
-
594
597
  // m_element.Content(m_contentPanel);
595
598
 
596
599
  /*
@@ -683,7 +686,8 @@ ScrollViewComponentView::ScrollViewComponentView(
683
686
  void ScrollViewComponentView::MountChildComponentView(
684
687
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
685
688
  uint32_t index) noexcept {
686
- base_type::MountChildComponentView(childComponentView, index);
689
+ // Call ComponentView::UnmountChildComponentView instead of base to handle out own Visual hosting
690
+ ComponentView::MountChildComponentView(childComponentView, index);
687
691
 
688
692
  ensureVisual();
689
693
  m_scrollVisual.InsertAt(
@@ -694,7 +698,8 @@ void ScrollViewComponentView::MountChildComponentView(
694
698
  void ScrollViewComponentView::UnmountChildComponentView(
695
699
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
696
700
  uint32_t index) noexcept {
697
- base_type::UnmountChildComponentView(childComponentView, index);
701
+ // Call ComponentView::UnmountChildComponentView instead of base to handle out own Visual hosting
702
+ ComponentView::UnmountChildComponentView(childComponentView, index);
698
703
  m_scrollVisual.Remove(childComponentView.as<ComponentView>()->OuterVisual());
699
704
  }
700
705
 
@@ -710,22 +715,17 @@ void ScrollViewComponentView::updateProps(
710
715
  facebook::react::Props::Shared const &props,
711
716
  facebook::react::Props::Shared const &oldProps) noexcept {
712
717
  const auto &newViewProps = *std::static_pointer_cast<const facebook::react::ScrollViewProps>(props);
713
- const auto &oldViewProps = *std::static_pointer_cast<const facebook::react::ScrollViewProps>(m_props);
718
+ const auto &oldViewProps =
719
+ *std::static_pointer_cast<const facebook::react::ScrollViewProps>(oldProps ? oldProps : viewProps());
714
720
 
715
721
  ensureVisual();
716
722
 
717
723
  if (!oldProps || oldViewProps.backgroundColor != newViewProps.backgroundColor) {
718
724
  updateBackgroundColor(newViewProps.backgroundColor);
719
725
  }
720
- if (oldViewProps.testId != newViewProps.testId) {
721
- m_visual.Comment(winrt::to_hstring(newViewProps.testId));
722
- }
723
726
 
724
727
  // update BaseComponentView props
725
- updateTransformProps(oldViewProps, newViewProps, m_visual);
726
- Super::updateProps(props, oldProps);
727
-
728
- m_props = std::static_pointer_cast<facebook::react::ViewProps const>(props);
728
+ base_type::updateProps(props, oldProps);
729
729
  }
730
730
 
731
731
  void ScrollViewComponentView::updateState(
@@ -758,16 +758,9 @@ void ScrollViewComponentView::updateLayoutMetrics(
758
758
  // Set Position & Size Properties
759
759
  ensureVisual();
760
760
 
761
- if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
762
- OuterVisual().IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
763
- }
764
-
765
761
  m_verticalScrollbarComponent->updateLayoutMetrics(layoutMetrics);
766
762
  m_horizontalScrollbarComponent->updateLayoutMetrics(layoutMetrics);
767
- Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
768
- m_visual.Size(
769
- {layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
770
- layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
763
+ base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
771
764
  m_scrollVisual.Size(
772
765
  {layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
773
766
  layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
@@ -785,10 +778,6 @@ void ScrollViewComponentView::updateContentVisualSize() noexcept {
785
778
 
786
779
  void ScrollViewComponentView::prepareForRecycle() noexcept {}
787
780
 
788
- facebook::react::SharedViewProps ScrollViewComponentView::viewProps() noexcept {
789
- return m_props;
790
- }
791
-
792
781
  /*
793
782
  ScrollViewComponentView::ScrollInteractionTrackerOwner::ScrollInteractionTrackerOwner(
794
783
  ScrollViewComponentView *outer)
@@ -835,7 +824,7 @@ void ScrollViewComponentView::OnPointerDown(const winrt::Windows::UI::Input::Poi
835
824
  */
836
825
 
837
826
  void ScrollViewComponentView::onThemeChanged() noexcept {
838
- updateBackgroundColor(std::static_pointer_cast<const facebook::react::ScrollViewProps>(m_props)->backgroundColor);
827
+ updateBackgroundColor(std::static_pointer_cast<const facebook::react::ScrollViewProps>(viewProps())->backgroundColor);
839
828
  m_verticalScrollbarComponent->OnThemeChanged();
840
829
  m_horizontalScrollbarComponent->OnThemeChanged();
841
830
  Super::onThemeChanged();
@@ -925,6 +914,8 @@ void ScrollViewComponentView::OnKeyDown(
925
914
  args.Handled(lineRight(true));
926
915
  break;
927
916
  }
917
+
918
+ base_type::OnKeyDown(source, args);
928
919
  }
929
920
 
930
921
  bool ScrollViewComponentView::scrollToEnd(bool animate) noexcept {
@@ -1131,37 +1122,35 @@ void ScrollViewComponentView::StartBringIntoView(
1131
1122
  }
1132
1123
  }
1133
1124
 
1134
- void ScrollViewComponentView::ensureVisual() noexcept {
1135
- if (!m_visual) {
1136
- m_visual = m_compContext.CreateSpriteVisual();
1137
- m_scrollVisual = m_compContext.CreateScrollerVisual();
1138
- m_verticalScrollbarComponent = std::make_shared<ScrollBarComponent>(*this, m_compContext, m_reactContext, true);
1139
- m_horizontalScrollbarComponent = std::make_shared<ScrollBarComponent>(*this, m_compContext, m_reactContext, false);
1140
- m_visual.InsertAt(m_scrollVisual, 0);
1141
- m_visual.InsertAt(m_verticalScrollbarComponent->Visual(), 1);
1142
- m_visual.InsertAt(m_horizontalScrollbarComponent->Visual(), 2);
1143
- m_scrollPositionChangedRevoker = m_scrollVisual.ScrollPositionChanged(
1144
- winrt::auto_revoke,
1145
- [this](
1146
- winrt::IInspectable const & /*sender*/,
1147
- winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) {
1148
- updateStateWithContentOffset();
1149
- auto eventEmitter = GetEventEmitter();
1150
- if (eventEmitter) {
1151
- facebook::react::ScrollViewMetrics scrollMetrics;
1152
- scrollMetrics.containerSize.height = m_layoutMetrics.frame.size.height;
1153
- scrollMetrics.containerSize.width = m_layoutMetrics.frame.size.width;
1154
- scrollMetrics.contentOffset.x = args.Position().x / m_layoutMetrics.pointScaleFactor;
1155
- scrollMetrics.contentOffset.y = args.Position().y / m_layoutMetrics.pointScaleFactor;
1156
- scrollMetrics.zoomScale = 1.0;
1157
- scrollMetrics.contentSize.height = std::max(m_contentSize.height, m_layoutMetrics.frame.size.height);
1158
- scrollMetrics.contentSize.width = std::max(m_contentSize.width, m_layoutMetrics.frame.size.width);
1159
- std::static_pointer_cast<facebook::react::ScrollViewEventEmitter const>(eventEmitter)
1160
- ->onScroll(scrollMetrics);
1161
- }
1162
- });
1163
- OuterVisual().InsertAt(m_visual, 0);
1164
- }
1125
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ScrollViewComponentView::createVisual() noexcept {
1126
+ auto visual = m_compContext.CreateSpriteVisual();
1127
+ m_scrollVisual = m_compContext.CreateScrollerVisual();
1128
+ m_verticalScrollbarComponent = std::make_shared<ScrollBarComponent>(*this, m_compContext, m_reactContext, true);
1129
+ m_horizontalScrollbarComponent = std::make_shared<ScrollBarComponent>(*this, m_compContext, m_reactContext, false);
1130
+ visual.InsertAt(m_scrollVisual, 0);
1131
+ visual.InsertAt(m_verticalScrollbarComponent->Visual(), 1);
1132
+ visual.InsertAt(m_horizontalScrollbarComponent->Visual(), 2);
1133
+ m_scrollPositionChangedRevoker = m_scrollVisual.ScrollPositionChanged(
1134
+ winrt::auto_revoke,
1135
+ [this](
1136
+ winrt::IInspectable const & /*sender*/,
1137
+ winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) {
1138
+ updateStateWithContentOffset();
1139
+ auto eventEmitter = GetEventEmitter();
1140
+ if (eventEmitter) {
1141
+ facebook::react::ScrollViewMetrics scrollMetrics;
1142
+ scrollMetrics.containerSize.height = m_layoutMetrics.frame.size.height;
1143
+ scrollMetrics.containerSize.width = m_layoutMetrics.frame.size.width;
1144
+ scrollMetrics.contentOffset.x = args.Position().x / m_layoutMetrics.pointScaleFactor;
1145
+ scrollMetrics.contentOffset.y = args.Position().y / m_layoutMetrics.pointScaleFactor;
1146
+ scrollMetrics.zoomScale = 1.0;
1147
+ scrollMetrics.contentSize.height = std::max(m_contentSize.height, m_layoutMetrics.frame.size.height);
1148
+ scrollMetrics.contentSize.width = std::max(m_contentSize.width, m_layoutMetrics.frame.size.width);
1149
+ std::static_pointer_cast<facebook::react::ScrollViewEventEmitter const>(eventEmitter)
1150
+ ->onScroll(scrollMetrics);
1151
+ }
1152
+ });
1153
+ return visual;
1165
1154
  }
1166
1155
 
1167
1156
  facebook::react::Tag ScrollViewComponentView::hitTest(
@@ -1174,19 +1163,19 @@ facebook::react::Tag ScrollViewComponentView::hitTest(
1174
1163
  ptViewport.x + m_scrollVisual.ScrollPosition().x / m_layoutMetrics.pointScaleFactor,
1175
1164
  ptViewport.y + m_scrollVisual.ScrollPosition().y / m_layoutMetrics.pointScaleFactor};
1176
1165
 
1177
- facebook::react::Tag targetTag;
1166
+ facebook::react::Tag targetTag = -1;
1178
1167
 
1179
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1180
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
1168
+ if ((ignorePointerEvents || viewProps()->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1169
+ viewProps()->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
1181
1170
  ptViewport.x >= 0 && ptViewport.x <= m_layoutMetrics.frame.size.width && ptViewport.y >= 0 &&
1182
1171
  ptViewport.y <= m_layoutMetrics.frame.size.height) {
1183
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1184
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) &&
1172
+ if ((ignorePointerEvents || viewProps()->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1173
+ viewProps()->pointerEvents == facebook::react::PointerEventsMode::BoxNone) &&
1185
1174
  anyHitTestHelper(targetTag, ptContent, localPt))
1186
1175
  return targetTag;
1187
1176
 
1188
- if (ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1189
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) {
1177
+ if (ignorePointerEvents || viewProps()->pointerEvents == facebook::react::PointerEventsMode::Auto ||
1178
+ viewProps()->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) {
1190
1179
  return this->Tag();
1191
1180
  }
1192
1181
  }
@@ -1208,10 +1197,6 @@ facebook::react::Point ScrollViewComponentView::getClientOffset() const noexcept
1208
1197
  parentOffset.y};
1209
1198
  }
1210
1199
 
1211
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ScrollViewComponentView::Visual() const noexcept {
1212
- return m_visual;
1213
- }
1214
-
1215
1200
  std::string ScrollViewComponentView::DefaultControlType() const noexcept {
1216
1201
  return "scrollbar";
1217
1202
  }
@@ -20,7 +20,7 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
20
20
 
21
21
  struct ScrollBarComponent;
22
22
 
23
- struct ScrollViewComponentView : ScrollViewComponentViewT<ScrollViewComponentView, ComponentView> {
23
+ struct ScrollViewComponentView : ScrollViewComponentViewT<ScrollViewComponentView, ViewComponentView> {
24
24
  /*
25
25
  struct ScrollInteractionTrackerOwner : public winrt::implements<
26
26
  ScrollInteractionTrackerOwner,
@@ -51,7 +51,7 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
51
51
  };
52
52
 
53
53
  */
54
- using Super = ScrollViewComponentViewT<ScrollViewComponentView, ComponentView>;
54
+ using Super = ScrollViewComponentViewT<ScrollViewComponentView, ViewComponentView>;
55
55
 
56
56
  [[nodiscard]] static winrt::Microsoft::ReactNative::ComponentView Create(
57
57
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
@@ -72,7 +72,6 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
72
72
  facebook::react::LayoutMetrics const &layoutMetrics,
73
73
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
74
74
  void prepareForRecycle() noexcept override;
75
- facebook::react::SharedViewProps viewProps() noexcept override;
76
75
  void OnKeyDown(
77
76
  const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
78
77
  const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
@@ -82,7 +81,6 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
82
81
  facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
83
82
  const noexcept override;
84
83
  facebook::react::Point getClientOffset() const noexcept override;
85
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept override;
86
84
 
87
85
  void onThemeChanged() noexcept override;
88
86
  void OnPointerReleased(
@@ -100,6 +98,8 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
100
98
 
101
99
  void scrollTo(winrt::Windows::Foundation::Numerics::float3 offset, bool animate) noexcept;
102
100
 
101
+ static facebook::react::SharedViewProps defaultProps() noexcept;
102
+
103
103
  ScrollViewComponentView(
104
104
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
105
105
  facebook::react::Tag tag,
@@ -111,9 +111,9 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
111
111
  bool lineDown(bool animate) noexcept;
112
112
  bool lineLeft(bool animate) noexcept;
113
113
  bool lineRight(bool animate) noexcept;
114
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept override;
114
115
 
115
116
  private:
116
- void ensureVisual() noexcept;
117
117
  void updateContentVisualSize() noexcept;
118
118
  bool scrollToEnd(bool animate) noexcept;
119
119
  bool scrollToStart(bool animate) noexcept;
@@ -125,14 +125,12 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
125
125
  void updateStateWithContentOffset() noexcept;
126
126
 
127
127
  facebook::react::Size m_contentSize;
128
- winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_visual{nullptr};
129
128
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual m_scrollVisual{nullptr};
130
129
  std::shared_ptr<ScrollBarComponent> m_horizontalScrollbarComponent{nullptr};
131
130
  std::shared_ptr<ScrollBarComponent> m_verticalScrollbarComponent{nullptr};
132
131
  winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollPositionChanged_revoker
133
132
  m_scrollPositionChangedRevoker{};
134
133
 
135
- facebook::react::SharedViewProps m_props;
136
134
  float m_zoomFactor{1.0f};
137
135
  bool m_isScrollingFromInertia = false;
138
136
  bool m_isScrolling = false;
@@ -29,13 +29,12 @@ SwitchComponentView::SwitchComponentView(
29
29
  facebook::react::Tag tag,
30
30
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
31
31
  : base_type(
32
+ SwitchComponentView::defaultProps(),
32
33
  compContext,
33
34
  tag,
34
35
  reactContext,
35
36
  ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
36
- false) {
37
- m_props = std::make_shared<facebook::react::SwitchProps const>();
38
- }
37
+ false) {}
39
38
 
40
39
  winrt::Microsoft::ReactNative::ComponentView SwitchComponentView::Create(
41
40
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
@@ -72,24 +71,17 @@ void SwitchComponentView::HandleCommand(
72
71
  void SwitchComponentView::updateProps(
73
72
  facebook::react::Props::Shared const &props,
74
73
  facebook::react::Props::Shared const &oldProps) noexcept {
75
- const auto &oldViewProps = *std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
74
+ const auto &oldViewProps =
75
+ *std::static_pointer_cast<const facebook::react::SwitchProps>(oldProps ? oldProps : viewProps());
76
76
  const auto &newViewProps = *std::static_pointer_cast<const facebook::react::SwitchProps>(props);
77
77
 
78
- ensureVisual();
79
-
80
78
  if (oldViewProps.backgroundColor != newViewProps.backgroundColor ||
81
79
  oldViewProps.thumbTintColor != newViewProps.thumbTintColor || oldViewProps.value != newViewProps.value ||
82
80
  oldViewProps.disabled != newViewProps.disabled) {
83
81
  m_visualUpdateRequired = true;
84
82
  }
85
- if (oldViewProps.testId != newViewProps.testId) {
86
- m_visual.Comment(winrt::to_hstring(newViewProps.testId));
87
- }
88
83
 
89
- // update BaseComponentView props
90
- updateTransformProps(oldViewProps, newViewProps, m_visual);
91
84
  Super::updateProps(props, oldProps);
92
- m_props = std::static_pointer_cast<facebook::react::ViewProps const>(props);
93
85
  }
94
86
 
95
87
  void SwitchComponentView::updateState(
@@ -99,17 +91,7 @@ void SwitchComponentView::updateState(
99
91
  void SwitchComponentView::updateLayoutMetrics(
100
92
  facebook::react::LayoutMetrics const &layoutMetrics,
101
93
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
102
- // Set Position & Size Properties
103
- ensureVisual();
104
-
105
- if ((layoutMetrics.displayType != m_layoutMetrics.displayType)) {
106
- OuterVisual().IsVisible(layoutMetrics.displayType != facebook::react::DisplayType::None);
107
- }
108
-
109
94
  Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
110
- m_visual.Size(
111
- {layoutMetrics.frame.size.width * layoutMetrics.pointScaleFactor,
112
- layoutMetrics.frame.size.height * layoutMetrics.pointScaleFactor});
113
95
 
114
96
  if (oldLayoutMetrics.pointScaleFactor != layoutMetrics.pointScaleFactor) {
115
97
  handleScaleChange();
@@ -135,7 +117,7 @@ void SwitchComponentView::handleScaleChange() noexcept {
135
117
  }
136
118
 
137
119
  void SwitchComponentView::updateVisuals() noexcept {
138
- const auto switchProps = std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
120
+ const auto &props = switchProps();
139
121
  auto &theme = *this->theme();
140
122
  winrt::Microsoft::ReactNative::Composition::Experimental::IBrush defaultColor;
141
123
  winrt::Microsoft::ReactNative::Composition::Experimental::IBrush fillColor;
@@ -144,8 +126,8 @@ void SwitchComponentView::updateVisuals() noexcept {
144
126
  auto thumbWidth = SwitchConstants::thumbWidth;
145
127
  auto thumbHeight = SwitchConstants::thumbWidth;
146
128
 
147
- if (switchProps->value) {
148
- if (switchProps->disabled) {
129
+ if (props.value) {
130
+ if (props.disabled) {
149
131
  defaultColor = theme.PlatformBrush("ToggleSwitchStrokeOnDisabled");
150
132
  fillColor = theme.PlatformBrush("ToggleSwitchFillOnDisabled");
151
133
  thumbFill = theme.PlatformBrush("ToggleSwitchKnobFillOnDisabled");
@@ -163,7 +145,7 @@ void SwitchComponentView::updateVisuals() noexcept {
163
145
  thumbFill = theme.PlatformBrush("ToggleSwitchKnobFillOn");
164
146
  }
165
147
  } else {
166
- if (switchProps->disabled) {
148
+ if (props.disabled) {
167
149
  defaultColor = theme.PlatformBrush("ToggleSwitchStrokeOffDisabled");
168
150
  fillColor = theme.PlatformBrush("ToggleSwitchFillOffDisabled");
169
151
  thumbFill = theme.PlatformBrush("ToggleSwitchKnobFillOffDisabled");
@@ -182,7 +164,7 @@ void SwitchComponentView::updateVisuals() noexcept {
182
164
  }
183
165
  }
184
166
 
185
- if (switchProps->disabled) {
167
+ if (props.disabled) {
186
168
  thumbWidth = SwitchConstants::thumbWidth;
187
169
  } else if (m_pressed) {
188
170
  thumbWidth = SwitchConstants::thumbWidthPressed;
@@ -194,18 +176,18 @@ void SwitchComponentView::updateVisuals() noexcept {
194
176
  thumbWidth = SwitchConstants::thumbWidth;
195
177
  }
196
178
 
197
- if (!switchProps->disabled && switchProps->thumbTintColor) {
198
- thumbFill = theme.Brush(*switchProps->thumbTintColor);
179
+ if (!props.disabled && props.thumbTintColor) {
180
+ thumbFill = theme.Brush(*props.thumbTintColor);
199
181
  }
200
182
 
201
- if (!switchProps->disabled && switchProps->onTintColor && switchProps->value) {
202
- fillColor = theme.Brush(*switchProps->onTintColor);
203
- } else if (!switchProps->disabled && switchProps->tintColor && !switchProps->value) {
204
- fillColor = theme.Brush(*switchProps->tintColor);
183
+ if (!props.disabled && props.onTintColor && props.value) {
184
+ fillColor = theme.Brush(*props.onTintColor);
185
+ } else if (!props.disabled && props.tintColor && !props.value) {
186
+ fillColor = theme.Brush(*props.tintColor);
205
187
  }
206
188
 
207
189
  // switch track - outline
208
- if ((!switchProps->onTintColor && switchProps->value) || (!switchProps->tintColor && !switchProps->value)) {
190
+ if ((!props.onTintColor && props.value) || (!props.tintColor && !props.value)) {
209
191
  m_trackVisual.StrokeThickness(std::round(SwitchConstants::trackStrokeThickness * m_layoutMetrics.pointScaleFactor));
210
192
  m_trackVisual.StrokeBrush(defaultColor);
211
193
  } else {
@@ -220,7 +202,7 @@ void SwitchComponentView::updateVisuals() noexcept {
220
202
  m_thumbVisual.AnimationClass(winrt::Microsoft::ReactNative::Composition::Experimental::AnimationClass::None);
221
203
  }
222
204
 
223
- if (switchProps->value) {
205
+ if (props.value) {
224
206
  m_thumbVisual.Offset(
225
207
  {(SwitchConstants::trackWidth - (SwitchConstants::thumbMargin + thumbWidth)) * m_layoutMetrics.pointScaleFactor,
226
208
  offsetY,
@@ -249,47 +231,18 @@ void SwitchComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::Compone
249
231
  base_type::FinalizeUpdates(updateMask);
250
232
  }
251
233
 
252
- void SwitchComponentView::prepareForRecycle() noexcept {}
253
-
254
- facebook::react::SharedViewProps SwitchComponentView::viewProps() noexcept {
255
- return m_props;
256
- }
257
-
258
- void SwitchComponentView::ensureVisual() noexcept {
259
- if (!m_visual) {
260
- m_visual = m_compContext.CreateSpriteVisual();
261
- OuterVisual().InsertAt(m_visual, 0);
262
-
263
- m_trackVisual = m_compContext.CreateRoundedRectangleVisual();
264
- m_visual.InsertAt(m_trackVisual, 0);
265
-
266
- m_thumbVisual = m_compContext.CreateRoundedRectangleVisual();
267
- m_thumbVisual.AnimationClass(winrt::Microsoft::ReactNative::Composition::Experimental::AnimationClass::SwitchThumb);
268
- m_trackVisual.InsertAt(m_thumbVisual, 0);
269
-
270
- handleScaleChange();
271
- }
272
- }
234
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual SwitchComponentView::createVisual() noexcept {
235
+ auto visual = m_compContext.CreateSpriteVisual();
273
236
 
274
- facebook::react::Tag SwitchComponentView::hitTest(
275
- facebook::react::Point pt,
276
- facebook::react::Point &localPt,
277
- bool ignorePointerEvents) const noexcept {
278
- facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
279
-
280
- if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
281
- m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
282
- ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
283
- ptLocal.y <= m_layoutMetrics.frame.size.height) {
284
- localPt = ptLocal;
285
- return Tag();
286
- }
237
+ m_trackVisual = m_compContext.CreateRoundedRectangleVisual();
238
+ visual.InsertAt(m_trackVisual, 0);
287
239
 
288
- return -1;
289
- }
240
+ m_thumbVisual = m_compContext.CreateRoundedRectangleVisual();
241
+ m_thumbVisual.AnimationClass(winrt::Microsoft::ReactNative::Composition::Experimental::AnimationClass::SwitchThumb);
242
+ m_trackVisual.InsertAt(m_thumbVisual, 0);
290
243
 
291
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual SwitchComponentView::Visual() const noexcept {
292
- return m_visual;
244
+ handleScaleChange();
245
+ return visual;
293
246
  }
294
247
 
295
248
  void SwitchComponentView::onThemeChanged() noexcept {
@@ -304,9 +257,7 @@ void SwitchComponentView::OnPointerPressed(
304
257
  return;
305
258
  }
306
259
 
307
- const auto switchProps = std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
308
-
309
- if (!switchProps->disabled) {
260
+ if (!switchProps().disabled) {
310
261
  m_pressed = true;
311
262
  m_supressAnimationForNextFrame = true;
312
263
 
@@ -364,27 +315,30 @@ void SwitchComponentView::OnKeyUp(
364
315
  }
365
316
 
366
317
  bool SwitchComponentView::toggle() noexcept {
367
- const auto switchProps = std::static_pointer_cast<const facebook::react::SwitchProps>(m_props);
368
-
369
- if (switchProps->disabled || !m_eventEmitter)
318
+ if (switchProps().disabled || !m_eventEmitter)
370
319
  return false;
371
320
 
372
321
  auto switchEventEmitter = std::static_pointer_cast<facebook::react::SwitchEventEmitter const>(m_eventEmitter);
373
322
 
374
323
  facebook::react::SwitchEventEmitter::OnChange args;
375
- args.value = !(switchProps->value);
324
+ args.value = !(switchProps().value);
376
325
  args.target = Tag();
377
326
 
378
327
  switchEventEmitter->onChange(args);
379
328
  return true;
380
329
  }
381
330
 
382
- bool SwitchComponentView::focusable() const noexcept {
383
- return m_props->focusable;
384
- }
385
-
386
331
  std::string SwitchComponentView::DefaultControlType() const noexcept {
387
332
  return "switch";
388
333
  }
389
334
 
335
+ facebook::react::SharedViewProps SwitchComponentView::defaultProps() noexcept {
336
+ static auto const defaultProps = std::make_shared<facebook::react::SwitchProps const>();
337
+ return defaultProps;
338
+ }
339
+
340
+ const facebook::react::SwitchProps &SwitchComponentView::switchProps() const noexcept {
341
+ return *std::static_pointer_cast<const facebook::react::SwitchProps>(viewProps());
342
+ }
343
+
390
344
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -13,8 +13,8 @@
13
13
 
14
14
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
15
15
 
16
- struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, ComponentView> {
17
- using Super = SwitchComponentViewT<SwitchComponentView, ComponentView>;
16
+ struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, ViewComponentView> {
17
+ using Super = SwitchComponentViewT<SwitchComponentView, ViewComponentView>;
18
18
 
19
19
  [[nodiscard]] static winrt::Microsoft::ReactNative::ComponentView Create(
20
20
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
@@ -37,9 +37,6 @@ struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, Component
37
37
  facebook::react::LayoutMetrics const &layoutMetrics,
38
38
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
39
39
  void FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept override;
40
- void prepareForRecycle() noexcept override;
41
- facebook::react::SharedViewProps viewProps() noexcept override;
42
- bool focusable() const noexcept override;
43
40
  void onThemeChanged() noexcept override;
44
41
  void OnKeyUp(
45
42
  const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
@@ -53,9 +50,6 @@ struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, Component
53
50
  void OnPointerExited(
54
51
  const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept override;
55
52
 
56
- facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
57
- const noexcept override;
58
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept override;
59
53
  std::string DefaultControlType() const noexcept override;
60
54
 
61
55
  SwitchComponentView(
@@ -63,6 +57,10 @@ struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, Component
63
57
  facebook::react::Tag tag,
64
58
  winrt::Microsoft::ReactNative::ReactContext const &reactContext);
65
59
 
60
+ static facebook::react::SharedViewProps defaultProps() noexcept;
61
+ const facebook::react::SwitchProps &switchProps() const noexcept;
62
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept override;
63
+
66
64
  private:
67
65
  void ensureVisual() noexcept;
68
66
  bool toggle() noexcept;
@@ -74,10 +72,8 @@ struct SwitchComponentView : SwitchComponentViewT<SwitchComponentView, Component
74
72
  bool m_supressAnimationForNextFrame{false};
75
73
  bool m_visualUpdateRequired{true};
76
74
  facebook::react::Size m_contentSize;
77
- winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_visual{nullptr};
78
75
  winrt::Microsoft::ReactNative::Composition::Experimental::IRoundedRectangleVisual m_trackVisual{nullptr};
79
76
  winrt::Microsoft::ReactNative::Composition::Experimental::IRoundedRectangleVisual m_thumbVisual{nullptr};
80
- facebook::react::SharedViewProps m_props;
81
77
  };
82
78
 
83
79
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation