Skip to content

Commit c75043f

Browse files
dmnplbLeleDallas
andauthored
fix: [IOPLT-1026] Add the proper accessibility state to all components in the loading state (#430)
## Short description This PR adds the proper accessibility state to all the components in the loading state ## List of changes proposed in this pull request - Add `accessibilityState: { busy: true }` to all the components in the loading state - Add an optional `loadingAccessibilityLabel` prop to add a custom text while the component is in this state - Update pages in the example app to reflect the mentioned changes ## How to test Use the screen reader and point to all components in the loading state. Previously, they were simply ignored. --------- Co-authored-by: Emanuele Dall'Ara <[email protected]>
1 parent ff71d9a commit c75043f

12 files changed

+144
-36
lines changed

example/src/pages/ListItem.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ const renderListItemTransaction = () => (
615615
amountAccessibilityLabel: "€ 1.000,00"
616616
}}
617617
isLoading={true}
618+
loadingAccessibilityLabel="Loading transaction"
618619
onPress={onButtonPress}
619620
/>
620621

example/src/pages/Modules.tsx

+19-8
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,14 @@ const renderModulePaymentNotice = () => (
145145
<View>
146146
<ModulePaymentNotice
147147
isLoading
148-
onPress={mockFn}
148+
loadingAccessibilityLabel="Loading payment notice"
149149
paymentNotice={{
150-
status: "default",
151-
amount: "100,00 €",
152-
amountAccessibilityLabel: "100,00 €"
150+
status: "in-progress"
153151
}}
152+
badgeText="In corso"
153+
subtitle="F24"
154154
title="Codice avviso"
155-
subtitle="302012131232131"
155+
onPress={mockFn}
156156
/>
157157
</View>
158158
</ComponentViewerBox>
@@ -216,7 +216,10 @@ const renderModuleCheckout = () => (
216216
/>
217217
</ComponentViewerBox>
218218
<ComponentViewerBox name="ModuleCheckout, loading">
219-
<ModuleCheckout isLoading />
219+
<ModuleCheckout
220+
isLoading
221+
loadingAccessibilityLabel="Loading checkout item"
222+
/>
220223
</ComponentViewerBox>
221224
</>
222225
);
@@ -250,6 +253,7 @@ const renderModuleAttachment = () => (
250253
title="Documento.pdf"
251254
format="pdf"
252255
isLoading
256+
loadingAccessibilityLabel="Loading attachment"
253257
onPress={modulePress}
254258
/>
255259
</ComponentViewerBox>
@@ -258,6 +262,7 @@ const renderModuleAttachment = () => (
258262
title="Documento.pdf"
259263
format="pdf"
260264
isFetching
265+
fetchingAccessibilityLabel="Fetching attachment"
261266
onPress={modulePress}
262267
/>
263268
</ComponentViewerBox>
@@ -325,7 +330,10 @@ const renderModuleCredential = () => (
325330
</ComponentViewerBox>
326331
<ComponentViewerBox name="ModuleCredential, loading">
327332
<View>
328-
<ModuleCredential isLoading={true} />
333+
<ModuleCredential
334+
isLoading={true}
335+
loadingAccessibilityLabel={"Loading credential"}
336+
/>
329337
</View>
330338
</ComponentViewerBox>
331339
</>
@@ -375,7 +383,10 @@ const renderModuleNavigation = () => (
375383
</ComponentViewerBox>
376384
<ComponentViewerBox name="ModuleNavigation, loading">
377385
<View>
378-
<ModuleNavigation isLoading={true} />
386+
<ModuleNavigation
387+
isLoading={true}
388+
loadingAccessibilityLabel={"Loading navigation"}
389+
/>
379390
</View>
380391
</ComponentViewerBox>
381392
</>

example/src/pages/Selection.tsx

+8-4
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ const mockRadioItems = (): ReadonlyArray<RadioItem<string>> => [
211211
disabled: true,
212212
loadingProps: {
213213
state: true,
214-
skeletonIcon: false
214+
skeletonIcon: false,
215+
loadingAccessibilityLabel: "Loading radio item"
215216
}
216217
},
217218
{
@@ -222,7 +223,8 @@ const mockRadioItems = (): ReadonlyArray<RadioItem<string>> => [
222223
disabled: true,
223224
loadingProps: {
224225
state: true,
225-
skeletonIcon: true
226+
skeletonIcon: true,
227+
loadingAccessibilityLabel: "Loading radio item"
226228
}
227229
},
228230
{
@@ -233,7 +235,8 @@ const mockRadioItems = (): ReadonlyArray<RadioItem<string>> => [
233235
disabled: true,
234236
loadingProps: {
235237
state: true,
236-
skeletonDescription: true
238+
skeletonDescription: true,
239+
loadingAccessibilityLabel: "Loading radio item"
237240
}
238241
},
239242
{
@@ -245,7 +248,8 @@ const mockRadioItems = (): ReadonlyArray<RadioItem<string>> => [
245248
loadingProps: {
246249
state: true,
247250
skeletonDescription: true,
248-
skeletonIcon: true
251+
skeletonIcon: true,
252+
loadingAccessibilityLabel: "Loading radio item"
249253
}
250254
}
251255
];

src/components/listitems/ListItemRadio.tsx

+14-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ type ListItemRadioLoadingProps =
3131
state: true;
3232
skeletonDescription?: boolean;
3333
skeletonIcon?: boolean;
34+
loadingAccessibilityLabel?: string;
3435
}
3536
| {
3637
state?: false;
3738
skeletonDescription?: never;
3839
skeletonIcon?: never;
40+
loadingAccessibilityLabel?: never;
3941
};
4042

4143
type Props = WithTestID<{
@@ -122,8 +124,15 @@ export const ListItemRadio = ({
122124
</View>
123125
);
124126

125-
const SkeletonComponent = () => (
126-
<View style={[IOSelectionListItemStyles.listItem, { rowGap: 8 }]}>
127+
const ListItemRadioSkeleton = ({
128+
loadingAccessibilityLabel
129+
}: Pick<ListItemRadioLoadingProps, "loadingAccessibilityLabel">) => (
130+
<View
131+
style={[IOSelectionListItemStyles.listItem, { rowGap: 8 }]}
132+
accessible={true}
133+
accessibilityLabel={loadingAccessibilityLabel}
134+
accessibilityState={{ busy: true }}
135+
>
127136
<View style={IOSelectionListItemStyles.listItemInner}>
128137
<View
129138
style={[
@@ -155,7 +164,9 @@ export const ListItemRadio = ({
155164
);
156165

157166
return loadingProps?.state ? (
158-
<SkeletonComponent />
167+
<ListItemRadioSkeleton
168+
loadingAccessibilityLabel={loadingProps?.loadingAccessibilityLabel}
169+
/>
159170
) : (
160171
<Pressable
161172
accessibilityRole="radio"

src/components/listitems/ListItemTransaction.tsx

+16-3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export type ListItemTransaction = WithTestID<
4141
PressableBaseProps & {
4242
showChevron?: boolean;
4343
isLoading?: boolean;
44+
loadingAccessibilityLabel?: string;
4445
/**
4546
* A logo that will be displayed on the left of the list item.
4647
*
@@ -102,6 +103,7 @@ const StartComponent = ({
102103

103104
export const ListItemTransaction = ({
104105
accessibilityLabel,
106+
loadingAccessibilityLabel,
105107
showChevron = false,
106108
isLoading = false,
107109
paymentLogoIcon,
@@ -116,7 +118,11 @@ export const ListItemTransaction = ({
116118
const theme = useIOTheme();
117119

118120
if (isLoading) {
119-
return <SkeletonComponent />;
121+
return (
122+
<ListItemTransactionSkeleton
123+
loadingAccessibilityLabel={loadingAccessibilityLabel}
124+
/>
125+
);
120126
}
121127

122128
const interactiveColor: IOColors = theme["interactiveElem-default"];
@@ -207,8 +213,15 @@ export const ListItemTransaction = ({
207213
}
208214
};
209215

210-
const SkeletonComponent = () => (
211-
<View style={IOListItemStyles.listItem} accessible={false}>
216+
const ListItemTransactionSkeleton = ({
217+
loadingAccessibilityLabel
218+
}: Pick<ListItemTransaction, "loadingAccessibilityLabel">) => (
219+
<View
220+
style={IOListItemStyles.listItem}
221+
accessible={true}
222+
accessibilityLabel={loadingAccessibilityLabel}
223+
accessibilityState={{ busy: true }}
224+
>
212225
<View style={IOListItemStyles.listItemInner}>
213226
<View style={{ marginRight: IOListItemVisualParams.iconMargin }}>
214227
<Placeholder.Box

src/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap

+12-2
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,12 @@ exports[`Test List Item Components - Experimental Enabled ListItemRadioWithAmou
13641364

13651365
exports[`Test List Item Components - Experimental Enabled ListItemTransaction Snapshot 1`] = `
13661366
<View
1367-
accessible={false}
1367+
accessibilityState={
1368+
{
1369+
"busy": true,
1370+
}
1371+
}
1372+
accessible={true}
13681373
style={
13691374
{
13701375
"marginHorizontal": -24,
@@ -2942,7 +2947,12 @@ exports[`Test List Item Components ListItemRadioWithAmount Snapshot 2`] = `
29422947

29432948
exports[`Test List Item Components ListItemTransaction Snapshot 1`] = `
29442949
<View
2945-
accessible={false}
2950+
accessibilityState={
2951+
{
2952+
"busy": true,
2953+
}
2954+
}
2955+
accessible={true}
29462956
style={
29472957
{
29482958
"marginHorizontal": -24,

src/components/modules/ModuleAttachment.tsx

+14-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type PartialProps = WithTestID<{
1616
format: "doc" | "pdf";
1717
isLoading?: boolean;
1818
isFetching?: boolean;
19+
loadingAccessibilityLabel?: string;
1920
fetchingAccessibilityLabel?: string;
2021
onPress: (event: GestureResponderEvent) => void;
2122
}>;
@@ -87,6 +88,7 @@ const ModuleAttachmentContent = ({
8788
* @param {string} accessibilityLabel - Optional accessibility label.
8889
* @param {boolean} disabled - If true, the button is disabled.
8990
* @param {string} fetchingAccessibilityLabel - Optional accessibility label to use during fetching.
91+
* @param {string} loadingAccessibilityLabel - Optional accessibility label to use during loading.
9092
* @param {string} format - Badge content. PDF or DOC.
9193
* @param {boolean} isLoading - If true, displays a skeleton loading component.
9294
* @param {boolean} isFetching - If true, displays an activity indicator.
@@ -99,6 +101,7 @@ export const ModuleAttachment = ({
99101
accessibilityLabel,
100102
disabled = false,
101103
fetchingAccessibilityLabel,
104+
loadingAccessibilityLabel,
102105
format,
103106
isLoading = false,
104107
isFetching = false,
@@ -117,7 +120,11 @@ export const ModuleAttachment = ({
117120
);
118121

119122
if (isLoading) {
120-
return <ModuleAttachmentSkeleton />;
123+
return (
124+
<ModuleAttachmentSkeleton
125+
loadingAccessibilityLabel={loadingAccessibilityLabel}
126+
/>
127+
);
121128
}
122129

123130
const pressableAccessibilityLabel =
@@ -149,8 +156,13 @@ export const ModuleAttachment = ({
149156
);
150157
};
151158

152-
const ModuleAttachmentSkeleton = () => (
159+
const ModuleAttachmentSkeleton = ({
160+
loadingAccessibilityLabel
161+
}: Pick<ModuleAttachmentProps, "loadingAccessibilityLabel">) => (
153162
<ModuleStatic
163+
accessible={true}
164+
accessibilityLabel={loadingAccessibilityLabel}
165+
accessibilityState={{ busy: true }}
154166
startBlock={
155167
<VStack space={4}>
156168
<Placeholder.Box animate="fade" radius={8} width={114} height={16} />

src/components/modules/ModuleCheckout.tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { PressableModuleBase } from "./PressableModuleBase";
2121

2222
type LoadingProps = {
2323
isLoading: true;
24+
loadingAccessibilityLabel?: string;
2425
};
2526

2627
type ImageProps =
@@ -45,7 +46,11 @@ export const ModuleCheckout = (props: ModuleCheckoutProps) => {
4546
const imageMargin: IOSpacingScale = 12;
4647

4748
if (props.isLoading) {
48-
return <ModuleCheckoutSkeleton />;
49+
return (
50+
<ModuleCheckoutSkeleton
51+
loadingAccessibilityLabel={props.loadingAccessibilityLabel}
52+
/>
53+
);
4954
}
5055

5156
const { paymentLogo, image, title, subtitle, ctaText, onPress } = props;
@@ -98,8 +103,13 @@ export const ModuleCheckout = (props: ModuleCheckoutProps) => {
98103
);
99104
};
100105

101-
const ModuleCheckoutSkeleton = () => (
106+
const ModuleCheckoutSkeleton = ({
107+
loadingAccessibilityLabel
108+
}: Pick<LoadingProps, "loadingAccessibilityLabel">) => (
102109
<ModuleStatic
110+
accessible={true}
111+
accessibilityLabel={loadingAccessibilityLabel}
112+
accessibilityState={{ busy: true }}
103113
startBlock={
104114
<HStack space={8} style={{ alignItems: "center" }}>
105115
<Placeholder.Box animate="fade" radius={8} height={24} width={24} />

src/components/modules/ModuleCredential.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type ImageProps =
3232

3333
type LoadingModuleProps = {
3434
isLoading: true;
35+
loadingAccessibilityLabel?: string;
3536
};
3637

3738
type BaseModuleProps = {
@@ -48,7 +49,9 @@ const ModuleCredential = (
4849
props: WithTestID<LoadingModuleProps | ModuleCredentialProps>
4950
) =>
5051
props.isLoading ? (
51-
<ModuleCredentialSkeleton />
52+
<ModuleCredentialSkeleton
53+
loadingAccessibilityLabel={props.loadingAccessibilityLabel}
54+
/>
5255
) : (
5356
<ModuleCredentialContent {...props} />
5457
);
@@ -144,8 +147,13 @@ const ModuleCredentialContent = ({
144147
);
145148
};
146149

147-
const ModuleCredentialSkeleton = () => (
150+
const ModuleCredentialSkeleton = ({
151+
loadingAccessibilityLabel
152+
}: Pick<LoadingModuleProps, "loadingAccessibilityLabel">) => (
148153
<ModuleStatic
154+
accessible={true}
155+
accessibilityLabel={loadingAccessibilityLabel}
156+
accessibilityState={{ busy: true }}
149157
startBlock={
150158
<HStack
151159
style={{ alignItems: "center" }}

src/components/modules/ModuleNavigation.tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828

2929
type LoadingProps = {
3030
isLoading: true;
31+
loadingAccessibilityLabel?: string;
3132
};
3233

3334
type ImageProps =
@@ -49,7 +50,11 @@ export const ModuleNavigation = (props: WithTestID<ModuleNavigationProps>) => {
4950
const { hugeFontEnabled } = useIOFontDynamicScale();
5051

5152
if (props.isLoading) {
52-
return <ModuleNavigationSkeleton />;
53+
return (
54+
<ModuleNavigationSkeleton
55+
loadingAccessibilityLabel={props.loadingAccessibilityLabel}
56+
/>
57+
);
5358
}
5459

5560
const { icon, image, title, subtitle, onPress, badge, ...pressableProps } =
@@ -111,8 +116,13 @@ export const ModuleNavigation = (props: WithTestID<ModuleNavigationProps>) => {
111116
);
112117
};
113118

114-
const ModuleNavigationSkeleton = () => (
119+
const ModuleNavigationSkeleton = ({
120+
loadingAccessibilityLabel
121+
}: Pick<LoadingProps, "loadingAccessibilityLabel">) => (
115122
<ModuleStatic
123+
accessible={true}
124+
accessibilityLabel={loadingAccessibilityLabel}
125+
accessibilityState={{ busy: true }}
116126
startBlock={
117127
<HStack
118128
style={{ alignItems: "center" }}

0 commit comments

Comments
 (0)