diff --git a/packages/main/cypress/specs/FileUploader.cy.tsx b/packages/main/cypress/specs/FileUploader.cy.tsx
index b2537c4decec..280b0611b7d0 100644
--- a/packages/main/cypress/specs/FileUploader.cy.tsx
+++ b/packages/main/cypress/specs/FileUploader.cy.tsx
@@ -478,6 +478,31 @@ describe("Interaction", () => {
});
describe("Accessibility", () => {
+ it("value state hidden text contains type label and default message", () => {
+ cy.mount(
+
+ );
+
+ cy.get("#uploader")
+ .shadow()
+ .find("#valueStateDesc")
+ .should("have.text", "Value State Error Invalid entry");
+ });
+
+ it("value state hidden text contains type label and custom message", () => {
+ cy.mount(
+
+ Custom error message.
+
+ );
+
+ cy.get("#uploader")
+ .shadow()
+ .find("#valueStateDesc")
+ .should("include.text", "Value State Error")
+ .and("include.text", "Custom error message.");
+ });
+
it("A11y attributes", () => {
cy.mount(
<>
diff --git a/packages/main/src/FileUploader.ts b/packages/main/src/FileUploader.ts
index 1c55c49063d3..9f8f14218861 100644
--- a/packages/main/src/FileUploader.ts
+++ b/packages/main/src/FileUploader.ts
@@ -35,6 +35,10 @@ import {
VALUE_STATE_INFORMATION,
VALUE_STATE_ERROR,
VALUE_STATE_WARNING,
+ VALUE_STATE_TYPE_SUCCESS,
+ VALUE_STATE_TYPE_INFORMATION,
+ VALUE_STATE_TYPE_ERROR,
+ VALUE_STATE_TYPE_WARNING,
FILEUPLOADER_DEFAULT_PLACEHOLDER,
FILEUPLOADER_DEFAULT_MULTIPLE_PLACEHOLDER,
FILEUPLOADER_ROLE_DESCRIPTION,
@@ -55,6 +59,8 @@ import ValueStateMessageCss from "./generated/themes/ValueStateMessage.css.js";
const convertBytesToMegabytes = (bytes: number) => (bytes / 1024) / 1024;
+type MappedValueState = Exclude<`${ValueState}`, "None">;
+
type FileData = {
fileName: string,
fileSize: number,
@@ -624,9 +630,35 @@ class FileUploader extends UI5Element implements IFormInputElement {
"ariaHasPopup": "dialog",
"ariaLabel": getAllAccessibleNameRefTexts(this) || getEffectiveAriaLabelText(this) || getAssociatedLabelForTexts(this) || undefined,
"ariaDescription": getAllAccessibleDescriptionRefTexts(this) || getEffectiveAriaDescriptionText(this) || undefined,
+ "ariaDescribedBy": this.hasValueState ? "valueStateDesc" : undefined,
+ };
+ }
+
+ get valueStateTypeMappings(): Record {
+ return {
+ "Positive": FileUploader.i18nBundle.getText(VALUE_STATE_TYPE_SUCCESS),
+ "Information": FileUploader.i18nBundle.getText(VALUE_STATE_TYPE_INFORMATION),
+ "Negative": FileUploader.i18nBundle.getText(VALUE_STATE_TYPE_ERROR),
+ "Critical": FileUploader.i18nBundle.getText(VALUE_STATE_TYPE_WARNING),
};
}
+ get ariaValueStateHiddenText(): string | undefined {
+ if (!this.hasValueState) {
+ return undefined;
+ }
+
+ const valueStateType = this.valueStateTypeMappings[this.valueState as MappedValueState];
+
+ if (this.shouldDisplayDefaultValueStateMessage) {
+ return this.valueStateText ? `${valueStateType} ${this.valueStateText}` : valueStateType;
+ }
+
+ return this.valueStateMessage.length
+ ? `${valueStateType} ${this.valueStateMessage.map(el => el.textContent).join(" ")}`
+ : valueStateType;
+ }
+
get inputTitle(): string {
return FileUploader.i18nBundle.getText(FILEUPLOADER_INPUT_TOOLTIP);
}
@@ -645,7 +677,7 @@ class FileUploader extends UI5Element implements IFormInputElement {
return this.placeholder ?? (this.multiple ? multiplePlaceholder : singlePlaceholder);
}
- get valueStateTextMappings(): Record {
+ get valueStateTextMappings(): Record {
return {
"Positive": FileUploader.i18nBundle.getText(VALUE_STATE_SUCCESS),
"Information": FileUploader.i18nBundle.getText(VALUE_STATE_INFORMATION),
@@ -654,8 +686,8 @@ class FileUploader extends UI5Element implements IFormInputElement {
};
}
- get valueStateText(): string {
- return this.valueStateTextMappings[this.valueState];
+ get valueStateText(): string | undefined {
+ return this.valueStateTextMappings[this.valueState as MappedValueState];
}
get hasValueState(): boolean {
diff --git a/packages/main/src/FileUploaderTemplate.tsx b/packages/main/src/FileUploaderTemplate.tsx
index bbceeaa01d3d..a54954d0ca88 100644
--- a/packages/main/src/FileUploaderTemplate.tsx
+++ b/packages/main/src/FileUploaderTemplate.tsx
@@ -35,10 +35,14 @@ export default function FileUploaderTemplate(this: FileUploader) {
aria-description={this.accInfo.ariaDescription}
aria-required={this.accInfo.ariaRequired}
aria-invalid={this.accInfo.ariaInvalid}
+ aria-describedby={this.accInfo.ariaDescribedBy}
onClick={this._onNativeInputClick}
onChange={this._onChange}
data-sap-focus-ref
/>
+ {this.hasValueState &&
+ {this.ariaValueStateHiddenText}
+ }
{this.hideInput ? (