Skip to content

Commit dbeb72b

Browse files
authored
feat(MultipleFileUpload): add aria live region to internal Progress (#8242)
* feat(MultipleFileUpload): add aria live region to internal Progress * add floor/cap load percentage * update description * update and add tests
1 parent 0cf2f93 commit dbeb72b

File tree

3 files changed

+312
-4
lines changed

3 files changed

+312
-4
lines changed

packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export interface MultipleFileUploadStatusItemProps extends React.HTMLProps<HTMLL
5050
progressAriaLabel?: string;
5151
/** Associates the progress bar with it's label for accessibility purposes. Required when title not used */
5252
progressAriaLabelledBy?: string;
53+
/** Modifies the text announced by assistive technologies when the progress bar updates. */
54+
progressAriaLiveMessage?: string | ((loadPercentage: number) => string);
5355
/** Unique identifier for progress. Generated if not specified. */
5456
progressId?: string;
5557
}
@@ -71,6 +73,7 @@ export const MultipleFileUploadStatusItem: React.FunctionComponent<MultipleFileU
7173
progressAriaLabel,
7274
progressAriaLabelledBy,
7375
progressId,
76+
progressAriaLiveMessage,
7477
buttonAriaLabel = 'Remove from list',
7578
...props
7679
}: MultipleFileUploadStatusItemProps) => {
@@ -139,6 +142,13 @@ export const MultipleFileUploadStatusItem: React.FunctionComponent<MultipleFileU
139142
<li className={css(styles.multipleFileUploadStatusItem, className)} {...props}>
140143
<div className={styles.multipleFileUploadStatusItemIcon}>{fileIcon || <FileIcon />}</div>
141144
<div className={styles.multipleFileUploadStatusItemMain}>
145+
<div className="pf-screen-reader" aria-live="polite">
146+
{progressAriaLiveMessage &&
147+
typeof progressAriaLiveMessage === 'function' &&
148+
progressAriaLiveMessage(+loadPercentage.toFixed(2))}
149+
{progressAriaLiveMessage && typeof progressAriaLiveMessage === 'string' && progressAriaLiveMessage}
150+
{!progressAriaLiveMessage && `Progress value is ${progressValue || Math.floor(loadPercentage)}%.`}
151+
</div>
142152
<Progress
143153
title={title}
144154
value={progressValue || loadPercentage}

packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,39 @@ describe('MultipleFileUploadStatusItem', () => {
2323
expect(asFragment()).toMatchSnapshot();
2424
});
2525

26-
test('renders custom file name/size/icon when passed', () => {
26+
test('renders custom file name/size/icon/progressAriaLiveMessage when passed', () => {
27+
const testFile = new File(['foo'], 'testFile.txt');
28+
const { asFragment } = render(
29+
<MultipleFileUploadStatusItem
30+
file={testFile}
31+
fileIcon={<FileImageIcon />}
32+
fileName="testCustomFileName.txt"
33+
fileSize={42}
34+
progressId="test-progress-id"
35+
progressAriaLiveMessage="test message"
36+
/>
37+
);
38+
39+
expect(asFragment()).toMatchSnapshot();
40+
});
41+
42+
test('renders custom function progressAriaLiveMessage when passed', () => {
43+
const testFile = new File(['foo'], 'testFile.txt');
44+
const { asFragment } = render(
45+
<MultipleFileUploadStatusItem
46+
file={testFile}
47+
fileIcon={<FileImageIcon />}
48+
fileName="testCustomFileName.txt"
49+
fileSize={42}
50+
progressId="test-progress-id"
51+
progressAriaLiveMessage={loadPercentage => `test message ${loadPercentage}`}
52+
/>
53+
);
54+
55+
expect(asFragment()).toMatchSnapshot();
56+
});
57+
58+
test('rendersdefault progressAriaLiveMessage when nothing is passed', () => {
2759
const testFile = new File(['foo'], 'testFile.txt');
2860
const { asFragment } = render(
2961
<MultipleFileUploadStatusItem

0 commit comments

Comments
 (0)