Skip to content

[0.74] Rework modal to be implemented entirely using public APIs #14271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Implement ISelectionProvider and ISelectionItemProvider",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "IRangeValue Provider",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Rework modal implementation to use public APIs",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
6 changes: 0 additions & 6 deletions packages/@react-native-windows/tester/overrides.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@
"type": "platform",
"file": "src/js/examples/HTTP/HTTPExampleMultiPartFormData.js"
},
{
"type": "patch",
"file": "src/js/examples/Modal/ModalOnShow.windows.js",
"baseFile": "packages/rn-tester/js/examples/Modal/ModalOnShow.js",
"baseHash": "5098723f16d232ef3c5971a6f153522f42f87f61"
},
{
"type": "patch",
"file": "src/js/examples/Modal/ModalPresentation.windows.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,33 +312,40 @@ class AccessibilityStateExamples extends React.Component {
The following list of TouchableHighlights toggles
accessibilityState.selected when touched:
</Text>
<FlatList
accessibilityLabel="List of selectable items"
data={selectableItems}
renderItem={item => (
<TouchableHighlight
style={{
width: 100,
height: 50,
backgroundColor: this.state.itemsSelected[item.index]
? 'gray'
: 'lightskyblue',
}}
accessibilityRole="button"
accessibilityLabel={'Selectable item ' + (item.index + 1)}
accessibilityState={{
selected: this.state.itemsSelected[item.index],
}}
onPress={() => this.selectPress(item.index)}>
<Text>
{this.state.itemsSelected[item.index]
? 'Selected'
: 'Unselected'}
</Text>
</TouchableHighlight>
)}
keyExtractor={(item, index) => index.toString()}
/>
<View
accessible
accessibilityLabel="Selection Container"
accessibilityState={{multiselectable: true, required: true}}
testID="selection-container">
<FlatList
accessibilityLabel="List of selectable items"
data={selectableItems}
renderItem={item => (
<TouchableHighlight
style={{
width: 100,
height: 50,
backgroundColor: this.state.itemsSelected[item.index]
? 'gray'
: 'lightskyblue',
}}
accessibilityRole="button"
accessibilityLabel={'Selectable item ' + (item.index + 1)}
testID={'Selectable item ' + (item.index + 1)}
accessibilityState={{
selected: this.state.itemsSelected[item.index],
}}
onPress={() => this.selectPress(item.index)}>
<Text>
{this.state.itemsSelected[item.index]
? 'Selected'
: 'Unselected'}
</Text>
</TouchableHighlight>
)}
keyExtractor={(item, index) => index.toString()}
/>
</View>
<Text>
The following TouchableHighlight cycles accessibilityState.checked
through unchecked/checked/mixed for the View under it:
Expand Down Expand Up @@ -429,7 +436,8 @@ class AccessibilityStateExamples extends React.Component {
</Text>
<TouchableHighlight
style={{width: 100, height: 50, backgroundColor: 'blue'}}
onPress={this.rangePress}>
onPress={this.rangePress}
testID="accessibilityValue-increment">
<Text>Range value increment</Text>
</TouchableHighlight>
<View
Expand All @@ -444,7 +452,9 @@ class AccessibilityStateExamples extends React.Component {
min: this.state.viewRangeMin,
max: this.state.viewRangeMax,
now: this.state.viewRangeNow,
}}>
}}
testID="accessibilityValue-number"
accessibilityState={{readOnly: true}}>
<Text>
The View's (accessibilityRole == adjustable, ie. Slider) properties
should be the following according to UIA: Min-{' '}
Expand All @@ -465,7 +475,10 @@ class AccessibilityStateExamples extends React.Component {
accessibilityValue={{
text: this.state.viewValueText,
}}
accessibilityRole="combobox">
accessibilityRole="combobox"
testID="accessibilityValue-text"
accessible
aria-readonly>
<Text>
The View's properties should be the following according to UIA:
Text- {this.state.viewValueText}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,9 @@ const styles = StyleSheet.create({
marginTop: 6,
},
modalContainer: {
// [Windows
width: 500,
height: 500,
// flex: 1,
// justifyContent: 'center',
// padding: 20,
// Windows ]
flex: 1,
justifyContent: 'center',
padding: 20,
},
modalInnerContainer: {
borderRadius: 10,
Expand Down
80 changes: 80 additions & 0 deletions packages/e2e-test-app-fabric/test/AccessibilityTest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* 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();
});
test('Components can store range data by setting the min, max, and now of accessibilityValue', async () => {
await searchBox('Sta');
const componentsTab = await app.findElementByTestID(
'accessibilityValue-number',
);
await componentsTab.waitForDisplayed({timeout: 5000});
const dump = await dumpVisualTree('accessibilityValue-number');
expect(dump).toMatchSnapshot();
});
test('Components can store value data by setting the text of accessibilityValue', async () => {
await searchBox('Sta');
const componentsTab = await app.findElementByTestID(
'accessibilityValue-text',
);
await componentsTab.waitForDisplayed({timeout: 5000});
const dump = await dumpVisualTree('accessibilityValue-text');
expect(dump).toMatchSnapshot();
});
});
Loading
Loading