Skip to content

Commit 23d72ce

Browse files
committed
feat: add accessibility
1 parent 232acc4 commit 23d72ce

22 files changed

Lines changed: 407 additions & 71 deletions

packages/pluggableWidgets/accordion-native/src/Accordion.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
<description />
6868
<returnType type="Boolean" />
6969
</property>
70-
<property key="accessible" type="enumeration" defaultValue="yes">
70+
<property key="accessible" type="enumeration" defaultValue="no">
7171
<caption>Accessible</caption>
7272
<description />
7373
<enumerationValues>

packages/pluggableWidgets/accordion-native/typings/AccordionProps.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,6 @@ export interface AccordionPreviewProps {
7070
collapsible: boolean;
7171
collapseBehavior: CollapseBehaviorEnum;
7272
icon: IconEnum;
73-
iconCollapsed: { type: "glyph"; iconClass: string } | { type: "image"; imageUrl: string } | null;
74-
iconExpanded: { type: "glyph"; iconClass: string } | { type: "image"; imageUrl: string } | null;
73+
iconCollapsed: { type: "glyph"; iconClass: string; } | { type: "image"; imageUrl: string; } | null;
74+
iconExpanded: { type: "glyph"; iconClass: string; } | { type: "image"; imageUrl: string; } | null;
7575
}

packages/pluggableWidgets/bottom-sheet-native/src/BottomSheet.editorConfig.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ export function getPreview(values: BottomSheetPreviewProps, isDarkMode: boolean)
8787
};
8888
}
8989

90-
export function getProperties(values: any, defaultProperties: Properties): Properties {
90+
export function getProperties(values: BottomSheetPreviewProps, defaultProperties: Properties): Properties {
9191
if (values.type === "modal") {
9292
if (values.modalRendering === "basic") {
93+
hidePropertyIn(defaultProperties, values, "accessible");
9394
hidePropertiesIn(defaultProperties, values, ["smallContent", "largeContent", "fullscreenContent"]);
9495
} else {
9596
hidePropertiesIn(defaultProperties, values, [
@@ -112,10 +113,23 @@ export function getProperties(values: any, defaultProperties: Properties): Prope
112113
hidePropertyIn(defaultProperties, values, "fullscreenContent");
113114
}
114115
}
116+
117+
if (values.accessible === "no" || (values.type === "modal" && values.modalRendering === "basic")) {
118+
hidePropertyIn(defaultProperties, values, "screenReaderCaption");
119+
hidePropertyIn(defaultProperties, values, "screenReaderHint");
120+
}
121+
122+
values.itemsBasic.forEach((item, index) => {
123+
if (item.modalAccessible === "no") {
124+
hidePropertyIn(defaultProperties, values, "itemsBasic", index, "modalScreenReaderCaption");
125+
hidePropertyIn(defaultProperties, values, "itemsBasic", index, "modalScreenReaderHint");
126+
}
127+
});
128+
115129
return defaultProperties;
116130
}
117131

118-
export function check(values: any): Problem[] {
132+
export function check(values: BottomSheetPreviewProps): Problem[] {
119133
const errors: Problem[] = [];
120134
if (values.type === "modal") {
121135
if (!values.triggerAttribute) {

packages/pluggableWidgets/bottom-sheet-native/src/BottomSheet.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ export function BottomSheet(props: BottomSheetProps<BottomSheetStyle>): ReactEle
2929
if (props.type === "expanding") {
3030
return (
3131
<ExpandingDrawer
32+
accessible={props.accessible === "yes"}
33+
screenReaderCaption={props.screenReaderCaption}
34+
screenReaderHint={props.screenReaderHint}
3235
smallContent={props.smallContent}
3336
largeContent={props.largeContent}
3437
fullscreenContent={props.showFullscreenContent ? props.fullscreenContent : null}

packages/pluggableWidgets/bottom-sheet-native/src/BottomSheet.xml

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<caption>Trigger attribute</caption>
2020
<description>Defines if the modal bottom sheet is visible or not. Initially this value should be false. When set to true, the bottom sheet will be shown. When the bottom sheet is hidden, the trigger attribute value is set to false.</description>
2121
<attributeTypes>
22-
<attributeType name="Boolean"/>
22+
<attributeType name="Boolean" />
2323
</attributeTypes>
2424
</property>
2525
<property key="modalRendering" type="enumeration" defaultValue="basic">
@@ -55,6 +55,25 @@
5555
<enumerationValue key="customStyle">Custom</enumerationValue>
5656
</enumerationValues>
5757
</property>
58+
<property key="modalAccessible" type="enumeration" defaultValue="yes">
59+
<caption>Accessible</caption>
60+
<category>General</category>
61+
<description />
62+
<enumerationValues>
63+
<enumerationValue key="yes">Yes</enumerationValue>
64+
<enumerationValue key="no">No</enumerationValue>
65+
</enumerationValues>
66+
</property>
67+
<property key="modalScreenReaderCaption" type="textTemplate" required="false">
68+
<caption>Screen reader caption</caption>
69+
<category>General</category>
70+
<description />
71+
</property>
72+
<property key="modalScreenReaderHint" type="textTemplate" required="false">
73+
<caption>Screen reader hint</caption>
74+
<category>General</category>
75+
<description />
76+
</property>
5877
</properties>
5978
</property>
6079
<property key="nativeImplementation" type="boolean" defaultValue="true">
@@ -87,9 +106,27 @@
87106
</property>
88107
</propertyGroup>
89108
<propertyGroup caption="Common">
90-
<systemProperty key="Name"/>
109+
<systemProperty key="Name" />
91110
<systemProperty key="Visibility" />
92111
</propertyGroup>
112+
<propertyGroup caption="Accessibilty">
113+
<property key="accessible" type="enumeration" defaultValue="no">
114+
<caption>Accessible</caption>
115+
<description />
116+
<enumerationValues>
117+
<enumerationValue key="yes">Yes</enumerationValue>
118+
<enumerationValue key="no">No</enumerationValue>
119+
</enumerationValues>
120+
</property>
121+
<property key="screenReaderCaption" type="textTemplate" required="false">
122+
<caption>Screen reader caption</caption>
123+
<description />
124+
</property>
125+
<property key="screenReaderHint" type="textTemplate" required="false">
126+
<caption>Screen reader hint</caption>
127+
<description />
128+
</property>
129+
</propertyGroup>
93130
</propertyGroup>
94131
</properties>
95132
</widget>

packages/pluggableWidgets/bottom-sheet-native/src/components/CustomModalSheet.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { createElement, ReactElement, ReactNode, useCallback, useEffect, useState } from "react";
22
import { InteractionManager, LayoutChangeEvent, SafeAreaView, StyleSheet, View } from "react-native";
33
import Modal, { OnSwipeCompleteParams } from "react-native-modal";
4-
import { EditableValue, ValueStatus } from "mendix";
4+
import { DynamicValue, EditableValue, ValueStatus } from "mendix";
55
import { BottomSheetStyle, defaultPaddings } from "../ui/Styles";
66

77
interface CustomModalSheetProps {
88
triggerAttribute?: EditableValue<boolean>;
99
content?: ReactNode;
1010
styles: BottomSheetStyle;
11+
accessible?: boolean;
12+
screenReaderCaption?: DynamicValue<string>;
13+
screenReaderHint?: DynamicValue<string>;
1114
}
1215

1316
export const CustomModalSheet = (props: CustomModalSheetProps): ReactElement => {
@@ -62,6 +65,10 @@ export const CustomModalSheet = (props: CustomModalSheetProps): ReactElement =>
6265

6366
return (
6467
<Modal
68+
accessible={props.accessible}
69+
accessibilityLabel={props.screenReaderCaption?.value}
70+
accessibilityHint={props.screenReaderHint?.value}
71+
accessibilityState={{ expanded: height > 0 }}
6572
isVisible={currentStatus}
6673
coverScreen
6774
backdropOpacity={0.5}

packages/pluggableWidgets/bottom-sheet-native/src/components/ExpandingDrawer.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { BottomSheetStyle } from "../ui/Styles";
21
import { createElement, ReactNode, useCallback, useState, ReactElement, Children } from "react";
3-
import BottomSheet from "reanimated-bottom-sheet";
42
import { Dimensions, LayoutChangeEvent, SafeAreaView, StyleSheet, View } from "react-native";
3+
import BottomSheet from "reanimated-bottom-sheet";
4+
import { DynamicValue } from "mendix";
5+
import { BottomSheetStyle } from "../ui/Styles";
56

67
interface ExpandingDrawerProps {
78
smallContent?: ReactNode;
@@ -10,6 +11,9 @@ interface ExpandingDrawerProps {
1011
onOpen?: () => void;
1112
onClose?: () => void;
1213
styles: BottomSheetStyle;
14+
accessible?: boolean;
15+
screenReaderCaption?: DynamicValue<string>;
16+
screenReaderHint?: DynamicValue<string>;
1317
}
1418

1519
export const ExpandingDrawer = (props: ExpandingDrawerProps): ReactElement => {
@@ -56,6 +60,10 @@ export const ExpandingDrawer = (props: ExpandingDrawerProps): ReactElement => {
5660
pointerEvents="box-none"
5761
>
5862
<View
63+
accessible={props.accessible}
64+
accessibilityLabel={props.screenReaderCaption?.value}
65+
accessibilityHint={props.screenReaderHint?.value}
66+
accessibilityState={{ expanded: isOpen }}
5967
onLayout={onLayoutHandlerHeader}
6068
style={!isSmallContentValid ? { height: 20 } : {}}
6169
pointerEvents="box-none"

packages/pluggableWidgets/bottom-sheet-native/src/components/NativeBottomSheet.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { createElement, ReactElement, useCallback, useEffect, useRef, useState }
22
import ActionSheet, { ActionSheetCustom } from "react-native-actionsheet";
33
import { Platform, Text } from "react-native";
44
import { EditableValue, ValueStatus } from "mendix";
5+
import { executeAction } from "@mendix/piw-utils-internal";
56
import { ItemsBasicType } from "../../typings/BottomSheetProps";
67
import { ModalItemContainerStyle, BottomSheetStyle, defaultMargins } from "../ui/Styles";
7-
import { executeAction } from "@mendix/piw-utils-internal";
88

99
interface NativeBottomSheetProps {
1010
name: string;
@@ -47,7 +47,14 @@ export const NativeBottomSheet = (props: NativeBottomSheetProps): ReactElement =
4747

4848
if (Platform.OS === "android" || !props.useNative) {
4949
const options = props.itemsBasic.map((item, index) => (
50-
<Text key={`${props.name}_item_${index}`} style={props.styles.modalItems[item.styleClass]}>
50+
<Text
51+
accessible={item.modalAccessible === "yes"}
52+
accessibilityLabel={item.modalScreenReaderCaption?.value || item.caption}
53+
accessibilityHint={item.modalScreenReaderHint?.value}
54+
accessibilityRole="button"
55+
key={`${props.name}_item_${index}`}
56+
style={props.styles.modalItems[item.styleClass]}
57+
>
5158
{item.caption}
5259
</Text>
5360
));

packages/pluggableWidgets/bottom-sheet-native/typings/BottomSheetProps.d.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,34 @@
44
* @author Mendix UI Content Team
55
*/
66
import { ComponentType, CSSProperties, ReactNode } from "react";
7-
import { ActionValue, EditableValue } from "mendix";
7+
import { ActionValue, DynamicValue, EditableValue } from "mendix";
88

99
export type TypeEnum = "modal" | "expanding";
1010

1111
export type ModalRenderingEnum = "basic" | "custom";
1212

1313
export type StyleClassEnum = "defaultStyle" | "primaryStyle" | "dangerStyle" | "customStyle";
1414

15+
export type ModalAccessibleEnum = "yes" | "no";
16+
1517
export interface ItemsBasicType {
1618
caption: string;
1719
action?: ActionValue;
1820
styleClass: StyleClassEnum;
21+
modalAccessible: ModalAccessibleEnum;
22+
modalScreenReaderCaption?: DynamicValue<string>;
23+
modalScreenReaderHint?: DynamicValue<string>;
1924
}
2025

26+
export type AccessibleEnum = "yes" | "no";
27+
2128
export interface ItemsBasicPreviewType {
2229
caption: string;
2330
action: {} | null;
2431
styleClass: StyleClassEnum;
32+
modalAccessible: ModalAccessibleEnum;
33+
modalScreenReaderCaption: string;
34+
modalScreenReaderHint: string;
2535
}
2636

2737
export interface BottomSheetProps<Style> {
@@ -38,6 +48,9 @@ export interface BottomSheetProps<Style> {
3848
fullscreenContent?: ReactNode;
3949
onOpen?: ActionValue;
4050
onClose?: ActionValue;
51+
accessible: AccessibleEnum;
52+
screenReaderCaption?: DynamicValue<string>;
53+
screenReaderHint?: DynamicValue<string>;
4154
}
4255

4356
export interface BottomSheetPreviewProps {
@@ -56,4 +69,7 @@ export interface BottomSheetPreviewProps {
5669
fullscreenContent: { widgetCount: number; renderer: ComponentType<{ caption?: string }> };
5770
onOpen: {} | null;
5871
onClose: {} | null;
72+
accessible: AccessibleEnum;
73+
screenReaderCaption: string;
74+
screenReaderHint: string;
5975
}

packages/pluggableWidgets/carousel-native/src/Carousel.editorConfig.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { RowLayoutProps, StructurePreviewProps } from "@mendix/piw-utils-internal";
2+
import { hidePropertyIn, Properties } from "@mendix/pluggable-widgets-tools";
23

34
import paginationSVG from "./assets/pagination.svg";
45

@@ -56,3 +57,12 @@ export function getPreview(values: CarouselPreviewProps, isDarkMode: boolean): S
5657
]
5758
};
5859
}
60+
61+
export function getProperties(values: CarouselPreviewProps, defaultProperties: Properties): Properties {
62+
if (values.accessible === "no") {
63+
hidePropertyIn(defaultProperties, values, "screenReaderCaption");
64+
hidePropertyIn(defaultProperties, values, "screenReaderHint");
65+
}
66+
67+
return defaultProperties;
68+
}

0 commit comments

Comments
 (0)