react-native-windows 0.74.28 → 0.74.30
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.
- package/Libraries/Components/Button.windows.js +9 -0
- package/Libraries/Components/Pressable/Pressable.windows.js +9 -0
- package/Libraries/Components/TextInput/TextInput.windows.js +11 -1
- package/Libraries/Components/Touchable/TouchableBounce.windows.js +225 -0
- package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +373 -0
- package/Libraries/Components/Touchable/TouchableOpacity.windows.js +7 -0
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +10 -0
- package/Libraries/Components/View/View.windows.js +11 -1
- package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
- package/Libraries/Components/View/ViewAccessibility.windows.js +5 -2
- package/Libraries/Components/View/ViewPropTypes.windows.js +3 -0
- package/Libraries/Image/Image.windows.js +7 -0
- package/Libraries/Text/Text.windows.js +11 -1
- package/Libraries/Text/TextProps.windows.js +3 -0
- package/Microsoft.ReactNative/CompositionComponentView.idl +13 -1
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +1 -2
- package/Microsoft.ReactNative/Fabric/ComponentView.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +0 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +293 -9
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +28 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +13 -32
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +1 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +18 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +191 -329
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +3 -61
- package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +66 -0
- package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.h +52 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +21 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +7 -4
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +79 -19
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -6
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +71 -17
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +16 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +62 -33
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +5 -2
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +1 -6
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +0 -3
- package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -2
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +5 -0
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +19 -1
- package/Microsoft.ReactNative/ReactNativeHost.cpp +5 -0
- package/Microsoft.ReactNative/ReactNativeIsland.idl +5 -1
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +6 -2
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +253 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +799 -0
- package/Shared/Shared.vcxitems +3 -2
- package/Shared/Shared.vcxitems.filters +2 -3
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +204 -0
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +287 -0
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +192 -0
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +216 -0
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +242 -0
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +259 -0
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +226 -0
- package/codegen/react/components/rnwcore/InputAccessory.g.h +192 -0
- package/codegen/react/components/rnwcore/ModalHostView.g.h +271 -0
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +238 -0
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +189 -0
- package/codegen/react/components/rnwcore/Switch.g.h +255 -0
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +192 -0
- package/just-task.js +1 -1
- package/package.json +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentDescriptor.h +0 -39
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.cpp +0 -18
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.h +0 -39
|
@@ -235,6 +235,13 @@ class TouchableOpacity extends React.Component<Props, State> {
|
|
|
235
235
|
this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded,
|
|
236
236
|
selected:
|
|
237
237
|
this.props['aria-selected'] ?? this.props.accessibilityState?.selected,
|
|
238
|
+
readOnly:
|
|
239
|
+
this.props['aria-readonly'] ?? this.props.accessibilityState?.readOnly, // Windows
|
|
240
|
+
multiselectable:
|
|
241
|
+
this.props['aria-multiselectable'] ??
|
|
242
|
+
this.props.accessibilityState?.multiselectable, // Windows
|
|
243
|
+
required:
|
|
244
|
+
this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows
|
|
238
245
|
};
|
|
239
246
|
|
|
240
247
|
_accessibilityState =
|
|
@@ -59,6 +59,9 @@ type Props = $ReadOnly<{|
|
|
|
59
59
|
'aria-disabled'?: ?boolean,
|
|
60
60
|
'aria-expanded'?: ?boolean,
|
|
61
61
|
'aria-selected'?: ?boolean,
|
|
62
|
+
'aria-readonly'?: ?boolean, // Windows
|
|
63
|
+
'aria-multiselectable'?: ?boolean, // Windows
|
|
64
|
+
'aria-required'?: ?boolean, // Windows
|
|
62
65
|
'aria-hidden'?: ?boolean,
|
|
63
66
|
'aria-live'?: ?('polite' | 'assertive' | 'off'),
|
|
64
67
|
'aria-label'?: ?Stringish,
|
|
@@ -158,6 +161,13 @@ class TouchableWithoutFeedback extends React.Component<Props, State> {
|
|
|
158
161
|
this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded,
|
|
159
162
|
selected:
|
|
160
163
|
this.props['aria-selected'] ?? this.props.accessibilityState?.selected,
|
|
164
|
+
readonly:
|
|
165
|
+
this.props['aria-readonly'] ?? this.props.accessibilityState?.readOnly, // Windows
|
|
166
|
+
multiselectable:
|
|
167
|
+
this.props['aria-multiselectable'] ??
|
|
168
|
+
this.props.accessibilityState?.multiselectable, // Windows
|
|
169
|
+
required:
|
|
170
|
+
this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows
|
|
161
171
|
};
|
|
162
172
|
|
|
163
173
|
// BACKWARD-COMPATIBILITY: Focus and blur events were never supported before
|
|
@@ -47,12 +47,15 @@ const View: React.AbstractComponent<
|
|
|
47
47
|
'aria-checked': ariaChecked,
|
|
48
48
|
'aria-disabled': ariaDisabled,
|
|
49
49
|
'aria-expanded': ariaExpanded,
|
|
50
|
+
'aria-multiselectable': ariaMultiselectable, // Windows
|
|
51
|
+
'aria-required': ariaRequired, // Windows
|
|
50
52
|
'aria-hidden': ariaHidden,
|
|
51
53
|
'aria-label': ariaLabel,
|
|
52
54
|
'aria-labelledby': ariaLabelledBy,
|
|
53
55
|
'aria-level': ariaLevel,
|
|
54
56
|
'aria-live': ariaLive,
|
|
55
57
|
'aria-posinset': ariaPosinset, // Windows
|
|
58
|
+
'aria-readonly': ariaReadOnly, // Windows
|
|
56
59
|
'aria-selected': ariaSelected,
|
|
57
60
|
'aria-setsize': ariaSetsize, // Windows
|
|
58
61
|
'aria-valuemax': ariaValueMax,
|
|
@@ -80,7 +83,10 @@ const View: React.AbstractComponent<
|
|
|
80
83
|
ariaChecked != null ||
|
|
81
84
|
ariaDisabled != null ||
|
|
82
85
|
ariaExpanded != null ||
|
|
83
|
-
ariaSelected != null
|
|
86
|
+
ariaSelected != null ||
|
|
87
|
+
ariaReadOnly != null || // Windows
|
|
88
|
+
ariaMultiselectable != null || // Windows
|
|
89
|
+
ariaRequired != null // Windows
|
|
84
90
|
) {
|
|
85
91
|
_accessibilityState = {
|
|
86
92
|
busy: ariaBusy ?? accessibilityState?.busy,
|
|
@@ -88,6 +94,10 @@ const View: React.AbstractComponent<
|
|
|
88
94
|
disabled: ariaDisabled ?? accessibilityState?.disabled,
|
|
89
95
|
expanded: ariaExpanded ?? accessibilityState?.expanded,
|
|
90
96
|
selected: ariaSelected ?? accessibilityState?.selected,
|
|
97
|
+
readOnly: ariaReadOnly ?? accessibilityState?.readOnly, // Windows
|
|
98
|
+
multiselectable:
|
|
99
|
+
ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows
|
|
100
|
+
required: ariaRequired ?? accessibilityState?.required, // Windows
|
|
91
101
|
};
|
|
92
102
|
}
|
|
93
103
|
let _accessibilityValue;
|
|
@@ -183,6 +183,21 @@ export interface AccessibilityState {
|
|
|
183
183
|
* When present, informs accessible tools the element is expanded or collapsed
|
|
184
184
|
*/
|
|
185
185
|
expanded?: boolean | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* When present, informs accessible tools the element is read only
|
|
188
|
+
* @platform windows
|
|
189
|
+
*/
|
|
190
|
+
readOnly?: boolean | undefined;
|
|
191
|
+
/**
|
|
192
|
+
* When present, informs accessible tools the element can have multiple items selected
|
|
193
|
+
* @platform windows
|
|
194
|
+
*/
|
|
195
|
+
multiselectable?: boolean | undefined;
|
|
196
|
+
/**
|
|
197
|
+
* When present, informs accessible tools the element requires selection
|
|
198
|
+
* @platform windows
|
|
199
|
+
*/
|
|
200
|
+
required?: boolean | undefined;
|
|
186
201
|
}
|
|
187
202
|
|
|
188
203
|
export interface AccessibilityValue {
|
|
@@ -179,8 +179,11 @@ export type AccessibilityState = {
|
|
|
179
179
|
disabled?: boolean,
|
|
180
180
|
selected?: boolean,
|
|
181
181
|
checked?: ?boolean | 'mixed',
|
|
182
|
-
busy?: boolean,
|
|
183
|
-
expanded?: boolean,
|
|
182
|
+
busy?: ?boolean,
|
|
183
|
+
expanded?: ?boolean,
|
|
184
|
+
readOnly?: ?boolean, // Windows
|
|
185
|
+
multiselectable?: ?boolean, // Windows
|
|
186
|
+
required?: ?boolean, // Windows
|
|
184
187
|
...
|
|
185
188
|
};
|
|
186
189
|
|
|
@@ -606,12 +606,15 @@ export type ViewProps = $ReadOnly<{|
|
|
|
606
606
|
'aria-disabled'?: ?boolean,
|
|
607
607
|
'aria-expanded'?: ?boolean,
|
|
608
608
|
'aria-selected'?: ?boolean,
|
|
609
|
+
'aria-readonly'?: ?boolean, // Windows
|
|
609
610
|
/** A value indicating whether the accessibility elements contained within
|
|
610
611
|
* this accessibility element are hidden.
|
|
611
612
|
*
|
|
612
613
|
* See https://reactnative.dev/docs/view#aria-hidden
|
|
613
614
|
*/
|
|
614
615
|
'aria-hidden'?: ?boolean,
|
|
616
|
+
'aria-multiselectable'?: ?boolean, // Windows
|
|
617
|
+
'aria-required'?: ?boolean, // Windows
|
|
615
618
|
|
|
616
619
|
/**
|
|
617
620
|
* Views that are only used to layout their children or otherwise don't draw
|
|
@@ -148,6 +148,9 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => {
|
|
|
148
148
|
'aria-disabled': ariaDisabled,
|
|
149
149
|
'aria-expanded': ariaExpanded,
|
|
150
150
|
'aria-selected': ariaSelected,
|
|
151
|
+
'aria-readonly': ariaReadOnly, // Windows
|
|
152
|
+
'aria-multiselectable': ariaMultiselectable, // Windows
|
|
153
|
+
'aria-required': ariaRequired, // Windows
|
|
151
154
|
height,
|
|
152
155
|
src,
|
|
153
156
|
width,
|
|
@@ -160,6 +163,10 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => {
|
|
|
160
163
|
disabled: ariaDisabled ?? props.accessibilityState?.disabled,
|
|
161
164
|
expanded: ariaExpanded ?? props.accessibilityState?.expanded,
|
|
162
165
|
selected: ariaSelected ?? props.accessibilityState?.selected,
|
|
166
|
+
readOnly: ariaReadOnly ?? props.accessibilityState?.readOnly, // Windows
|
|
167
|
+
multiselectable:
|
|
168
|
+
ariaMultiselectable ?? props.accessibilityState?.multiselectable, // Windows
|
|
169
|
+
required: ariaRequired ?? props.accessibilityState?.required, // Windows
|
|
163
170
|
};
|
|
164
171
|
const accessibilityLabel = props['aria-label'] ?? props.accessibilityLabel;
|
|
165
172
|
|
|
@@ -46,11 +46,14 @@ const Text: React.AbstractComponent<
|
|
|
46
46
|
'aria-checked': ariaChecked,
|
|
47
47
|
'aria-disabled': ariaDisabled,
|
|
48
48
|
'aria-expanded': ariaExpanded,
|
|
49
|
+
'aria-multiselectable': ariaMultiselectable, // Windows
|
|
50
|
+
'aria-required': ariaRequired, // Windows
|
|
49
51
|
'aria-label': ariaLabel,
|
|
50
52
|
'aria-level': ariaLevel, // Windows
|
|
51
53
|
'aria-posinset': ariaPosinset, // Windows
|
|
52
54
|
'aria-setsize': ariaSetsize, // Windows
|
|
53
55
|
'aria-selected': ariaSelected,
|
|
56
|
+
'aria-readonly': ariaReadOnly, //Windows
|
|
54
57
|
ellipsizeMode,
|
|
55
58
|
id,
|
|
56
59
|
nativeID,
|
|
@@ -78,7 +81,10 @@ const Text: React.AbstractComponent<
|
|
|
78
81
|
ariaChecked != null ||
|
|
79
82
|
ariaDisabled != null ||
|
|
80
83
|
ariaExpanded != null ||
|
|
81
|
-
ariaSelected != null
|
|
84
|
+
ariaSelected != null ||
|
|
85
|
+
ariaReadOnly != null || // Windows
|
|
86
|
+
ariaMultiselectable != null || // Windows
|
|
87
|
+
ariaRequired != null // Windows
|
|
82
88
|
) {
|
|
83
89
|
_accessibilityState = {
|
|
84
90
|
busy: ariaBusy ?? accessibilityState?.busy,
|
|
@@ -86,6 +92,10 @@ const Text: React.AbstractComponent<
|
|
|
86
92
|
disabled: ariaDisabled ?? accessibilityState?.disabled,
|
|
87
93
|
expanded: ariaExpanded ?? accessibilityState?.expanded,
|
|
88
94
|
selected: ariaSelected ?? accessibilityState?.selected,
|
|
95
|
+
readOnly: ariaReadOnly ?? accessibilityState?.readOnly, // Windows
|
|
96
|
+
multiselectable:
|
|
97
|
+
ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows
|
|
98
|
+
required: ariaRequired ?? accessibilityState?.required, // Windows
|
|
89
99
|
};
|
|
90
100
|
}
|
|
91
101
|
|
|
@@ -97,6 +97,9 @@ export type TextProps = $ReadOnly<{|
|
|
|
97
97
|
'aria-posinset'?: ?number, // Windows
|
|
98
98
|
'aria-setsize'?: ?number, // Windows
|
|
99
99
|
'aria-level'?: ?number, // Windows
|
|
100
|
+
'aria-readonly'?: ?boolean, // Windows
|
|
101
|
+
'aria-multiselectable'?: ?boolean, // Windows
|
|
102
|
+
'aria-required'?: ?boolean, // Windows
|
|
100
103
|
|
|
101
104
|
/**
|
|
102
105
|
* Represents the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.
|
|
@@ -7,6 +7,7 @@ import "ViewProps.idl";
|
|
|
7
7
|
import "Composition.Input.idl";
|
|
8
8
|
import "CompositionSwitcher.idl";
|
|
9
9
|
import "IReactContext.idl";
|
|
10
|
+
import "ReactNativeIsland.idl";
|
|
10
11
|
|
|
11
12
|
#include "DocString.h"
|
|
12
13
|
|
|
@@ -110,8 +111,19 @@ namespace Microsoft.ReactNative.Composition
|
|
|
110
111
|
[default_interface]
|
|
111
112
|
runtimeclass RootComponentView : ViewComponentView {
|
|
112
113
|
Microsoft.ReactNative.ComponentView GetFocusedComponent();
|
|
114
|
+
Microsoft.ReactNative.ReactNativeIsland ReactNativeIsland { get; };
|
|
115
|
+
DOC_STRING("Is non-null if this RootComponentView is the content of a portal")
|
|
116
|
+
PortalComponentView Portal { get; };
|
|
113
117
|
};
|
|
114
|
-
|
|
118
|
+
|
|
119
|
+
[experimental]
|
|
120
|
+
[webhosthidden]
|
|
121
|
+
[default_interface]
|
|
122
|
+
DOC_STRING("Used to implement UI that is hosted outside the main UI tree, such as modal.")
|
|
123
|
+
runtimeclass PortalComponentView : Microsoft.ReactNative.ComponentView {
|
|
124
|
+
RootComponentView ContentRoot { get; };
|
|
125
|
+
};
|
|
126
|
+
|
|
115
127
|
[experimental]
|
|
116
128
|
[webhosthidden]
|
|
117
129
|
[default_interface]
|
|
@@ -639,11 +639,10 @@ facebook::react::Tag ComponentView::hitTest(
|
|
|
639
639
|
}
|
|
640
640
|
|
|
641
641
|
winrt::IInspectable ComponentView::EnsureUiaProvider() noexcept {
|
|
642
|
-
assert(false);
|
|
643
642
|
return nullptr;
|
|
644
643
|
}
|
|
645
644
|
|
|
646
|
-
std::optional<std::string> ComponentView::
|
|
645
|
+
std::optional<std::string> ComponentView::getAccessiblityValue() noexcept {
|
|
647
646
|
return std::nullopt;
|
|
648
647
|
}
|
|
649
648
|
|
|
@@ -207,7 +207,7 @@ struct ComponentView
|
|
|
207
207
|
virtual facebook::react::Tag
|
|
208
208
|
hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept;
|
|
209
209
|
virtual winrt::IInspectable EnsureUiaProvider() noexcept;
|
|
210
|
-
virtual std::optional<std::string>
|
|
210
|
+
virtual std::optional<std::string> getAccessiblityValue() noexcept;
|
|
211
211
|
virtual void setAcccessiblityValue(std::string &&value) noexcept;
|
|
212
212
|
virtual bool getAcccessiblityIsReadOnly() noexcept;
|
|
213
213
|
virtual ToggleState getToggleState() noexcept;
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
#include <Fabric/Composition/CompositionViewComponentView.h>
|
|
16
16
|
#include <Fabric/Composition/DebuggingOverlayComponentView.h>
|
|
17
17
|
#include <Fabric/Composition/ImageComponentView.h>
|
|
18
|
-
#include <Fabric/Composition/Modal/WindowsModalHostViewComponentView.h>
|
|
19
|
-
#include <Fabric/Composition/Modal/WindowsModalHostViewShadowNode.h>
|
|
20
18
|
#include <Fabric/Composition/ParagraphComponentView.h>
|
|
21
19
|
#include <Fabric/Composition/RootComponentView.h>
|
|
22
20
|
#include <Fabric/Composition/ScrollViewComponentView.h>
|
|
@@ -59,9 +57,6 @@ ComponentViewDescriptor const &ComponentViewRegistry::dequeueComponentViewWithCo
|
|
|
59
57
|
} else if (componentHandle == facebook::react::ImageShadowNode::Handle()) {
|
|
60
58
|
view = winrt::Microsoft::ReactNative::Composition::implementation::ImageComponentView::Create(
|
|
61
59
|
compContext, tag, m_context);
|
|
62
|
-
} else if (componentHandle == facebook::react::WindowsModalHostViewShadowNode::Handle()) {
|
|
63
|
-
view = winrt::Microsoft::ReactNative::Composition::implementation::WindowsModalHostComponentView::Create(
|
|
64
|
-
compContext, tag, m_context);
|
|
65
60
|
} else if (componentHandle == facebook::react::WindowsTextInputShadowNode::Handle()) {
|
|
66
61
|
view = winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView::Create(
|
|
67
62
|
compContext, tag, m_context);
|
|
@@ -11,7 +11,21 @@ namespace winrt::Microsoft::ReactNative::implementation {
|
|
|
11
11
|
|
|
12
12
|
CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider(
|
|
13
13
|
const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept
|
|
14
|
-
: m_view{componentView} {
|
|
14
|
+
: m_view{componentView} {
|
|
15
|
+
auto strongView = m_view.view();
|
|
16
|
+
|
|
17
|
+
if (!strongView)
|
|
18
|
+
return;
|
|
19
|
+
|
|
20
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
21
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
22
|
+
if (!props)
|
|
23
|
+
return;
|
|
24
|
+
|
|
25
|
+
if (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value()) {
|
|
26
|
+
AddSelectionItemsToContainer(this);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
15
29
|
|
|
16
30
|
HRESULT __stdcall CompositionDynamicAutomationProvider::Navigate(
|
|
17
31
|
NavigateDirection direction,
|
|
@@ -127,8 +141,12 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_ProviderOptions(Prov
|
|
|
127
141
|
return S_OK;
|
|
128
142
|
}
|
|
129
143
|
|
|
130
|
-
bool
|
|
131
|
-
return
|
|
144
|
+
bool accessibilityValueHasTextValue(const facebook::react::AccessibilityValue &value) {
|
|
145
|
+
return value.text.has_value();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
bool accessibilityValueHasNumericValue(const facebook::react::AccessibilityValue &value) {
|
|
149
|
+
return (value.min.has_value() && value.max.has_value() && value.now.has_value());
|
|
132
150
|
}
|
|
133
151
|
|
|
134
152
|
bool expandableControl(const facebook::react::SharedViewProps props) {
|
|
@@ -171,7 +189,6 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
171
189
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
172
190
|
if (props == nullptr)
|
|
173
191
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
174
|
-
auto accessibilityRole = props->accessibilityRole;
|
|
175
192
|
// Invoke control pattern is used to support controls that do not maintain state
|
|
176
193
|
// when activated but rather initiate or perform a single, unambiguous action.
|
|
177
194
|
if (patternId == UIA_InvokePatternId && (props->onAccessibilityTap)) {
|
|
@@ -185,8 +202,15 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
185
202
|
}
|
|
186
203
|
|
|
187
204
|
if (patternId == UIA_ValuePatternId &&
|
|
188
|
-
(strongView
|
|
189
|
-
|
|
205
|
+
((strongView
|
|
206
|
+
.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() &&
|
|
207
|
+
!accessibilityValueHasNumericValue(props->accessibilityValue)) ||
|
|
208
|
+
accessibilityValueHasTextValue(props->accessibilityValue))) {
|
|
209
|
+
*pRetVal = static_cast<IValueProvider *>(this);
|
|
210
|
+
AddRef();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (patternId == UIA_RangeValuePatternId && accessibilityValueHasNumericValue(props->accessibilityValue)) {
|
|
190
214
|
*pRetVal = static_cast<IValueProvider *>(this);
|
|
191
215
|
AddRef();
|
|
192
216
|
}
|
|
@@ -203,6 +227,18 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
203
227
|
AddRef();
|
|
204
228
|
}
|
|
205
229
|
|
|
230
|
+
if (patternId == UIA_SelectionPatternId && props->accessibilityState.has_value() &&
|
|
231
|
+
props->accessibilityState->multiselectable.has_value() && props->accessibilityState->required.has_value()) {
|
|
232
|
+
*pRetVal = static_cast<ISelectionProvider *>(this);
|
|
233
|
+
AddRef();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (patternId == UIA_SelectionItemPatternId && props->accessibilityState.has_value() &&
|
|
237
|
+
props->accessibilityState->selected.has_value()) {
|
|
238
|
+
*pRetVal = static_cast<ISelectionItemProvider *>(this);
|
|
239
|
+
AddRef();
|
|
240
|
+
}
|
|
241
|
+
|
|
206
242
|
return S_OK;
|
|
207
243
|
}
|
|
208
244
|
|
|
@@ -346,6 +382,7 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
|
|
|
346
382
|
case UIA_IsOffscreenPropertyId: {
|
|
347
383
|
pRetVal->vt = VT_BOOL;
|
|
348
384
|
pRetVal->boolVal = (compositionView->getClipState() == ClipState::FullyClipped) ? VARIANT_TRUE : VARIANT_FALSE;
|
|
385
|
+
break;
|
|
349
386
|
}
|
|
350
387
|
case UIA_HelpTextPropertyId: {
|
|
351
388
|
pRetVal->vt = VT_BSTR;
|
|
@@ -454,6 +491,8 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::SetValue(LPCWSTR val) {
|
|
|
454
491
|
|
|
455
492
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)
|
|
456
493
|
->setAcccessiblityValue(winrt::to_string(val));
|
|
494
|
+
// TODO: Edit once/if onAccessibilityAction props supports returning UIA event data. See
|
|
495
|
+
// https://github.com/react-native-community/discussions-and-proposals/issues/843.
|
|
457
496
|
DispatchAccessibilityAction(m_view, "setValue");
|
|
458
497
|
return S_OK;
|
|
459
498
|
}
|
|
@@ -467,7 +506,7 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_Value(BSTR *pRetVal)
|
|
|
467
506
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
468
507
|
|
|
469
508
|
*pRetVal = StringToBSTR(winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)
|
|
470
|
-
->
|
|
509
|
+
->getAccessiblityValue()
|
|
471
510
|
.value_or(""));
|
|
472
511
|
return S_OK;
|
|
473
512
|
}
|
|
@@ -480,8 +519,88 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsReadOnly(BOOL *pRe
|
|
|
480
519
|
if (!strongView)
|
|
481
520
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
482
521
|
|
|
483
|
-
|
|
484
|
-
|
|
522
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
523
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
524
|
+
if (props == nullptr)
|
|
525
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
526
|
+
auto accessibilityRole = props->accessibilityRole;
|
|
527
|
+
if (props->accessibilityState.has_value() && props->accessibilityState->readOnly.has_value()) {
|
|
528
|
+
*pRetVal = props->accessibilityState->readOnly.value();
|
|
529
|
+
} else {
|
|
530
|
+
// Use default IsReadOnly value.
|
|
531
|
+
*pRetVal = false;
|
|
532
|
+
}
|
|
533
|
+
return S_OK;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_LargeChange(double *pRetVal) {
|
|
537
|
+
// no-op
|
|
538
|
+
return S_OK;
|
|
539
|
+
}
|
|
540
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_Maximum(double *pRetVal) {
|
|
541
|
+
if (pRetVal == nullptr)
|
|
542
|
+
return E_POINTER;
|
|
543
|
+
auto strongView = m_view.view();
|
|
544
|
+
|
|
545
|
+
if (!strongView)
|
|
546
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
547
|
+
|
|
548
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
549
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
550
|
+
|
|
551
|
+
if (props == nullptr)
|
|
552
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
553
|
+
|
|
554
|
+
*pRetVal = props->accessibilityValue.max.value();
|
|
555
|
+
return S_OK;
|
|
556
|
+
}
|
|
557
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_Minimum(double *pRetVal) {
|
|
558
|
+
if (pRetVal == nullptr)
|
|
559
|
+
return E_POINTER;
|
|
560
|
+
auto strongView = m_view.view();
|
|
561
|
+
|
|
562
|
+
if (!strongView)
|
|
563
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
564
|
+
|
|
565
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
566
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
567
|
+
|
|
568
|
+
if (props == nullptr)
|
|
569
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
570
|
+
|
|
571
|
+
*pRetVal = props->accessibilityValue.min.value();
|
|
572
|
+
return S_OK;
|
|
573
|
+
}
|
|
574
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_SmallChange(double *pRetVal) {
|
|
575
|
+
// no-op
|
|
576
|
+
return S_OK;
|
|
577
|
+
}
|
|
578
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_Value(double *pRetVal) {
|
|
579
|
+
if (pRetVal == nullptr)
|
|
580
|
+
return E_POINTER;
|
|
581
|
+
auto strongView = m_view.view();
|
|
582
|
+
|
|
583
|
+
if (!strongView)
|
|
584
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
585
|
+
|
|
586
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
587
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
588
|
+
|
|
589
|
+
if (props == nullptr)
|
|
590
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
591
|
+
|
|
592
|
+
*pRetVal = props->accessibilityValue.now.value();
|
|
593
|
+
return S_OK;
|
|
594
|
+
}
|
|
595
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::SetValue(double val) {
|
|
596
|
+
auto strongView = m_view.view();
|
|
597
|
+
|
|
598
|
+
if (!strongView)
|
|
599
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
600
|
+
|
|
601
|
+
// TODO: Edit once/if onAccessibilityAction props supports returning UIA event data. See
|
|
602
|
+
// https://github.com/react-native-community/discussions-and-proposals/issues/843.
|
|
603
|
+
DispatchAccessibilityAction(m_view, "setValue");
|
|
485
604
|
return S_OK;
|
|
486
605
|
}
|
|
487
606
|
|
|
@@ -552,4 +671,169 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::Collapse() {
|
|
|
552
671
|
return S_OK;
|
|
553
672
|
}
|
|
554
673
|
|
|
674
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_CanSelectMultiple(BOOL *pRetVal) {
|
|
675
|
+
if (pRetVal == nullptr)
|
|
676
|
+
return E_POINTER;
|
|
677
|
+
auto strongView = m_view.view();
|
|
678
|
+
|
|
679
|
+
if (!strongView)
|
|
680
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
681
|
+
|
|
682
|
+
auto props =
|
|
683
|
+
std::static_pointer_cast<const facebook::react::ViewProps>(winrt::get_self<ComponentView>(strongView)->props());
|
|
684
|
+
|
|
685
|
+
if (props == nullptr)
|
|
686
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
687
|
+
|
|
688
|
+
*pRetVal = (props->accessibilityState.has_value() && props->accessibilityState->multiselectable.has_value())
|
|
689
|
+
? props->accessibilityState->multiselectable.value()
|
|
690
|
+
: false;
|
|
691
|
+
|
|
692
|
+
return S_OK;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsSelectionRequired(BOOL *pRetVal) {
|
|
696
|
+
if (pRetVal == nullptr)
|
|
697
|
+
return E_POINTER;
|
|
698
|
+
auto strongView = m_view.view();
|
|
699
|
+
|
|
700
|
+
if (!strongView)
|
|
701
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
702
|
+
|
|
703
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
704
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
705
|
+
|
|
706
|
+
if (props == nullptr)
|
|
707
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
708
|
+
|
|
709
|
+
*pRetVal = (props->accessibilityState.has_value() && props->accessibilityState->required.has_value())
|
|
710
|
+
? props->accessibilityState->required.value()
|
|
711
|
+
: false;
|
|
712
|
+
|
|
713
|
+
return S_OK;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::GetSelection(SAFEARRAY **pRetVal) {
|
|
717
|
+
auto strongView = m_view.view();
|
|
718
|
+
|
|
719
|
+
if (!strongView)
|
|
720
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
721
|
+
|
|
722
|
+
std::vector<int> selectedItems;
|
|
723
|
+
for (size_t i = 0; i < m_selectionItems.size(); i++) {
|
|
724
|
+
auto selectionItem = m_selectionItems.at(i);
|
|
725
|
+
auto provider = selectionItem.as<CompositionDynamicAutomationProvider>();
|
|
726
|
+
BOOL selected;
|
|
727
|
+
auto hr = provider->get_IsSelected(&selected);
|
|
728
|
+
if (hr == S_OK && selected) {
|
|
729
|
+
selectedItems.push_back(int(i));
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, ULONG(selectedItems.size()));
|
|
734
|
+
if (*pRetVal == nullptr)
|
|
735
|
+
return E_OUTOFMEMORY;
|
|
736
|
+
|
|
737
|
+
for (size_t i = 0; i < selectedItems.size(); i++) {
|
|
738
|
+
auto pos = static_cast<long>(i);
|
|
739
|
+
SafeArrayPutElement(*pRetVal, &pos, m_selectionItems.at(selectedItems.at(i)).get());
|
|
740
|
+
}
|
|
741
|
+
return S_OK;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
void CompositionDynamicAutomationProvider::AddToSelectionItems(winrt::com_ptr<IRawElementProviderSimple> &item) {
|
|
745
|
+
if (std::find(m_selectionItems.begin(), m_selectionItems.end(), item) != m_selectionItems.end()) {
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
m_selectionItems.push_back(item);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
void CompositionDynamicAutomationProvider::RemoveFromSelectionItems(winrt::com_ptr<IRawElementProviderSimple> &item) {
|
|
752
|
+
std::erase(m_selectionItems, item);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::AddToSelection() {
|
|
756
|
+
auto strongView = m_view.view();
|
|
757
|
+
|
|
758
|
+
if (!strongView)
|
|
759
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
760
|
+
|
|
761
|
+
DispatchAccessibilityAction(m_view, "addToSelection");
|
|
762
|
+
return S_OK;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsSelected(BOOL *pRetVal) {
|
|
766
|
+
if (pRetVal == nullptr)
|
|
767
|
+
return E_POINTER;
|
|
768
|
+
auto strongView = m_view.view();
|
|
769
|
+
|
|
770
|
+
if (!strongView)
|
|
771
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
772
|
+
|
|
773
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
774
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
|
|
775
|
+
|
|
776
|
+
if (props == nullptr)
|
|
777
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
778
|
+
|
|
779
|
+
*pRetVal = (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value())
|
|
780
|
+
? props->accessibilityState->selected.value()
|
|
781
|
+
: false;
|
|
782
|
+
|
|
783
|
+
return S_OK;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
IRawElementProviderSimple *findSelectionContainer(winrt::Microsoft::ReactNative::ComponentView current) {
|
|
787
|
+
if (!current)
|
|
788
|
+
return nullptr;
|
|
789
|
+
|
|
790
|
+
auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
|
|
791
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(current)->props());
|
|
792
|
+
if (props->accessibilityState.has_value() && props->accessibilityState->multiselectable.has_value() &&
|
|
793
|
+
props->accessibilityState->required.has_value()) {
|
|
794
|
+
auto uiaProvider =
|
|
795
|
+
current.as<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>()->EnsureUiaProvider();
|
|
796
|
+
if (uiaProvider != nullptr) {
|
|
797
|
+
auto spProviderSimple = uiaProvider.try_as<IRawElementProviderSimple>();
|
|
798
|
+
if (spProviderSimple != nullptr) {
|
|
799
|
+
spProviderSimple->AddRef();
|
|
800
|
+
return spProviderSimple.get();
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
} else {
|
|
804
|
+
return findSelectionContainer(current.Parent());
|
|
805
|
+
}
|
|
806
|
+
return nullptr;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::get_SelectionContainer(IRawElementProviderSimple **pRetVal) {
|
|
810
|
+
if (pRetVal == nullptr)
|
|
811
|
+
return E_POINTER;
|
|
812
|
+
auto strongView = m_view.view();
|
|
813
|
+
|
|
814
|
+
if (!strongView)
|
|
815
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
816
|
+
|
|
817
|
+
*pRetVal = findSelectionContainer(strongView.Parent());
|
|
818
|
+
return S_OK;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::RemoveFromSelection() {
|
|
822
|
+
auto strongView = m_view.view();
|
|
823
|
+
|
|
824
|
+
if (!strongView)
|
|
825
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
826
|
+
DispatchAccessibilityAction(m_view, "removeFromSelection");
|
|
827
|
+
return S_OK;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
HRESULT __stdcall CompositionDynamicAutomationProvider::Select() {
|
|
831
|
+
auto strongView = m_view.view();
|
|
832
|
+
|
|
833
|
+
if (!strongView)
|
|
834
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
835
|
+
DispatchAccessibilityAction(m_view, "select");
|
|
836
|
+
return S_OK;
|
|
837
|
+
}
|
|
838
|
+
|
|
555
839
|
} // namespace winrt::Microsoft::ReactNative::implementation
|