Skip to content
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

Mobile: Accessibility: Improve setting control accessibility #11358

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
17 changes: 14 additions & 3 deletions packages/app-mobile/components/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface DropdownProps {
headerStyle?: TextStyle;
itemStyle?: TextStyle;
disabled?: boolean;
accessibilityHint?: string;

labelTransform?: 'trim';
items: DropdownListItem[];
Expand Down Expand Up @@ -169,6 +170,7 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
<TouchableOpacity
style={itemWrapperStyle}
accessibilityRole="menuitem"
accessibilityState={{ selected: item.value === this.props.selectedValue }}
key={key}
onPress={() => {
this.onCloseList();
Expand Down Expand Up @@ -209,12 +211,19 @@ class Dropdown extends Component<DropdownProps, DropdownState> {
style={headerWrapperStyle}
disabled={this.props.disabled}
onPress={this.onOpenList}
role='button'
accessibilityRole='button'
accessibilityHint={[this.props.accessibilityHint, _('Opens dropdown')].join(' ')}
>
<Text ellipsizeMode="tail" numberOfLines={1} style={headerStyle}>
{headerLabel}
</Text>
<Text style={headerArrowStyle}>{'▼'}</Text>
<Text
style={headerArrowStyle}
aria-hidden={true}
importantForAccessibility='no'
accessibilityElementsHidden={true}
accessibilityRole='image'
>{'▼'}</Text>
</TouchableOpacity>
{this.state.listVisible ? null : this.props.coverableChildrenRight}
</View>
Expand All @@ -237,11 +246,13 @@ class Dropdown extends Component<DropdownProps, DropdownState> {

<View
accessibilityRole='menu'
style={wrapperStyle}>
style={wrapperStyle}
>
<FlatList
ref={this.onListLoad}
style={itemListStyle}
data={this.props.items}
extraData={this.props.selectedValue}
renderItem={itemRenderer}
getItemLayout={(_data, index) => ({
length: itemHeight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SettingsToggle from './SettingsToggle';
import FileSystemPathSelector from './FileSystemPathSelector';
import shim from '@joplin/lib/shim';
import { themeStyle } from '../../global-style';
import { useId } from 'react';

interface Props {
settingId: string;
Expand Down Expand Up @@ -39,16 +40,19 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
const descriptionComp = !settingDescription ? null : <Text style={styleSheet.settingDescriptionText}>{settingDescription}</Text>;
const containerStyle = props.styles.getContainerStyle(!!settingDescription);

const labelId = useId();

if (md.isEnum) {
const value = props.value?.toString();

const items = Setting.enumOptionsToValueLabels(md.options(), md.optionsOrder ? md.optionsOrder() : []);
const label = md.label();

return (
<View key={props.settingId} style={{ flexDirection: 'column', borderBottomWidth: 1, borderBottomColor: theme.dividerColor }}>
<View style={containerStyle}>
<Text key="label" style={styleSheet.settingText}>
{md.label()}
{label}
</Text>
<Dropdown
key="control"
Expand All @@ -69,6 +73,7 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
onValueChange={(itemValue: string) => {
void props.updateSettingValue(props.settingId, itemValue);
}}
accessibilityHint={label}
/>
</View>
{descriptionComp}
Expand All @@ -90,15 +95,16 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
const unitLabel = md.unitLabel ? md.unitLabel(props.value) : props.value;
const minimum = 'minimum' in md ? md.minimum : 0;
const maximum = 'maximum' in md ? md.maximum : 10;
const label = md.label();

// Note: Do NOT add the minimumTrackTintColor and maximumTrackTintColor props
// on the Slider as they are buggy and can crash the app on certain devices.
// https://github.com/laurent22/joplin/issues/2733
// https://github.com/react-native-community/react-native-slider/issues/161
return (
<View key={props.settingId} style={styleSheet.settingContainer}>
<Text key="label" style={styleSheet.settingText}>
{md.label()}
<Text key="label" style={styleSheet.settingText} nativeID={labelId}>
{label}
</Text>
<View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', flex: 1 }}>
<Text style={styleSheet.sliderUnits}>{unitLabel}</Text>
Expand All @@ -110,6 +116,7 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
maximumValue={maximum}
value={props.value}
onValueChange={newValue => void props.updateSettingValue(props.settingId, newValue)}
accessibilityHint={label}
/>
</View>
</View>
Expand All @@ -129,7 +136,7 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
return (
<View key={props.settingId} style={{ flexDirection: 'column', borderBottomWidth: 1, borderBottomColor: theme.dividerColor }}>
<View key={props.settingId} style={containerStyle}>
<Text key="label" style={styleSheet.settingText}>
<Text key="label" style={styleSheet.settingText} nativeID={labelId}>
{md.label()}
</Text>
<TextInput
Expand All @@ -143,6 +150,7 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
value={props.value}
onChangeText={(newValue: string) => void props.updateSettingValue(props.settingId, newValue)}
secureTextEntry={!!md.secure}
aria-labelledby={labelId}
/>
</View>
{descriptionComp}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const SettingsToggle: FunctionComponent<Props> = props => {
trackColor={{ false: theme.dividerColor }}
value={props.value}
onValueChange={(value: boolean) => void props.updateSettingValue(props.settingId, value)}
accessibilityHint={props.label}
/>
</View>
{props.description}
Expand Down
Loading