From d429f4f99690602159a221634cffc2b1936f74da Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:07:42 -0800 Subject: [PATCH] Implement ISelectionProvider and ISelectionItemProvider (#14019) Adds support for ISelectionProvider interface Adds support for ISelectionItemProvider interface Adds support for accessibilityState:selected Adjusts AccessibilityState native type on Windows to be std::optional instead of bool Adjusts AccessibilityState native type on Windows to include multiselectable and required fields of type std::optional Adds multiselectable and required fields to AccessibilityState type in JS with type boolean | undefined Adds support for aria-multiselectable and aria-required. Adds support for the following accessibilityActions: addToSelection, removeFromSelection, select Fixes crash in AccessibilityInsights. --- ...-a7e4e9a7-38af-4609-a0a4-152046e6e53b.json | 7 + .../AccessibilityExampleWindows.tsx | 61 +- .../test/AccessibilityTest.test.ts | 62 + .../AccessibilityTest.test.ts.snap | 449 + .../__snapshots__/snapshotPages.test.js.snap | 79884 +++++++++------- .../RNTesterApp-Fabric/RNTesterApp-Fabric.cpp | 35 +- .../CompositionDynamicAutomationProvider.cpp | 194 +- .../CompositionDynamicAutomationProvider.h | 20 +- .../CompositionViewComponentView.cpp | 13 + .../Fabric/Composition/UiaHelpers.cpp | 24 + .../Fabric/Composition/UiaHelpers.h | 5 + .../components/view/AccessibilityPrimitives.h | 252 + .../view/accessibilityPropsConversions.h | 795 + vnext/overrides.json | 37 + .../Libraries/Components/Button.windows.js | 6 + .../Components/Pressable/Pressable.windows.js | 6 + .../Components/TextInput/TextInput.windows.js | 9 +- .../Touchable/TouchableBounce.windows.js | 227 + .../TouchableNativeFeedback.windows.js | 371 + .../Touchable/TouchableOpacity.windows.js | 5 + .../TouchableWithoutFeedback.windows.js | 6 + .../Libraries/Components/View/View.windows.js | 9 +- .../Components/View/ViewAccessibility.d.ts | 10 + .../View/ViewAccessibility.windows.js | 6 +- .../Components/View/ViewPropTypes.windows.js | 2 + .../src-win/Libraries/Image/Image.windows.js | 5 + vnext/src-win/Libraries/Text/Text.windows.js | 9 +- .../Libraries/Text/TextProps.windows.js | 2 + 28 files changed, 49658 insertions(+), 32853 deletions(-) create mode 100644 change/react-native-windows-a7e4e9a7-38af-4609-a0a4-152046e6e53b.json create mode 100644 packages/e2e-test-app-fabric/test/AccessibilityTest.test.ts create mode 100644 packages/e2e-test-app-fabric/test/__snapshots__/AccessibilityTest.test.ts.snap create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h create mode 100644 vnext/src-win/Libraries/Components/Touchable/TouchableBounce.windows.js create mode 100644 vnext/src-win/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js diff --git a/change/react-native-windows-a7e4e9a7-38af-4609-a0a4-152046e6e53b.json b/change/react-native-windows-a7e4e9a7-38af-4609-a0a4-152046e6e53b.json new file mode 100644 index 00000000000..c0f555b2bba --- /dev/null +++ b/change/react-native-windows-a7e4e9a7-38af-4609-a0a4-152046e6e53b.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Implement ISelectionProvider and ISelectionItemProvider", + "packageName": "react-native-windows", + "email": "34109996+chiaramooney@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/@react-native-windows/tester/src/js/examples-win/Accessibility/AccessibilityExampleWindows.tsx b/packages/@react-native-windows/tester/src/js/examples-win/Accessibility/AccessibilityExampleWindows.tsx index a9924e7cfeb..b148c49a33e 100644 --- a/packages/@react-native-windows/tester/src/js/examples-win/Accessibility/AccessibilityExampleWindows.tsx +++ b/packages/@react-native-windows/tester/src/js/examples-win/Accessibility/AccessibilityExampleWindows.tsx @@ -312,33 +312,40 @@ class AccessibilityStateExamples extends React.Component { The following list of TouchableHighlights toggles accessibilityState.selected when touched: - ( - this.selectPress(item.index)}> - - {this.state.itemsSelected[item.index] - ? 'Selected' - : 'Unselected'} - - - )} - keyExtractor={(item, index) => index.toString()} - /> + + ( + this.selectPress(item.index)}> + + {this.state.itemsSelected[item.index] + ? 'Selected' + : 'Unselected'} + + + )} + keyExtractor={(item, index) => index.toString()} + /> + The following TouchableHighlight cycles accessibilityState.checked through unchecked/checked/mixed for the View under it: diff --git a/packages/e2e-test-app-fabric/test/AccessibilityTest.test.ts b/packages/e2e-test-app-fabric/test/AccessibilityTest.test.ts new file mode 100644 index 00000000000..62be53287d6 --- /dev/null +++ b/packages/e2e-test-app-fabric/test/AccessibilityTest.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * @format + */ + +import {dumpVisualTree} from '@react-native-windows/automation-commands'; +import {goToApiExample} from './RNTesterNavigation'; +import {app} from '@react-native-windows/automation'; +import {verifyNoErrorLogs} from './Helpers'; + +beforeAll(async () => { + // If window is partially offscreen, tests will fail to click on certain elements + await app.setWindowPosition(0, 0); + await app.setWindowSize(1000, 1250); + await goToApiExample('Accessibility Windows'); +}); + +afterEach(async () => { + await verifyNoErrorLogs(); +}); + +const searchBox = async (input: string) => { + const searchBox = await app.findElementByTestID('example_search'); + await app.waitUntil( + async () => { + await searchBox.setValue(input); + return (await searchBox.getText()) === input; + }, + { + interval: 1500, + timeout: 5000, + timeoutMsg: `Unable to enter correct search text into test searchbox.`, + }, + ); +}; + +describe('Accessibility Tests', () => { + test('Elements can set accessibilityState:selected to false', async () => { + await searchBox('Sta'); + const component = await app.findElementByTestID('Selectable item 1'); + await component.waitForDisplayed({timeout: 5000}); + const dump = await dumpVisualTree('Selectable item 1'); + expect(dump).toMatchSnapshot(); + }); + test('Elements can set accessibilityState:selected to true', async () => { + await searchBox('Sta'); + const component = await app.findElementByTestID('Selectable item 1'); + await component.waitForDisplayed({timeout: 5000}); + await component.click(); + const dump = await dumpVisualTree('Selectable item 1'); + expect(dump).toMatchSnapshot(); + }); + test('Selectable items must have a Selection Container. Elements can set accessibilityState:multiselectable and accessibilityState:required to true', async () => { + await searchBox('Sta'); + const componentsTab = await app.findElementByTestID('selection-container'); + await componentsTab.waitForDisplayed({timeout: 5000}); + const dump = await dumpVisualTree('selection-container'); + expect(dump).toMatchSnapshot(); + }); +}); diff --git a/packages/e2e-test-app-fabric/test/__snapshots__/AccessibilityTest.test.ts.snap b/packages/e2e-test-app-fabric/test/__snapshots__/AccessibilityTest.test.ts.snap new file mode 100644 index 00000000000..2b60c38d4e8 --- /dev/null +++ b/packages/e2e-test-app-fabric/test/__snapshots__/AccessibilityTest.test.ts.snap @@ -0,0 +1,449 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Accessibility Tests Elements can set accessibilityState:selected to false 1`] = ` +{ + "Automation Tree": { + "AutomationId": "Selectable item 1", + "ControlType": 50000, + "IsKeyboardFocusable": true, + "LocalizedControlType": "button", + "Name": "Selectable item 1", + "__Children": [ + { + "AutomationId": "", + "ControlType": 50020, + "LocalizedControlType": "text", + "Name": "Unselected", + }, + ], + }, + "Component Tree": { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": { + "AccessibilityLabel": "Selectable item 1", + "TestId": "Selectable item 1", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ParagraphComponentView", + "_Props": {}, + }, + ], + }, + "Visual Tree": { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(135, 206, 250, 255)", + }, + "Comment": "Selectable item 1", + "Offset": "0, 0, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + }, + ], + }, + ], + }, +} +`; + +exports[`Accessibility Tests Elements can set accessibilityState:selected to true 1`] = ` +{ + "Automation Tree": { + "AutomationId": "Selectable item 1", + "ControlType": 50026, + "IsKeyboardFocusable": true, + "LocalizedControlType": "group", + "Name": "Selectable item 1", + "SelectionItemPattern.IsSelected": true, + "__Children": [ + { + "AutomationId": "", + "ControlType": 50020, + "LocalizedControlType": "text", + "Name": "Selected", + }, + ], + }, + "Component Tree": { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": { + "AccessibilityLabel": "Selectable item 1", + "TestId": "Selectable item 1", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ParagraphComponentView", + "_Props": {}, + }, + ], + }, + "Visual Tree": { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(128, 128, 128, 255)", + }, + "Comment": "Selectable item 1", + "Offset": "0, 0, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + }, + ], + }, + ], + }, +} +`; + +exports[`Accessibility Tests Selectable items must have a Selection Container. Elements can set accessibilityState:multiselectable and accessibilityState:required to true 1`] = ` +{ + "Automation Tree": { + "AutomationId": "selection-container", + "ControlType": 50026, + "LocalizedControlType": "group", + "Name": "Selection Container", + "SelectionPattern.CanSelectMultiple": true, + "SelectionPattern.IsSelectionRequired": true, + "__Children": [ + { + "AutomationId": "Selectable item 1", + "ControlType": 50000, + "IsKeyboardFocusable": true, + "LocalizedControlType": "button", + "Name": "Selectable item 1", + "__Children": [ + { + "AutomationId": "", + "ControlType": 50020, + "LocalizedControlType": "text", + "Name": "Unselected", + }, + ], + }, + { + "AutomationId": "Selectable item 2", + "ControlType": 50000, + "IsKeyboardFocusable": true, + "LocalizedControlType": "button", + "Name": "Selectable item 2", + "__Children": [ + { + "AutomationId": "", + "ControlType": 50020, + "LocalizedControlType": "text", + "Name": "Unselected", + }, + ], + }, + { + "AutomationId": "Selectable item 3", + "ControlType": 50000, + "IsKeyboardFocusable": true, + "LocalizedControlType": "button", + "Name": "Selectable item 3", + "__Children": [ + { + "AutomationId": "", + "ControlType": 50020, + "LocalizedControlType": "text", + "Name": "Unselected", + }, + ], + }, + ], + }, + "Component Tree": { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": { + "AccessibilityLabel": "Selection Container", + "TestId": "selection-container", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ScrollViewComponentView", + "_Props": { + "AccessibilityLabel": "List of selectable items", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": {}, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": { + "AccessibilityLabel": "Selectable item 1", + "TestId": "Selectable item 1", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ParagraphComponentView", + "_Props": {}, + }, + ], + }, + { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": { + "AccessibilityLabel": "Selectable item 2", + "TestId": "Selectable item 2", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ParagraphComponentView", + "_Props": {}, + }, + ], + }, + { + "Type": "Microsoft.ReactNative.Composition.ViewComponentView", + "_Props": { + "AccessibilityLabel": "Selectable item 3", + "TestId": "Selectable item 3", + }, + "__Children": [ + { + "Type": "Microsoft.ReactNative.Composition.ParagraphComponentView", + "_Props": {}, + }, + ], + }, + ], + }, + ], + }, + ], + }, + "Visual Tree": { + "Comment": "selection-container", + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(0, 0, 0, 0)", + }, + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(0, 0, 0, 0)", + }, + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "916, 150", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(135, 206, 250, 255)", + }, + "Comment": "Selectable item 1", + "Offset": "0, 0, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + }, + ], + }, + ], + }, + ], + }, + { + "Offset": "0, 50, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(135, 206, 250, 255)", + }, + "Comment": "Selectable item 2", + "Offset": "0, 0, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + }, + ], + }, + ], + }, + ], + }, + { + "Offset": "0, 100, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Brush": { + "Brush Type": "ColorBrush", + "Color": "rgba(135, 206, 250, 255)", + }, + "Comment": "Selectable item 3", + "Offset": "0, 0, 0", + "Size": "100, 50", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "0, 0, 0", + "Size": "100, 20", + "Visual Type": "SpriteVisual", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + "Offset": "-13, 0, 0", + "Size": "12, 0", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "-12, 3, 0", + "Opacity": 0, + "Size": "12, 144", + "Visual Type": "Visual", + }, + { + "Offset": "0, 4, 0", + "Opacity": 0, + "Size": "12, 12", + "Visual Type": "SpriteVisual", + }, + { + "Offset": "0, -16, 0", + "Opacity": 0, + "Size": "12, 12", + "Visual Type": "SpriteVisual", + }, + { + "Offset": "-5, 16, 0", + "Size": "6, 118", + "Visual Type": "Visual", + }, + ], + }, + { + "Offset": "0, -13, 0", + "Size": "0, 12", + "Visual Type": "SpriteVisual", + "__Children": [ + { + "Offset": "3, -12, 0", + "Opacity": 0, + "Size": "910, 12", + "Visual Type": "Visual", + }, + { + "Offset": "4, 0, 0", + "Opacity": 0, + "Size": "12, 12", + "Visual Type": "SpriteVisual", + }, + { + "Offset": "-16, 0, 0", + "Opacity": 0, + "Size": "12, 12", + "Visual Type": "SpriteVisual", + }, + { + "Offset": "16, -5, 0", + "Size": "884, 6", + "Visual Type": "Visual", + }, + ], + }, + ], + }, + ], + }, + ], + }, +} +`; diff --git a/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap b/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap index 36429eab3de..cb35c326aed 100644 --- a/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap +++ b/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap @@ -301,181 +301,196 @@ exports[`snapshotAllPages Accessibility Windows 4`] = ` The following list of TouchableHighlights toggles accessibilityState.selected when touched: - - - + + + - - Unselected - + testID="Selectable item 1" + > + + Unselected + + - - + - - Unselected - + testID="Selectable item 2" + > + + Unselected + + - - + - - Unselected - + testID="Selectable item 3" + > + + Unselected + + - - + + The following TouchableHighlight cycles accessibilityState.checked through unchecked/checked/mixed for the View under it: @@ -1216,6 +1231,8 @@ exports[`snapshotAllPages Alerts 1`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1276,6 +1293,8 @@ exports[`snapshotAllPages Alerts 2`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1335,6 +1354,8 @@ exports[`snapshotAllPages Alerts 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1395,6 +1416,8 @@ exports[`snapshotAllPages Alerts 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1454,6 +1477,8 @@ exports[`snapshotAllPages Alerts 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1513,6 +1538,8 @@ exports[`snapshotAllPages Alerts 6`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1572,6 +1599,8 @@ exports[`snapshotAllPages Alerts 7`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1649,6 +1678,8 @@ exports[`snapshotAllPages Alerts 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1703,6 +1734,8 @@ exports[`snapshotAllPages Alerts 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1757,6 +1790,8 @@ exports[`snapshotAllPages Alerts 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1811,6 +1846,8 @@ exports[`snapshotAllPages Alerts 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1865,6 +1902,8 @@ exports[`snapshotAllPages Alerts 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1924,6 +1963,8 @@ exports[`snapshotAllPages Alerts 9`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -1978,6 +2019,8 @@ exports[`snapshotAllPages Alerts 9`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -2032,6 +2075,8 @@ exports[`snapshotAllPages Alerts 9`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -2163,6 +2208,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2230,6 +2277,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2297,6 +2346,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2364,6 +2415,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2431,6 +2484,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2498,6 +2553,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2565,6 +2622,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2632,6 +2691,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2699,6 +2760,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2766,6 +2829,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2833,6 +2898,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2900,6 +2967,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": false, } } @@ -2969,6 +3038,8 @@ exports[`snapshotAllPages Animated 1`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3104,6 +3175,8 @@ exports[`snapshotAllPages Animated 2`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3293,6 +3366,8 @@ exports[`snapshotAllPages Animated 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3595,6 +3670,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3649,6 +3726,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3703,6 +3782,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3889,6 +3970,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3943,6 +4026,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -3997,6 +4082,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4183,6 +4270,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4237,6 +4326,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4291,6 +4382,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4477,6 +4570,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4531,6 +4626,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4585,6 +4682,8 @@ exports[`snapshotAllPages Animated 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4835,6 +4934,8 @@ exports[`snapshotAllPages Animated 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -4952,6 +5053,8 @@ exports[`snapshotAllPages Animated 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5069,6 +5172,8 @@ exports[`snapshotAllPages Animated 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5210,6 +5315,8 @@ exports[`snapshotAllPages Animated 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5327,6 +5434,8 @@ exports[`snapshotAllPages Animated 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5444,6 +5553,8 @@ exports[`snapshotAllPages Animated 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5566,6 +5677,8 @@ exports[`snapshotAllPages Animated 6`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5725,6 +5838,8 @@ exports[`snapshotAllPages Animated 7`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5907,6 +6022,8 @@ exports[`snapshotAllPages Animated 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -5962,6 +6079,8 @@ exports[`snapshotAllPages Animated 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -6016,6 +6135,8 @@ exports[`snapshotAllPages Animated 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -6070,6 +6191,8 @@ exports[`snapshotAllPages Animated 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -6175,6 +6298,8 @@ exports[`snapshotAllPages Animated 9`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -6306,6 +6431,8 @@ exports[`snapshotAllPages Animated 10`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -6387,337 +6514,816 @@ exports[`snapshotAllPages Animated 11`] = ` `; -exports[`snapshotAllPages AppState 1`] = ``; - -exports[`snapshotAllPages AppState 2`] = ` - - - -`; - -exports[`snapshotAllPages AppState 3`] = ` - - - [] - - -`; - -exports[`snapshotAllPages AppState 4`] = ` +exports[`snapshotAllPages Animated 12`] = ` - - 0 - - -`; - -exports[`snapshotAllPages AppState 5`] = ` - - - [] - - -`; - -exports[`snapshotAllPages Border 1`] = ` - -`; - -exports[`snapshotAllPages Border 2`] = ` - + + -`; - -exports[`snapshotAllPages Border 3`] = ` - -`; - -exports[`snapshotAllPages Border 4`] = ` - -`; - -exports[`snapshotAllPages Border 5`] = ` - -`; - -exports[`snapshotAllPages Border 6`] = ` - -`; - -exports[`snapshotAllPages Border 7`] = ` - -`; - -exports[`snapshotAllPages Border 8`] = ` - + "borderWidth": 1, + "margin": 20, + "opacity": 0.9, + "padding": 20, + } + } + > + + Change Opacity + + - -`; - -exports[`snapshotAllPages Border 9`] = ` - - + > + + Add + + + > + + Subtract + + + > + + Multiply + + - -`; - -exports[`snapshotAllPages Border 10`] = ` - + + Divide + + + + + Modulo + + + +`; + +exports[`snapshotAllPages Animated 13`] = ` + + + + + + + Press count : 0 + + + + + + + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + + +`; + +exports[`snapshotAllPages AppState 1`] = ` + +`; + +exports[`snapshotAllPages AppState 2`] = ` + + + +`; + +exports[`snapshotAllPages AppState 3`] = ` + + + [] + + +`; + +exports[`snapshotAllPages AppState 4`] = ` + + + 0 + + +`; + +exports[`snapshotAllPages AppState 5`] = ` + + + [] + + +`; + +exports[`snapshotAllPages Border 1`] = ` + `; -exports[`snapshotAllPages Border 11`] = ` +exports[`snapshotAllPages Border 2`] = ` `; -exports[`snapshotAllPages Border 12`] = ` +exports[`snapshotAllPages Border 3`] = ` `; -exports[`snapshotAllPages Border 13`] = ` +exports[`snapshotAllPages Border 4`] = ` `; -exports[`snapshotAllPages Border 14`] = ` +exports[`snapshotAllPages Border 5`] = ` `; -exports[`snapshotAllPages Border 15`] = ` +exports[`snapshotAllPages Border 6`] = ` `; -exports[`snapshotAllPages Border 16`] = ` +exports[`snapshotAllPages Border 7`] = ` `; -exports[`snapshotAllPages Border 17`] = ` +exports[`snapshotAllPages Border 8`] = ` + testID="border-test-custom-borders-ios-clipping" +> + + `; -exports[`snapshotAllPages Button 1`] = ` +exports[`snapshotAllPages Border 9`] = ` + + + + + +`; + +exports[`snapshotAllPages Border 10`] = ` + +`; + +exports[`snapshotAllPages Border 11`] = ` + +`; + +exports[`snapshotAllPages Border 12`] = ` + +`; + +exports[`snapshotAllPages Border 13`] = ` + +`; + +exports[`snapshotAllPages Border 14`] = ` + +`; + +exports[`snapshotAllPages Border 15`] = ` + +`; + +exports[`snapshotAllPages Border 16`] = ` + +`; + +exports[`snapshotAllPages Border 17`] = ` + +`; + +exports[`snapshotAllPages Button 1`] = ` + - + + + + + + + Change height + + + + + `; -exports[`snapshotAllPages Flyout 1`] = ` +exports[`snapshotAllPages FlatList 10`] = ` - Placement Options: - - - - + }, + ] + } + > + - Open Flyout + Pizza - - - - - Open Flyout without Target + Burger - - - - - Open Flyout with Offset + Risotto - - - - - Text Input to Anchor flyout to: - - - - - -`; - -exports[`snapshotAllPages Glyph UWP 1`] = ` - - - Glyph: default Accent color - - - - Glyph: red - - - - Multiple glyphs: red - - - - Multiple glyphs - - - -`; - -exports[`snapshotAllPages Keyboard 1`] = ` - - - - Keyboard is - - - closed - - - - - No events observed - - - -`; - -exports[`snapshotAllPages Keyboard 2`] = ` - - - - Keyboard is - - - closed - - - - - No events observed - - - -`; - -exports[`snapshotAllPages Keyboard 3`] = ` - - - No tab index, this item will be tabbed to last - - - - tabIndex default - - - - These 3 items should tab in the order of first, last, middle: - - - - - tabIndex 1 - - - - - tabIndex 3 - - - - - tabIndex 2 - - - - - Controls like Picker should also do the same tab in the order of first, last, middle: - - - - - - - -`; - -exports[`snapshotAllPages Keyboard Focus Example 1`] = ` - - - - Please select a item to set focus - - - - - - View accept focus - - - - - - - - Test Purpose: focus on TextInput, then timeout and blur on TextInput2, TextInput still keep focus - - - - - - Test Purpose: focus on TextInput2, then timeout and blur on TextInput2, TextInput2 lose focus - - - - Key - unknown - - - - + - - - Last focus event for TouchableHighlight: - - - + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + disabled={false} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + [ + { + "backgroundColor": "pink", + "height": 70, + "justifyContent": "center", + "marginVertical": 8, + "paddingHorizontal": 20, + }, + { + "backgroundColor": "pink", + }, + ] + } + testID="French Fries" + > + + French Fries + + + + - - - Last focus event for TouchableOpacity: - - - - - Last focus event for TouchableWithoutFeedback: - - - - -`; - -exports[`snapshotAllPages Keyboard extension Example 1`] = ` - - - - - OnKeyDown Key and Code - - - - - - - - - OnKeyDownCapture Key and Code - - - - - - - - - - - OnKeyUp Key and Code - - - - - - - - - OnKeyUpCapture Key and Code - - - - - - - - - - - - - -`; - -exports[`snapshotAllPages Layout - Flexbox 1`] = ` - - - - Layout - - - - - + + Onion Rings + + + + - Flex Direction + Fried Shrimps + + - - row - - - - - - - - - - row-reverse - - - - - - - - - - column + Water - + + + + - - - - - - - - column-reverse + Coke - + + + - - - - - - - + - - top: 15, left: 160 - - + Beer + + + + Cheesecake + + + + + + + +`; + +exports[`snapshotAllPages FlatList 11`] = ` + + + + + + + - Justify Content - Main Direction + Pizza + + - - flex-start - - - - - - - - - - center + Burger - + + + - - - - - - - - flex-end - - - - - - - - - - space-between - - + - - - - - - - - space-around - - - - - - - - + Risotto + - Align Items - Other Direction + French Fries + + - - flex-start - - - - - - - - - - - - - - - - + - + Onion Rings + + + + + + - + Fried Shrimps + + + + + + - + Water + + + + + + - - - center + } + > + Coke - + + + + - - - - - - - - - - - - - - - - - - - - flex-end + Beer - - - - - - - - - - - - - - - - - - - - Flex Wrap + Cheesecake - + - - - - - - - - - - - - - - - - - - - - + } + /> `; -exports[`snapshotAllPages Layout Events 1`] = ` - - - layout events are called on mount and whenever layout is recalculated. Note that the layout event will typically be received - - - before - - the layout has updated on screen, especially when using layout animations. - - - Press here to change layout. - - - - - - ViewLayout: - - undefined - - - - - A simple piece of text. - - - - - Text w/h: - ? - / - ? - - Image x/y: - ? - / - ? - - - -`; - -exports[`snapshotAllPages Legacy Native Module 1`] = ` +exports[`snapshotAllPages FlatList 12`] = ` -`; - -exports[`snapshotAllPages LegacyControlStyleTest 1`] = ` - +> - - - + - - + - - Show Round Border - + + Pizza + + - - - -`; - -exports[`snapshotAllPages LegacyImageTest 1`] = ` - - - - - - - - Show Border - + + Burger + + - - - - - - Set image to RTL - + + Risotto + + - - - -`; - -exports[`snapshotAllPages LegacyLoginTest 1`] = ` - - - - - - - Show Password - + + French Fries + + - - - - - LOGIN - - - - -`; - -exports[`snapshotAllPages LegacySelectableTextTest 1`] = ` - - - Pressed: - 0 - times. - - - Text before - - - click here - - - text after - - - - - Toggle Selectable - + + Onion Rings + + - - - - - - Clear State - + + Fried Shrimps + + - - - -`; - -exports[`snapshotAllPages LegacyTextHitTestTest 1`] = ` - - - Pressed: - 0 - times. - - - Nested - - - pressable - - - text: - - + - Click here - - - - - - Nested text inside pressable text: - - - - Click here - - - - - Multiline pressable test: - - - Click here -or click here. - - - - Multiline pressable RTL text: - - - أحب اللغة -العربية - - - - RTL text in LTR flow direction: - - + Water + + + + - أحب اللغة العربية - - - - RTL text in RTL flow direction: - - - أحب اللغة العربية - - - - LTR text in RTL flow direction: - - - Click here - - - - Bidirectional text in a single run: - - + + + Coke + + + + - أحب اللغة العربية hello - - - - Bidirectional text in separate runs: - - + + + Beer + + + + - أحب اللغة العربية - hello - - - - Add pressable inline text child: - - + + + Cheesecake + + + + - Click to add - - - - + + + +`; + +exports[`snapshotAllPages FlatList 13`] = ` + - Click anywhere to toggle pressability: - - - Click here - - - - Wrapped text pressability: - + } +> - - abcdef - - + testID="output" + /> - - + - - Clear State - + + Pizza + + - - - -`; - -exports[`snapshotAllPages LegacyTextInputTest 1`] = ` - - - - - - <Log Start> - - -`; - -exports[`snapshotAllPages Linking 1`] = ` - - - - - Open - https://www.facebook.com - + + Burger + + - - - - Open - http://www.facebook.com - + + Risotto + + - - - - Open - http://facebook.com - + + French Fries + + - - - - Open - fb://notifications - - - - - - - Open - geo:37.484847,-122.148386 - - - - - - - Open - tel:9876543210 - + + Onion Rings + + - - - -`; - -exports[`snapshotAllPages Linking 2`] = ` - - - - - Open Settings - - - - -`; - -exports[`snapshotAllPages Modal 1`] = ` - - - - Show Modal - - - - - Animation Type - - - - - slide + Fried Shrimps - none + Water - - fade - - - - - - - - Status Bar Translucent 🟢 - - - - - - Hardware Acceleration 🟢 - - - - - - Presentation Style ⚫️ - - - - - fullScreen + Coke - pageSheet + Beer - formSheet + Cheesecake + + + +`; + +exports[`snapshotAllPages FlatList 14`] = ` + + + - - - overFullScreen - - - - + } + testID="output" + /> - - - Transparent - - - - - + - - Supported Orientation ⚫️ - - + "onViewableItemsChanged": [Function], + "viewabilityConfig": { + "minimumViewTime": 1000, + "viewAreaCoveragePercentThreshold": 100, + "waitForInteraction": true, + }, + }, + ] + } + > + - portrait + Pizza - portrait-upside-down + Burger - landscape + Risotto - landscape-left + French Fries - landscape-right + Onion Rings - - - - - Actions - - + + + Fried Shrimps + + + + - onShow + Water + + + Coke + + + + - onDismiss ⚫️ + Beer - - - -`; - -exports[`snapshotAllPages Modal 2`] = ` - - - onShow is called - 0 - times - - - onDismiss is called - 0 - times - - - + + + Cheesecake + + + + - Show Modal - - + /> + + `; -exports[`snapshotAllPages Mouse Click Events 1`] = ` +exports[`snapshotAllPages FlatList 15`] = ` - Primary Pressed x - 0 - - - Auxiliary Pressed x - 0 - - - Secondary Pressed x - 0 - - - + + - - - - Clear state - - - - - - - I'm a view! - - - - - - - I'm a button! - - - - - -`; - -exports[`snapshotAllPages Mouse Events 1`] = ` - - - + - - Hoverable - - text - - - - This is a TouchableHighlight + + Pizza - - This is an overlay view + + Burger - - - - - - -`; - -exports[`snapshotAllPages Native Animated Example 1`] = ` - - - - Native: - - - - - - - - JavaScript - : - - - - + + + Risotto + + + + - - -`; - -exports[`snapshotAllPages Native Animated Example 2`] = ` - - - - Native: - - - - + + + French Fries + + + + - - - - JavaScript - : - - - - + + + Onion Rings + + + + - - -`; - -exports[`snapshotAllPages Native Animated Example 3`] = ` - - - - Native: - - - - + + + Fried Shrimps + + + + - - - - JavaScript - : - - - - + + + Water + + + + - - -`; - -exports[`snapshotAllPages Native Animated Example 4`] = ` - - - - Native: - - - - + + + Coke + + + + - - - - JavaScript - : - - - - + + + Beer + + + + - + > + + + Cheesecake + + + + + + `; -exports[`snapshotAllPages Native Animated Example 5`] = ` +exports[`snapshotAllPages Flyout 1`] = ` - - - Native: - - - - - - - JavaScript - : - + > + Placement Options: + + - - -`; - -exports[`snapshotAllPages Native Animated Example 6`] = ` - - - - Native: - + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + [ + { + "backgroundColor": { + "windowsbrush": [ + "ButtonBackground", + ], + }, + "borderBottomWidth": 1.5, + "borderColor": { + "windowsbrush": [ + "ButtonBorderBrush", + ], + }, + "borderRadius": 3, + "borderWidth": 1, + }, + ] + } + > + + + + Open Flyout + + + + - - - - JavaScript - : - + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + [ + { + "backgroundColor": { + "windowsbrush": [ + "ButtonBackground", + ], + }, + "borderBottomWidth": 1.5, + "borderColor": { + "windowsbrush": [ + "ButtonBorderBrush", + ], + }, + "borderRadius": 3, + "borderWidth": 1, + }, + ] + } + > + + + + Open Flyout without Target + + + + - - -`; - -exports[`snapshotAllPages Native Animated Example 7`] = ` - - - - Native: - + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + [ + { + "backgroundColor": { + "windowsbrush": [ + "ButtonBackground", + ], + }, + "borderBottomWidth": 1.5, + "borderColor": { + "windowsbrush": [ + "ButtonBorderBrush", + ], + }, + "borderRadius": 3, + "borderWidth": 1, + }, + ] + } + > + + + + Open Flyout with Offset + + + + - - - - - JavaScript - : + > + Text Input to Anchor flyout to: + - - - @@ -32700,753 +32049,822 @@ exports[`snapshotAllPages Native Animated Example 7`] = ` `; -exports[`snapshotAllPages Native Animated Example 8`] = ` - + + Glyph: default Accent color + + - - - Native: - - - + + Glyph: red + + - - - - - JavaScript - : - - - + + Multiple glyphs: red + + - + + Multiple glyphs + + - + } + /> `; -exports[`snapshotAllPages Native Animated Example 9`] = ` - - +exports[`snapshotAllPages Keyboard 1`] = ` + + - Native: + Keyboard is - - - - - - - JavaScript - : + > + closed - + - + + No events observed + `; -exports[`snapshotAllPages Native Animated Example 10`] = ` - - - + + + Keyboard is + + - - - Value: - 0 + > + closed + - -`; - -exports[`snapshotAllPages Native Animated Example 11`] = ` - + > + + No events observed + + `; -exports[`snapshotAllPages Native Animated Example 12`] = ` +exports[`snapshotAllPages Keyboard 3`] = ` + + No tab index, this item will be tabbed to last + - - - - - Scroll me sideways! - - - - - -`; - -exports[`snapshotAllPages Native Animated Example 13`] = ` - - - Native: + tabIndex default + + These 3 items should tab in the order of first, last, middle: + - - - - - JavaScript - : - - - - + tabIndex={1} + > + + tabIndex 1 + + - - -`; - -exports[`snapshotAllPages Native Animated Example 14`] = ` - - - - Force JS Stalls - - + tabIndex={3} + > + + tabIndex 3 + + + + + tabIndex 2 + + + + Controls like Picker should also do the same tab in the order of first, last, middle: + - - Track JS Stalls - - - - -`; - -exports[`snapshotAllPages PanResponder Sample 1`] = ` - - - - Basic gesture handling - - - + - - - + /> `; -exports[`snapshotAllPages Performance API Examples 1`] = ` +exports[`snapshotAllPages Keyboard Focus Example 1`] = ` - + + Please select a item to set focus + + + + - + View accept focus + + + + - performance.memory + /> + + + + Test Purpose: focus on TextInput, then timeout and blur on TextInput2, TextInput still keep focus + - + + Test Purpose: focus on TextInput2, then timeout and blur on TextInput2, TextInput2 lose focus + + + /> + + Key + unknown + + + + + + Last focus event for TouchableHighlight: + + + + - - - - Click to update memory info - - - - - - - jsHeapSizeLimit: undefined bytes - - - totalJSHeapSize: undefined bytes - - - usedJSHeapSize: undefined bytes - - + /> + + Last focus event for TouchableOpacity: + + + + + Last focus event for TouchableWithoutFeedback: + + `; -exports[`snapshotAllPages Performance API Examples 2`] = ` +exports[`snapshotAllPages Keyboard extension Example 1`] = ` + + + + + OnKeyDown Key and Code + + + + + + + + + OnKeyDownCapture Key and Code + + + + + + + + + + + OnKeyUp Key and Code + + + + + + + + + OnKeyUpCapture Key and Code + + + + + + + + + + + + + +`; + +exports[`snapshotAllPages Layout - Flexbox 1`] = ` - performance.reactNativeStartupTiming + Layout - - - - - - - Click to update React startup timing - - - - - - - startTime: undefined ms - - - initializeRuntimeStart: undefined ms - - - executeJavaScriptBundleEntryPointStart: undefined ms - - - executeJavaScriptBundleEntryPointEnd: undefined ms - - - initializeRuntimeEnd: undefined ms - - - endTime: undefined ms - - - - - -`; - -exports[`snapshotAllPages Performance Comparison Examples 1`] = ` - - - + - - Show Bad + + Flex Direction - Show Good + row - - - - - - -`; - -exports[`snapshotAllPages Performance Comparison Examples 2`] = ` - - - + + + + + + + + + row-reverse + + + + + + + + + + column + + + + + + + + + + column-reverse + + + + + + + + + + + top: 15, left: 160 + + + + - - Show Bad + + Justify Content - Main Direction - Show Good + flex-start - - - - - - -`; - -exports[`snapshotAllPages Performance Comparison Examples 3`] = ` - - - + + + + + + + + + center + + + + + + + + + + flex-end + + + + + + + + + + space-between + + + + + + + + + + space-around + + + + + + + + + + - - Show Bad + + Align Items - Other Direction - Show Good + flex-start - - - - - - -`; - -exports[`snapshotAllPages Performance Comparison Examples 4`] = ` - - - - - - - Show Bad - - - - - Show Good - - - - - - - -`; - -exports[`snapshotAllPages Performance Comparison Examples 5`] = ` - - - - - + > + + + + + + + + + + + + + + + + + + - Show Bad + center - - + + + + + + + + + + + + + + + + + + + + flex-end + + + + + + + + + + + + + + + + + + + + + + + + - - Show Good + + Flex Wrap - - - - - -`; - -exports[`snapshotAllPages Performance Comparison Examples 6`] = ` - - - - - - Show Bad - - - - - Show Good - + > + + + + + + + + + + + + + + + + + - - + `; -exports[`snapshotAllPages PlatformColor 1`] = ` - -`; - -exports[`snapshotAllPages PlatformColor 2`] = ` - - +exports[`snapshotAllPages Layout Events 1`] = ` + + + layout events are called on mount and whenever layout is recalculated. Note that the layout event will typically be received + - Unexpected Platform.OS: windows + before - - - -`; - -exports[`snapshotAllPages PlatformColor 3`] = ` - - Not applicable on this platform - -`; - -exports[`snapshotAllPages PlatformColor 4`] = ` - + > + Press here to change layout. + + - - Unexpected Platform.OS: windows + /> + + ViewLayout: + + undefined + + - + > + A simple piece of text. + + + + + Text w/h: + ? + / + ? + + Image x/y: + ? + / + ? + `; -exports[`snapshotAllPages Pointer Events 1`] = ` +exports[`snapshotAllPages Legacy Native Module 1`] = ` + +`; + +exports[`snapshotAllPages LegacyControlStyleTest 1`] = ` - + - - - A: unspecified - - - + + + + + - - - B: none - - - - - - C: unspecified - - - + Show Round Border + + +`; + +exports[`snapshotAllPages LegacyImageTest 1`] = ` + - - - - - -`; - -exports[`snapshotAllPages Pointer Events 2`] = ` - - - + + + - A: unspecified - - - - - - B: none - - - - - - C: unspecified - - - + Show Border + - + + > + Set image to RTL + + `; -exports[`snapshotAllPages Pointer Events 3`] = ` +exports[`snapshotAllPages LegacyLoginTest 1`] = ` + + - - - - A: unspecified - - + } + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + [ + { + "backgroundColor": { + "windowsbrush": [ + "ButtonBackground", + ], + }, + "borderBottomWidth": 1.5, + "borderColor": { + "windowsbrush": [ + "ButtonBorderBrush", + ], + }, + "borderRadius": 3, + "borderWidth": 1, + }, + ] + } + testID="show-password-toggle" + > + - - - B: box-none - - - - - - C: unspecified - - - - - - - C: explicitly unspecified - - - + Show Password + - - - + } + > + LOGIN + + `; -exports[`snapshotAllPages Pointer Events 4`] = ` - - + - + + Text before + + + click here + + + text after + + + - A: unspecified - - - - - - B: box-none - - - - - - C: unspecified - - - - - - - C: explicitly unspecified - - - + Toggle Selectable + - - - - -`; - -exports[`snapshotAllPages Pointer Events 5`] = ` - - - - A: unspecified - - - - - - B: box-only - - - - - - C: unspecified - - - - - - - C: explicitly unspecified - - - + Clear State + + +`; + +exports[`snapshotAllPages LegacyTextHitTestTest 1`] = ` + + + Pressed: + 0 + times. + + + Nested + + + pressable + + + text: + + + Click here + + + + + + Nested text inside pressable text: + + + + Click here + + + + + Multiline pressable test: + + + Click here +or click here. + + + + Multiline pressable RTL text: + + + أحب اللغة +العربية + + + + RTL text in LTR flow direction: + + + أحب اللغة العربية + + + + RTL text in RTL flow direction: + + + أحب اللغة العربية + + + + LTR text in RTL flow direction: + + + Click here + + + + Bidirectional text in a single run: + + + أحب اللغة العربية hello + + + + Bidirectional text in separate runs: + + + أحب اللغة العربية + hello + + + + Add pressable inline text child: + + + Click to add + + + + + Click anywhere to toggle pressability: + + + Click here + + + + Wrapped text pressability: + - - + > + abcdef + + - -`; - -exports[`snapshotAllPages Pointer Events 6`] = ` - - + - A: unspecified + Clear State - - - - B: box-only - - - - - - C: unspecified - - - - - - - C: explicitly unspecified - - - - - +`; + +exports[`snapshotAllPages LegacyTextInputTest 1`] = ` + + + + + - - - - + <Log Start> + `; -exports[`snapshotAllPages Pointer Events 7`] = ` +exports[`snapshotAllPages Linking 1`] = ` - + - A: overflow: - visible + Open + https://www.facebook.com - + - - - B: overflowing - - - + } + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + collapsable={false} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "opacity": 1, + } + } + > - - - C: fully outside - - - - - - D: child of fully outside - - - + Open + http://www.facebook.com + - - - + > + + Open + http://facebook.com + + - - -`; - -exports[`snapshotAllPages Pointer Events 8`] = ` - - - A: overflow: - hidden - - - - - - B: overflowing - - - - - - - C: fully outside - - - - - - D: child of fully outside - - - + Open + fb://notifications + - - - - - - -`; - -exports[`snapshotAllPages Popup 1`] = ` - - - The following tests popup Anchor - - - - Text Input to Anchor popup to: - - - - - + > + + + Open + geo:37.484847,-122.148386 + + + - - - Open Popup - - + } + > + Open + tel:9876543210 + `; -exports[`snapshotAllPages Popup 2`] = ` +exports[`snapshotAllPages Linking 2`] = ` - + - - - Toggle popup - - + "fontSize": 14, + "fontWeight": "400", + "margin": 8, + "textAlign": "center", + }, + ] + } + > + Open Settings + `; -exports[`snapshotAllPages Popup 3`] = ` - +exports[`snapshotAllPages Modal 1`] = ` + - - - - Toggle popup - - - + + Show Modal + - -`; - -exports[`snapshotAllPages Pressable 1`] = ` -[ - + Animation Type + + - - Press Me - + + + slide + + + + + + + none + + + + + + + fade + + + - , + - - , -] -`; - -exports[`snapshotAllPages Pressable 2`] = ` - - - Press Me + Status Bar Translucent 🟢 + - -`; - -exports[`snapshotAllPages Pressable 3`] = ` - - + Hardware Acceleration 🟢 + + - - Press Me - - + value={false} + /> - -`; - -exports[`snapshotAllPages Pressable 4`] = ` - - - - - -`; - -exports[`snapshotAllPages Pressable 5`] = ` - - + Presentation Style ⚫️ + + - - - + - radius 30 - + + fullScreen + + - - - - + - radius 150 - + + pageSheet + + - - + accessible={true} + disabled={false} + focusable={true} + hitSlop={4} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + > + + + formSheet + + + - - radius 70, with border - + + overFullScreen + + - with border, default color and radius + Transparent + - + Supported Orientation ⚫️ + + - - - - use foreground - - - -`; - -exports[`snapshotAllPages Pressable 6`] = ` -[ - - Text has built-in onPress handling - , - - - , -] -`; - -exports[`snapshotAllPages Pressable 7`] = ` - - - + + + portrait + + + + + + + portrait-upside-down + + + + - + + + landscape + + + + - Press Me - + + + landscape-left + + + + + + + landscape-right + + + - - -`; - -exports[`snapshotAllPages Pressable 8`] = ` - - - 3D Touch is not available on this device - - - + "fontWeight": "bold", + "margin": 3, + } + } + > + Actions + - - Press Me - + + + onShow + + + + + + + onDismiss ⚫️ + + + - -`; - -exports[`snapshotAllPages Pressable 9`] = ` - + + Backdrop Color ⚫️ + + + + + red + + + + - - Press Outside This View - + + + blue + + + + + + + default + + + - - - `; -exports[`snapshotAllPages Pressable 10`] = ` +exports[`snapshotAllPages Modal 2`] = ` + + onShow is called + 0 + times + + + onDismiss is called + 0 + times + - + + Show Modal + - - Native Methods Exist - `; -exports[`snapshotAllPages Pressable 11`] = ` -[ +exports[`snapshotAllPages Mouse Click Events 1`] = ` + + + Primary Pressed x + 0 + + + Auxiliary Pressed x + 0 + + + Secondary Pressed x + 0 + + + - + + + Clear state + + + + + + - Disabled Pressable + I'm a view! - , + + + + + I'm a button! + + + + + +`; + +exports[`snapshotAllPages Mouse Events 1`] = ` + + - - Enabled Pressable - - , -] + + + Hoverable + + text + + + + + This is a TouchableHighlight + + + + + + + This is an overlay view + + + + + + + + + `; -exports[`snapshotAllPages Pressable 12`] = ` - +exports[`snapshotAllPages Moving Light Example 1`] = ` + + + Size: 25 + + + Color: white + - - Press Me - + + + Toggle Light + + + + + Last Event Value: No Event yet + + `; -exports[`snapshotAllPages Pressable 13`] = ` -[ +exports[`snapshotAllPages Native Animated Example 1`] = ` + + + + Native: + + - - Press Me - - - , + /> + + + + JavaScript + : + + - - , - - - - Click to focus textbox - - - , -] + /> + + `; -exports[`snapshotAllPages Pressable 14`] = ` -[ +exports[`snapshotAllPages Native Animated Example 2`] = ` + + + + Native: + + - - Press Me - - - - , + + + + JavaScript + : + + - - - defaultText - - , -] + + `; -exports[`snapshotAllPages Pressable 15`] = ` -[ +exports[`snapshotAllPages Native Animated Example 3`] = ` + + + + Native: + + - - Press Me - - - , + /> + + + + JavaScript + : + + , -] + > + + + `; -exports[`snapshotAllPages Pressable 16`] = ` - +exports[`snapshotAllPages Native Animated Example 4`] = ` + + + + Native: + + + + + + + JavaScript + : + + + + > + + `; -exports[`snapshotAllPages Pressable 17`] = ` +exports[`snapshotAllPages Native Animated Example 5`] = ` + + + Native: + + + + /> + + + + JavaScript + : + + + + + +`; + +exports[`snapshotAllPages Native Animated Example 6`] = ` + + + + Native: + + + + > + + + + + JavaScript + : + + + + + +`; + +exports[`snapshotAllPages Native Animated Example 7`] = ` + + + + Native: + + + + > + + + + + JavaScript + : + + + + + +`; + +exports[`snapshotAllPages Native Animated Example 8`] = ` + + + + Native: + + + + > + + + + + JavaScript + : + + + + + +`; + +exports[`snapshotAllPages Native Animated Example 9`] = ` + + + + Native: + + + + > + + + + + JavaScript + : + + + + + +`; + +exports[`snapshotAllPages Native Animated Example 10`] = ` + + - + + + + Value: + 0 + + +`; + +exports[`snapshotAllPages Native Animated Example 11`] = ` + + + +`; + +exports[`snapshotAllPages Native Animated Example 12`] = ` + + - + + + + Scroll me sideways! + + + + + +`; + +exports[`snapshotAllPages Native Animated Example 13`] = ` + + + + Native: + + + + + + + + + JavaScript + : + + + + > + + + + +`; + +exports[`snapshotAllPages Native Animated Example 14`] = ` + + + Force JS Stalls + + + + + + Track JS Stalls + + + + +`; + +exports[`snapshotAllPages PanResponder Sample 1`] = ` + + + + Basic gesture handling + + + + > + + + + + +`; + +exports[`snapshotAllPages Performance API Examples 1`] = ` + - + + performance.memory + + + + > + + + + + + Click to update memory info + + + + + + + jsHeapSizeLimit: undefined bytes + + + totalJSHeapSize: undefined bytes + + + usedJSHeapSize: undefined bytes + + + + `; -exports[`snapshotAllPages Pressable 18`] = ` +exports[`snapshotAllPages Performance API Examples 2`] = ` - - Pressable with accessible=true and focusable=true - - - - - Pressable with accessible=false + > + performance.reactNativeStartupTiming - - Pressable with focusable=false - - - - - Pressable with accessible=false and focusable=false - + + + + Click to log some marks and measures + + + + `; -exports[`snapshotAllPages Pressable 19`] = ` - +exports[`snapshotAllPages Performance API Examples 4`] = ` + - - Pressable with ToolTip "Pressable" - + > + + + + + Click to update React startup timing + + + + + + + startTime: undefined ms + + + initializeRuntimeStart: undefined ms + + + executeJavaScriptBundleEntryPointStart: undefined ms + + + executeJavaScriptBundleEntryPointEnd: undefined ms + + + initializeRuntimeEnd: undefined ms + + + endTime: undefined ms + + + `; -exports[`snapshotAllPages Pressable 20`] = ` - +exports[`snapshotAllPages Performance Comparison Examples 1`] = ` + + - - Parent Pressable - - + + + + Show Bad + + + + + Show Good + + + + - - Child Pressable - + /> `; -exports[`snapshotAllPages Pressable 21`] = ` +exports[`snapshotAllPages Performance Comparison Examples 2`] = ` - - View #1, front is visible, back is hidden. - + "flex": 1, + }, + { + "backgroundColor": "#f2f2f7ff", + }, + ] + } +> - - Front - - - + + + Show Bad + + + + + Show Good + + + + - - Back (You should not see this) - + /> - +`; + +exports[`snapshotAllPages Performance Comparison Examples 3`] = ` + - View #2, front is hidden, back is visible. - + "flex": 1, + }, + { + "backgroundColor": "#f2f2f7ff", + }, + ] + } +> - - Front (You should not see this) - - - + + + Show Bad + + + + + Show Good + + + + - - Back - + /> `; -exports[`snapshotAllPages RTLExample 1`] = ` - - - - Left-to-Right - - + }, + { + "backgroundColor": "#f2f2f7ff", + }, + ] + } +> - - forceRTL - - - - - -`; - -exports[`snapshotAllPages RTLExample 2`] = ` - - - - - - LTR - + + Show Bad + + + + + Show Good + + + + +`; + +exports[`snapshotAllPages Performance Comparison Examples 5`] = ` + - - - + > + + Show Bad + + - Text Text Text + Show Good - - - Button - - - + /> + + +`; + +exports[`snapshotAllPages Performance Comparison Examples 6`] = ` + + - - - + > + + Show Bad + + - Text Text Text + Show Good - - - Button - - - + /> `; -exports[`snapshotAllPages RTLExample 3`] = ` - - + - - LTR - + + Get Pixel Density + + + +`; + +exports[`snapshotAllPages PixelRatio 2`] = ` + - - Left-to-Right language without text alignment. - - - من اليمين إلى اليسار اللغة دون محاذاة النص - - - מימין לשמאל השפה בלי יישור טקסט - - - -`; - -exports[`snapshotAllPages RTLExample 4`] = ` - - - - - LTR - + + Get Font Scale + + + +`; + +exports[`snapshotAllPages PixelRatio 3`] = ` + - - Left-to-Right language without text alignment. - - - من اليمين إلى اليسار اللغة دون محاذاة النص - - + Layout Size(dp): + + + + + - מימין לשמאל השפה בלי יישור טקסט - + + Pixel Size: + + + 0 + px + + `; -exports[`snapshotAllPages RTLExample 5`] = ` - - + + + Layout Size(dp): + + + + + - - - LTR - - + Nearest Layout Size: + + + + 0 + dp + + +`; + +exports[`snapshotAllPages PlatformColor 1`] = ` + +`; + +exports[`snapshotAllPages PlatformColor 2`] = ` + - Left-to-Right language without text alignment. - - - من اليمين إلى اليسار اللغة دون محاذاة النص + Unexpected Platform.OS: windows - - מימין לשמאל השפה בלי יישור טקסט - + /> `; -exports[`snapshotAllPages RTLExample 6`] = ` - - + Not applicable on this platform + +`; + +exports[`snapshotAllPages PlatformColor 4`] = ` + + + + Unexpected Platform.OS: windows + + + +`; + +exports[`snapshotAllPages Pointer Events 1`] = ` + + + + A: unspecified + + + + + + B: none + + + - LTR - + + + C: unspecified + + + - - LRT or RTL TextInput. - - + "fontSize": 9, + } + } + /> + `; -exports[`snapshotAllPages RTLExample 7`] = ` +exports[`snapshotAllPages Pointer Events 2`] = ` + A: unspecified + + + + + + B: none + + + - LTR - + + + C: unspecified + + + - - - - Without directional meaning - - - - With directional meaning - + /> `; -exports[`snapshotAllPages RTLExample 8`] = ` +exports[`snapshotAllPages Pointer Events 3`] = ` - LTR + A: unspecified - - - - - + + + B: box-none + + + + + + C: unspecified + + + + + + + C: explicitly unspecified + + + + + + + + + @@ -40040,1007 +42286,975 @@ exports[`snapshotAllPages RTLExample 8`] = ` `; -exports[`snapshotAllPages RTLExample 9`] = ` +exports[`snapshotAllPages Pointer Events 4`] = ` - - Styles - - - paddingStart: 50, - - - paddingEnd: 10 - - - - Demo: - - - The - teal - is padding. - + + A: unspecified + + + + + B: box-none + + + + + + C: unspecified + + + + - LTR + C: explicitly unspecified - -`; - -exports[`snapshotAllPages RTLExample 10`] = ` - - - Styles - - - marginStart: 50, - - - marginEnd: 10 - - - - Demo: - - - The green is margin. - + + + + + +`; + +exports[`snapshotAllPages Pointer Events 5`] = ` + + + A: unspecified + + + + + B: box-only + + + - LTR + C: unspecified - - - - -`; - -exports[`snapshotAllPages RTLExample 11`] = ` - - - Styles - - - start: 50 - - - - Demo: - - - The orange is position. - - - - - LTR + C: explicitly unspecified - - - Styles - - - end: 50 - - - - Demo: - - - The orange is position. - + + + + + +`; + +exports[`snapshotAllPages Pointer Events 6`] = ` + + + A: unspecified + + + + + B: box-only + + + - LTR + C: unspecified + + + + + + + C: explicitly unspecified - -`; - -exports[`snapshotAllPages RTLExample 12`] = ` - - - Styles - - - borderStartWidth: 10, - - - borderEndWidth: 50 - - - - Demo: - + + + + + +`; + +exports[`snapshotAllPages Pointer Events 7`] = ` + - - + + A: overflow: + visible + + + + - - - + + + + + + C: fully outside + + + + + - LTR - - + } + > + D: child of fully outside + - -`; - -exports[`snapshotAllPages RTLExample 13`] = ` - - - Styles - - - borderStartColor: 'red', - - - borderEndColor: 'green', - - - - Demo: - + + + + + +`; + +exports[`snapshotAllPages Pointer Events 8`] = ` + - - + + A: overflow: + hidden + + + + + + B: overflowing + + + + + + + C: fully outside + + + - - - LTR - - + } + > + D: child of fully outside + + + + + + `; -exports[`snapshotAllPages RTLExample 14`] = ` - +exports[`snapshotAllPages Popup 1`] = ` + - Styles - - - borderTopStartRadius: 10, - - - borderTopEndRadius: 20, - - - borderBottomStartRadius: 30, - - - borderBottomEndRadius: 40 + The following tests popup Anchor - - - Demo: - + + Text Input to Anchor popup to: + + + + - + - - - - LTR - - - + Open Popup + @@ -41048,555 +43262,286 @@ exports[`snapshotAllPages RTLExample 14`] = ` `; -exports[`snapshotAllPages RTLExample 15`] = ` - - + - Styles - - - borderStartStartRadius: 10, - - - borderStartEndRadius: 20, - - - borderEndStartRadius: 30, - - - borderEndEndRadius: 40 - - - - Demo: - - - - + - - - - LTR - - - - + Toggle popup + `; -exports[`snapshotAllPages RTLExample 16`] = ` - - + - Styles - - - borderStartColor: 'red', - - - borderEndColor: 'green', - - - borderStartWidth: 10, - - - borderEndWidth: 50, - - - borderTopStartRadius: 10, - - - borderTopEndRadius: 20, - - - borderBottomStartRadius: 30, - - - borderBottomEndRadius: 40 - - - - Demo: - - - - + - - - - LTR - - - - + Toggle popup + `; -exports[`snapshotAllPages ScrollView 1`] = ` - - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - + - - Item 11 - - + Press Me + - + , + + + , +] +`; + +exports[`snapshotAllPages Pressable 2`] = ` + - - Scroll to top + + Press Me + +`; + +exports[`snapshotAllPages Pressable 3`] = ` + - - Scroll to bottom + + Press me and move your finger + +`; + +exports[`snapshotAllPages Pressable 4`] = ` + + + + + Press Me + + + + + +`; + +exports[`snapshotAllPages Pressable 4`] = ` + - - Flash scroll indicators - + `; -exports[`snapshotAllPages ScrollView 2`] = ` +exports[`snapshotAllPages Pressable 5`] = ` - - LTR Layout - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - + + + + + - - Item 10 - - - - - Item 11 - - + radius 150 + - + + + + radius 70, with border + + + + + + - - Scroll to start + + with border, default color and radius + + - - Scroll to end - + + + use foreground + `; -exports[`snapshotAllPages ScrollView 3`] = ` - +exports[`snapshotAllPages Pressable 6`] = ` +[ + + Text has built-in onPress handling + , + , +] +`; + +exports[`snapshotAllPages Pressable 7`] = ` + + + - RTL Layout - - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - - - - - - Scroll to start + + Press Me + + + + + +`; + +exports[`snapshotAllPages Pressable 8`] = ` + + + + 3D Touch is not available on this device + + + + + + Press Me + + +`; + +exports[`snapshotAllPages Pressable 9`] = ` + + - - Scroll to end + + Press Outside This View + + + `; -exports[`snapshotAllPages ScrollView 4`] = ` - - + - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - - - + + - Scrolling enabled = true + Native Methods Exist + +`; + +exports[`snapshotAllPages Pressable 11`] = ` +[ + + Disabled Pressable + + , + - - Disable Scrolling + + Enabled Pressable - + , +] +`; + +exports[`snapshotAllPages Pressable 12`] = ` + - - Enable Scrolling + + Press Me `; -exports[`snapshotAllPages ScrollView 5`] = ` - - + + + Press Me + + + , + + + , + - + Click to focus textbox + + + , +] +`; + +exports[`snapshotAllPages Pressable 14`] = ` +[ + + - - Item 0 - - - - - Item 1 - - - + - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - + Press Me + - - - - - setContentContainerStyle - - + value={false} + /> + , + + + + defaultText + + , +] +`; + +exports[`snapshotAllPages Pressable 15`] = ` +[ + - - setContentInset + + Press Me - - + , + , +] `; -exports[`snapshotAllPages ScrollView 6`] = ` +exports[`snapshotAllPages Pressable 16`] = ` - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - - - - - - - Deceleration Rate: normal - - - + testID="advanced_borders_pressable" + /> `; -exports[`snapshotAllPages ScrollView 7`] = ` - - + - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - - - - - + - - setDisableIntervalMomentum: false - - - + - - setDisableScrollViewPanResponder: false - - - - -`; - -exports[`snapshotAllPages ScrollView 8`] = ` - - - - - STICKY HEADER - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - - - - - + - - invertStickyHeaders: false - - - + - - Scroll to top - - - + - - Scroll to bottom - - - + } + accessible={true} + disabled={false} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "backgroundColor": "black", + "height": 50, + "opacity": 0.5, + "width": 50, + } + } + /> + + + + + `; -exports[`snapshotAllPages ScrollView 9`] = ` - - + - - - - Sticky Header 1 - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - + Pressable with accessible=true and focusable=true + + + + + Pressable with accessible=false + + + + + Pressable with focusable=false + + + + + Pressable with accessible=false and focusable=false + + + +`; + +exports[`snapshotAllPages Pressable 19`] = ` + + + + Pressable with ToolTip "Pressable" + + + +`; + +exports[`snapshotAllPages Pressable 20`] = ` + + + + Parent Pressable + + - - Item 8 - - - - - Item 9 - - - + + Child Pressable + + + + +`; + +exports[`snapshotAllPages Pressable 21`] = ` + + + View #1, front is visible, back is hidden. + + + - - Item 10 - - - - - Item 11 - - - - - Sticky Header 2 - - - + + Front + + + - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - - - - Sticky Header 3 - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - - + } + > + + Back (You should not see this) + - - + + + View #2, front is hidden, back is visible. + + - Scroll to top + Front (You should not see this) - Scroll to bottom + Back `; -exports[`snapshotAllPages ScrollView 10`] = ` +exports[`snapshotAllPages Pressable 23`] = ` - - - - - - Press to change color - - - - + + Pressable 1 of 3 + + + + + Pressable 2 of 3 + + + + + Pressable 3 of 3 + + + +`; + +exports[`snapshotAllPages RTLExample 1`] = ` + + + + Left-to-Right + + + + + forceRTL + + + - + + + +`; + +exports[`snapshotAllPages RTLExample 2`] = ` + + + + + + LTR + + + + + + + + - + + + > + + Text Text Text + + + + - + + Button + + + + + + - + - + + + > + + Text Text Text + + - - - - - scroll to top - - - - - - - - - scroll to bottom - - + } + > + Button + @@ -45384,838 +46631,746 @@ exports[`snapshotAllPages ScrollView 10`] = ` `; -exports[`snapshotAllPages ScrollView 11`] = ` +exports[`snapshotAllPages RTLExample 3`] = ` - - - - - - Button - - + "borderWidth": 1, + }, + { + "backgroundColor": "gray", + }, + ] + } + > - - Item 0 + + LTR - + + + - - Item 1 - - - + Left-to-Right language without text alignment. + + - - Item 2 - - - + من اليمين إلى اليسار اللغة دون محاذاة النص + + - - Item 3 - - - + מימין לשמאל השפה בלי יישור טקסט + + + +`; + +exports[`snapshotAllPages RTLExample 4`] = ` + + + + - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 + + LTR - - - Keyboard Dismiss Mode - + - - - none - - - + + من اليمين إلى اليسار اللغة دون محاذاة النص + + - - on-drag - - + מימין לשמאל השפה בלי יישור טקסט + - +`; + +exports[`snapshotAllPages RTLExample 5`] = ` + + - Keyboard Should Persist taps - - - - never - + + + LTR + + - + + - - always - - - + - - handled - - + من اليمين إلى اليسار اللغة دون محاذاة النص + + + מימין לשמאל השפה בלי יישור טקסט + `; -exports[`snapshotAllPages ScrollView 12`] = ` +exports[`snapshotAllPages RTLExample 6`] = ` - - Content Size Changed: - original - - - - - - Item 0 - - - - - Item 1 - - + "borderRadius": 3, + "borderWidth": 1, + }, + { + "backgroundColor": "gray", + }, + ] + } + > - - Item 2 + + LTR - + + + + LRT or RTL TextInput. + + + + +`; + +exports[`snapshotAllPages RTLExample 7`] = ` + + + - - Item 3 - - - - - Item 4 - - + "borderRadius": 3, + "borderWidth": 1, + }, + { + "backgroundColor": "gray", + }, + ] + } + > - - Item 5 + + LTR - + + + + - - Item 6 - - - - - Item 7 - - - + - - Item 8 - - - + + + - - Item 9 - - - - - Item 10 - - - + - - Item 11 - - + With directional meaning + - + + +`; + +exports[`snapshotAllPages RTLExample 8`] = ` + - - Change Content Size - - - -`; - -exports[`snapshotAllPages ScrollView 13`] = ` - - - Scroll State: - none - - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - + "borderRadius": 3, + "borderWidth": 1, + }, + { + "backgroundColor": "gray", + }, + ] + } + > - - Item 3 + + LTR - + + + - - Item 4 - - - + - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - + + + +`; + +exports[`snapshotAllPages RTLExample 9`] = ` + + + Styles + + + paddingStart: 50, + + + paddingEnd: 10 + + + + Demo: + + + The + teal + is padding. + + + - - Item 8 - - + } + > - - Item 9 - - - - - Item 10 - - - - - Item 11 - + + + + LTR + + + - + `; -exports[`snapshotAllPages ScrollView 14`] = ` +exports[`snapshotAllPages RTLExample 10`] = ` + + Styles + - onScroll: - none + marginStart: 50, - + marginEnd: 10 + + + - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - + + The green is margin. + + + - - Item 8 - - + } + > - - Item 9 - - - - - Item 10 - - - - - Item 11 - + + + + LTR + + + - + `; -exports[`snapshotAllPages ScrollView 15`] = ` +exports[`snapshotAllPages RTLExample 11`] = ` - + + Styles + + + start: 50 + + + + Demo: + + + The orange is position. + + - - - - - Item 0 - - + } + > - - Item 1 - - - - - Item 2 - - - - - Item 3 - + + + + LTR + + + - + + + + Styles + + + end: 50 + + + + Demo: + + + The orange is position. + + + - - Item 4 - - + } + > - - Item 5 - - - - - Item 6 - - - - - Item 7 - + + + + LTR + + + - + + +`; + +exports[`snapshotAllPages RTLExample 12`] = ` + + + Styles + + + borderStartWidth: 10, + + + borderEndWidth: 50 + + + + Demo: + + + - - Item 8 - - - + + - - Item 9 - - - - - Item 10 - - - - - Item 11 - + } + } + > + + + + LTR + + + + - + `; -exports[`snapshotAllPages ScrollView 16`] = ` +exports[`snapshotAllPages RTLExample 13`] = ` - - - + + borderStartColor: 'red', + + + borderEndColor: 'green', + + + + Demo: + + + - - Item 0 - - - + + - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - - - - - Item 10 - - - - - Item 11 - + } + } + > + + + + LTR + + + + - - + +`; + +exports[`snapshotAllPages RTLExample 14`] = ` + + + Styles + + + borderTopStartRadius: 10, + + + borderTopEndRadius: 20, + + + borderBottomStartRadius: 30, + + + borderBottomEndRadius: 40 + + + + Demo: + + - - removeClippedSubviews: false - + + + + + + + LTR + + + + + + `; -exports[`snapshotAllPages ScrollView 17`] = ` +exports[`snapshotAllPages RTLExample 15`] = ` - + Styles + + + borderStartStartRadius: 10, + + + borderStartEndRadius: 20, + + + borderEndStartRadius: 30, + + + borderEndEndRadius: 40 + + + - - + + - - Item 0 - - - + + - - Item 1 - - - + + + + LTR + + + + + + + + +`; + +exports[`snapshotAllPages RTLExample 16`] = ` + + + Styles + + + borderStartColor: 'red', + + + borderEndColor: 'green', + + + borderStartWidth: 10, + + + borderEndWidth: 50, + + + borderTopStartRadius: 10, + + + borderTopEndRadius: 20, + + + borderBottomStartRadius: 30, + + + borderBottomEndRadius: 40 + + + + Demo: + + + + + + + + + LTR + + + + + + + + +`; + +exports[`snapshotAllPages ScrollView 1`] = ` + + + + + + Item 0 + + + + + Item 1 + + + - setScrollIndicatorInsets + Scroll to top - showsHorizontalScrollIndicator: true + Scroll to bottom - showsVerticalScrollIndicator: true + Flash scroll indicators `; -exports[`snapshotAllPages ScrollView 18`] = ` +exports[`snapshotAllPages ScrollView 2`] = ` - - - - - Item 0 - - - - - Item 1 - - - - - Item 2 - - - - - Item 3 - - - - - Item 4 - - - - - Item 5 - - - - - Item 6 - - - - - Item 7 - - - - - Item 8 - - - - - Item 9 - + } + > + LTR Layout + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + - + - - Item 10 - - - - - Item 11 - - + } + accessible={true} + collapsable={false} + focusable={true} + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + onKeyUp={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "alignItems": "center", + "backgroundColor": "#cccccc", + "borderRadius": 3, + "margin": 5, + "opacity": 1, + "padding": 5, + } + } + testID="scroll_to_start_button" + > + + Scroll to start + - - - - snapToEnd: true - + testID="scroll_to_end_button" + > + + Scroll to end + + + +`; + +exports[`snapshotAllPages ScrollView 3`] = ` + - - snapToStart: true + + RTL Layout - - - - setSnapToInterval - - - + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + - - reset snapToOffsets - - - -`; - -exports[`snapshotAllPages ScrollView 19`] = ` - - - - Item 0 + Scroll to start - Item 1 + Scroll to end - + +`; + +exports[`snapshotAllPages ScrollView 4`] = ` + + + - - Item 2 - - - - - Item 3 - - - + - - Item 4 - - - - - Item 5 - - + + + + Item 0 + + + + - - Item 6 - - - - - Item 7 - - - - Item 8 + Scroll to start - - Item 9 - - - - - Item 10 - - - - Item 11 + Scroll to end - + `; -exports[`snapshotAllPages ScrollView 20`] = ` +exports[`snapshotAllPages ScrollView 5`] = ` + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + Scrolling enabled = true + + + + Disable Scrolling + + + + + Enable Scrolling + + + +`; + +exports[`snapshotAllPages ScrollView 5`] = ` + @@ -48540,7 +50546,7 @@ exports[`snapshotAllPages ScrollView 20`] = ` "minWidth": 96, "padding": 5, }, - null, + undefined, ] } > @@ -48558,7 +50564,7 @@ exports[`snapshotAllPages ScrollView 20`] = ` "minWidth": 96, "padding": 5, }, - null, + undefined, ] } > @@ -48576,7 +50582,7 @@ exports[`snapshotAllPages ScrollView 20`] = ` "minWidth": 96, "padding": 5, }, - null, + undefined, ] } > @@ -48594,7 +50600,7 @@ exports[`snapshotAllPages ScrollView 20`] = ` "minWidth": 96, "padding": 5, }, - null, + undefined, ] } > @@ -48612,7 +50618,7 @@ exports[`snapshotAllPages ScrollView 20`] = ` "minWidth": 96, "padding": 5, }, - null, + undefined, ] } > @@ -48620,65 +50626,117 @@ exports[`snapshotAllPages ScrollView 20`] = ` Item 5 - - - - + + Item 6 + + + + + Item 7 + + + - - Add to top - + > + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + - Remove top + setContentContainerStyle - Change height top + setContentInset - +`; + +exports[`snapshotAllPages ScrollView 6`] = ` + + - + + + Item 0 + + + + + Item 1 + + + - - Add to end - - - + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + - - Remove end - + > + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + - Change height end + Deceleration Rate: normal `; -exports[`snapshotAllPages ScrollViewAnimated 1`] = ` - - + - + + Item 0 + + + + + Item 1 + + + - + Item 2 + + + - - Scroll me horizontally - - + "backgroundColor": "#cccccc", + "borderRadius": 3, + "margin": 5, + "minWidth": 96, + "padding": 5, + }, + undefined, + ] + } + > + + Item 3 + - - - -`; - -exports[`snapshotAllPages ScrollViewSimpleExample 1`] = ` - - - + + Item 4 + + + + + Item 5 + + + - - Item 0 - - - + Item 6 + + + + + Item 7 + + + + + Item 8 + + + - - Item 1 - + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + - - Item 2 + + setDisableIntervalMomentum: false - - Item 3 + + setDisableScrollViewPanResponder: false - - - + +`; + +exports[`snapshotAllPages ScrollView 8`] = ` + + + + + STICKY HEADER + + + + Item 0 + + + + + Item 1 + + + - - Item 0 - - - + + Item 2 + + + - - Item 1 - - - + + Item 3 + + + - - Item 2 - - - + + Item 4 + + + - - Item 3 - - - + + Item 5 + + + - - Item 4 - - - + + Item 6 + + + - - Item 5 - - - + + Item 7 + + + - - Item 6 - - - + + Item 8 + + + - - Item 7 - - - + + Item 9 + + + - - Item 8 - - - + + Item 10 + + + - - Item 9 - - - + + Item 11 + + + + + + + + invertStickyHeaders: false + + + + + Scroll to top + + + + + Scroll to bottom + + + + +`; + +exports[`snapshotAllPages ScrollView 9`] = ` + + + + + + Sticky Header 1 + + + - - Item 10 - - - + + Item 0 + + + + + Item 1 + + + - - Item 11 - - - + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + - - Item 12 - - - + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + - - Item 13 - - - + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + - - Item 14 - - - + + Item 11 + + + + + Sticky Header 2 + + + - - Item 15 - - - + + Item 0 + + + + + Item 1 + + + - - Item 16 - - - + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + - - Item 17 - - - + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + - - Item 18 - - - + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + - - Item 19 - - + "minWidth": 96, + "padding": 5, + }, + undefined, + ] + } + > + + Item 11 + - + + + Sticky Header 3 + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + - - Item 5 + + Scroll to top - - Item 6 + + Scroll to bottom - + +`; + +exports[`snapshotAllPages ScrollView 10`] = ` + + + - - Item 7 - - - - - Item 8 - - - + + + + Press to change color + + + + + + + + + + + + + + + + - - Item 9 - - - + + + scroll to top + + + + + - - Item 10 - + + + + scroll to bottom + + + + - - - Item 11 - - + + + + + Press to change color + + + + + + + + + + + + + + + + +`; + +exports[`snapshotAllPages ScrollView 11`] = ` + + + + + + + Button + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + + Keyboard Dismiss Mode + + - - Item 12 + + none - - Item 13 + + on-drag - + + Keyboard Should Persist taps + + - - Item 14 - - + } + > - - Item 15 + + never - - Item 16 + + always - - Item 17 + + handled - + +`; + +exports[`snapshotAllPages ScrollView 12`] = ` + + + Content Size Changed: + original + + + + - - Item 18 - - - + Item 0 + + + + + Item 1 + + + + + Item 2 + + + - - Item 19 - - - - - + Item 3 + + + + + Item 4 + + + + + Item 5 + + + - - Item 0 - - - + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + - - Item 1 - - - + + Item 9 + + + - - Item 2 - - - + + Item 10 + + + + + Item 11 + + + + + + + Change Content Size + + + +`; + +exports[`snapshotAllPages ScrollView 13`] = ` + + + Scroll State: + none + + + + + + Item 0 + + + - - Item 3 - - - + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + - - Item 4 - - - + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + - - Item 5 - - - + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + - - Item 6 - - - + + Item 10 + + + - - Item 7 - - - + + Item 11 + + + + + +`; + +exports[`snapshotAllPages ScrollView 14`] = ` + + + onScroll: + none + + + + + + Item 0 + + + - - Item 8 - - - + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + - - Item 9 - - - + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + - - Item 10 - - - + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + - - Item 11 - - - + + Item 10 + + + + + Item 11 + + + + + +`; + +exports[`snapshotAllPages ScrollView 15`] = ` + + + } + style={ + [ + { + "backgroundColor": "#eeeeee", + "height": 300, + }, + { + "height": 200, + }, + ] + } + > + + + - - Item 12 - - - + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + - - Item 13 - - - + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + - - Item 14 - - - + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + - - Item 15 - - - + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + +`; + +exports[`snapshotAllPages ScrollView 16`] = ` + + + + - - Item 16 - - - + + Item 0 + + + - - Item 17 - - - + + Item 1 + + + - - Item 18 - - - + + Item 2 + + + - - Item 19 - - + "minWidth": 96, + "padding": 5, + }, + undefined, + ] + } + > + + Item 3 + - - - - - - Item 0 - - - + + Item 4 + + + + + Item 5 + + + - - Item 1 - - - + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + - - Item 2 - - - + + Item 9 + + + + + Item 10 + + + - - Item 3 - - - + + Item 11 + + + + + + + removeClippedSubviews: false + + + +`; + +exports[`snapshotAllPages ScrollView 17`] = ` + + + + + + Item 0 + + + + + Item 1 + + + - - Item 4 - - - + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + - - Item 5 - - - + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + - - Item 6 - - - + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + - - Item 7 - - - + + Item 11 + + + + + + + setScrollIndicatorInsets + + + + + showsHorizontalScrollIndicator: true + + + + + showsVerticalScrollIndicator: true + + + +`; + +exports[`snapshotAllPages ScrollView 18`] = ` + + + + + + Item 0 + + + - - Item 8 - - - + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + - - Item 9 - - - + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + - - Item 10 - - - + + Item 7 + + + + + Item 8 + + + - - Item 11 - - - - - Item 12 - - - - - Item 13 - - - - - Item 14 - - - - - Item 15 - - - - - Item 16 - - - - - Item 17 - - - + + Item 9 + + + - - Item 18 - - - + + Item 10 + + + - - Item 19 - - + "minWidth": 96, + "padding": 5, + }, + undefined, + ] + } + > + + Item 11 + - - + + + + snapToEnd: true + + + + + snapToStart: true + + + + + setSnapToInterval + + + + + reset snapToOffsets + + + +`; + +exports[`snapshotAllPages ScrollView 19`] = ` + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + +`; + +exports[`snapshotAllPages ScrollView 20`] = ` + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + + + + Add to top + + + + + Remove top + + + + + Change height top + + + + + + + Add to end + + + + + Remove end + + + + + Change height end + + + + +`; + +exports[`snapshotAllPages ScrollViewAnimated 1`] = ` + + + + + + + + Scroll me horizontally + + + + + + +`; + +exports[`snapshotAllPages ScrollViewSimpleExample 1`] = ` + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + Item 12 + + + + + Item 13 + + + + + Item 14 + + + + + Item 15 + + + + + Item 16 + + + + + Item 17 + + + + + Item 18 + + + + + Item 19 + + + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + Item 12 + + + + + Item 13 + + + + + Item 14 + + + + + Item 15 + + + + + Item 16 + + + + + Item 17 + + + + + Item 18 + + + + + Item 19 + + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + Item 12 + + + + + Item 13 + + + + + Item 14 + + + + + Item 15 + + + + + Item 16 + + + + + Item 17 + + + + + Item 18 + + + + + Item 19 + + + + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + Item 12 + + + + + Item 13 + + + + + Item 14 + + + + + Item 15 + + + + + Item 16 + + + + + Item 17 + + + + + Item 18 + + + + + Item 19 + + + + + - + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + Item 12 + + + + + Item 13 + + + + + Item 14 + + + + + Item 15 + + + + + Item 16 + + + + + Item 17 + + + + + Item 18 + + + + + Item 19 + + + + + + + + + Item 0 + + + + + Item 1 + + + + + Item 2 + + + + + Item 3 + + + + + Item 4 + + + + + Item 5 + + + + + Item 6 + + + + + Item 7 + + + + + Item 8 + + + + + Item 9 + + + + + Item 10 + + + + + Item 11 + + + + + Item 12 + + + + + Item 13 + + + + + Item 14 + + + + + Item 15 + + + + + Item 16 + + + + + Item 17 + + + + + Item 18 + + + + + Item 19 + + + + + + +`; + +exports[`snapshotAllPages SectionList 1`] = ` +[ + + + Menu + + , + + + + contentInset top: 44 + + + + + + Toggle header size + + + + + + + + + + Main dishes + + + + + + Pizza + + + + + + + Burger + + + + + + + Risotto + + + + + + + Sides + + + + + + French Fries + + + + + + + Onion Rings + + + + + + + Fried Shrimps + + + + + + + + , +] +`; + +exports[`snapshotAllPages SectionList 2`] = ` + + + + + + + + Test + + + + + + + + + + Main dishes + + + + + Pizza + + + + + - Item 0 + Burger + + - Item 1 + Risotto + + + + + Sides + + + - Item 2 + French Fries + + - Item 3 + Onion Rings + + - Item 4 + Fried Shrimps + + + + + + +`; + +exports[`snapshotAllPages SectionList 3`] = ` + + + + + + + + + Main dishes + + + - Item 5 + Pizza + + - Item 6 + Burger + + - Item 7 + Risotto + + + + + Sides + + + - Item 8 + French Fries + + - Item 9 + Onion Rings + + + + Fried Shrimps + + + + + + + + +`; + +exports[`snapshotAllPages SectionList 4`] = ` + + + + + - + + + + - Item 10 + Section separator for leading undefined and trailing Pizza has not been pressed - - Item 11 - + + Pizza + + + + + separator for leading Pizza and trailing Burger has not been pressed + + + + - - Item 12 - + + Burger + + + + + separator for leading Burger and trailing Risotto has not been pressed + + + + + + Risotto + + + + + Section separator for leading Risotto and trailing undefined has not been pressed + + + + + + + - + + + + - Item 13 + Section separator for leading undefined and trailing French Fries has not been pressed - - Item 14 - + + French Fries + + + + + separator for leading French Fries and trailing Onion Rings has not been pressed + + + + - - Item 15 - + + Onion Rings + + + + + separator for leading Onion Rings and trailing Fried Shrimps has not been pressed + + + + + + Fried Shrimps + + + + + Section separator for leading Fried Shrimps and trailing undefined has not been pressed + + + + + + + + + +`; + +exports[`snapshotAllPages SectionList 5`] = ` + + + + stickySectionHeadersEnabled false + + + + + + Sticky On + + + + + + + + + - - Item 16 - - + Main dishes + + + - Item 17 + Pizza + + - Item 18 + Burger + + - Item 19 + Risotto - - - + + + + Sides + + + - Item 0 + French Fries + + - Item 1 + Onion Rings + + - Item 2 + Fried Shrimps - + + + + + +`; + +exports[`snapshotAllPages SectionList 6`] = ` + + + + inverted false + + + + + + Toggle true + + + + + + + + + - - Item 3 - - + Main dishes + + + - Item 4 + Pizza + + - Item 5 + Burger + + - Item 6 + Risotto - + + + - - Item 7 - - + Sides + + + - Item 8 + French Fries + + - Item 9 + Onion Rings + + - Item 10 + Fried Shrimps - + + + + + +`; + +exports[`snapshotAllPages SectionList 7`] = ` + + + + - - Item 11 - - + Main dishes + + + - Item 12 + Pizza + + - Item 13 + Burger + + - Item 14 + Risotto + + + + + Sides + + + - Item 15 + French Fries + + - Item 16 + Onion Rings + + - Item 17 + Fried Shrimps + + + - - Item 18 + + Virtualized + : + - - Item 19 - - - - - - -`; - -exports[`snapshotAllPages SectionList 1`] = ` -[ - - - Menu - - , - - - - contentInset top: 44 - - - - - - Toggle header size - - - - - - - - - + Log Viewable + : + + - Main dishes - + value={false} + /> - + + Debug + : + + - - Pizza - - + } + value={false} + /> - + + Inverted + : + + - - Burger - - + } + value={false} + /> + + + + scroll to: + + - - Risotto - + + + Top + + + - - - Sides - - - - - French Fries - + + + 3rd Section + + + - - Onion Rings - + + + 6th Section + + + - - Fried Shrimps - + + + Out of Viewable Area (See warning) + + + - - - - , -] -`; - -exports[`snapshotAllPages SectionList 2`] = ` - - - + - - - - - Test - - - - - - - Onion Rings - - - - - - Fried Shrimps - - - - - - - - -`; - -exports[`snapshotAllPages SectionList 3`] = ` - - - - - - - - - Main dishes - + + Onion Rings + + + + Fried Shrimps + + + + + - - Pizza - - - - - - - Burger - - - - - - - Risotto - - - - - - - Sides - - - - - - French Fries - - - - - - - Onion Rings - - - - - - - Fried Shrimps - - - - - - - - -`; - -exports[`snapshotAllPages SectionList 4`] = ` - - - - - - Main dishes - - - - - - - Section separator for leading undefined and trailing Pizza has not been pressed - - - - - Pizza - - - - - separator for leading Pizza and trailing Burger has not been pressed - - - - - - - - - Burger - - - - - separator for leading Burger and trailing Risotto has not been pressed - - - - - - - - - Risotto - - - - - Section separator for leading Risotto and trailing undefined has not been pressed - - - - - - - - Sides - - - - - - - Section separator for leading undefined and trailing French Fries has not been pressed - - - - - French Fries - - - - - separator for leading French Fries and trailing Onion Rings has not been pressed - - - - - - - - - Onion Rings - - - - - separator for leading Onion Rings and trailing Fried Shrimps has not been pressed - - - - - - - - - Fried Shrimps - - - - - Section separator for leading Fried Shrimps and trailing undefined has not been pressed - - - - - - - - - -`; - -exports[`snapshotAllPages SectionList 5`] = ` - - - - stickySectionHeadersEnabled false - - - - - - Sticky On - - - - - - - - - - Main dishes - - - - - - Pizza - - - - - - - Burger - - - - - - - Risotto - - - - - - - Sides - - - - - - French Fries - - - - - - - Onion Rings - - - - - - - Fried Shrimps - - - - - - - - -`; - -exports[`snapshotAllPages SectionList 6`] = ` - - - - inverted false - - - - - - Toggle true - - - - - - - - - - Main dishes - - - - - - Pizza - - - - - - - Burger - - - - - - - Risotto - - - - - - - Sides - - - - - - French Fries - - - - - - - Onion Rings - - - - - - - Fried Shrimps - - - - - - - - -`; - -exports[`snapshotAllPages SectionList 7`] = ` - - - - - - - - Virtualized - : - - - - - - Log Viewable - : - - - - - - Debug - : - - - - - - Inverted - : - - - - - - - - scroll to: - - - - - - - Top - - - - - - - - - - - 3rd Section - - - - - - - - - - - 6th Section - - - - - - - - - - - Out of Viewable Area (See warning) - - - - - - - - - + } + refreshing={false} + renderItem={[Function]} + scrollEventThrottle={0.0001} + stickyHeaderIndices={ + [ + 1, + 3, + 6, + 10, + ] + } + style={ + { + "backgroundColor": "white", + } + } + viewabilityConfig={ + { + "minimumViewTime": 3000, + "viewAreaCoveragePercentThreshold": 100, + "waitForInteraction": true, + } + } + > + + + + + + + LIST HEADER + + + + + + + + + SECTION HEADER: + empty section + + + + + + + + SECTION FOOTER: + empty section + + + + + + + + SECTION HEADER: + s1 + + + + + + + + + SECTION SEPARATOR + + + + + Item In Header Section + - + Section s1 + + + + + + SECTION SEPARATOR + + + + + + + + SECTION FOOTER: + s1 + + + + + + + + SECTION HEADER: + s2 + + + + + + + + + SECTION SEPARATOR + + + + + ITEM SEPARATOR + + + + + + + + + SECTION SEPARATOR + + + + + + + + SECTION FOOTER: + s2 + + + + + + + + SECTION HEADER: + 0 - 9 + + + + + + + + + + + LIST FOOTER + + + + + + + + + + + + Main dishes + + + + + + Pizza + + + + + + + Burger + + + + + + + Risotto + + + + + + + Sides + + + + + + French Fries + + + + + + + Onion Rings + + + + + + + Fried Shrimps + + + + + + + + +`; + +exports[`snapshotAllPages SectionList 11`] = ` + + + + + + + + + + Main dishes + + + + + + Pizza + + + + + + + Burger + + + + + + + Risotto + + + + + + + Sides + + + + + + French Fries + + + + + + + Onion Rings + + + + + + + Fried Shrimps + + + + + + + + +`; + +exports[`snapshotAllPages SectionList 12`] = ` + + + + + + + + + + Main dishes + + + + + + Pizza + + + + + + + Burger + + + + + + + Risotto + + + + + + + Sides + + + + + + French Fries + + + + + + + Onion Rings + + + + + + + Fried Shrimps + + + + + + + + +`; + +exports[`snapshotAllPages Share 1`] = ` + + + Native Experience + + + Our top priority for React Native is to match the expectations people have for each platform. This is why React Native renders to platform primitives. We value native look-and-feel over cross-platform consistency. For example, the TextInput in React Native renders to a UITextField on iOS. This ensures that integration with password managers and keyboard controls work out of the box. By using platform primitives, React Native apps are also able to stay up-to-date with design and behavior changes from new releases of Android and iOS. + + + + + + SHARE + + + + + +`; + +exports[`snapshotAllPages Share 2`] = ` + + + Massive Scale + + + Hundreds of screens in the Facebook app are implemented with React Native. The Facebook app is used by billions of people on a huge range of devices. This is why we invest in the most challenging problems at scale. Deploying React Native in our apps lets us identify problems that we wouldn’t see at a smaller scale. For example, Facebook focuses on improving performance across a broad spectrum of devices from the newest iPhone to many older generations of Android devices. This focus informs our architecture projects such as Hermes, Fabric, and TurboModules. + + + + + + SHARE + + + + + +`; + +exports[`snapshotAllPages Share 3`] = ` + + + action: + null + + + Create native apps + + + React Native combines the best parts of native development with React, a best-in-class JavaScript library for building user interfaces. + + + + + + SHARE + + + + + +`; + +exports[`snapshotAllPages SwipeableCard 1`] = ` +[ + + + + + + + + + Section # + 0 + + + + + + + + Section # + 1 + + + + + + + + Section # + 2 + + + + + + + + Section # + 3 + + + + + + + + Section # + 4 + + + + + + + + , + + + + + + + + + Section # + 0 + + + + + + + + Section # + 1 + + + + + + + + Section # + 2 + + + + + + + + Section # + 3 + + + + + + + + Section # + 4 + + + + + + + + , +] +`; + +exports[`snapshotAllPages Switch 1`] = ` + + + + + Off + + + + + + On + + + +`; + +exports[`snapshotAllPages Switch 2`] = ` + + + + + Off + + + + + + On + + + +`; + +exports[`snapshotAllPages Switch 3`] = ` + + + + + + Off + + + + + + + On + + + +`; + +exports[`snapshotAllPages Switch 4`] = ` + +`; + +exports[`snapshotAllPages Switch 5`] = ` + + + + +`; + +exports[`snapshotAllPages Switch 6`] = ` + + + +`; + +exports[`snapshotAllPages Switch 7`] = ` + + + +`; + +exports[`snapshotAllPages Switch 8`] = ` + + + + + + + + + + +`; + +exports[`snapshotAllPages Text 1`] = ` + + + Text with background color only + + + Text with background color and uniform borderRadii + + + Text with background color and non-uniform borders + + + Text with borderWidth + + + Text with background AND borderWidth + + +`; + +exports[`snapshotAllPages Text 2`] = ` + + + Truncated text is baaaaad. + + + Shrinking to fit available space is much better! + + + Add text to me to watch me shrink! + + + Multiline text component shrinking is supported, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy + + + Text limited by height, watch as this reeeeaaaally loooooong teeeeeeext grooooows and then shriiiinks as you add text to me! ioahsdia soady auydoa aoisyd aosdy + + + + Differently sized nested elements will shrink together. + + + LARGE TEXT! + + + + + Reset + + + Remove Text + + + Add Text + + + +`; + +exports[`snapshotAllPages Text 3`] = ` +[ + + + + This is adjusting text. + + + , + + + + + + Set Height to 20 + + + + + , + + + + + + Set Height to 40 + + + + + , + + + + + + Set Height to 60 + + + + + , +] +`; + +exports[`snapshotAllPages Text 4`] = ` + + + None: + + WillNotHaveAHyphenWhenBreakingForNewLine + , + + + Full: + + WillHaveAHyphenWhenBreakingForNewLine + , +] +`; + +exports[`snapshotAllPages Text 6`] = ` + + This text is indented by 10px padding on all sides. + +`; + +exports[`snapshotAllPages Text 7`] = ` + + + Increase size + + + Decrease size + + + + Language + + + + + + Arabic + + + + + + + Chinese + + + + + - } - refreshing={false} - renderItem={[Function]} - scrollEventThrottle={0.0001} - stickyHeaderIndices={ - [ - 1, - 3, - 6, - 10, - ] - } - style={ - { - "backgroundColor": "white", - } - } - viewabilityConfig={ - { - "minimumViewTime": 3000, - "viewAreaCoveragePercentThreshold": 100, - "waitForInteraction": true, - } - } - > - - - - - - - LIST HEADER - - - - + English + + + - - - SECTION HEADER: - empty section - - - - - - - - SECTION FOOTER: - empty section - - - + Emoji + + + - - - SECTION HEADER: - s1 - - - + German + + + - - - - SECTION SEPARATOR - - - - - Item In Header Section - - - Section s1 - - - - - - SECTION SEPARATOR - - - + } + > + Greek + + + - - - SECTION FOOTER: - s1 - - - + Hebrew + + + - - - SECTION HEADER: - s2 - - - + Hindi + + + - - - - SECTION SEPARATOR - - - - - ITEM SEPARATOR - - - + } + > + Igbo + + + - - - - SECTION SEPARATOR - - - + } + > + Irish + + + - - - SECTION FOOTER: - s2 - - - + Japanese + + + - - - SECTION HEADER: - 0 - 9 - - - + Korean + + + - - - - - - LIST FOOTER - - - + Norwegian + - - - -`; - -exports[`snapshotAllPages Share 1`] = ` - - - Native Experience - - - Our top priority for React Native is to match the expectations people have for each platform. This is why React Native renders to platform primitives. We value native look-and-feel over cross-platform consistency. For example, the TextInput in React Native renders to a UITextField on iOS. This ensures that integration with password managers and keyboard controls work out of the box. By using platform primitives, React Native apps are also able to stay up-to-date with design and behavior changes from new releases of Android and iOS. - - - - - SHARE - + + Polish + + - - - -`; - -exports[`snapshotAllPages Share 2`] = ` - - - Massive Scale - - - Hundreds of screens in the Facebook app are implemented with React Native. The Facebook app is used by billions of people on a huge range of devices. This is why we invest in the most challenging problems at scale. Deploying React Native in our apps lets us identify problems that we wouldn’t see at a smaller scale. For example, Facebook focuses on improving performance across a broad spectrum of devices from the newest iPhone to many older generations of Android devices. This focus informs our architecture projects such as Hermes, Fabric, and TurboModules. - - - - - SHARE - - - - - -`; - -exports[`snapshotAllPages Share 3`] = ` - - - action: - null - - - Create native apps - - - React Native combines the best parts of native development with React, a best-in-class JavaScript library for building user interfaces. - - - + + Romanian + + + - - SHARE - + + Russian + + - - - -`; - -exports[`snapshotAllPages SwipeableCard 1`] = ` -[ - - - - - - - - Section # - 0 - - - - - - - - Section # - 1 - - - - - - - - Section # - 2 - - - - - - - - Section # - 3 - - - - - - - - Section # - 4 - - - - - + + Swedish + + - - , - - - + - - - - - Section # - 0 - - - - - - - - Section # - 1 - - - - - - - - Section # - 2 - - - - - - - - Section # - 3 - - - - - - - - Section # - 4 - - - - - + + Thai + + - , -] -`; - -exports[`snapshotAllPages Switch 1`] = ` - - - + + - - Off + The quick brown fox jumps over the lazy dog. - + Alignment: + + - - On - - - -`; - -exports[`snapshotAllPages Switch 2`] = ` - - - - - Off - - - - + + + Left Align + + + + - - On - - - -`; - -exports[`snapshotAllPages Switch 3`] = ` - - - - - - Off - - - - + + Center Align + + + + - - - On - + + + Right Align + + + `; -exports[`snapshotAllPages Switch 4`] = ` - -`; - -exports[`snapshotAllPages Switch 5`] = ` - - - + Sans-Serif + , + - -`; - -exports[`snapshotAllPages Switch 6`] = ` - - + Sans-Serif Bold + , + - -`; - -exports[`snapshotAllPages Switch 7`] = ` - - + Serif + , + - -`; - -exports[`snapshotAllPages Switch 8`] = ` - - + Serif Bold + , + - - - - , + - - , + - - + } + > + Unknown Font Family + , +] `; -exports[`snapshotAllPages Text 1`] = ` +exports[`snapshotAllPages Text 9`] = ` + + + showSoftInputOnFocus: false + + + + + + +`; + +exports[`snapshotAllPages TextInput 20`] = ` + + + Uncontrolled: + + + + Controlled: + + + + + + + Update controlled Input + + + + + +`; + +exports[`snapshotAllPages TextInput 21`] = ` + + + Do not clear text on focus: + + + + Clear text on focus: + + + +`; + +exports[`snapshotAllPages TextInput 22`] = ` + + + Measure: + setTimeout + ( + fn, 200 + ) - + 0 + + + + + Measure: + setTimeout + ( + fn, 500 + ) - + 0 + + `; @@ -81221,6 +95153,8 @@ exports[`snapshotAllPages Timers 2`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81286,6 +95220,8 @@ exports[`snapshotAllPages Timers 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81340,6 +95276,8 @@ exports[`snapshotAllPages Timers 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81394,6 +95332,8 @@ exports[`snapshotAllPages Timers 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81448,6 +95388,8 @@ exports[`snapshotAllPages Timers 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81502,6 +95444,8 @@ exports[`snapshotAllPages Timers 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81565,6 +95509,8 @@ exports[`snapshotAllPages Timers 4`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81630,6 +95576,8 @@ exports[`snapshotAllPages Timers 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81689,6 +95637,8 @@ exports[`snapshotAllPages Timers 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81744,6 +95694,8 @@ exports[`snapshotAllPages Timers 5`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81927,6 +95879,8 @@ exports[`snapshotAllPages Touchable* and onPress 2`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -81996,6 +95950,8 @@ exports[`snapshotAllPages Touchable* and onPress 3`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82181,6 +96137,8 @@ exports[`snapshotAllPages Touchable* and onPress 8`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82267,6 +96225,8 @@ exports[`snapshotAllPages Touchable* and onPress 9`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82412,6 +96372,8 @@ exports[`snapshotAllPages Touchable* and onPress 11`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82550,6 +96512,8 @@ exports[`snapshotAllPages Touchable* and onPress 12`] = ` "checked": undefined, "disabled": undefined, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82604,6 +96568,8 @@ exports[`snapshotAllPages Touchable* and onPress 14`] = ` "checked": undefined, "disabled": true, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82659,6 +96625,8 @@ exports[`snapshotAllPages Touchable* and onPress 14`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82812,6 +96780,8 @@ exports[`snapshotAllPages Touchable* and onPress 14`] = ` "checked": undefined, "disabled": true, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82862,6 +96832,8 @@ exports[`snapshotAllPages Touchable* and onPress 14`] = ` "checked": undefined, "disabled": false, "expanded": undefined, + "multiselectable": undefined, + "required": undefined, "selected": undefined, } } @@ -82904,6 +96876,152 @@ exports[`snapshotAllPages Touchable* and onPress 14`] = ` `; +exports[`snapshotAllPages Touchable* and onPress 15`] = ` + + + + Touchable Highlight (Control 1 in Set of 3) + + + + + Touchable Opacity (Control 2 in Set of 3) + + + + TouchableWithoutFeedback (Control 3 in Set of 3) + + +`; + exports[`snapshotAllPages TransferProperties 1`] = ` + + + + + RepeatedlyFetch + + + + GetCurrentPattern(UIA_ValuePatternId, reinterpret_cast(&valuePattern)); if (SUCCEEDED(hr) && valuePattern) { hr = valuePattern->get_Value(&value); @@ -389,6 +392,34 @@ void DumpUIAPatternInfo(IUIAutomationElement *pTarget, const winrt::Windows::Dat } expandCollapsePattern->Release(); } + + // Dump ISelectionItemProvider Information + ISelectionItemProvider *selectionItemPattern; + hr = pTarget->GetCurrentPattern(UIA_SelectionItemPatternId, reinterpret_cast(&selectionItemPattern)); + if (SUCCEEDED(hr) && selectionItemPattern) { + hr = selectionItemPattern->get_IsSelected(&isSelected); + if (SUCCEEDED(hr)) { + InsertBooleanValueIfNotDefault(result, L"SelectionItemPattern.IsSelected", isSelected); + } + selectionItemPattern->Release(); + } + + // Dump ISelectionProvider Information + ISelectionProvider *selectionPattern; + hr = pTarget->GetCurrentPattern(UIA_SelectionPatternId, reinterpret_cast(&selectionPattern)); + if (SUCCEEDED(hr) && selectionPattern) { + hr = selectionPattern->get_CanSelectMultiple(&multipleSelection); + if (SUCCEEDED(hr)) { + InsertBooleanValueIfNotDefault(result, L"SelectionPattern.CanSelectMultiple", multipleSelection, false); + } + hr = selectionPattern->get_IsSelectionRequired(&selectionRequired); + if (SUCCEEDED(hr)) { + InsertBooleanValueIfNotDefault(result, L"SelectionPattern.IsSelectionRequired", selectionRequired, false); + } + selectionPattern->Release(); + } + + ::SysFreeString(value); } winrt::Windows::Data::Json::JsonObject DumpUIATreeRecurse( diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp index e5160eee6a6..a06a7a675cc 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp @@ -11,7 +11,21 @@ namespace winrt::Microsoft::ReactNative::implementation { CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider( const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept - : m_view{componentView} {} + : m_view{componentView} { + auto strongView = m_view.view(); + + if (!strongView) + return; + + auto props = std::static_pointer_cast( + winrt::get_self(strongView)->props()); + if (!props) + return; + + if (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value()) { + AddSelectionItemsToContainer(this); + } +} HRESULT __stdcall CompositionDynamicAutomationProvider::Navigate( NavigateDirection direction, @@ -203,6 +217,18 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE AddRef(); } + if (patternId == UIA_SelectionPatternId && props->accessibilityState.has_value() && + props->accessibilityState->multiselectable.has_value() && props->accessibilityState->required.has_value()) { + *pRetVal = static_cast(this); + AddRef(); + } + + if (patternId == UIA_SelectionItemPatternId && props->accessibilityState.has_value() && + props->accessibilityState->selected.has_value()) { + *pRetVal = static_cast(this); + AddRef(); + } + return S_OK; } @@ -346,6 +372,7 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT case UIA_IsOffscreenPropertyId: { pRetVal->vt = VT_BOOL; pRetVal->boolVal = (compositionView->getClipState() == ClipState::FullyClipped) ? VARIANT_TRUE : VARIANT_FALSE; + break; } case UIA_HelpTextPropertyId: { pRetVal->vt = VT_BSTR; @@ -552,4 +579,169 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::Collapse() { return S_OK; } +HRESULT __stdcall CompositionDynamicAutomationProvider::get_CanSelectMultiple(BOOL *pRetVal) { + if (pRetVal == nullptr) + return E_POINTER; + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + + auto props = + std::static_pointer_cast(winrt::get_self(strongView)->props()); + + if (props == nullptr) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = (props->accessibilityState.has_value() && props->accessibilityState->multiselectable.has_value()) + ? props->accessibilityState->multiselectable.value() + : false; + + return S_OK; +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsSelectionRequired(BOOL *pRetVal) { + if (pRetVal == nullptr) + return E_POINTER; + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + + auto props = std::static_pointer_cast( + winrt::get_self(strongView)->props()); + + if (props == nullptr) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = (props->accessibilityState.has_value() && props->accessibilityState->required.has_value()) + ? props->accessibilityState->required.value() + : false; + + return S_OK; +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::GetSelection(SAFEARRAY **pRetVal) { + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + + std::vector selectedItems; + for (size_t i = 0; i < m_selectionItems.size(); i++) { + auto selectionItem = m_selectionItems.at(i); + auto provider = selectionItem.as(); + BOOL selected; + auto hr = provider->get_IsSelected(&selected); + if (hr == S_OK && selected) { + selectedItems.push_back(int(i)); + } + } + + *pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, ULONG(selectedItems.size())); + if (*pRetVal == nullptr) + return E_OUTOFMEMORY; + + for (size_t i = 0; i < selectedItems.size(); i++) { + auto pos = static_cast(i); + SafeArrayPutElement(*pRetVal, &pos, m_selectionItems.at(selectedItems.at(i)).get()); + } + return S_OK; +} + +void CompositionDynamicAutomationProvider::AddToSelectionItems(winrt::com_ptr &item) { + if (std::find(m_selectionItems.begin(), m_selectionItems.end(), item) != m_selectionItems.end()) { + return; + } + m_selectionItems.push_back(item); +} + +void CompositionDynamicAutomationProvider::RemoveFromSelectionItems(winrt::com_ptr &item) { + std::erase(m_selectionItems, item); +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::AddToSelection() { + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + + DispatchAccessibilityAction(m_view, "addToSelection"); + return S_OK; +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::get_IsSelected(BOOL *pRetVal) { + if (pRetVal == nullptr) + return E_POINTER; + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + + auto props = std::static_pointer_cast( + winrt::get_self(strongView)->props()); + + if (props == nullptr) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value()) + ? props->accessibilityState->selected.value() + : false; + + return S_OK; +} + +IRawElementProviderSimple *findSelectionContainer(winrt::Microsoft::ReactNative::ComponentView current) { + if (!current) + return nullptr; + + auto props = std::static_pointer_cast( + winrt::get_self(current)->props()); + if (props->accessibilityState.has_value() && props->accessibilityState->multiselectable.has_value() && + props->accessibilityState->required.has_value()) { + auto uiaProvider = + current.as()->EnsureUiaProvider(); + if (uiaProvider != nullptr) { + auto spProviderSimple = uiaProvider.try_as(); + if (spProviderSimple != nullptr) { + spProviderSimple->AddRef(); + return spProviderSimple.get(); + } + } + } else { + return findSelectionContainer(current.Parent()); + } + return nullptr; +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::get_SelectionContainer(IRawElementProviderSimple **pRetVal) { + if (pRetVal == nullptr) + return E_POINTER; + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = findSelectionContainer(strongView.Parent()); + return S_OK; +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::RemoveFromSelection() { + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + DispatchAccessibilityAction(m_view, "removeFromSelection"); + return S_OK; +} + +HRESULT __stdcall CompositionDynamicAutomationProvider::Select() { + auto strongView = m_view.view(); + + if (!strongView) + return UIA_E_ELEMENTNOTAVAILABLE; + DispatchAccessibilityAction(m_view, "select"); + return S_OK; +} + } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h index fd37624b580..bf403a9dad3 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h @@ -17,7 +17,9 @@ class CompositionDynamicAutomationProvider : public winrt::implements< IScrollItemProvider, IValueProvider, IToggleProvider, - IExpandCollapseProvider> { + IExpandCollapseProvider, + ISelectionProvider, + ISelectionItemProvider> { public: CompositionDynamicAutomationProvider( const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept; @@ -57,8 +59,24 @@ class CompositionDynamicAutomationProvider : public winrt::implements< virtual HRESULT __stdcall Expand() override; virtual HRESULT __stdcall Collapse() override; + // inherited via ISelectionProvider + virtual HRESULT __stdcall get_CanSelectMultiple(BOOL *pRetVal) override; + virtual HRESULT __stdcall get_IsSelectionRequired(BOOL *pRetVal) override; + virtual HRESULT __stdcall GetSelection(SAFEARRAY **pRetVal) override; + + // inherited via ISelectionItemProvider + virtual HRESULT __stdcall AddToSelection() override; + virtual HRESULT __stdcall get_IsSelected(BOOL *pRetVal) override; + virtual HRESULT __stdcall get_SelectionContainer(IRawElementProviderSimple **pRetVal) override; + virtual HRESULT __stdcall RemoveFromSelection() override; + virtual HRESULT __stdcall Select() override; + + void AddToSelectionItems(winrt::com_ptr &item); + void RemoveFromSelectionItems(winrt::com_ptr &item); + private: ::Microsoft::ReactNative::ReactTaggedView m_view; + std::vector> m_selectionItems; }; } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index 9f7578a0451..7969adbbbc0 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -747,6 +747,19 @@ void ComponentView::updateAccessibilityProps( UIA_LiveSettingPropertyId, oldViewProps.accessibilityLiveRegion, newViewProps.accessibilityLiveRegion); + + if ((oldViewProps.accessibilityState.has_value() && oldViewProps.accessibilityState->selected.has_value()) != + ((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value()))) { + auto compProvider = + m_uiaProvider.try_as(); + if (compProvider) { + if ((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value())) { + winrt::Microsoft::ReactNative::implementation::AddSelectionItemsToContainer(compProvider.get()); + } else { + winrt::Microsoft::ReactNative::implementation::RemoveSelectionItemsFromContainer(compProvider.get()); + } + } + } } std::optional ComponentView::getAcccessiblityValue() noexcept { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp index db919ea10bf..11e1f4881d4 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp @@ -214,6 +214,30 @@ ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept { } } +void AddSelectionItemsToContainer(CompositionDynamicAutomationProvider *provider) noexcept { + winrt::com_ptr selectionContainer; + provider->get_SelectionContainer(selectionContainer.put()); + if (!selectionContainer) + return; + auto selectionContainerProvider = selectionContainer.as(); + auto simpleProvider = static_cast(provider); + winrt::com_ptr simpleProviderPtr; + simpleProviderPtr.copy_from(simpleProvider); + selectionContainerProvider->AddToSelectionItems(simpleProviderPtr); +} + +void RemoveSelectionItemsFromContainer(CompositionDynamicAutomationProvider *provider) noexcept { + winrt::com_ptr selectionContainer; + provider->get_SelectionContainer(selectionContainer.put()); + if (!selectionContainer) + return; + auto selectionContainerProvider = selectionContainer.as(); + auto simpleProvider = static_cast(provider); + winrt::com_ptr simpleProviderPtr; + simpleProviderPtr.copy_from(simpleProvider); + selectionContainerProvider->RemoveFromSelectionItems(simpleProviderPtr); +} + ToggleState GetToggleState(const std::optional &state) noexcept { if (state.has_value()) { if (state->checked == facebook::react::AccessibilityState::Checked) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h index 20b03314aac..0104c5853e7 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -37,5 +38,9 @@ void DispatchAccessibilityAction(::Microsoft::ReactNative::ReactTaggedView &view ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept; +void AddSelectionItemsToContainer(CompositionDynamicAutomationProvider *provider) noexcept; + +void RemoveSelectionItemsFromContainer(CompositionDynamicAutomationProvider *provider) noexcept; + ToggleState GetToggleState(const std::optional &state) noexcept; } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h new file mode 100644 index 00000000000..e1ba1e6a3fd --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +namespace facebook::react { + +enum class AccessibilityTraits : uint32_t { + None = 0, + Button = (1 << 0), + Link = (1 << 1), + Image = (1 << 2), + Selected = (1 << 3), + PlaysSound = (1 << 4), + KeyboardKey = (1 << 5), + StaticText = (1 << 6), + SummaryElement = (1 << 7), + NotEnabled = (1 << 8), + UpdatesFrequently = (1 << 9), + SearchField = (1 << 10), + StartsMediaSession = (1 << 11), + Adjustable = (1 << 12), + AllowsDirectInteraction = (1 << 13), + CausesPageTurn = (1 << 14), + Header = (1 << 15), + Switch = (1 << 16), + TabBar = (1 << 17), +}; + +constexpr enum AccessibilityTraits operator|( + const enum AccessibilityTraits lhs, + const enum AccessibilityTraits rhs) { + return (enum AccessibilityTraits)((uint32_t)lhs | (uint32_t)rhs); +} + +constexpr enum AccessibilityTraits operator&( + const enum AccessibilityTraits lhs, + const enum AccessibilityTraits rhs) { + return (enum AccessibilityTraits)((uint32_t)lhs & (uint32_t)rhs); +} + +struct AccessibilityAction { + std::string name{""}; + std::optional label{}; +}; + +inline static bool operator==( + const AccessibilityAction& lhs, + const AccessibilityAction& rhs) { + return lhs.name == rhs.name && lhs.label == rhs.label; +} + +inline static bool operator!=( + const AccessibilityAction& lhs, + const AccessibilityAction& rhs) { + return !(rhs == lhs); +} + +struct AccessibilityState { + bool disabled{false}; + std::optional selected{std::nullopt}; // [Windows] - Do not remove; required for Windows ISelectionItemProvider Implementation + bool busy{false}; + std::optional expanded{std::nullopt}; + std::optional multiselectable{std::nullopt}; // [Windows] - Do not remove; required for Windows ISelectionProvider Implementation + std::optional required{std::nullopt}; // [Windows] - Do not remove; required for Windows ISelectionProvider Implementation + enum { Unchecked, Checked, Mixed, None } checked{None}; +}; + +constexpr bool operator==( + const AccessibilityState& lhs, + const AccessibilityState& rhs) { + return lhs.disabled == rhs.disabled && lhs.selected == rhs.selected && + lhs.checked == rhs.checked && lhs.busy == rhs.busy && + lhs.expanded == rhs.expanded; +} + +constexpr bool operator!=( + const AccessibilityState& lhs, + const AccessibilityState& rhs) { + return !(rhs == lhs); +} + +struct AccessibilityLabelledBy { + std::vector value{}; +}; + +inline static bool operator==( + const AccessibilityLabelledBy& lhs, + const AccessibilityLabelledBy& rhs) { + return lhs.value == rhs.value; +} + +inline static bool operator!=( + const AccessibilityLabelledBy& lhs, + const AccessibilityLabelledBy& rhs) { + return !(lhs == rhs); +} + +struct AccessibilityValue { + std::optional min; + std::optional max; + std::optional now; + std::optional text{}; +}; + +constexpr bool operator==( + const AccessibilityValue& lhs, + const AccessibilityValue& rhs) { + return lhs.min == rhs.min && lhs.max == rhs.max && lhs.now == rhs.now && + lhs.text == rhs.text; +} + +constexpr bool operator!=( + const AccessibilityValue& lhs, + const AccessibilityValue& rhs) { + return !(rhs == lhs); +} + +enum class ImportantForAccessibility : uint8_t { + Auto, + Yes, + No, + NoHideDescendants, +}; + +enum class AccessibilityLiveRegion : uint8_t { + None, + Polite, + Assertive, +}; + +enum class AccessibilityRole { + None, + Button, + Dropdownlist, + Togglebutton, + Link, + Search, + Image, + Keyboardkey, + Text, + Adjustable, + Imagebutton, + Header, + Summary, + Alert, + Checkbox, + Combobox, + Menu, + Menubar, + Menuitem, + Progressbar, + Radio, + Radiogroup, + Scrollbar, + Spinbutton, + Switch, + Tab, + Tabbar, + Tablist, + Timer, + List, + Toolbar, + Grid, + Pager, + Scrollview, + Horizontalscrollview, + Viewgroup, + Webview, + Drawerlayout, + Slidingdrawer, + Iconmenu, +}; + +enum class Role { + Alert, + Alertdialog, + Application, + Article, + Banner, + Button, + Cell, + Checkbox, + Columnheader, + Combobox, + Complementary, + Contentinfo, + Definition, + Dialog, + Directory, + Document, + Feed, + Figure, + Form, + Grid, + Group, + Heading, + Img, + Link, + List, + Listitem, + Log, + Main, + Marquee, + Math, + Menu, + Menubar, + Menuitem, + Meter, + Navigation, + None, + Note, + Option, + Presentation, + Progressbar, + Radio, + Radiogroup, + Region, + Row, + Rowgroup, + Rowheader, + Scrollbar, + Searchbox, + Separator, + Slider, + Spinbutton, + Status, + Summary, + Switch, + Tab, + Table, + Tablist, + Tabpanel, + Term, + Timer, + Toolbar, + Tooltip, + Tree, + Treegrid, + Treeitem, +}; + +} // namespace facebook::react diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h new file mode 100644 index 00000000000..19826f1abbe --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h @@ -0,0 +1,795 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace facebook::react { + +inline void fromString(const std::string& string, AccessibilityTraits& result) { + if (string == "none") { + result = AccessibilityTraits::None; + return; + } + if (string == "button" || string == "togglebutton") { + result = AccessibilityTraits::Button; + return; + } + if (string == "link") { + result = AccessibilityTraits::Link; + return; + } + if (string == "image" || string == "img") { + result = AccessibilityTraits::Image; + return; + } + if (string == "selected") { + result = AccessibilityTraits::Selected; + return; + } + if (string == "plays") { + result = AccessibilityTraits::PlaysSound; + return; + } + if (string == "keyboardkey" || string == "key") { + result = AccessibilityTraits::KeyboardKey; + return; + } + if (string == "text") { + result = AccessibilityTraits::StaticText; + return; + } + if (string == "disabled") { + result = AccessibilityTraits::NotEnabled; + return; + } + if (string == "frequentUpdates") { + result = AccessibilityTraits::UpdatesFrequently; + return; + } + if (string == "search") { + result = AccessibilityTraits::SearchField; + return; + } + if (string == "startsMedia") { + result = AccessibilityTraits::StartsMediaSession; + return; + } + if (string == "adjustable") { + result = AccessibilityTraits::Adjustable; + return; + } + if (string == "allowsDirectInteraction") { + result = AccessibilityTraits::AllowsDirectInteraction; + return; + } + if (string == "pageTurn") { + result = AccessibilityTraits::CausesPageTurn; + return; + } + if (string == "header" || string == "heading") { + result = AccessibilityTraits::Header; + return; + } + if (string == "imagebutton") { + result = AccessibilityTraits::Image | AccessibilityTraits::Button; + return; + } + if (string == "summary") { + result = AccessibilityTraits::SummaryElement; + return; + } + if (string == "switch") { + result = AccessibilityTraits::Switch; + return; + } + if (string == "tabbar") { + result = AccessibilityTraits::TabBar; + return; + } + if (string == "progressbar") { + result = AccessibilityTraits::UpdatesFrequently; + return; + } + result = AccessibilityTraits::None; +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + AccessibilityTraits& result) { + if (value.hasType()) { + fromString((std::string)value, result); + return; + } + + result = {}; + + react_native_expect(value.hasType>()); + if (value.hasType>()) { + auto items = (std::vector)value; + for (auto& item : items) { + AccessibilityTraits itemAccessibilityTraits; + fromString(item, itemAccessibilityTraits); + result = result | itemAccessibilityTraits; + } + } else { + LOG(ERROR) << "AccessibilityTraits parsing: unsupported type"; + } +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + AccessibilityState& result) { + auto map = (std::unordered_map)value; + auto selected = map.find("selected"); + if (selected != map.end()) { + fromRawValue(context, selected->second, result.selected); + } + auto disabled = map.find("disabled"); + if (disabled != map.end()) { + fromRawValue(context, disabled->second, result.disabled); + } + auto checked = map.find("checked"); + if (checked != map.end()) { + if (checked->second.hasType()) { + if ((std::string)checked->second == "mixed") { + result.checked = AccessibilityState::Mixed; + } else { + result.checked = AccessibilityState::None; + } + } else if (checked->second.hasType()) { + if ((bool)checked->second == true) { + result.checked = AccessibilityState::Checked; + } else { + result.checked = AccessibilityState::Unchecked; + } + } else { + result.checked = AccessibilityState::None; + } + } + auto busy = map.find("busy"); + if (busy != map.end()) { + fromRawValue(context, busy->second, result.busy); + } + auto expanded = map.find("expanded"); + if (expanded != map.end()) { + fromRawValue(context, expanded->second, result.expanded); + } + // [Windows] - DO NOT REMOVE - required for Windows ISelectionProvider Implementation + auto multiselectable = map.find("multiselectable"); + if (multiselectable != map.end()) { + fromRawValue(context, multiselectable->second, result.multiselectable); + } + auto required = map.find("required"); + if (required != map.end()) { + fromRawValue(context, required->second, result.required); + } + // [Windows] - DO NOT REMOVE +} + +inline std::string toString( + const ImportantForAccessibility& importantForAccessibility) { + switch (importantForAccessibility) { + case ImportantForAccessibility::Auto: + return "auto"; + case ImportantForAccessibility::Yes: + return "yes"; + case ImportantForAccessibility::No: + return "no"; + case ImportantForAccessibility::NoHideDescendants: + return "no-hide-descendants"; + } +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + ImportantForAccessibility& result) { + result = ImportantForAccessibility::Auto; + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "auto") { + result = ImportantForAccessibility::Auto; + } else if (string == "yes") { + result = ImportantForAccessibility::Yes; + } else if (string == "no") { + result = ImportantForAccessibility::No; + } else if (string == "no-hide-descendants") { + result = ImportantForAccessibility::NoHideDescendants; + } else { + LOG(ERROR) << "Unsupported ImportantForAccessibility value: " << string; + react_native_expect(false); + } + } else { + LOG(ERROR) << "Unsupported ImportantForAccessibility type"; + } +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + AccessibilityAction& result) { + auto map = (std::unordered_map)value; + + auto name = map.find("name"); + react_native_assert(name != map.end() && name->second.hasType()); + if (name != map.end()) { + fromRawValue(context, name->second, result.name); + } + + auto label = map.find("label"); + if (label != map.end()) { + if (label->second.hasType()) { + result.label = (std::string)label->second; + } + } +} + +inline void fromRawValue( + const PropsParserContext&, + const RawValue& value, + AccessibilityValue& result) { + auto map = (std::unordered_map)value; + + auto min = map.find("min"); + if (min != map.end()) { + if (min->second.hasType()) { + result.min = (int)min->second; + } + } + + auto max = map.find("max"); + if (max != map.end()) { + if (max->second.hasType()) { + result.max = (int)max->second; + } + } + + auto now = map.find("now"); + if (now != map.end()) { + if (now->second.hasType()) { + result.now = (int)now->second; + } + } + + auto text = map.find("text"); + if (text != map.end()) { + if (text->second.hasType()) { + result.text = (std::string)text->second; + } + } +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + AccessibilityLabelledBy& result) { + if (value.hasType()) { + result.value.push_back((std::string)value); + } else if (value.hasType>()) { + result.value = (std::vector)value; + } +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + AccessibilityLiveRegion& result) { + result = AccessibilityLiveRegion::None; + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "none") { + result = AccessibilityLiveRegion::None; + } else if (string == "polite") { + result = AccessibilityLiveRegion::Polite; + } else if (string == "assertive") { + result = AccessibilityLiveRegion::Assertive; + } else { + LOG(ERROR) << "Unsupported AccessibilityLiveRegion value: " << string; + react_native_expect(false); + } + } else { + LOG(ERROR) << "Unsupported AccessibilityLiveRegion type"; + } +} + +inline std::string toString(const AccessibilityRole& accessibilityRole) { + switch (accessibilityRole) { + case AccessibilityRole::None: + return "none"; + case AccessibilityRole::Button: + return "button"; + case AccessibilityRole::Dropdownlist: + return "dropdownlist"; + case AccessibilityRole::Togglebutton: + return "togglebutton"; + case AccessibilityRole::Link: + return "link"; + case AccessibilityRole::Search: + return "search"; + case AccessibilityRole::Image: + return "image"; + case AccessibilityRole::Keyboardkey: + return "keyboardkey"; + case AccessibilityRole::Text: + return "text"; + case AccessibilityRole::Adjustable: + return "adjustable"; + case AccessibilityRole::Imagebutton: + return "imagebutton"; + case AccessibilityRole::Header: + return "header"; + case AccessibilityRole::Summary: + return "summary"; + case AccessibilityRole::Alert: + return "alert"; + case AccessibilityRole::Checkbox: + return "checkbox"; + case AccessibilityRole::Combobox: + return "combobox"; + case AccessibilityRole::Menu: + return "menu"; + case AccessibilityRole::Menubar: + return "menubar"; + case AccessibilityRole::Menuitem: + return "menuitem"; + case AccessibilityRole::Progressbar: + return "progressbar"; + case AccessibilityRole::Radio: + return "radio"; + case AccessibilityRole::Radiogroup: + return "radiogroup"; + case AccessibilityRole::Scrollbar: + return "scrollbar"; + case AccessibilityRole::Spinbutton: + return "spinbutton"; + case AccessibilityRole::Switch: + return "switch"; + case AccessibilityRole::Tab: + return "tab"; + case AccessibilityRole::Tabbar: + return "tabbar"; + case AccessibilityRole::Tablist: + return "tablist"; + case AccessibilityRole::Timer: + return "timer"; + case AccessibilityRole::List: + return "timer"; + case AccessibilityRole::Toolbar: + return "toolbar"; + case AccessibilityRole::Grid: + return "grid"; + case AccessibilityRole::Pager: + return "pager"; + case AccessibilityRole::Scrollview: + return "scrollview"; + case AccessibilityRole::Horizontalscrollview: + return "horizontalscrollview"; + case AccessibilityRole::Viewgroup: + return "viewgroup"; + case AccessibilityRole::Webview: + return "webview"; + case AccessibilityRole::Drawerlayout: + return "drawerlayout"; + case AccessibilityRole::Slidingdrawer: + return "slidingdrawer"; + case AccessibilityRole::Iconmenu: + return "iconmenu"; + } + + LOG(ERROR) << "Unsupported AccessibilityRole value"; + react_native_expect(false); + // sane default for prod + return "none"; +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + AccessibilityRole& result) { + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "none") { + result = AccessibilityRole::None; + } else if (string == "button") { + result = AccessibilityRole::Button; + } else if (string == "dropdownlist") { + result = AccessibilityRole::Dropdownlist; + } else if (string == "togglebutton") { + result = AccessibilityRole::Togglebutton; + } else if (string == "link") { + result = AccessibilityRole::Link; + } else if (string == "search") { + result = AccessibilityRole::Search; + } else if (string == "image") { + result = AccessibilityRole::Image; + } else if (string == "keyboardkey") { + result = AccessibilityRole::Keyboardkey; + } else if (string == "text") { + result = AccessibilityRole::Text; + } else if (string == "adjustable") { + result = AccessibilityRole::Adjustable; + } else if (string == "imagebutton") { + result = AccessibilityRole::Imagebutton; + } else if (string == "header") { + result = AccessibilityRole::Header; + } else if (string == "summary") { + result = AccessibilityRole::Summary; + } else if (string == "alert") { + result = AccessibilityRole::Alert; + } else if (string == "checkbox") { + result = AccessibilityRole::Checkbox; + } else if (string == "combobox") { + result = AccessibilityRole::Combobox; + } else if (string == "menu") { + result = AccessibilityRole::Menu; + } else if (string == "menubar") { + result = AccessibilityRole::Menubar; + } else if (string == "menuitem") { + result = AccessibilityRole::Menuitem; + } else if (string == "progressbar") { + result = AccessibilityRole::Progressbar; + } else if (string == "radio") { + result = AccessibilityRole::Radio; + } else if (string == "radiogroup") { + result = AccessibilityRole::Radiogroup; + } else if (string == "scrollbar") { + result = AccessibilityRole::Scrollbar; + } else if (string == "spinbutton") { + result = AccessibilityRole::Spinbutton; + } else if (string == "switch") { + result = AccessibilityRole::Switch; + } else if (string == "tab") { + result = AccessibilityRole::Tab; + } else if (string == "tabbar") { + result = AccessibilityRole::Tabbar; + } else if (string == "tablist") { + result = AccessibilityRole::Tablist; + } else if (string == "timer") { + result = AccessibilityRole::Timer; + } else if (string == "toolbar") { + result = AccessibilityRole::Toolbar; + } else if (string == "grid") { + result = AccessibilityRole::Grid; + } else if (string == "pager") { + result = AccessibilityRole::Pager; + } else if (string == "scrollview") { + result = AccessibilityRole::Scrollview; + } else if (string == "horizontalscrollview") { + result = AccessibilityRole::Horizontalscrollview; + } else if (string == "viewgroup") { + result = AccessibilityRole::Viewgroup; + } else if (string == "webview") { + result = AccessibilityRole::Webview; + } else if (string == "drawerlayout") { + result = AccessibilityRole::Drawerlayout; + } else if (string == "slidingdrawer") { + result = AccessibilityRole::Slidingdrawer; + } else if (string == "iconmenu") { + result = AccessibilityRole::Iconmenu; + } else { + LOG(ERROR) << "Unsupported AccessibilityRole value: " << string; + react_native_expect(false); + // sane default for prod + result = AccessibilityRole::None; + } + return; + } + + LOG(ERROR) << "Unsupported AccessibilityRole type"; + react_native_expect(false); + // sane default for prod + result = AccessibilityRole::None; +} + +inline std::string toString(const Role& role) { + switch (role) { + case Role::Alert: + return "alert"; + case Role::Alertdialog: + return "alertdialog"; + case Role::Application: + return "application"; + case Role::Article: + return "article"; + case Role::Banner: + return "banner"; + case Role::Button: + return "button"; + case Role::Cell: + return "cell"; + case Role::Checkbox: + return "checkbox"; + case Role::Columnheader: + return "columnheader"; + case Role::Combobox: + return "combobox"; + case Role::Complementary: + return "complementary"; + case Role::Contentinfo: + return "contentinfo"; + case Role::Definition: + return "definition"; + case Role::Dialog: + return "dialog"; + case Role::Directory: + return "directory"; + case Role::Document: + return "document"; + case Role::Feed: + return "feed"; + case Role::Figure: + return "figure"; + case Role::Form: + return "form"; + case Role::Grid: + return "grid"; + case Role::Group: + return "group"; + case Role::Heading: + return "heading"; + case Role::Img: + return "img"; + case Role::Link: + return "link"; + case Role::List: + return "list"; + case Role::Listitem: + return "listitem"; + case Role::Log: + return "log"; + case Role::Main: + return "main"; + case Role::Marquee: + return "marquee"; + case Role::Math: + return "math"; + case Role::Menu: + return "menu"; + case Role::Menubar: + return "menubar"; + case Role::Menuitem: + return "menuitem"; + case Role::Meter: + return "meter"; + case Role::Navigation: + return "navigation"; + case Role::None: + return "none"; + case Role::Note: + return "note"; + case Role::Option: + return "option"; + case Role::Presentation: + return "presentation"; + case Role::Progressbar: + return "progressbar"; + case Role::Radio: + return "radio"; + case Role::Radiogroup: + return "radiogroup"; + case Role::Region: + return "region"; + case Role::Row: + return "row"; + case Role::Rowgroup: + return "rowgroup"; + case Role::Rowheader: + return "rowheader"; + case Role::Scrollbar: + return "scrollbar"; + case Role::Searchbox: + return "searchbox"; + case Role::Separator: + return "separator"; + case Role::Slider: + return "slider"; + case Role::Spinbutton: + return "spinbutton"; + case Role::Status: + return "status"; + case Role::Summary: + return "summary"; + case Role::Switch: + return "switch"; + case Role::Tab: + return "tab"; + case Role::Table: + return "table"; + case Role::Tablist: + return "tablist"; + case Role::Tabpanel: + return "tabpanel"; + case Role::Term: + return "term"; + case Role::Timer: + return "timer"; + case Role::Toolbar: + return "toolbar"; + case Role::Tooltip: + return "tooltip"; + case Role::Tree: + return "tree"; + case Role::Treegrid: + return "treegrid"; + case Role::Treeitem: + return "treeitem"; + } + + LOG(ERROR) << "Unsupported Role value"; + react_native_expect(false); + // sane default for prod + return "none"; +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + Role& result) { + react_native_expect(value.hasType()); + if (value.hasType()) { + auto string = (std::string)value; + if (string == "alert") { + result = Role::Alert; + } else if (string == "alertdialog") { + result = Role::Alertdialog; + } else if (string == "application") { + result = Role::Application; + } else if (string == "article") { + result = Role::Article; + } else if (string == "banner") { + result = Role::Banner; + } else if (string == "button") { + result = Role::Button; + } else if (string == "cell") { + result = Role::Cell; + } else if (string == "checkbox") { + result = Role::Checkbox; + } else if (string == "columnheader") { + result = Role::Columnheader; + } else if (string == "combobox") { + result = Role::Combobox; + } else if (string == "complementary") { + result = Role::Complementary; + } else if (string == "contentinfo") { + result = Role::Contentinfo; + } else if (string == "definition") { + result = Role::Definition; + } else if (string == "dialog") { + result = Role::Dialog; + } else if (string == "directory") { + result = Role::Directory; + } else if (string == "document") { + result = Role::Document; + } else if (string == "feed") { + result = Role::Feed; + } else if (string == "figure") { + result = Role::Figure; + } else if (string == "form") { + result = Role::Form; + } else if (string == "grid") { + result = Role::Grid; + } else if (string == "group") { + result = Role::Group; + } else if (string == "heading") { + result = Role::Heading; + } else if (string == "img") { + result = Role::Img; + } else if (string == "link") { + result = Role::Link; + } else if (string == "list") { + result = Role::List; + } else if (string == "listitem") { + result = Role::Listitem; + } else if (string == "log") { + result = Role::Log; + } else if (string == "main") { + result = Role::Main; + } else if (string == "marquee") { + result = Role::Marquee; + } else if (string == "math") { + result = Role::Math; + } else if (string == "menu") { + result = Role::Menu; + } else if (string == "menubar") { + result = Role::Menubar; + } else if (string == "menuitem") { + result = Role::Menuitem; + } else if (string == "meter") { + result = Role::Meter; + } else if (string == "navigation") { + result = Role::Navigation; + } else if (string == "none") { + result = Role::None; + } else if (string == "note") { + result = Role::Note; + } else if (string == "option") { + result = Role::Option; + } else if (string == "presentation") { + result = Role::Presentation; + } else if (string == "progressbar") { + result = Role::Progressbar; + } else if (string == "radio") { + result = Role::Radio; + } else if (string == "radiogroup") { + result = Role::Radiogroup; + } else if (string == "region") { + result = Role::Region; + } else if (string == "row") { + result = Role::Row; + } else if (string == "rowgroup") { + result = Role::Rowgroup; + } else if (string == "rowheader") { + result = Role::Rowheader; + } else if (string == "scrollbar") { + result = Role::Scrollbar; + } else if (string == "searchbox") { + result = Role::Searchbox; + } else if (string == "separator") { + result = Role::Separator; + } else if (string == "slider") { + result = Role::Slider; + } else if (string == "spinbutton") { + result = Role::Spinbutton; + } else if (string == "status") { + result = Role::Status; + } else if (string == "summary") { + result = Role::Summary; + } else if (string == "switch") { + result = Role::Switch; + } else if (string == "tab") { + result = Role::Tab; + } else if (string == "table") { + result = Role::Table; + } else if (string == "tablist") { + result = Role::Tablist; + } else if (string == "tabpanel") { + result = Role::Tabpanel; + } else if (string == "term") { + result = Role::Term; + } else if (string == "timer") { + result = Role::Timer; + } else if (string == "toolbar") { + result = Role::Toolbar; + } else if (string == "tooltip") { + result = Role::Tooltip; + } else if (string == "tree") { + result = Role::Tree; + } else if (string == "treegrid") { + result = Role::Treegrid; + } else if (string == "treeitem") { + result = Role::Treeitem; + } else { + LOG(ERROR) << "Unsupported Role value: " << string; + react_native_expect(false); + // sane default for prod + result = Role::None; + } + return; + } + + LOG(ERROR) << "Unsupported Role type"; + react_native_expect(false); + // sane default for prod + result = Role::None; +} + +} // namespace facebook::react diff --git a/vnext/overrides.json b/vnext/overrides.json index 28607151782..50ae24c46bb 100644 --- a/vnext/overrides.json +++ b/vnext/overrides.json @@ -97,6 +97,31 @@ "baseFile": "packages/react-native/ReactCommon/react/bridging/CallbackWrapper.h", "baseHash": "fe1adea3ede6ed141bc6db212be72091722ffa02", "issue": 12195 + }. + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h", + "baseFile": "packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.h", + "baseHash": "e82eb139eab8a6e122421416fb724811bfadd6fb", + "issue": 14128 + }, + { + "type": "derived", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h", + "baseHash": "6db5b174fe1dc7d108ae7f9e730decfe5f633bd8" + }, + { + "type": "derived", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h", + "baseHash": "4b2822199233e660f36c01df18fbbff7799968cc" + }, + { + "type": "derived", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp", + "baseFile": "packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp", + "baseHash": "b15afcf4971fd2c9c9a9859ffcb2113bec28fc35" }, { "type": "patch", @@ -383,12 +408,24 @@ "baseHash": "965bd1e103f7bd92340917acf231516659aba36c", "issue": 0 }, + { + "type": "derived", + "file": "src-win/Libraries/Components/Touchable/TouchableBounce.windows.js", + "baseFile": "packages/react-native/Libraries/Components/Touchable/TouchableBounce.js", + "baseHash": "39541effd705b515e24600d5bc984542a5cd668b" + }, { "type": "patch", "file": "src-win/Libraries/Components/Touchable/TouchableHighlight.windows.js", "baseFile": "packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js", "baseHash": "9d57e5e91830560775ab1b1cc0836bd35de10281" }, + { + "type": "derived", + "file": "src-win/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js", + "baseFile": "packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js", + "baseHash": "8a1cc3c55ca3af68c5627479b3614fa44a1ffbea" + }, { "type": "patch", "file": "src-win/Libraries/Components/Touchable/TouchableOpacity.windows.js", diff --git a/vnext/src-win/Libraries/Components/Button.windows.js b/vnext/src-win/Libraries/Components/Button.windows.js index d9c8b643ca3..2f61329e692 100644 --- a/vnext/src-win/Libraries/Components/Button.windows.js +++ b/vnext/src-win/Libraries/Components/Button.windows.js @@ -164,6 +164,8 @@ type ButtonProps = $ReadOnly<{| 'aria-disabled'?: ?boolean, 'aria-expanded'?: ?boolean, 'aria-selected'?: ?boolean, + 'aria-multiselectable'?: ?boolean, // Windows + 'aria-required'?: ?boolean, // Windows /** * [Android] Controlling if a view fires accessibility events and if it is reported to accessibility services. @@ -308,6 +310,8 @@ const Button: React.AbstractComponent< 'aria-expanded': ariaExpanded, 'aria-label': ariaLabel, 'aria-selected': ariaSelected, + 'aria-multiselectable': ariaMultiselectable, // Windows + 'aria-required': ariaRequired, // Windows importantForAccessibility, color, onPress, @@ -343,6 +347,8 @@ const Button: React.AbstractComponent< disabled: ariaDisabled ?? accessibilityState?.disabled, expanded: ariaExpanded ?? accessibilityState?.expanded, selected: ariaSelected ?? accessibilityState?.selected, + multiselectable: ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows + required: ariaRequired ?? accessibilityState?.required, // Windows }; const disabled = diff --git a/vnext/src-win/Libraries/Components/Pressable/Pressable.windows.js b/vnext/src-win/Libraries/Components/Pressable/Pressable.windows.js index c8cb9f48329..87db12e06bb 100644 --- a/vnext/src-win/Libraries/Components/Pressable/Pressable.windows.js +++ b/vnext/src-win/Libraries/Components/Pressable/Pressable.windows.js @@ -75,6 +75,8 @@ type Props = $ReadOnly<{| 'aria-disabled'?: ?boolean, 'aria-expanded'?: ?boolean, 'aria-selected'?: ?boolean, + 'aria-multiselectable'?: ?boolean, // Windows + 'aria-required'?: ?boolean, // Windows /** * A value indicating whether the accessibility elements contained within * this accessibility element are hidden. @@ -259,6 +261,8 @@ function Pressable(props: Props, forwardedRef): React.Node { 'aria-expanded': ariaExpanded, 'aria-label': ariaLabel, 'aria-selected': ariaSelected, + 'aria-multiselectable': ariaMultiselectable, // Windows + 'aria-required': ariaRequired, // Windows cancelable, children, delayHoverIn, @@ -299,6 +303,8 @@ function Pressable(props: Props, forwardedRef): React.Node { disabled: ariaDisabled ?? accessibilityState?.disabled, expanded: ariaExpanded ?? accessibilityState?.expanded, selected: ariaSelected ?? accessibilityState?.selected, + multiselectable: ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows + required: ariaRequired ?? accessibilityState?.required, // Windows }; _accessibilityState = diff --git a/vnext/src-win/Libraries/Components/TextInput/TextInput.windows.js b/vnext/src-win/Libraries/Components/TextInput/TextInput.windows.js index 646ffd610b0..a90a1e9f2e8 100644 --- a/vnext/src-win/Libraries/Components/TextInput/TextInput.windows.js +++ b/vnext/src-win/Libraries/Components/TextInput/TextInput.windows.js @@ -1190,6 +1190,8 @@ function InternalTextInput(props: Props): React.Node { 'aria-disabled': ariaDisabled, 'aria-expanded': ariaExpanded, 'aria-selected': ariaSelected, + 'aria-multiselectable': ariaMultiselectable, // Windows + 'aria-required': ariaRequired, // Windows accessibilityState, id, tabIndex, @@ -1590,7 +1592,9 @@ function InternalTextInput(props: Props): React.Node { ariaChecked != null || ariaDisabled != null || ariaExpanded != null || - ariaSelected != null + ariaSelected != null || + ariaMultiselectable != null || // Windows + ariaRequired != null // Windows ) { _accessibilityState = { busy: ariaBusy ?? accessibilityState?.busy, @@ -1598,6 +1602,9 @@ function InternalTextInput(props: Props): React.Node { disabled: ariaDisabled ?? accessibilityState?.disabled, expanded: ariaExpanded ?? accessibilityState?.expanded, selected: ariaSelected ?? accessibilityState?.selected, + multiselectable: + ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows + required: ariaRequired ?? accessibilityState?.required, // Windows }; } diff --git a/vnext/src-win/Libraries/Components/Touchable/TouchableBounce.windows.js b/vnext/src-win/Libraries/Components/Touchable/TouchableBounce.windows.js new file mode 100644 index 00000000000..c36f12d6455 --- /dev/null +++ b/vnext/src-win/Libraries/Components/Touchable/TouchableBounce.windows.js @@ -0,0 +1,227 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; + +import Animated from '../../Animated/Animated'; +import Pressability, { + type PressabilityConfig, +} from '../../Pressability/Pressability'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; +import Platform from '../../Utilities/Platform'; +import * as React from 'react'; + +type Props = $ReadOnly<{| + ...React.ElementConfig, + + onPressAnimationComplete?: ?() => void, + onPressWithCompletion?: ?(callback: () => void) => void, + releaseBounciness?: ?number, + releaseVelocity?: ?number, + style?: ?ViewStyleProp, + + hostRef: React.RefSetter>, +|}>; + +type State = $ReadOnly<{| + pressability: Pressability, + scale: Animated.Value, +|}>; + +class TouchableBounce extends React.Component { + state: State = { + pressability: new Pressability(this._createPressabilityConfig()), + scale: new Animated.Value(1), + }; + + _createPressabilityConfig(): PressabilityConfig { + return { + cancelable: !this.props.rejectResponderTermination, + disabled: this.props.disabled, + hitSlop: this.props.hitSlop, + delayLongPress: this.props.delayLongPress, + delayPressIn: this.props.delayPressIn, + delayPressOut: this.props.delayPressOut, + minPressDuration: 0, + pressRectOffset: this.props.pressRetentionOffset, + android_disableSound: this.props.touchSoundDisabled, + onBlur: event => { + if (Platform.isTV) { + this._bounceTo(1, 0.4, 0); + } + if (this.props.onBlur != null) { + this.props.onBlur(event); + } + }, + onFocus: event => { + if (Platform.isTV) { + this._bounceTo(0.93, 0.1, 0); + } + if (this.props.onFocus != null) { + this.props.onFocus(event); + } + }, + onLongPress: this.props.onLongPress, + onPress: event => { + const {onPressAnimationComplete, onPressWithCompletion} = this.props; + const releaseBounciness = this.props.releaseBounciness ?? 10; + const releaseVelocity = this.props.releaseVelocity ?? 10; + + if (onPressWithCompletion != null) { + onPressWithCompletion(() => { + this.state.scale.setValue(0.93); + this._bounceTo( + 1, + releaseVelocity, + releaseBounciness, + onPressAnimationComplete, + ); + }); + return; + } + + this._bounceTo( + 1, + releaseVelocity, + releaseBounciness, + onPressAnimationComplete, + ); + if (this.props.onPress != null) { + this.props.onPress(event); + } + }, + onPressIn: event => { + this._bounceTo(0.93, 0.1, 0); + if (this.props.onPressIn != null) { + this.props.onPressIn(event); + } + }, + onPressOut: event => { + this._bounceTo(1, 0.4, 0); + if (this.props.onPressOut != null) { + this.props.onPressOut(event); + } + }, + }; + } + + _bounceTo( + toValue: number, + velocity: number, + bounciness: number, + callback?: ?() => void, + ) { + Animated.spring(this.state.scale, { + toValue, + velocity, + bounciness, + useNativeDriver: true, + }).start(callback); + } + + render(): React.Node { + // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before + // adopting `Pressability`, so preserve that behavior. + const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} = + this.state.pressability.getEventHandlers(); + const accessibilityLiveRegion = + this.props['aria-live'] === 'off' + ? 'none' + : this.props['aria-live'] ?? this.props.accessibilityLiveRegion; + const _accessibilityState = { + busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy, + checked: + this.props['aria-checked'] ?? this.props.accessibilityState?.checked, + disabled: + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled, + expanded: + this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, + selected: + this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + multiselectable: + this.props['aria-multiselectable'] ?? + this.props.accessibilityState?.multiselectable, // Windows + required: + this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows + }; + + const accessibilityValue = { + max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max, + min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min, + now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now, + text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text, + }; + + const accessibilityLabel = + this.props['aria-label'] ?? this.props.accessibilityLabel; + return ( + + {this.props.children} + {__DEV__ ? ( + + ) : null} + + ); + } + + componentDidUpdate(prevProps: Props, prevState: State) { + this.state.pressability.configure(this._createPressabilityConfig()); + } + + componentDidMount(): mixed { + this.state.pressability.configure(this._createPressabilityConfig()); + } + + componentWillUnmount(): void { + this.state.pressability.reset(); + this.state.scale.resetAnimation(); + } +} + +module.exports = (React.forwardRef((props, hostRef) => ( + +)): component( + ref: React.RefSetter, + ...props: $ReadOnly<$Diff> +)); diff --git a/vnext/src-win/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js b/vnext/src-win/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js new file mode 100644 index 00000000000..b2c34d09d6d --- /dev/null +++ b/vnext/src-win/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js @@ -0,0 +1,371 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import type {PressEvent} from '../../Types/CoreEventTypes'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; + +import View from '../../Components/View/View'; +import Pressability, { + type PressabilityConfig, +} from '../../Pressability/Pressability'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; +import {findHostInstance_DEPRECATED} from '../../ReactNative/RendererProxy'; +import processColor from '../../StyleSheet/processColor'; +import Platform from '../../Utilities/Platform'; +import {Commands} from '../View/ViewNativeComponent'; +import invariant from 'invariant'; +import * as React from 'react'; + +type Props = $ReadOnly<{| + ...React.ElementConfig, + + /** + * Determines the type of background drawable that's going to be used to + * display feedback. It takes an object with `type` property and extra data + * depending on the `type`. It's recommended to use one of the static + * methods to generate that dictionary. + */ + background?: ?( + | $ReadOnly<{| + type: 'ThemeAttrAndroid', + attribute: + | 'selectableItemBackground' + | 'selectableItemBackgroundBorderless', + rippleRadius: ?number, + |}> + | $ReadOnly<{| + type: 'RippleAndroid', + color: ?number, + borderless: boolean, + rippleRadius: ?number, + |}> + ), + + /** + * TV preferred focus (see documentation for the View component). + */ + hasTVPreferredFocus?: ?boolean, + + /** + * TV next focus down (see documentation for the View component). + */ + nextFocusDown?: ?number, + + /** + * TV next focus forward (see documentation for the View component). + */ + nextFocusForward?: ?number, + + /** + * TV next focus left (see documentation for the View component). + */ + nextFocusLeft?: ?number, + + /** + * TV next focus right (see documentation for the View component). + */ + nextFocusRight?: ?number, + + /** + * TV next focus up (see documentation for the View component). + */ + nextFocusUp?: ?number, + + /** + * Set to true to add the ripple effect to the foreground of the view, instead + * of the background. This is useful if one of your child views has a + * background of its own, or you're e.g. displaying images, and you don't want + * the ripple to be covered by them. + * + * Check TouchableNativeFeedback.canUseNativeForeground() first, as this is + * only available on Android 6.0 and above. If you try to use this on older + * versions, this will fallback to background. + */ + useForeground?: ?boolean, +|}>; + +type State = $ReadOnly<{| + pressability: Pressability, +|}>; + +class TouchableNativeFeedback extends React.Component { + /** + * Creates a value for the `background` prop that uses the Android theme's + * default background for selectable elements. + */ + static SelectableBackground: (rippleRadius: ?number) => $ReadOnly<{| + attribute: 'selectableItemBackground', + type: 'ThemeAttrAndroid', + rippleRadius: ?number, + |}> = (rippleRadius: ?number) => ({ + type: 'ThemeAttrAndroid', + attribute: 'selectableItemBackground', + rippleRadius, + }); + + /** + * Creates a value for the `background` prop that uses the Android theme's + * default background for borderless selectable elements. Requires API 21+. + */ + static SelectableBackgroundBorderless: (rippleRadius: ?number) => $ReadOnly<{| + attribute: 'selectableItemBackgroundBorderless', + type: 'ThemeAttrAndroid', + rippleRadius: ?number, + |}> = (rippleRadius: ?number) => ({ + type: 'ThemeAttrAndroid', + attribute: 'selectableItemBackgroundBorderless', + rippleRadius, + }); + + /** + * Creates a value for the `background` prop that uses the Android ripple with + * the supplied color. If `borderless` is true, the ripple will render outside + * of the view bounds. Requires API 21+. + */ + static Ripple: ( + color: string, + borderless: boolean, + rippleRadius: ?number, + ) => $ReadOnly<{| + borderless: boolean, + color: ?number, + rippleRadius: ?number, + type: 'RippleAndroid', + |}> = (color: string, borderless: boolean, rippleRadius: ?number) => { + const processedColor = processColor(color); + invariant( + processedColor == null || typeof processedColor === 'number', + 'Unexpected color given for Ripple color', + ); + return { + type: 'RippleAndroid', + // $FlowFixMe[incompatible-type] + color: processedColor, + borderless, + rippleRadius, + }; + }; + + /** + * Whether `useForeground` is supported. + */ + static canUseNativeForeground: () => boolean = () => + Platform.OS === 'android'; + + state: State = { + pressability: new Pressability(this._createPressabilityConfig()), + }; + + _createPressabilityConfig(): PressabilityConfig { + const accessibilityStateDisabled = + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled; + return { + cancelable: !this.props.rejectResponderTermination, + disabled: + this.props.disabled != null + ? this.props.disabled + : accessibilityStateDisabled, + hitSlop: this.props.hitSlop, + delayLongPress: this.props.delayLongPress, + delayPressIn: this.props.delayPressIn, + delayPressOut: this.props.delayPressOut, + minPressDuration: 0, + pressRectOffset: this.props.pressRetentionOffset, + android_disableSound: this.props.touchSoundDisabled, + onLongPress: this.props.onLongPress, + onPress: this.props.onPress, + onPressIn: event => { + if (Platform.OS === 'android') { + this._dispatchHotspotUpdate(event); + this._dispatchPressedStateChange(true); + } + if (this.props.onPressIn != null) { + this.props.onPressIn(event); + } + }, + onPressMove: event => { + if (Platform.OS === 'android') { + this._dispatchHotspotUpdate(event); + } + }, + onPressOut: event => { + if (Platform.OS === 'android') { + this._dispatchPressedStateChange(false); + } + if (this.props.onPressOut != null) { + this.props.onPressOut(event); + } + }, + }; + } + + _dispatchPressedStateChange(pressed: boolean): void { + if (Platform.OS === 'android') { + const hostComponentRef = findHostInstance_DEPRECATED(this); + if (hostComponentRef == null) { + console.warn( + 'Touchable: Unable to find HostComponent instance. ' + + 'Has your Touchable component been unmounted?', + ); + } else { + Commands.setPressed(hostComponentRef, pressed); + } + } + } + + _dispatchHotspotUpdate(event: PressEvent): void { + if (Platform.OS === 'android') { + const {locationX, locationY} = event.nativeEvent; + const hostComponentRef = findHostInstance_DEPRECATED(this); + if (hostComponentRef == null) { + console.warn( + 'Touchable: Unable to find HostComponent instance. ' + + 'Has your Touchable component been unmounted?', + ); + } else { + Commands.hotspotUpdate( + hostComponentRef, + locationX ?? 0, + locationY ?? 0, + ); + } + } + } + + render(): React.Node { + const element = React.Children.only<$FlowFixMe>(this.props.children); + const children: Array = [element.props.children]; + if (__DEV__) { + if (element.type === View) { + children.push( + , + ); + } + } + + // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before + // adopting `Pressability`, so preserve that behavior. + const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} = + this.state.pressability.getEventHandlers(); + + let _accessibilityState = { + busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy, + checked: + this.props['aria-checked'] ?? this.props.accessibilityState?.checked, + disabled: + this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled, + expanded: + this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, + selected: + this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + multiselectable: + this.props['aria-multiselectable'] ?? + this.props.accessibilityState?.multiselectable, // Windows + required: + this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows + }; + + _accessibilityState = + this.props.disabled != null + ? { + ..._accessibilityState, + disabled: this.props.disabled, + } + : _accessibilityState; + + const accessibilityValue = { + max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max, + min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min, + now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now, + text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text, + }; + + const accessibilityLiveRegion = + this.props['aria-live'] === 'off' + ? 'none' + : this.props['aria-live'] ?? this.props.accessibilityLiveRegion; + + const accessibilityLabel = + this.props['aria-label'] ?? this.props.accessibilityLabel; + return React.cloneElement( + element, + { + ...eventHandlersWithoutBlurAndFocus, + ...getBackgroundProp( + this.props.background === undefined + ? TouchableNativeFeedback.SelectableBackground() + : this.props.background, + this.props.useForeground === true, + ), + accessible: this.props.accessible !== false, + accessibilityHint: this.props.accessibilityHint, + accessibilityLanguage: this.props.accessibilityLanguage, + accessibilityLabel: accessibilityLabel, + accessibilityRole: this.props.accessibilityRole, + accessibilityState: _accessibilityState, + accessibilityActions: this.props.accessibilityActions, + onAccessibilityAction: this.props.onAccessibilityAction, + accessibilityValue: accessibilityValue, + importantForAccessibility: + this.props['aria-hidden'] === true + ? 'no-hide-descendants' + : this.props.importantForAccessibility, + accessibilityViewIsModal: + this.props['aria-modal'] ?? this.props.accessibilityViewIsModal, + accessibilityLiveRegion: accessibilityLiveRegion, + accessibilityElementsHidden: + this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden, + hasTVPreferredFocus: this.props.hasTVPreferredFocus, + hitSlop: this.props.hitSlop, + focusable: + this.props.focusable !== false && + this.props.onPress !== undefined && + !this.props.disabled, + nativeID: this.props.id ?? this.props.nativeID, + nextFocusDown: this.props.nextFocusDown, + nextFocusForward: this.props.nextFocusForward, + nextFocusLeft: this.props.nextFocusLeft, + nextFocusRight: this.props.nextFocusRight, + nextFocusUp: this.props.nextFocusUp, + onLayout: this.props.onLayout, + testID: this.props.testID, + }, + ...children, + ); + } + + componentDidUpdate(prevProps: Props, prevState: State) { + this.state.pressability.configure(this._createPressabilityConfig()); + } + + componentDidMount(): mixed { + this.state.pressability.configure(this._createPressabilityConfig()); + } + + componentWillUnmount(): void { + this.state.pressability.reset(); + } +} + +const getBackgroundProp = + Platform.OS === 'android' + ? /* $FlowFixMe[missing-local-annot] The type annotation(s) required by + * Flow's LTI update could not be added via codemod */ + (background, useForeground: boolean) => + useForeground && TouchableNativeFeedback.canUseNativeForeground() + ? {nativeForegroundAndroid: background} + : {nativeBackgroundAndroid: background} + : /* $FlowFixMe[missing-local-annot] The type annotation(s) required by + * Flow's LTI update could not be added via codemod */ + (background, useForeground: boolean) => null; + +TouchableNativeFeedback.displayName = 'TouchableNativeFeedback'; + +module.exports = TouchableNativeFeedback; diff --git a/vnext/src-win/Libraries/Components/Touchable/TouchableOpacity.windows.js b/vnext/src-win/Libraries/Components/Touchable/TouchableOpacity.windows.js index 663829617ae..989283c8dd6 100644 --- a/vnext/src-win/Libraries/Components/Touchable/TouchableOpacity.windows.js +++ b/vnext/src-win/Libraries/Components/Touchable/TouchableOpacity.windows.js @@ -235,6 +235,11 @@ class TouchableOpacity extends React.Component { this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, selected: this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + multiselectable: + this.props['aria-multiselectable'] ?? + this.props.accessibilityState?.multiselectable, // Windows + required: + this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows }; _accessibilityState = diff --git a/vnext/src-win/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js b/vnext/src-win/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js index b9a2351f936..ee4875b260a 100644 --- a/vnext/src-win/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +++ b/vnext/src-win/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js @@ -59,6 +59,8 @@ type Props = $ReadOnly<{| 'aria-disabled'?: ?boolean, 'aria-expanded'?: ?boolean, 'aria-selected'?: ?boolean, + 'aria-multiselectable'?: ?boolean, // Windows + 'aria-required'?: ?boolean, // Windows 'aria-hidden'?: ?boolean, 'aria-live'?: ?('polite' | 'assertive' | 'off'), 'aria-label'?: ?Stringish, @@ -158,6 +160,10 @@ class TouchableWithoutFeedback extends React.Component { this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded, selected: this.props['aria-selected'] ?? this.props.accessibilityState?.selected, + multiselectable: + this.props['aria-multiselectable'] ?? + this.props.accessibilityState?.multiselectable, // Windows + required: this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows }; // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before diff --git a/vnext/src-win/Libraries/Components/View/View.windows.js b/vnext/src-win/Libraries/Components/View/View.windows.js index 51c4df0329a..c33e961dc4e 100644 --- a/vnext/src-win/Libraries/Components/View/View.windows.js +++ b/vnext/src-win/Libraries/Components/View/View.windows.js @@ -47,6 +47,8 @@ const View: React.AbstractComponent< 'aria-checked': ariaChecked, 'aria-disabled': ariaDisabled, 'aria-expanded': ariaExpanded, + 'aria-multiselectable': ariaMultiselectable, // Windows + 'aria-required': ariaRequired, // Windows 'aria-hidden': ariaHidden, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, @@ -80,7 +82,9 @@ const View: React.AbstractComponent< ariaChecked != null || ariaDisabled != null || ariaExpanded != null || - ariaSelected != null + ariaSelected != null || + ariaMultiselectable != null || // Windows + ariaRequired != null // Windows ) { _accessibilityState = { busy: ariaBusy ?? accessibilityState?.busy, @@ -88,6 +92,9 @@ const View: React.AbstractComponent< disabled: ariaDisabled ?? accessibilityState?.disabled, expanded: ariaExpanded ?? accessibilityState?.expanded, selected: ariaSelected ?? accessibilityState?.selected, + multiselectable: + ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows + required: ariaRequired ?? accessibilityState?.required, // Windows }; } let _accessibilityValue; diff --git a/vnext/src-win/Libraries/Components/View/ViewAccessibility.d.ts b/vnext/src-win/Libraries/Components/View/ViewAccessibility.d.ts index 9ac8d1722e5..dcd37958523 100644 --- a/vnext/src-win/Libraries/Components/View/ViewAccessibility.d.ts +++ b/vnext/src-win/Libraries/Components/View/ViewAccessibility.d.ts @@ -183,6 +183,16 @@ export interface AccessibilityState { * When present, informs accessible tools the element is expanded or collapsed */ expanded?: boolean | undefined; + /** + * When present, informs accessible tools the element can have multiple items selected + * @platform windows + */ + multiselectable?: boolean | undefined; + /** + * When present, informs accessible tools the element requires selection + * @platform windows + */ + required?: boolean | undefined; } export interface AccessibilityValue { diff --git a/vnext/src-win/Libraries/Components/View/ViewAccessibility.windows.js b/vnext/src-win/Libraries/Components/View/ViewAccessibility.windows.js index dee11efda99..b970d698137 100644 --- a/vnext/src-win/Libraries/Components/View/ViewAccessibility.windows.js +++ b/vnext/src-win/Libraries/Components/View/ViewAccessibility.windows.js @@ -179,8 +179,10 @@ export type AccessibilityState = { disabled?: boolean, selected?: boolean, checked?: ?boolean | 'mixed', - busy?: boolean, - expanded?: boolean, + busy?: ?boolean, + expanded?: ?boolean, + multiselectable?: ?boolean, // Windows + required?: ?boolean, // Windows ... }; diff --git a/vnext/src-win/Libraries/Components/View/ViewPropTypes.windows.js b/vnext/src-win/Libraries/Components/View/ViewPropTypes.windows.js index 8c21541f919..f485c8b5ec9 100644 --- a/vnext/src-win/Libraries/Components/View/ViewPropTypes.windows.js +++ b/vnext/src-win/Libraries/Components/View/ViewPropTypes.windows.js @@ -612,6 +612,8 @@ export type ViewProps = $ReadOnly<{| * See https://reactnative.dev/docs/view#aria-hidden */ 'aria-hidden'?: ?boolean, + 'aria-multiselectable'?: ?boolean, // Windows + 'aria-required'?: ?boolean, // Windows /** * Views that are only used to layout their children or otherwise don't draw diff --git a/vnext/src-win/Libraries/Image/Image.windows.js b/vnext/src-win/Libraries/Image/Image.windows.js index 99d778ad54b..ec4f5ba6695 100644 --- a/vnext/src-win/Libraries/Image/Image.windows.js +++ b/vnext/src-win/Libraries/Image/Image.windows.js @@ -148,6 +148,8 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { 'aria-disabled': ariaDisabled, 'aria-expanded': ariaExpanded, 'aria-selected': ariaSelected, + 'aria-multiselectable': ariaMultiselectable, // Windows + 'aria-required': ariaRequired, // Windows height, src, width, @@ -160,6 +162,9 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { disabled: ariaDisabled ?? props.accessibilityState?.disabled, expanded: ariaExpanded ?? props.accessibilityState?.expanded, selected: ariaSelected ?? props.accessibilityState?.selected, + multiselectable: + ariaMultiselectable ?? props.accessibilityState?.multiselectable, // Windows + required: ariaRequired ?? props.accessibilityState?.required, // Windows }; const accessibilityLabel = props['aria-label'] ?? props.accessibilityLabel; diff --git a/vnext/src-win/Libraries/Text/Text.windows.js b/vnext/src-win/Libraries/Text/Text.windows.js index 6c439cbfd4e..e4ff93bd81e 100644 --- a/vnext/src-win/Libraries/Text/Text.windows.js +++ b/vnext/src-win/Libraries/Text/Text.windows.js @@ -46,6 +46,8 @@ const Text: React.AbstractComponent< 'aria-checked': ariaChecked, 'aria-disabled': ariaDisabled, 'aria-expanded': ariaExpanded, + 'aria-multiselectable': ariaMultiselectable, // Windows + 'aria-required': ariaRequired, // Windows 'aria-label': ariaLabel, 'aria-level': ariaLevel, // Windows 'aria-posinset': ariaPosinset, // Windows @@ -78,7 +80,9 @@ const Text: React.AbstractComponent< ariaChecked != null || ariaDisabled != null || ariaExpanded != null || - ariaSelected != null + ariaSelected != null || + ariaMultiselectable != null || // Windows + ariaRequired != null // Windows ) { _accessibilityState = { busy: ariaBusy ?? accessibilityState?.busy, @@ -86,6 +90,9 @@ const Text: React.AbstractComponent< disabled: ariaDisabled ?? accessibilityState?.disabled, expanded: ariaExpanded ?? accessibilityState?.expanded, selected: ariaSelected ?? accessibilityState?.selected, + multiselectable: + ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows + required: ariaRequired ?? accessibilityState?.required, // Windows }; } diff --git a/vnext/src-win/Libraries/Text/TextProps.windows.js b/vnext/src-win/Libraries/Text/TextProps.windows.js index 561859c4b72..7d9833b4d2e 100644 --- a/vnext/src-win/Libraries/Text/TextProps.windows.js +++ b/vnext/src-win/Libraries/Text/TextProps.windows.js @@ -97,6 +97,8 @@ export type TextProps = $ReadOnly<{| 'aria-posinset'?: ?number, // Windows 'aria-setsize'?: ?number, // Windows 'aria-level'?: ?number, // Windows + 'aria-multiselectable'?: ?boolean, // Windows + 'aria-required'?: ?boolean, // Windows /** * Represents the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.