react-native-windows 0.81.1 → 0.81.3

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 (59) hide show
  1. package/Libraries/Components/Pressable/Pressable.d.ts +8 -0
  2. package/Libraries/Components/Pressable/Pressable.windows.js +21 -2
  3. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +26 -0
  4. package/Microsoft.ReactNative/Fabric/ComponentView.h +2 -0
  5. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +0 -1
  6. package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +2 -5
  7. package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +1 -4
  8. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +65 -32
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +9 -0
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +8 -0
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +2 -1
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +4 -7
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +1 -5
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +68 -53
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +1 -5
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +18 -14
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +10 -3
  18. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +30 -8
  19. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +4 -1
  20. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +3 -2
  21. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +0 -1
  22. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +550 -4
  23. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +52 -0
  24. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +8 -0
  25. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +3 -0
  26. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +53 -2
  27. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +8 -1
  28. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +0 -1
  29. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +0 -1
  30. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +3 -1
  31. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +6 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +1 -1
  33. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +28 -10
  34. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +0 -1
  35. package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +1 -1
  36. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.h +2 -1
  37. package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +8 -0
  38. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
  39. package/Microsoft.ReactNative/Utils/IcuUtils.cpp +84 -0
  40. package/Microsoft.ReactNative/Utils/IcuUtils.h +42 -0
  41. package/Microsoft.ReactNative.Cxx/StructInfo.h +8 -1
  42. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  43. package/Shared/Shared.vcxitems +1 -0
  44. package/Shared/Shared.vcxitems.filters +1 -0
  45. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +14 -0
  46. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +14 -0
  47. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +14 -0
  48. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +14 -0
  49. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +14 -0
  50. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +14 -0
  51. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +14 -0
  52. package/codegen/react/components/rnwcore/InputAccessory.g.h +14 -0
  53. package/codegen/react/components/rnwcore/ModalHostView.g.h +14 -0
  54. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +14 -0
  55. package/codegen/react/components/rnwcore/SafeAreaView.g.h +14 -0
  56. package/codegen/react/components/rnwcore/Switch.g.h +14 -0
  57. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +14 -0
  58. package/codegen/react/components/rnwcore/VirtualView.g.h +14 -0
  59. package/package.json +4 -4
@@ -120,6 +120,14 @@ export interface PressableProps
120
120
  */
121
121
  disabled?: null | boolean | undefined;
122
122
 
123
+ //[ Windows
124
+ /**
125
+ * When the pressable is pressed it will take focus
126
+ * Default value: true
127
+ */
128
+ focusOnPress?: null | boolean | undefined;
129
+ // Windows]
130
+
123
131
  /**
124
132
  * Additional distance outside of this view in which a press is detected.
125
133
  */
@@ -71,6 +71,14 @@ type PressableBaseProps = $ReadOnly<{
71
71
  */
72
72
  disabled?: ?boolean,
73
73
 
74
+ // [Windows
75
+ /**
76
+ * When the pressable is pressed it will take focus
77
+ * Default value: true
78
+ */
79
+ focusOnPress?: ?boolean,
80
+ // Windows]
81
+
74
82
  /**
75
83
  * Additional distance outside of this view in which a press is detected.
76
84
  */
@@ -238,6 +246,7 @@ function Pressable({
238
246
  delayLongPress,
239
247
  disabled,
240
248
  focusable,
249
+ focusOnPress, // Windows
241
250
  hitSlop,
242
251
  onBlur,
243
252
  onFocus,
@@ -309,6 +318,16 @@ function Pressable({
309
318
  hitSlop,
310
319
  };
311
320
 
321
+ const onPressWithFocus = React.useCallback(
322
+ (args: GestureResponderEvent) => {
323
+ if (focusable !== false && focusOnPress !== false) {
324
+ viewRef?.current?.focus();
325
+ }
326
+ onPress?.(args);
327
+ },
328
+ [focusOnPress, onPress, focusable],
329
+ );
330
+
312
331
  const config = useMemo(
313
332
  () => ({
314
333
  cancelable,
@@ -325,7 +344,7 @@ function Pressable({
325
344
  onHoverIn,
326
345
  onHoverOut,
327
346
  onLongPress,
328
- onPress,
347
+ onPress: onPressWithFocus,
329
348
  onPressIn(event: GestureResponderEvent): void {
330
349
  if (android_rippleConfig != null) {
331
350
  android_rippleConfig.onPressIn(event);
@@ -369,7 +388,7 @@ function Pressable({
369
388
  onHoverIn,
370
389
  onHoverOut,
371
390
  onLongPress,
372
- onPress,
391
+ onPressWithFocus,
373
392
  onPressIn,
374
393
  onPressMove,
375
394
  onPressOut,
@@ -8,6 +8,7 @@
8
8
  #include "DynamicReader.h"
9
9
 
10
10
  #include "ComponentView.g.cpp"
11
+ #include "CreateAutomationPeerArgs.g.h"
11
12
  #include "LayoutMetricsChangedArgs.g.cpp"
12
13
  #include "MountChildComponentViewArgs.g.cpp"
13
14
  #include "UnmountChildComponentViewArgs.g.cpp"
@@ -641,7 +642,32 @@ facebook::react::Tag ComponentView::hitTest(
641
642
  return -1;
642
643
  }
643
644
 
645
+ struct CreateAutomationPeerArgs
646
+ : public winrt::Microsoft::ReactNative::implementation::CreateAutomationPeerArgsT<CreateAutomationPeerArgs> {
647
+ CreateAutomationPeerArgs(winrt::Windows::Foundation::IInspectable defaultAutomationPeer)
648
+ : m_defaultAutomationPeer(defaultAutomationPeer) {}
649
+
650
+ winrt::Windows::Foundation::IInspectable DefaultAutomationPeer() const noexcept {
651
+ return m_defaultAutomationPeer;
652
+ }
653
+
654
+ private:
655
+ winrt::Windows::Foundation::IInspectable m_defaultAutomationPeer;
656
+ };
657
+
644
658
  winrt::IInspectable ComponentView::EnsureUiaProvider() noexcept {
659
+ if (m_uiaProvider == nullptr) {
660
+ if (m_builder && m_builder->CreateAutomationPeerHandler()) {
661
+ m_uiaProvider = m_builder->CreateAutomationPeerHandler()(
662
+ *this, winrt::make<CreateAutomationPeerArgs>(CreateAutomationProvider()));
663
+ } else {
664
+ m_uiaProvider = CreateAutomationProvider();
665
+ }
666
+ }
667
+ return m_uiaProvider;
668
+ }
669
+
670
+ winrt::Windows::Foundation::IInspectable ComponentView::CreateAutomationProvider() noexcept {
645
671
  return nullptr;
646
672
  }
647
673
 
@@ -208,6 +208,7 @@ struct ComponentView
208
208
  virtual facebook::react::Tag
209
209
  hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept;
210
210
  virtual winrt::Windows::Foundation::IInspectable EnsureUiaProvider() noexcept;
211
+ virtual winrt::Windows::Foundation::IInspectable CreateAutomationProvider() noexcept;
211
212
  virtual std::optional<std::string> getAccessiblityValue() noexcept;
212
213
  virtual void setAcccessiblityValue(std::string &&value) noexcept;
213
214
  virtual bool getAcccessiblityIsReadOnly() noexcept;
@@ -265,6 +266,7 @@ struct ComponentView
265
266
  facebook::react::LayoutMetrics m_layoutMetrics;
266
267
  winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::ComponentView> m_children{
267
268
  winrt::single_threaded_vector<winrt::Microsoft::ReactNative::ComponentView>()};
269
+ winrt::Windows::Foundation::IInspectable m_uiaProvider{nullptr};
268
270
 
269
271
  winrt::event<
270
272
  winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs>>
@@ -4,7 +4,6 @@
4
4
  #pragma once
5
5
 
6
6
  #include "ActivityIndicatorComponentView.h"
7
- #include "CompositionDynamicAutomationProvider.h"
8
7
 
9
8
  #include <Windows.UI.Composition.h>
10
9
  #include <Windows.h>
@@ -8,11 +8,8 @@
8
8
  namespace winrt::Microsoft::ReactNative::implementation {
9
9
 
10
10
  CompositionAnnotationProvider::CompositionAnnotationProvider(
11
- const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
12
- CompositionDynamicAutomationProvider *parentProvider) noexcept
13
- : m_view{componentView} {
14
- m_parentProvider.copy_from(parentProvider);
15
- }
11
+ const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept
12
+ : m_view{componentView} {}
16
13
  HRESULT __stdcall CompositionAnnotationProvider::get_AnnotationTypeId(int *retVal) {
17
14
  if (retVal == nullptr)
18
15
  return E_POINTER;
@@ -1,6 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #include <Fabric/Composition/CompositionDynamicAutomationProvider.h>
4
3
  #include <Fabric/Composition/CompositionViewComponentView.h>
5
4
  #include <Fabric/ReactTaggedView.h>
6
5
  #include <UIAutomation.h>
@@ -12,8 +11,7 @@ namespace winrt::Microsoft::ReactNative::implementation {
12
11
  class CompositionAnnotationProvider : public winrt::implements<CompositionAnnotationProvider, IAnnotationProvider> {
13
12
  public:
14
13
  CompositionAnnotationProvider(
15
- const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
16
- CompositionDynamicAutomationProvider *parentProvider) noexcept;
14
+ const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept;
17
15
 
18
16
  // inherited via IAnnotationProvider
19
17
  virtual HRESULT __stdcall get_AnnotationTypeId(int *retVal) override;
@@ -25,7 +23,6 @@ class CompositionAnnotationProvider : public winrt::implements<CompositionAnnota
25
23
  private:
26
24
  ::Microsoft::ReactNative::ReactTaggedView m_view;
27
25
  winrt::com_ptr<IAnnotationProvider> m_annotationProvider;
28
- winrt::com_ptr<CompositionDynamicAutomationProvider> m_parentProvider;
29
26
  };
30
27
 
31
28
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -2,6 +2,7 @@
2
2
  #include "CompositionDynamicAutomationProvider.h"
3
3
  #include <Fabric/ComponentView.h>
4
4
  #include <Fabric/Composition/CompositionAnnotationProvider.h>
5
+ #include <Fabric/Composition/CompositionTextProvider.h>
5
6
  #include <Fabric/Composition/CompositionTextRangeProvider.h>
6
7
  #include <Fabric/Composition/ParagraphComponentView.h>
7
8
  #include <Fabric/Composition/ScrollViewComponentView.h>
@@ -45,19 +46,6 @@ CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider(
45
46
  if (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value()) {
46
47
  AddSelectionItemsToContainer(this);
47
48
  }
48
-
49
- if (strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
50
- strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>()) {
51
- m_textProvider = winrt::make<CompositionTextProvider>(
52
- strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), this)
53
- .try_as<ITextProvider2>();
54
- }
55
-
56
- if (strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ViewComponentView>()) {
57
- m_annotationProvider = winrt::make<CompositionAnnotationProvider>(
58
- strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), this)
59
- .try_as<IAnnotationProvider>();
60
- }
61
49
  }
62
50
 
63
51
  CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider(
@@ -161,6 +149,13 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::SetFocus(void) {
161
149
  return UiaSetFocusHelper(m_view);
162
150
  }
163
151
 
152
+ winrt::IUnknown CompositionDynamicAutomationProvider::TryGetChildSiteLinkAutomationProvider() {
153
+ if (m_childSiteLink) {
154
+ return m_childSiteLink.AutomationProvider().as<winrt::IUnknown>();
155
+ }
156
+ return nullptr;
157
+ }
158
+
164
159
  HRESULT __stdcall CompositionDynamicAutomationProvider::get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal) {
165
160
  if (pRetVal == nullptr)
166
161
  return E_POINTER;
@@ -297,16 +292,31 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
297
292
  if (patternId == UIA_TextPatternId &&
298
293
  (strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
299
294
  strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>())) {
295
+ if (!m_textProvider) {
296
+ m_textProvider = winrt::make<CompositionTextProvider>(
297
+ strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>())
298
+ .as<ITextProvider2>();
299
+ }
300
300
  m_textProvider.as<IUnknown>().copy_to(pRetVal);
301
301
  }
302
302
 
303
303
  if (patternId == UIA_TextPattern2Id &&
304
304
  strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>()) {
305
+ if (!m_textProvider) {
306
+ m_textProvider = winrt::make<CompositionTextProvider>(
307
+ strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>())
308
+ .as<ITextProvider2>();
309
+ }
305
310
  m_textProvider.as<IUnknown>().copy_to(pRetVal);
306
311
  }
307
312
  if (patternId == UIA_AnnotationPatternId &&
308
313
  strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ViewComponentView>() &&
309
314
  accessibilityAnnotationHasValue(props->accessibilityAnnotation)) {
315
+ if (!m_annotationProvider) {
316
+ m_annotationProvider = winrt::make<CompositionAnnotationProvider>(
317
+ strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>())
318
+ .as<IAnnotationProvider>();
319
+ }
310
320
  m_annotationProvider.as<IUnknown>().copy_to(pRetVal);
311
321
  }
312
322
 
@@ -949,9 +959,18 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetSelection(SAFEARRAY *
949
959
  std::vector<int> selectedItems;
950
960
  for (size_t i = 0; i < m_selectionItems.size(); i++) {
951
961
  auto selectionItem = m_selectionItems.at(i);
952
- auto provider = selectionItem.as<CompositionDynamicAutomationProvider>();
962
+
963
+ winrt::com_ptr<IUnknown> unkSelectionItemProvider;
964
+ auto hr = selectionItem->GetPatternProvider(UIA_SelectionItemPatternId, unkSelectionItemProvider.put());
965
+ if (FAILED(hr))
966
+ return hr;
967
+
968
+ auto selectionItemProvider = unkSelectionItemProvider.try_as<ISelectionItemProvider>();
969
+ if (!selectionItemProvider)
970
+ return E_FAIL;
971
+
953
972
  BOOL selected;
954
- auto hr = provider->get_IsSelected(&selected);
973
+ hr = selectionItemProvider->get_IsSelected(&selected);
955
974
  if (hr == S_OK && selected) {
956
975
  selectedItems.push_back(int(i));
957
976
  }
@@ -1010,27 +1029,28 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsSelected(BOOL *pRe
1010
1029
  return S_OK;
1011
1030
  }
1012
1031
 
1013
- IRawElementProviderSimple *findSelectionContainer(winrt::Microsoft::ReactNative::ComponentView current) {
1032
+ winrt::Microsoft::ReactNative::ComponentView findSelectionContainer(
1033
+ winrt::Microsoft::ReactNative::ComponentView current) noexcept {
1014
1034
  if (!current)
1015
1035
  return nullptr;
1016
1036
 
1017
- auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
1018
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(current)->props());
1019
- if (props->accessibilityState.has_value() && props->accessibilityState->multiselectable.has_value() &&
1020
- props->accessibilityState->required.has_value()) {
1021
- auto uiaProvider =
1022
- current.as<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>()->EnsureUiaProvider();
1023
- if (uiaProvider != nullptr) {
1024
- auto spProviderSimple = uiaProvider.try_as<IRawElementProviderSimple>();
1025
- if (spProviderSimple != nullptr) {
1026
- spProviderSimple->AddRef();
1027
- return spProviderSimple.get();
1028
- }
1037
+ if (auto viewbase = current.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>()) {
1038
+ auto props = viewbase->viewProps();
1039
+ if (props->accessibilityState.has_value() && props->accessibilityState->multiselectable.has_value() &&
1040
+ props->accessibilityState->required.has_value()) {
1041
+ return current;
1029
1042
  }
1030
- } else {
1031
- return findSelectionContainer(current.Parent());
1032
1043
  }
1033
- return nullptr;
1044
+ return findSelectionContainer(current.Parent());
1045
+ }
1046
+
1047
+ winrt::Microsoft::ReactNative::ComponentView CompositionDynamicAutomationProvider::GetSelectionContainer() noexcept {
1048
+ auto strongView = m_view.view();
1049
+
1050
+ if (!strongView)
1051
+ return nullptr;
1052
+
1053
+ return findSelectionContainer(strongView.Parent());
1034
1054
  }
1035
1055
 
1036
1056
  HRESULT __stdcall CompositionDynamicAutomationProvider::get_SelectionContainer(IRawElementProviderSimple **pRetVal) {
@@ -1041,7 +1061,20 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_SelectionContainer(I
1041
1061
  if (!strongView)
1042
1062
  return UIA_E_ELEMENTNOTAVAILABLE;
1043
1063
 
1044
- *pRetVal = findSelectionContainer(strongView.Parent());
1064
+ *pRetVal = nullptr;
1065
+
1066
+ auto selectionContainerView = GetSelectionContainer();
1067
+ auto uiaProvider =
1068
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(selectionContainerView)
1069
+ ->EnsureUiaProvider();
1070
+ if (uiaProvider != nullptr) {
1071
+ auto spProviderSimple = uiaProvider.try_as<IRawElementProviderSimple>();
1072
+ if (spProviderSimple != nullptr) {
1073
+ spProviderSimple->AddRef();
1074
+ *pRetVal = spProviderSimple.get();
1075
+ }
1076
+ }
1077
+
1045
1078
  return S_OK;
1046
1079
  }
1047
1080
 
@@ -97,6 +97,15 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
97
97
 
98
98
  void AddToSelectionItems(winrt::com_ptr<IRawElementProviderSimple> &item);
99
99
  void RemoveFromSelectionItems(winrt::com_ptr<IRawElementProviderSimple> &item);
100
+ winrt::Microsoft::ReactNative::ComponentView GetSelectionContainer() noexcept;
101
+
102
+ void SetChildSiteLink(winrt::Microsoft::UI::Content::ChildSiteLink childSiteLink) {
103
+ m_childSiteLink = childSiteLink;
104
+ }
105
+
106
+ // If this object is for a ChildSiteLink, returns the ChildSiteLink's automation provider.
107
+ // This will be a provider object from the hosted framework (for example, WinUI).
108
+ winrt::IUnknown TryGetChildSiteLinkAutomationProvider();
100
109
 
101
110
  private:
102
111
  ::Microsoft::ReactNative::ReactTaggedView m_view;
@@ -15,6 +15,7 @@
15
15
  #include <winrt/Windows.UI.Input.h>
16
16
  #include "Composition.Input.h"
17
17
  #include "CompositionViewComponentView.h"
18
+ #include "ParagraphComponentView.h"
18
19
  #include "ReactNativeIsland.h"
19
20
  #include "RootComponentView.h"
20
21
 
@@ -1101,6 +1102,13 @@ void CompositionEventHandler::onPointerExited(
1101
1102
  void CompositionEventHandler::onPointerPressed(
1102
1103
  const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
1103
1104
  winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
1105
+ namespace Composition = winrt::Microsoft::ReactNative::Composition;
1106
+
1107
+ // Clears any active text selection when left pointer is pressed
1108
+ if (pointerPoint.Properties().PointerUpdateKind() != Composition::Input::PointerUpdateKind::RightButtonPressed) {
1109
+ RootComponentView().ClearCurrentTextSelection();
1110
+ }
1111
+
1104
1112
  PointerId pointerId = pointerPoint.PointerId();
1105
1113
 
1106
1114
  auto staleTouch = std::find_if(m_activeTouches.begin(), m_activeTouches.end(), [pointerId](const auto &pair) {
@@ -219,7 +219,8 @@ HRESULT __stdcall CompositionRootAutomationProvider::ElementProviderFromPoint(
219
219
  auto local = rootView->ConvertScreenToLocal({static_cast<float>(x), static_cast<float>(y)});
220
220
  auto provider = rootView->UiaProviderFromPoint(
221
221
  {static_cast<LONG>(local.X * rootView->LayoutMetrics().PointScaleFactor),
222
- static_cast<LONG>(local.Y * rootView->LayoutMetrics().PointScaleFactor)});
222
+ static_cast<LONG>(local.Y * rootView->LayoutMetrics().PointScaleFactor)},
223
+ {static_cast<LONG>(x), static_cast<LONG>(y)});
223
224
  auto spFragment = provider.try_as<IRawElementProviderFragment>();
224
225
  if (spFragment) {
225
226
  *pRetVal = spFragment.detach();
@@ -10,10 +10,8 @@
10
10
  namespace winrt::Microsoft::ReactNative::implementation {
11
11
 
12
12
  CompositionTextProvider::CompositionTextProvider(
13
- const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
14
- CompositionDynamicAutomationProvider *parentProvider) noexcept
13
+ const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept
15
14
  : m_view{componentView} {
16
- m_parentProvider.copy_from(parentProvider);
17
15
  EnsureTextRangeProvider();
18
16
  }
19
17
 
@@ -24,10 +22,9 @@ void CompositionTextProvider::EnsureTextRangeProvider() {
24
22
  return;
25
23
 
26
24
  if (!m_textRangeProvider) {
27
- m_textRangeProvider =
28
- winrt::make<CompositionTextRangeProvider>(
29
- strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), m_parentProvider.get())
30
- .try_as<ITextRangeProvider>();
25
+ m_textRangeProvider = winrt::make<CompositionTextRangeProvider>(
26
+ strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>())
27
+ .as<ITextRangeProvider>();
31
28
  }
32
29
  }
33
30
 
@@ -1,6 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #include <Fabric/Composition/CompositionDynamicAutomationProvider.h>
4
3
  #include <Fabric/Composition/CompositionViewComponentView.h>
5
4
  #include <Fabric/ReactTaggedView.h>
6
5
  #include <UIAutomation.h>
@@ -11,9 +10,7 @@ namespace winrt::Microsoft::ReactNative::implementation {
11
10
 
12
11
  class CompositionTextProvider : public winrt::implements<CompositionTextProvider, ITextProvider, ITextProvider2> {
13
12
  public:
14
- CompositionTextProvider(
15
- const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
16
- CompositionDynamicAutomationProvider *parentProvider) noexcept;
13
+ CompositionTextProvider(const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept;
17
14
 
18
15
  // inherited via ITextProvider
19
16
  virtual HRESULT __stdcall get_DocumentRange(ITextRangeProvider **pRetVal) override;
@@ -35,7 +32,6 @@ class CompositionTextProvider : public winrt::implements<CompositionTextProvider
35
32
  private:
36
33
  ::Microsoft::ReactNative::ReactTaggedView m_view;
37
34
  winrt::com_ptr<ITextRangeProvider> m_textRangeProvider;
38
- winrt::com_ptr<CompositionDynamicAutomationProvider> m_parentProvider;
39
35
  };
40
36
 
41
37
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -11,18 +11,14 @@
11
11
  namespace winrt::Microsoft::ReactNative::implementation {
12
12
 
13
13
  CompositionTextRangeProvider::CompositionTextRangeProvider(
14
- const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
15
- CompositionDynamicAutomationProvider *parentProvider) noexcept
16
- : m_view{componentView} {
17
- m_parentProvider.copy_from(parentProvider);
18
- }
14
+ const winrt::Microsoft::ReactNative::ComponentView &componentView) noexcept
15
+ : m_view{componentView} {}
19
16
 
20
17
  HRESULT __stdcall CompositionTextRangeProvider::Clone(ITextRangeProvider **pRetVal) {
21
18
  if (pRetVal == nullptr)
22
19
  return E_POINTER;
23
20
 
24
- auto clone = winrt::make<winrt::Microsoft::ReactNative::implementation::CompositionTextRangeProvider>(
25
- m_view.view().as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), m_parentProvider.get());
21
+ auto clone = winrt::make<winrt::Microsoft::ReactNative::implementation::CompositionTextRangeProvider>(m_view.view());
26
22
  *pRetVal = clone.detach();
27
23
  return S_OK;
28
24
  }
@@ -91,13 +87,13 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
91
87
  if (!strongView)
92
88
  return UIA_E_ELEMENTNOTAVAILABLE;
93
89
 
94
- auto props = std::static_pointer_cast<const facebook::react::ParagraphProps>(
90
+ auto props = std::static_pointer_cast<const facebook::react::BaseViewProps>(
95
91
  winrt::get_self<ComponentView>(strongView)->props());
96
92
 
97
- auto textinputProps = std::static_pointer_cast<const facebook::react::WindowsTextInputProps>(
98
- winrt::get_self<ComponentView>(strongView)->props());
93
+ auto asParagraph =
94
+ strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>();
99
95
 
100
- auto isTextInput =
96
+ auto asTextInput =
101
97
  strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>();
102
98
 
103
99
  if (props == nullptr)
@@ -106,15 +102,16 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
106
102
  if (attributeId == UIA_BackgroundColorAttributeId) {
107
103
  pRetVal->vt = VT_I4;
108
104
  pRetVal->lVal = (*props->backgroundColor).AsColorRefWithAlpha();
109
- } else if (attributeId == UIA_CapStyleAttributeId) {
105
+ } else if (attributeId == UIA_CapStyleAttributeId && asParagraph) {
110
106
  pRetVal->vt = VT_I4;
111
107
  auto fontVariant = facebook::react::FontVariant::Default;
112
108
  auto textTransform = facebook::react::TextTransform::None;
113
- if (props->textAttributes.fontVariant.has_value()) {
114
- fontVariant = props->textAttributes.fontVariant.value();
109
+
110
+ if (asParagraph->paragraphProps().textAttributes.fontVariant.has_value()) {
111
+ fontVariant = asParagraph->paragraphProps().textAttributes.fontVariant.value();
115
112
  }
116
- if (props->textAttributes.textTransform.has_value()) {
117
- textTransform = props->textAttributes.textTransform.value();
113
+ if (asParagraph->paragraphProps().textAttributes.textTransform.has_value()) {
114
+ textTransform = asParagraph->paragraphProps().textAttributes.textTransform.value();
118
115
  }
119
116
  if (fontVariant == facebook::react::FontVariant::SmallCaps) {
120
117
  pRetVal->lVal = CapStyle_SmallCap;
@@ -125,39 +122,44 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
125
122
  } else if (textTransform == facebook::react::TextTransform::Uppercase) {
126
123
  pRetVal->lVal = CapStyle_AllCap;
127
124
  }
128
- } else if (attributeId == UIA_FontNameAttributeId) {
125
+ } else if (attributeId == UIA_FontNameAttributeId && asParagraph) {
129
126
  pRetVal->vt = VT_BSTR;
130
- auto fontName = props->textAttributes.fontFamily;
127
+ auto fontName = asParagraph->paragraphProps().textAttributes.fontFamily;
131
128
  if (fontName.empty()) {
132
129
  fontName = "Segoe UI";
133
130
  }
134
131
  std::wstring wfontName(fontName.begin(), fontName.end());
135
132
  pRetVal->bstrVal = SysAllocString(wfontName.c_str());
136
- } else if (attributeId == UIA_FontSizeAttributeId) {
133
+ } else if (attributeId == UIA_FontSizeAttributeId && asParagraph) {
137
134
  pRetVal->vt = VT_R8;
138
- pRetVal->dblVal = props->textAttributes.fontSize;
139
- } else if (attributeId == UIA_FontWeightAttributeId) {
140
- if (props->textAttributes.fontWeight.has_value()) {
135
+ pRetVal->dblVal = asParagraph->paragraphProps().textAttributes.fontSize;
136
+ } else if (attributeId == UIA_FontWeightAttributeId && asParagraph) {
137
+ if (asParagraph->paragraphProps().textAttributes.fontWeight.has_value()) {
141
138
  pRetVal->vt = VT_I4;
142
- pRetVal->lVal = static_cast<long>(props->textAttributes.fontWeight.value());
139
+ pRetVal->lVal = static_cast<long>(asParagraph->paragraphProps().textAttributes.fontWeight.value());
143
140
  }
144
- } else if (attributeId == UIA_ForegroundColorAttributeId) {
141
+ } else if (attributeId == UIA_ForegroundColorAttributeId && asParagraph) {
145
142
  pRetVal->vt = VT_I4;
146
- pRetVal->lVal = (*props->textAttributes.foregroundColor).AsColorRefWithAlpha();
147
- } else if (attributeId == UIA_IsItalicAttributeId) {
143
+ pRetVal->lVal = (*asParagraph->paragraphProps().textAttributes.foregroundColor).AsColorRefWithAlpha();
144
+ } else if (attributeId == UIA_IsItalicAttributeId && asParagraph) {
148
145
  pRetVal->vt = VT_BOOL;
149
- pRetVal->boolVal = (props->textAttributes.fontStyle.has_value() &&
150
- props->textAttributes.fontStyle.value() == facebook::react::FontStyle::Italic)
146
+ pRetVal->boolVal =
147
+ (asParagraph->paragraphProps().textAttributes.fontStyle.has_value() &&
148
+ asParagraph->paragraphProps().textAttributes.fontStyle.value() == facebook::react::FontStyle::Italic)
151
149
  ? VARIANT_TRUE
152
150
  : VARIANT_FALSE;
153
151
  } else if (attributeId == UIA_IsReadOnlyAttributeId) {
154
152
  pRetVal->vt = VT_BOOL;
155
- pRetVal->boolVal = isTextInput ? textinputProps->editable ? VARIANT_FALSE : VARIANT_TRUE : VARIANT_TRUE;
156
- } else if (attributeId == UIA_HorizontalTextAlignmentAttributeId) {
153
+ if (asTextInput) {
154
+ pRetVal->boolVal = asTextInput->windowsTextInputProps().editable ? VARIANT_FALSE : VARIANT_TRUE;
155
+ } else {
156
+ pRetVal->boolVal = VARIANT_TRUE;
157
+ }
158
+ } else if (attributeId == UIA_HorizontalTextAlignmentAttributeId && asParagraph) {
157
159
  pRetVal->vt = VT_I4;
158
160
  auto textAlign = facebook::react::TextAlignment::Center;
159
- if (props->textAttributes.alignment.has_value()) {
160
- textAlign = props->textAttributes.alignment.value();
161
+ if (asParagraph->paragraphProps().textAttributes.alignment.has_value()) {
162
+ textAlign = asParagraph->paragraphProps().textAttributes.alignment.value();
161
163
  }
162
164
  if (textAlign == facebook::react::TextAlignment::Left) {
163
165
  pRetVal->lVal = HorizontalTextAlignment_Left;
@@ -170,40 +172,42 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
170
172
  } else if (textAlign == facebook::react::TextAlignment::Natural) {
171
173
  pRetVal->lVal = HorizontalTextAlignment_Left;
172
174
  }
173
- } else if (attributeId == UIA_StrikethroughColorAttributeId) {
174
- if (props->textAttributes.textDecorationLineType.has_value() &&
175
- (props->textAttributes.textDecorationLineType.value() ==
175
+ } else if (attributeId == UIA_StrikethroughColorAttributeId && asParagraph) {
176
+ if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
177
+ (asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
176
178
  facebook::react::TextDecorationLineType::Strikethrough ||
177
- props->textAttributes.textDecorationLineType.value() ==
179
+ asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
178
180
  facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
179
181
  pRetVal->vt = VT_I4;
180
- pRetVal->lVal = (*props->textAttributes.textDecorationColor).AsColorRefWithAlpha();
182
+ pRetVal->lVal = (*asParagraph->paragraphProps().textAttributes.textDecorationColor).AsColorRefWithAlpha();
181
183
  }
182
- } else if (attributeId == UIA_StrikethroughStyleAttributeId) {
183
- if (props->textAttributes.textDecorationLineType.has_value() &&
184
- (props->textAttributes.textDecorationLineType.value() ==
184
+ } else if (attributeId == UIA_StrikethroughStyleAttributeId && asParagraph) {
185
+ if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
186
+ (asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
185
187
  facebook::react::TextDecorationLineType::Strikethrough ||
186
- props->textAttributes.textDecorationLineType.value() ==
188
+ asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
187
189
  facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
188
190
  pRetVal->vt = VT_I4;
189
- auto style = props->textAttributes.textDecorationStyle.value();
191
+ auto style = asParagraph->paragraphProps().textAttributes.textDecorationStyle.value();
190
192
  pRetVal->lVal = GetTextDecorationLineStyle(style);
191
193
  }
192
- } else if (attributeId == UIA_UnderlineColorAttributeId) {
193
- if (props->textAttributes.textDecorationLineType.has_value() &&
194
- (props->textAttributes.textDecorationLineType.value() == facebook::react::TextDecorationLineType::Underline ||
195
- props->textAttributes.textDecorationLineType.value() ==
194
+ } else if (attributeId == UIA_UnderlineColorAttributeId && asParagraph) {
195
+ if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
196
+ (asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
197
+ facebook::react::TextDecorationLineType::Underline ||
198
+ asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
196
199
  facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
197
200
  pRetVal->vt = VT_I4;
198
- pRetVal->lVal = (*props->textAttributes.textDecorationColor).AsColorRefWithAlpha();
201
+ pRetVal->lVal = (*asParagraph->paragraphProps().textAttributes.textDecorationColor).AsColorRefWithAlpha();
199
202
  }
200
- } else if (attributeId == UIA_UnderlineStyleAttributeId) {
201
- if (props->textAttributes.textDecorationLineType.has_value() &&
202
- (props->textAttributes.textDecorationLineType.value() == facebook::react::TextDecorationLineType::Underline ||
203
- props->textAttributes.textDecorationLineType.value() ==
203
+ } else if (attributeId == UIA_UnderlineStyleAttributeId && asParagraph) {
204
+ if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
205
+ (asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
206
+ facebook::react::TextDecorationLineType::Underline ||
207
+ asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
204
208
  facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
205
209
  pRetVal->vt = VT_I4;
206
- auto style = props->textAttributes.textDecorationStyle.value();
210
+ auto style = asParagraph->paragraphProps().textAttributes.textDecorationStyle.value();
207
211
  pRetVal->lVal = GetTextDecorationLineStyle(style);
208
212
  }
209
213
  }
@@ -214,7 +218,18 @@ HRESULT __stdcall CompositionTextRangeProvider::GetBoundingRectangles(SAFEARRAY
214
218
  if (pRetVal == nullptr)
215
219
  return E_POINTER;
216
220
  UiaRect rect;
217
- auto hr = m_parentProvider->get_BoundingRectangle(&rect);
221
+
222
+ auto strongView = m_view.view();
223
+ if (!strongView)
224
+ return UIA_E_ELEMENTNOTAVAILABLE;
225
+
226
+ auto componentView = strongView.as<winrt::Microsoft::ReactNative::implementation::ComponentView>();
227
+ auto provider = componentView->EnsureUiaProvider();
228
+ auto repf = provider.try_as<IRawElementProviderFragment>();
229
+ if (!repf)
230
+ return E_FAIL;
231
+
232
+ auto hr = repf->get_BoundingRectangle(&rect);
218
233
  if (FAILED(hr))
219
234
  return hr;
220
235
  *pRetVal = SafeArrayCreateVector(VT_R8, 0, 4);