react-native-windows 0.74.25 → 0.74.27

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 (87) hide show
  1. package/Libraries/Modal/Modal.windows.js +352 -0
  2. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +26 -46
  3. package/Microsoft.ReactNative/Fabric/ComponentView.h +6 -19
  4. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +5 -0
  5. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +4 -0
  6. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +164 -3
  7. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +7 -0
  8. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +205 -101
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +21 -13
  10. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +9 -2
  11. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +2 -1
  12. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +59 -9
  13. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +2 -0
  14. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +78 -30
  15. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +21 -1
  16. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +10 -0
  17. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +3 -0
  18. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +14 -1
  19. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -0
  20. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -1
  21. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +25 -0
  22. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  23. package/codegen/NativeAccessibilityInfoSpec.g.h +1 -0
  24. package/codegen/NativeAccessibilityManagerSpec.g.h +1 -0
  25. package/codegen/NativeActionSheetManagerSpec.g.h +1 -0
  26. package/codegen/NativeAlertManagerSpec.g.h +1 -0
  27. package/codegen/NativeAnimatedModuleSpec.g.h +1 -0
  28. package/codegen/NativeAnimatedTurboModuleSpec.g.h +1 -0
  29. package/codegen/NativeAnimationsDebugModuleSpec.g.h +1 -0
  30. package/codegen/NativeAppStateSpec.g.h +1 -0
  31. package/codegen/NativeAppThemeSpec.g.h +1 -0
  32. package/codegen/NativeAppearanceSpec.g.h +1 -0
  33. package/codegen/NativeBlobModuleSpec.g.h +1 -0
  34. package/codegen/NativeBugReportingSpec.g.h +1 -0
  35. package/codegen/NativeClipboardSpec.g.h +1 -0
  36. package/codegen/NativeDevLoadingViewSpec.g.h +1 -0
  37. package/codegen/NativeDevMenuSpec.g.h +1 -0
  38. package/codegen/NativeDevSettingsSpec.g.h +1 -0
  39. package/codegen/NativeDevToolsSettingsManagerSpec.g.h +1 -0
  40. package/codegen/NativeDeviceEventManagerSpec.g.h +1 -0
  41. package/codegen/NativeDeviceInfoSpec.g.h +1 -0
  42. package/codegen/NativeDialogManagerAndroidSpec.g.h +1 -0
  43. package/codegen/NativeDialogManagerWindowsSpec.g.h +1 -0
  44. package/codegen/NativeExceptionsManagerSpec.g.h +1 -0
  45. package/codegen/NativeFileReaderModuleSpec.g.h +1 -0
  46. package/codegen/NativeFrameRateLoggerSpec.g.h +1 -0
  47. package/codegen/NativeHeadlessJsTaskSupportSpec.g.h +1 -0
  48. package/codegen/NativeI18nManagerSpec.g.h +1 -0
  49. package/codegen/NativeImageEditorSpec.g.h +1 -0
  50. package/codegen/NativeImageLoaderAndroidSpec.g.h +1 -0
  51. package/codegen/NativeImageLoaderIOSSpec.g.h +1 -0
  52. package/codegen/NativeImageStoreAndroidSpec.g.h +1 -0
  53. package/codegen/NativeImageStoreIOSSpec.g.h +1 -0
  54. package/codegen/NativeIntentAndroidSpec.g.h +1 -0
  55. package/codegen/NativeIntersectionObserverSpec.g.h +1 -0
  56. package/codegen/NativeJSCHeapCaptureSpec.g.h +1 -0
  57. package/codegen/NativeJSCSamplingProfilerSpec.g.h +1 -0
  58. package/codegen/NativeKeyboardObserverSpec.g.h +1 -0
  59. package/codegen/NativeLinkingManagerSpec.g.h +1 -0
  60. package/codegen/NativeLogBoxSpec.g.h +1 -0
  61. package/codegen/NativeModalManagerSpec.g.h +1 -0
  62. package/codegen/NativeMutationObserverSpec.g.h +1 -0
  63. package/codegen/NativeNetworkingAndroidSpec.g.h +1 -0
  64. package/codegen/NativeNetworkingIOSSpec.g.h +1 -0
  65. package/codegen/NativePerformanceObserverSpec.g.h +1 -0
  66. package/codegen/NativePerformanceSpec.g.h +1 -0
  67. package/codegen/NativePermissionsAndroidSpec.g.h +1 -0
  68. package/codegen/NativePlatformConstantsAndroidSpec.g.h +1 -0
  69. package/codegen/NativePlatformConstantsIOSSpec.g.h +1 -0
  70. package/codegen/NativePlatformConstantsWinSpec.g.h +1 -0
  71. package/codegen/NativePushNotificationManagerIOSSpec.g.h +1 -0
  72. package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +1 -0
  73. package/codegen/NativeRedBoxSpec.g.h +1 -0
  74. package/codegen/NativeSampleTurboModuleSpec.g.h +1 -0
  75. package/codegen/NativeSegmentFetcherSpec.g.h +1 -0
  76. package/codegen/NativeSettingsManagerSpec.g.h +1 -0
  77. package/codegen/NativeShareModuleSpec.g.h +1 -0
  78. package/codegen/NativeSoundManagerSpec.g.h +1 -0
  79. package/codegen/NativeSourceCodeSpec.g.h +1 -0
  80. package/codegen/NativeStatusBarManagerAndroidSpec.g.h +1 -0
  81. package/codegen/NativeStatusBarManagerIOSSpec.g.h +1 -0
  82. package/codegen/NativeTimingSpec.g.h +1 -0
  83. package/codegen/NativeToastAndroidSpec.g.h +1 -0
  84. package/codegen/NativeUIManagerSpec.g.h +1 -0
  85. package/codegen/NativeVibrationSpec.g.h +1 -0
  86. package/codegen/NativeWebSocketModuleSpec.g.h +1 -0
  87. package/package.json +3 -3
@@ -20,6 +20,13 @@ struct CompContext;
20
20
 
21
21
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
22
22
 
23
+ struct FocusPrimitive {
24
+ std::shared_ptr<BorderPrimitive> m_focusInnerPrimitive;
25
+ std::shared_ptr<BorderPrimitive> m_focusOuterPrimitive;
26
+ winrt::com_ptr<ComponentView> m_focusVisualComponent{nullptr}; // The owning component of focus visuals being hosted
27
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_focusVisual{nullptr};
28
+ };
29
+
23
30
  struct ComponentView : public ComponentViewT<
24
31
  ComponentView,
25
32
  winrt::Microsoft::ReactNative::implementation::ComponentView,
@@ -28,7 +35,8 @@ struct ComponentView : public ComponentViewT<
28
35
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
29
36
  facebook::react::Tag tag,
30
37
  winrt::Microsoft::ReactNative::ReactContext const &reactContext,
31
- ComponentViewFeatures flags);
38
+ ComponentViewFeatures flags,
39
+ winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder);
32
40
  virtual ~ComponentView();
33
41
 
34
42
  virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept {
@@ -99,6 +107,8 @@ struct ComponentView : public ComponentViewT<
99
107
  void Toggle() noexcept override;
100
108
  virtual winrt::Microsoft::ReactNative::implementation::ClipState getClipState() noexcept;
101
109
 
110
+ virtual std::pair<facebook::react::Cursor, HCURSOR> cursor() const noexcept;
111
+
102
112
  const facebook::react::LayoutMetrics &layoutMetrics() const noexcept;
103
113
 
104
114
  virtual std::string DefaultControlType() const noexcept;
@@ -125,13 +135,10 @@ struct ComponentView : public ComponentViewT<
125
135
  facebook::react::SharedViewEventEmitter m_eventEmitter;
126
136
 
127
137
  private:
128
- void updateFocusLayoutMetrics(facebook::react::LayoutMetrics const &layoutMetrics) noexcept;
138
+ void updateFocusLayoutMetrics() noexcept;
129
139
  void updateClippingPath(
130
140
  facebook::react::LayoutMetrics const &layoutMetrics,
131
141
  const facebook::react::ViewProps &viewProps) noexcept;
132
- void finalizeFocusVisual(
133
- facebook::react::LayoutMetrics const &layoutMetrics,
134
- const facebook::react::ViewProps &viewProps) noexcept;
135
142
  void UpdateCenterPropertySet() noexcept;
136
143
  void FinalizeTransform(
137
144
  facebook::react::LayoutMetrics const &layoutMetrics,
@@ -140,16 +147,18 @@ struct ComponentView : public ComponentViewT<
140
147
  facebook::react::BorderMetrics focusBorderMetrics(bool inner, const facebook::react::LayoutMetrics &layoutMetrics)
141
148
  const noexcept;
142
149
 
150
+ virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual visualToHostFocus() noexcept;
151
+ virtual winrt::com_ptr<ComponentView> focusVisualRoot(const facebook::react::Rect &focusRect) noexcept;
152
+
143
153
  bool m_hasTransformMatrixFacade : 1 {false};
144
- bool m_showingFocusVisual : 1 {false};
145
154
  bool m_FinalizeTransform : 1 {false};
146
155
  bool m_tooltipTracked : 1 {false};
147
156
  ComponentViewFeatures m_flags;
148
- void showFocusVisual(bool show) noexcept;
157
+ void hostFocusVisual(bool show, winrt::com_ptr<ComponentView> view) noexcept;
158
+ winrt::com_ptr<ComponentView>
159
+ m_componentHostingFocusVisual; // The component that we are showing our focus visuals within
149
160
  std::shared_ptr<BorderPrimitive> m_borderPrimitive;
150
- std::shared_ptr<BorderPrimitive> m_focusInnerPrimitive;
151
- std::shared_ptr<BorderPrimitive> m_focusOuterPrimitive;
152
- winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_focusVisual{nullptr};
161
+ std::unique_ptr<FocusPrimitive> m_focusPrimitive{nullptr};
153
162
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_outerVisual{nullptr};
154
163
  winrt::event<winrt::Windows::Foundation::EventHandler<winrt::IInspectable>> m_themeChangedEvent;
155
164
  };
@@ -176,7 +185,6 @@ struct ViewComponentView : public ViewComponentViewT<
176
185
  facebook::react::LayoutMetrics const &layoutMetrics,
177
186
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
178
187
  void prepareForRecycle() noexcept override;
179
- bool TryFocus() noexcept;
180
188
  bool focusable() const noexcept override;
181
189
  void OnKeyDown(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
182
190
  void OnKeyUp(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
@@ -201,7 +209,8 @@ struct ViewComponentView : public ViewComponentViewT<
201
209
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
202
210
  facebook::react::Tag tag,
203
211
  winrt::Microsoft::ReactNative::ReactContext const &reactContext,
204
- ComponentViewFeatures flags);
212
+ ComponentViewFeatures flags,
213
+ winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder = nullptr);
205
214
 
206
215
  virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept;
207
216
 
@@ -219,7 +228,6 @@ struct ViewComponentView : public ViewComponentViewT<
219
228
  bool m_hasNonVisualChildren{false};
220
229
  facebook::react::SharedViewProps m_props;
221
230
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_visual{nullptr};
222
- winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate m_createVisualHandler{nullptr};
223
231
  winrt::Microsoft::ReactNative::Composition::Experimental::CreateInternalVisualDelegate m_createInternalVisualHandler{
224
232
  nullptr};
225
233
  };
@@ -22,8 +22,15 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
22
22
  ContentIslandComponentView::ContentIslandComponentView(
23
23
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
24
24
  facebook::react::Tag tag,
25
- winrt::Microsoft::ReactNative::ReactContext const &reactContext)
26
- : base_type(ViewComponentView::defaultProps(), compContext, tag, reactContext, ComponentViewFeatures::Default) {
25
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
26
+ ReactCompositionViewComponentBuilder *builder)
27
+ : base_type(
28
+ ViewComponentView::defaultProps(),
29
+ compContext,
30
+ tag,
31
+ reactContext,
32
+ ComponentViewFeatures::Default,
33
+ builder) {
27
34
  m_mountedToken = Mounted([](const winrt::IInspectable &, const winrt::Microsoft::ReactNative::ComponentView &view) {
28
35
  view.as<ContentIslandComponentView>()->OnMounted();
29
36
  });
@@ -40,7 +40,8 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
40
40
  ContentIslandComponentView(
41
41
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
42
42
  facebook::react::Tag tag,
43
- winrt::Microsoft::ReactNative::ReactContext const &reactContext);
43
+ winrt::Microsoft::ReactNative::ReactContext const &reactContext,
44
+ ReactCompositionViewComponentBuilder *builder);
44
45
  ~ContentIslandComponentView() noexcept;
45
46
 
46
47
  private:
@@ -24,6 +24,7 @@
24
24
  #include "IReactContext.h"
25
25
  #include "ReactHost/ReactInstanceWin.h"
26
26
  #include "ReactNativeHost.h"
27
+ #include "WindowsModalHostViewShadowNode.h"
27
28
 
28
29
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
29
30
  WindowsModalHostComponentView::WindowsModalHostComponentView(
@@ -33,6 +34,23 @@ WindowsModalHostComponentView::WindowsModalHostComponentView(
33
34
  : Super(compContext, tag, reactContext) {}
34
35
 
35
36
  WindowsModalHostComponentView::~WindowsModalHostComponentView() {
37
+ // dispatch onDismiss event
38
+ auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
39
+ facebook::react::ModalHostViewEventEmitter::OnDismiss onDismissArgs;
40
+ emitter->onDismiss(onDismissArgs);
41
+
42
+ // reset the topWindowID
43
+ if (m_prevWindowID) {
44
+ auto host =
45
+ winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
46
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
47
+ host.InstanceSettings().Properties(), m_prevWindowID);
48
+ m_prevWindowID = 0;
49
+ }
50
+
51
+ // enable input to parent
52
+ EnableWindow(m_parentHwnd, true);
53
+
36
54
  // Check if the window handle (m_hwnd) exists and destroy it if necessary
37
55
  if (m_hwnd) {
38
56
  // Close/Destroy the modal window
@@ -77,17 +95,19 @@ void WindowsModalHostComponentView::EnsureModalCreated() {
77
95
  m_prevWindowID =
78
96
  winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_reactContext.Properties().Handle());
79
97
 
80
- auto roothwnd = GetHwndForParenting();
98
+ m_parentHwnd = GetHwndForParenting();
99
+
100
+ auto windowsStyle = m_showTitleBar ? WS_OVERLAPPEDWINDOW : WS_POPUP;
81
101
 
82
102
  m_hwnd = CreateWindow(
83
103
  c_modalWindowClassName,
84
104
  L"React-Native Modal",
85
- WS_OVERLAPPEDWINDOW,
105
+ windowsStyle,
86
106
  CW_USEDEFAULT,
87
107
  CW_USEDEFAULT,
88
108
  MODAL_MIN_WIDTH,
89
109
  MODAL_MIN_HEIGHT,
90
- roothwnd, // parent
110
+ m_parentHwnd, // parent
91
111
  nullptr,
92
112
  hInstance,
93
113
  spunk.get());
@@ -126,7 +146,7 @@ void WindowsModalHostComponentView::EnsureModalCreated() {
126
146
  constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
127
147
 
128
148
  RECT rc;
129
- GetClientRect(roothwnd, &rc);
149
+ GetClientRect(m_parentHwnd, &rc);
130
150
  // Maximum size is set to size of parent hwnd
131
151
  constraints.MaximumSize = {(rc.right - rc.left) * ScaleFactor(m_hwnd), (rc.bottom - rc.top) / ScaleFactor(m_hwnd)};
132
152
  constraints.MinimumSize = {MODAL_MIN_WIDTH * ScaleFactor(m_hwnd), MODAL_MIN_HEIGHT * ScaleFactor(m_hwnd)};
@@ -141,6 +161,14 @@ void WindowsModalHostComponentView::ShowOnUIThread() {
141
161
  ShowWindow(m_hwnd, SW_NORMAL);
142
162
  BringWindowToTop(m_hwnd);
143
163
  SetFocus(m_hwnd);
164
+
165
+ // disable input to parent
166
+ EnableWindow(m_parentHwnd, false);
167
+
168
+ // dispatch onShow event
169
+ auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
170
+ facebook::react::ModalHostViewEventEmitter::OnShow onShowArgs;
171
+ emitter->onShow(onShowArgs);
144
172
  }
145
173
  }
146
174
 
@@ -149,12 +177,21 @@ void WindowsModalHostComponentView::HideOnUIThread() noexcept {
149
177
  SendMessage(m_hwnd, WM_CLOSE, 0, 0);
150
178
  }
151
179
 
180
+ // dispatch onDismiss event
181
+ auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
182
+ facebook::react::ModalHostViewEventEmitter::OnDismiss onDismissArgs;
183
+ emitter->onDismiss(onDismissArgs);
184
+
185
+ // enable input to parent
186
+ EnableWindow(m_parentHwnd, true);
187
+
152
188
  // reset the topWindowID
153
189
  if (m_prevWindowID) {
154
190
  auto host =
155
191
  winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
156
192
  winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
157
193
  host.InstanceSettings().Properties(), m_prevWindowID);
194
+ m_prevWindowID = 0;
158
195
  }
159
196
  }
160
197
 
@@ -266,22 +303,32 @@ void WindowsModalHostComponentView::AdjustWindowSize() noexcept {
266
303
  if (m_layoutMetrics.overflowInset.right == 0 && m_layoutMetrics.overflowInset.bottom == 0) {
267
304
  return;
268
305
  }
306
+
269
307
  // Modal's size is based on it's children, use the overflow to calculate the width/height
270
308
  float xPos = (-m_layoutMetrics.overflowInset.right * (m_layoutMetrics.pointScaleFactor));
271
309
  float yPos = (-m_layoutMetrics.overflowInset.bottom * (m_layoutMetrics.pointScaleFactor));
272
310
  RECT rc;
273
311
  GetClientRect(m_hwnd, &rc);
274
312
  RECT rect = {0, 0, (int)xPos, (int)yPos};
275
- AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); // Adjust for title bar and borders
276
- MoveWindow(m_hwnd, 0, 0, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), true);
313
+
314
+ if (m_showTitleBar) {
315
+ AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); // Adjust for title bar and borders
316
+ }
277
317
 
278
318
  // set the layoutMetrics
279
- m_layoutMetrics.frame.size = {
280
- (float)rect.right - rect.left + m_layoutMetrics.frame.origin.x,
281
- (float)rect.bottom - rect.top + m_layoutMetrics.frame.origin.y};
319
+ m_layoutMetrics.frame.size = {(float)rect.right - rect.left, (float)rect.bottom - rect.top};
282
320
  m_layoutMetrics.overflowInset.right = 0;
283
321
  m_layoutMetrics.overflowInset.bottom = 0;
284
322
 
323
+ // get Modal's position based on parent
324
+ RECT parentRC;
325
+ GetWindowRect(m_parentHwnd, &parentRC);
326
+ float xCor = (parentRC.left + parentRC.right - m_layoutMetrics.frame.size.width) / 2; // midpointx - width / 2
327
+ float yCor = (parentRC.top + parentRC.bottom - m_layoutMetrics.frame.size.height) / 2; // midpointy - height / 2
328
+
329
+ // Adjust window position and size
330
+ MoveWindow(m_hwnd, (int)xCor, (int)yCor, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), true);
331
+
285
332
  // Let RNWIsland know that Modal's size has changed
286
333
  winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(m_reactNativeIsland)
287
334
  ->NotifySizeChanged();
@@ -294,6 +341,9 @@ void WindowsModalHostComponentView::updateProps(
294
341
  *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(oldProps ? oldProps : viewProps());
295
342
  const auto &newModalProps = *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(props);
296
343
  newModalProps.visible ? m_isVisible = true : m_isVisible = false;
344
+ if (!m_isVisible) {
345
+ HideOnUIThread();
346
+ }
297
347
  base_type::updateProps(props, oldProps);
298
348
  }
299
349
 
@@ -60,9 +60,11 @@ struct WindowsModalHostComponentView
60
60
  static void RegisterWndClass() noexcept;
61
61
 
62
62
  private:
63
+ HWND m_parentHwnd{nullptr};
63
64
  HWND m_hwnd{nullptr};
64
65
  uint64_t m_prevWindowID;
65
66
  bool m_isVisible{false};
67
+ bool m_showTitleBar{false};
66
68
  winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland;
67
69
  };
68
70
 
@@ -6,6 +6,7 @@
6
6
  #include <Fabric/Composition/CompositionViewComponentView.h>
7
7
  #include <Fabric/Composition/ContentIslandComponentView.h>
8
8
  #include <strsafe.h>
9
+ #include "CompositionContextHelper.h"
9
10
  #include "DynamicWriter.h"
10
11
  #include "ReactHost/MsoUtils.h"
11
12
 
@@ -52,24 +53,6 @@ LayoutHandler ReactCompositionViewComponentBuilder::LayoutHandler() const noexce
52
53
  void ReactCompositionViewComponentBuilder::InitializeComponentView(
53
54
  const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
54
55
  auto self = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view);
55
- self->MarkAsCustomComponent();
56
- if (m_customCommandHandler)
57
- self->CustomCommandHandler(m_customCommandHandler);
58
- if (m_finalizeUpdateHandler)
59
- self->FinalizeUpdateHandler(m_finalizeUpdateHandler);
60
- if (m_updatePropsHandler)
61
- self->UpdatePropsHandler(m_updatePropsHandler);
62
- if (m_updateStateHandler)
63
- self->UpdateStateHandler(m_updateStateHandler);
64
- if (m_updateEventEmitterHandler)
65
- self->UpdateEventEmitterHandler(m_updateEventEmitterHandler);
66
- if (m_mountChildComponentViewHandler)
67
- self->MountChildComponentViewHandler(m_mountChildComponentViewHandler);
68
- if (m_unmountChildComponentViewHandler)
69
- self->UnmountChildComponentViewHandler(m_unmountChildComponentViewHandler);
70
- if (m_createVisualHandler)
71
- view.as<winrt::Microsoft::ReactNative::Composition::implementation::ViewComponentView>()->CreateVisualHandler(
72
- m_createVisualHandler);
73
56
  }
74
57
 
75
58
  void ReactCompositionViewComponentBuilder::SetComponentViewInitializer(
@@ -78,8 +61,9 @@ void ReactCompositionViewComponentBuilder::SetComponentViewInitializer(
78
61
  const IReactContext &reactContext,
79
62
  int32_t tag,
80
63
  const Experimental::ICompositionContext &context,
81
- ComponentViewFeatures) {
82
- auto view = winrt::make<winrt::Microsoft::ReactNative::implementation::ComponentView>(tag, reactContext);
64
+ ComponentViewFeatures,
65
+ ReactCompositionViewComponentBuilder &builder) {
66
+ auto view = winrt::make<winrt::Microsoft::ReactNative::implementation::ComponentView>(tag, reactContext, &builder);
83
67
  initializer(view);
84
68
  return view;
85
69
  };
@@ -94,9 +78,10 @@ void ReactCompositionViewComponentBuilder::SetViewComponentViewInitializer(
94
78
  const IReactContext &reactContext,
95
79
  int32_t tag,
96
80
  const Experimental::ICompositionContext &context,
97
- ComponentViewFeatures features) {
81
+ ComponentViewFeatures features,
82
+ ReactCompositionViewComponentBuilder &builder) {
98
83
  auto view = winrt::make<implementation::ViewComponentView>(
99
- implementation::ViewComponentView::defaultProps(), context, tag, reactContext, features);
84
+ implementation::ViewComponentView::defaultProps(), context, tag, reactContext, features, &builder);
100
85
  initializer(view);
101
86
  return view;
102
87
  };
@@ -108,14 +93,15 @@ void ReactCompositionViewComponentBuilder::SetViewComponentViewInitializer(
108
93
 
109
94
  void ReactCompositionViewComponentBuilder::SetContentIslandComponentViewInitializer(
110
95
  const ComponentIslandComponentViewInitializer &initializer) noexcept {
111
- m_fnCreateView =
112
- [initializer](
113
- const IReactContext &reactContext,
114
- int32_t tag,
115
- const Experimental::ICompositionContext &context,
116
- ComponentViewFeatures) -> winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView {
96
+ m_fnCreateView = [initializer](
97
+ const IReactContext &reactContext,
98
+ int32_t tag,
99
+ const Experimental::ICompositionContext &context,
100
+ ComponentViewFeatures /*features*/,
101
+ ReactCompositionViewComponentBuilder &builder)
102
+ -> winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView {
117
103
  auto view = winrt::make<winrt::Microsoft::ReactNative::Composition::implementation::ContentIslandComponentView>(
118
- context, tag, reactContext);
104
+ context, tag, reactContext, &builder);
119
105
  initializer(view);
120
106
  return view;
121
107
  };
@@ -166,46 +152,108 @@ void ReactCompositionViewComponentBuilder::SetCustomCommandHandler(HandleCommand
166
152
  m_customCommandHandler = impl;
167
153
  }
168
154
 
155
+ const HandleCommandDelegate &ReactCompositionViewComponentBuilder::CustomCommandHandler() const noexcept {
156
+ return m_customCommandHandler;
157
+ }
158
+
169
159
  void ReactCompositionViewComponentBuilder::SetFinalizeUpdateHandler(UpdateFinalizerDelegate impl) noexcept {
170
160
  m_finalizeUpdateHandler = impl;
171
161
  }
172
162
 
163
+ const UpdateFinalizerDelegate &ReactCompositionViewComponentBuilder::FinalizeUpdateHandler() const noexcept {
164
+ return m_finalizeUpdateHandler;
165
+ }
166
+
173
167
  void ReactCompositionViewComponentBuilder::SetUpdatePropsHandler(UpdatePropsDelegate impl) noexcept {
174
168
  m_updatePropsHandler = impl;
175
169
  }
176
170
 
171
+ const winrt::Microsoft::ReactNative::UpdatePropsDelegate &ReactCompositionViewComponentBuilder::UpdatePropsHandler()
172
+ const noexcept {
173
+ return m_updatePropsHandler;
174
+ }
175
+
177
176
  void ReactCompositionViewComponentBuilder::SetUpdateStateHandler(UpdateStateDelegate impl) noexcept {
178
177
  m_updateStateHandler = impl;
179
178
  }
180
179
 
180
+ const winrt::Microsoft::ReactNative::UpdateStateDelegate &ReactCompositionViewComponentBuilder::UpdateStateHandler()
181
+ const noexcept {
182
+ return m_updateStateHandler;
183
+ }
184
+
181
185
  void ReactCompositionViewComponentBuilder::SetUpdateEventEmitterHandler(UpdateEventEmitterDelegate impl) noexcept {
182
186
  m_updateEventEmitterHandler = impl;
183
187
  }
184
188
 
189
+ const UpdateEventEmitterDelegate &ReactCompositionViewComponentBuilder::UpdateEventEmitterHandler() const noexcept {
190
+ return m_updateEventEmitterHandler;
191
+ }
192
+
185
193
  void ReactCompositionViewComponentBuilder::SetMountChildComponentViewHandler(
186
194
  MountChildComponentViewDelegate impl) noexcept {
187
195
  m_mountChildComponentViewHandler = impl;
188
196
  }
189
197
 
198
+ const MountChildComponentViewDelegate &ReactCompositionViewComponentBuilder::MountChildComponentViewHandler()
199
+ const noexcept {
200
+ return m_mountChildComponentViewHandler;
201
+ }
202
+
190
203
  void ReactCompositionViewComponentBuilder::SetUnmountChildComponentViewHandler(
191
204
  UnmountChildComponentViewDelegate impl) noexcept {
192
205
  m_unmountChildComponentViewHandler = impl;
193
206
  }
194
207
 
208
+ const UnmountChildComponentViewDelegate &ReactCompositionViewComponentBuilder::UnmountChildComponentViewHandler()
209
+ const noexcept {
210
+ return m_unmountChildComponentViewHandler;
211
+ }
212
+
195
213
  void ReactCompositionViewComponentBuilder::SetCreateVisualHandler(CreateVisualDelegate impl) noexcept {
196
214
  m_createVisualHandler = impl;
197
215
  }
198
216
 
217
+ const CreateVisualDelegate &ReactCompositionViewComponentBuilder::CreateVisualHandler() const noexcept {
218
+ return m_createVisualHandler;
219
+ }
220
+
199
221
  void ReactCompositionViewComponentBuilder::SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept {
200
222
  m_features = viewFeatures;
201
223
  }
202
224
 
225
+ void ReactCompositionViewComponentBuilder::SetVisualToMountChildrenIntoHandler(
226
+ VisualToMountChildrenIntoDelegate impl) noexcept {
227
+ m_visualToMountChildrenIntoHandler = [impl](const winrt::Microsoft::ReactNative::ComponentView &view) {
228
+ return winrt::Microsoft::ReactNative::Composition::Experimental::implementation::MicrosoftCompositionContextHelper::
229
+ CreateVisual(impl(view));
230
+ };
231
+ }
232
+
233
+ void ReactCompositionViewComponentBuilder::SetIVisualToMountChildrenIntoHandler(
234
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate impl) noexcept {
235
+ m_visualToMountChildrenIntoHandler = impl;
236
+ }
237
+
238
+ const winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate &
239
+ ReactCompositionViewComponentBuilder::VisualToMountChildrenIntoHandler() const noexcept {
240
+ return m_visualToMountChildrenIntoHandler;
241
+ }
242
+
243
+ void ReactCompositionViewComponentBuilder::SetUpdateLayoutMetricsHandler(UpdateLayoutMetricsDelegate impl) noexcept {
244
+ m_updateLayoutMetricsHandler = impl;
245
+ }
246
+
247
+ const UpdateLayoutMetricsDelegate &ReactCompositionViewComponentBuilder::UpdateLayoutMetricsHandler() const noexcept {
248
+ return m_updateLayoutMetricsHandler;
249
+ }
250
+
203
251
  winrt::Microsoft::ReactNative::ComponentView ReactCompositionViewComponentBuilder::CreateView(
204
252
  const IReactContext &reactContext,
205
253
  int32_t tag,
206
254
  const Experimental::ICompositionContext &context) noexcept {
207
255
  assert(m_fnCreateView);
208
- auto view = m_fnCreateView(reactContext, tag, context, m_features);
256
+ auto view = m_fnCreateView(reactContext, tag, context, m_features, *this);
209
257
  InitializeComponentView(view);
210
258
  return view;
211
259
  }
@@ -44,6 +44,10 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
44
44
  void SetContentIslandComponentViewInitializer(const ComponentIslandComponentViewInitializer &initializer) noexcept;
45
45
  void SetCreateVisualHandler(CreateVisualDelegate impl) noexcept;
46
46
  void SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept;
47
+ void SetVisualToMountChildrenIntoHandler(VisualToMountChildrenIntoDelegate impl) noexcept;
48
+ void SetIVisualToMountChildrenIntoHandler(
49
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate impl) noexcept;
50
+ void SetUpdateLayoutMetricsHandler(UpdateLayoutMetricsDelegate impl) noexcept;
47
51
 
48
52
  public:
49
53
  IComponentProps CreateProps(ViewProps props, const IComponentProps &cloneFrom) noexcept;
@@ -60,6 +64,18 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
60
64
  facebook::react::Tag tag,
61
65
  const Experimental::ICompositionContext &context) noexcept;
62
66
 
67
+ const UpdateFinalizerDelegate &FinalizeUpdateHandler() const noexcept;
68
+ const HandleCommandDelegate &CustomCommandHandler() const noexcept;
69
+ const winrt::Microsoft::ReactNative::UpdatePropsDelegate &UpdatePropsHandler() const noexcept;
70
+ const winrt::Microsoft::ReactNative::UpdateStateDelegate &UpdateStateHandler() const noexcept;
71
+ const UpdateEventEmitterDelegate &UpdateEventEmitterHandler() const noexcept;
72
+ const MountChildComponentViewDelegate &MountChildComponentViewHandler() const noexcept;
73
+ const UnmountChildComponentViewDelegate &UnmountChildComponentViewHandler() const noexcept;
74
+ const UpdateLayoutMetricsDelegate &UpdateLayoutMetricsHandler() const noexcept;
75
+ const CreateVisualDelegate &CreateVisualHandler() const noexcept;
76
+ const winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate &
77
+ VisualToMountChildrenIntoHandler() const noexcept;
78
+
63
79
  private:
64
80
  void InitializeComponentView(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
65
81
 
@@ -74,7 +90,8 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
74
90
  const IReactContext &reactContext,
75
91
  int32_t tag,
76
92
  const Experimental::ICompositionContext &context,
77
- ComponentViewFeatures features)>
93
+ ComponentViewFeatures features,
94
+ ReactCompositionViewComponentBuilder &builder)>
78
95
  m_fnCreateView;
79
96
  std::function<facebook::react::ComponentDescriptorConstructor *()> m_descriptorConstructorFactory;
80
97
  winrt::Microsoft::ReactNative::HandleCommandDelegate m_customCommandHandler;
@@ -86,6 +103,9 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
86
103
  winrt::Microsoft::ReactNative::UnmountChildComponentViewDelegate m_unmountChildComponentViewHandler;
87
104
 
88
105
  winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate m_createVisualHandler;
106
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisualToMountChildrenIntoDelegate
107
+ m_visualToMountChildrenIntoHandler;
108
+ UpdateLayoutMetricsDelegate m_updateLayoutMetricsHandler;
89
109
  };
90
110
 
91
111
  } // namespace winrt::Microsoft::ReactNative::Composition
@@ -1258,4 +1258,14 @@ std::string ScrollViewComponentView::DefaultControlType() const noexcept {
1258
1258
  return "scrollbar";
1259
1259
  }
1260
1260
 
1261
+ winrt::com_ptr<ComponentView> ScrollViewComponentView::focusVisualRoot(
1262
+ const facebook::react::Rect &focusRect) noexcept {
1263
+ return get_strong();
1264
+ }
1265
+
1266
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual
1267
+ ScrollViewComponentView::visualToHostFocus() noexcept {
1268
+ return m_scrollVisual;
1269
+ }
1270
+
1261
1271
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -110,6 +110,9 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
110
110
  bool lineRight(bool animate) noexcept;
111
111
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept override;
112
112
 
113
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual visualToHostFocus() noexcept override;
114
+ winrt::com_ptr<ComponentView> focusVisualRoot(const facebook::react::Rect &focusRect) noexcept override;
115
+
113
116
  private:
114
117
  void updateContentVisualSize() noexcept;
115
118
  bool scrollToEnd(bool animate) noexcept;
@@ -165,6 +165,10 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
165
165
 
166
166
  //@cmember Show the caret
167
167
  BOOL TxShowCaret(BOOL fShow) override {
168
+ // Only show the caret if we have focus
169
+ if (fShow && !m_outer->m_hasFocus) {
170
+ return false;
171
+ }
168
172
  m_outer->ShowCaret(m_outer->windowsTextInputProps().caretHidden ? false : fShow);
169
173
  return true;
170
174
  }
@@ -232,7 +236,7 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
232
236
 
233
237
  //@cmember Establish a new cursor shape
234
238
  void TxSetCursor(HCURSOR hcur, BOOL fText) override {
235
- assert(false);
239
+ m_outer->m_hcursor = hcur;
236
240
  }
237
241
 
238
242
  //@cmember Converts screen coordinates of a specified point to the client coordinates
@@ -728,6 +732,9 @@ void WindowsTextInputComponentView::OnPointerMoved(
728
732
  auto hr = m_textServices->TxSendMessage(msg, static_cast<WPARAM>(wParam), static_cast<LPARAM>(lParam), &lresult);
729
733
  args.Handled(hr != S_FALSE);
730
734
  }
735
+
736
+ m_textServices->OnTxSetCursor(
737
+ DVASPECT_CONTENT, -1, nullptr, nullptr, nullptr, nullptr, nullptr, ptContainer.x, ptContainer.y);
731
738
  }
732
739
 
733
740
  void WindowsTextInputComponentView::OnKeyDown(
@@ -915,6 +922,7 @@ void WindowsTextInputComponentView::UnmountChildComponentView(
915
922
 
916
923
  void WindowsTextInputComponentView::onLostFocus(
917
924
  const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
925
+ m_hasFocus = false;
918
926
  Super::onLostFocus(args);
919
927
  if (m_textServices) {
920
928
  LRESULT lresult;
@@ -926,6 +934,7 @@ void WindowsTextInputComponentView::onLostFocus(
926
934
 
927
935
  void WindowsTextInputComponentView::onGotFocus(
928
936
  const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
937
+ m_hasFocus = true;
929
938
  Super::onGotFocus(args);
930
939
  if (m_textServices) {
931
940
  LRESULT lresult;
@@ -1473,6 +1482,10 @@ WindowsTextInputComponentView::createVisual() noexcept {
1473
1482
  return visual;
1474
1483
  }
1475
1484
 
1485
+ std::pair<facebook::react::Cursor, HCURSOR> WindowsTextInputComponentView::cursor() const noexcept {
1486
+ return {viewProps()->cursor, m_hcursor};
1487
+ }
1488
+
1476
1489
  void WindowsTextInputComponentView::onThemeChanged() noexcept {
1477
1490
  const auto &props = windowsTextInputProps();
1478
1491
  updateCursorColor(props.cursorColor, props.textAttributes.foregroundColor);
@@ -78,6 +78,8 @@ struct WindowsTextInputComponentView
78
78
 
79
79
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept;
80
80
 
81
+ std::pair<facebook::react::Cursor, HCURSOR> cursor() const noexcept override;
82
+
81
83
  private:
82
84
  struct DrawBlock {
83
85
  DrawBlock(WindowsTextInputComponentView &view);
@@ -128,10 +130,12 @@ struct WindowsTextInputComponentView
128
130
  int m_cDrawBlock{0};
129
131
  bool m_needsRedraw{false};
130
132
  bool m_drawing{false};
133
+ bool m_hasFocus{false};
131
134
  bool m_clearTextOnSubmit{false};
132
135
  bool m_multiline{false};
133
136
  DWORD m_propBitsMask{0};
134
137
  DWORD m_propBits{0};
138
+ HCURSOR m_hcursor{nullptr};
135
139
  std::vector<facebook::react::CompWindowsTextInputSubmitKeyEventsStruct> m_submitKeyEvents;
136
140
  };
137
141
 
@@ -26,7 +26,7 @@ UnimplementedNativeViewComponentView::UnimplementedNativeViewComponentView(
26
26
  ~(ComponentViewFeatures::Background | ComponentViewFeatures::ShadowProps |
27
27
  ComponentViewFeatures::NativeBorder)) {
28
28
  m_labelVisual = compContext.CreateSpriteVisual();
29
- OuterVisual().InsertAt(m_labelVisual, 1);
29
+ OuterVisual().InsertAt(m_labelVisual, 0);
30
30
  }
31
31
 
32
32
  winrt::Microsoft::ReactNative::ComponentView UnimplementedNativeViewComponentView::Create(