From 636f558c2cfdc901d1f0290ed9cdbd0dbb25aedc Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Wed, 9 Sep 2020 12:08:30 +0300 Subject: [PATCH 1/4] feat(ui5-panel): implement headerAriaLabelledBy property --- packages/base/src/util/AriaLabelHelper.js | 41 +++++++++++++++++++ .../src/util/getEffectiveAriaLabelText.js | 28 ------------- packages/main/src/Button.js | 2 +- packages/main/src/Card.js | 2 +- packages/main/src/ComboBox.js | 2 +- packages/main/src/DatePicker.js | 2 +- packages/main/src/Input.js | 2 +- packages/main/src/List.js | 2 +- packages/main/src/Panel.hbs | 4 ++ packages/main/src/Panel.js | 36 +++++++++++++++- packages/main/src/Select.js | 2 +- packages/main/src/TextArea.js | 2 +- packages/main/src/themes/Panel.css | 2 + packages/main/test/pages/Panel.html | 32 +++++++++++++++ 14 files changed, 122 insertions(+), 37 deletions(-) create mode 100644 packages/base/src/util/AriaLabelHelper.js delete mode 100644 packages/base/src/util/getEffectiveAriaLabelText.js diff --git a/packages/base/src/util/AriaLabelHelper.js b/packages/base/src/util/AriaLabelHelper.js new file mode 100644 index 000000000000..d96731cb90c7 --- /dev/null +++ b/packages/base/src/util/AriaLabelHelper.js @@ -0,0 +1,41 @@ +import findNodeOwner from "./findNodeOwner.js"; + +const getEffectiveAriaLabelText = el => { + if (!el.ariaLabelledby) { + if (el.ariaLabel) { + return el.ariaLabel; + } + + return undefined; + } + + return getAriaLabelledByTexts(el); +}; + +/** + * + * @param {HTMLElement} el Defines the HTMLElement, for which you need to get all related texts + * @param {HTMLElement} ownerDocument (Optional) Defines the HTMLElement(might document or custom element) where the you want to search for the texts. + * @param {String} readyIds (Optional) Defines a string of elements ids. The text of these elements will be returned. If used you should provide either el or ownerDocument + */ +const getAriaLabelledByTexts = (el, ownerDocument, readyIds = "") => { + const ids = readyIds.split(" ") || el.ariaLabelledby.split(" "); + const owner = ownerDocument || findNodeOwner(el); + let result = ""; + + ids.forEach((elementId, index) => { + const element = owner.querySelector(`[id='${elementId}']`); + result += `${element ? element.textContent : ""}`; + + if (index < ids.length - 1) { + result += " "; + } + }); + + return result; +}; + +export { + getEffectiveAriaLabelText, + getAriaLabelledByTexts, +}; diff --git a/packages/base/src/util/getEffectiveAriaLabelText.js b/packages/base/src/util/getEffectiveAriaLabelText.js deleted file mode 100644 index ea32e7ae5647..000000000000 --- a/packages/base/src/util/getEffectiveAriaLabelText.js +++ /dev/null @@ -1,28 +0,0 @@ -import findNodeOwner from "./findNodeOwner.js"; - -const getEffectiveAriaLabelText = el => { - if (!el.ariaLabelledby) { - if (el.ariaLabel) { - return el.ariaLabel; - } - - return undefined; - } - - const ids = el.ariaLabelledby.split(" "); - const owner = findNodeOwner(el); - let result = ""; - - ids.forEach((elementId, index) => { - const element = owner.querySelector(`[id='${elementId}']`); - result += `${element ? element.textContent : ""}`; - - if (index < ids.length - 1) { - result += " "; - } - }); - - return result; -}; - -export default getEffectiveAriaLabelText; diff --git a/packages/main/src/Button.js b/packages/main/src/Button.js index cca223285988..403d72a53385 100644 --- a/packages/main/src/Button.js +++ b/packages/main/src/Button.js @@ -3,7 +3,7 @@ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import ButtonDesign from "./types/ButtonDesign.js"; import ButtonTemplate from "./generated/templates/ButtonTemplate.lit.js"; import Icon from "./Icon.js"; diff --git a/packages/main/src/Card.js b/packages/main/src/Card.js index fdf61c3bbd6d..29d206e7b5c7 100644 --- a/packages/main/src/Card.js +++ b/packages/main/src/Card.js @@ -1,7 +1,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import CardTemplate from "./generated/templates/CardTemplate.lit.js"; import Icon from "./Icon.js"; diff --git a/packages/main/src/ComboBox.js b/packages/main/src/ComboBox.js index d3f8df83316d..d3541663b321 100644 --- a/packages/main/src/ComboBox.js +++ b/packages/main/src/ComboBox.js @@ -3,7 +3,7 @@ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import { isPhone } from "@ui5/webcomponents-base/dist/Device.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import "@ui5/webcomponents-icons/dist/icons/slim-arrow-down.js"; import "@ui5/webcomponents-icons/dist/icons/decline.js"; import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; diff --git a/packages/main/src/DatePicker.js b/packages/main/src/DatePicker.js index 21a363a5c567..574edf4363da 100644 --- a/packages/main/src/DatePicker.js +++ b/packages/main/src/DatePicker.js @@ -9,7 +9,7 @@ import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; import CalendarType from "@ui5/webcomponents-base/dist/types/CalendarType.js"; import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import { isShow, isF4 } from "@ui5/webcomponents-base/dist/Keys.js"; import { isPhone, isIE } from "@ui5/webcomponents-base/dist/Device.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; diff --git a/packages/main/src/Input.js b/packages/main/src/Input.js index 9a15d0b155de..14c104087838 100644 --- a/packages/main/src/Input.js +++ b/packages/main/src/Input.js @@ -14,7 +14,7 @@ import { } from "@ui5/webcomponents-base/dist/Keys.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import "@ui5/webcomponents-icons/dist/icons/decline.js"; import InputType from "./types/InputType.js"; import Popover from "./Popover.js"; diff --git a/packages/main/src/List.js b/packages/main/src/List.js index 4f1522cea780..f1c3712da1cc 100644 --- a/packages/main/src/List.js +++ b/packages/main/src/List.js @@ -4,7 +4,7 @@ import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation import { getLastTabbableElement } from "@ui5/webcomponents-base/dist/util/TabbableElements.js"; import { isTabNext } from "@ui5/webcomponents-base/dist/Keys.js"; import NavigationMode from "@ui5/webcomponents-base/dist/types/NavigationMode.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import ListMode from "./types/ListMode.js"; import ListSeparators from "./types/ListSeparators.js"; import BusyIndicator from "./BusyIndicator.js"; diff --git a/packages/main/src/Panel.hbs b/packages/main/src/Panel.hbs index dc073a376746..514b5d705587 100644 --- a/packages/main/src/Panel.hbs +++ b/packages/main/src/Panel.hbs @@ -39,12 +39,16 @@ role="heading" aria-level="{{headerAriaLevel}}" class="ui5-panel-header-title" + aria-labelledby="{{_id}}-headerText" > {{headerText}} {{/if}} +
+ {{headerAriaLabelledByText}} +
diff --git a/packages/main/src/Panel.js b/packages/main/src/Panel.js index 21fb157babc9..7d70d21d7d97 100644 --- a/packages/main/src/Panel.js +++ b/packages/main/src/Panel.js @@ -4,10 +4,14 @@ import slideDown from "@ui5/webcomponents-base/dist/animations/slideDown.js"; import slideUp from "@ui5/webcomponents-base/dist/animations/slideUp.js"; import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { + getEffectiveAriaLabelText, + getAriaLabelledByTexts, +} from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import { getAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import "@ui5/webcomponents-icons/dist/icons/navigation-right-arrow.js"; +import findNodeOwner from "@ui5/webcomponents-base/dist/util/findNodeOwner.js"; import Button from "./Button.js"; import TitleLevel from "./types/TitleLevel.js"; import PanelAccessibleRole from "./types/PanelAccessibleRole.js"; @@ -118,6 +122,7 @@ const metadata = { type: TitleLevel, defaultValue: TitleLevel.H2, }, + /** * @type {String} * @defaultvalue "" @@ -127,6 +132,7 @@ const metadata = { ariaLabel: { type: String, }, + /** * Receives id(or many ids) of the elements that label the panel * @@ -139,23 +145,40 @@ const metadata = { type: String, defaultValue: "", }, + + /** + * Receives id(or many ids) of the elements that label the header of the panel + * + * @type {String} + * @defaultvalue "" + * @private + * @since 1.0.0-rc.9 + */ + headerAriaLabelledBy: { + type: String, + }, + /** * @private */ _hasHeader: { type: Boolean, }, + _header: { type: Object, }, + _contentExpanded: { type: Boolean, noAttribute: true, }, + _animationRunning: { type: Boolean, noAttribute: true, }, + _buttonAccInfo: { type: Object, }, @@ -396,6 +419,10 @@ class Panel extends UI5Element { return getEffectiveAriaLabelText(this); } + get header() { + return this.getDomRef().querySelector(`#${this._id}-header-title`); + } + get headerAriaLevel() { return this.headerLevel.slice(1); } @@ -404,6 +431,13 @@ class Panel extends UI5Element { return (this.header.length || this.fixed) ? "-1" : "0"; } + get headerAriaLabelledByText() { + if (!this.headerAriaLabelledBy) { + return; + } + return getAriaLabelledByTexts(this.header, findNodeOwner(this), this.headerAriaLabelledBy); + } + get nonFixedInternalHeader() { return !this._hasHeader && !this.fixed; } diff --git a/packages/main/src/Select.js b/packages/main/src/Select.js index f383f138f1a7..700714a22d6b 100644 --- a/packages/main/src/Select.js +++ b/packages/main/src/Select.js @@ -12,7 +12,7 @@ import { } from "@ui5/webcomponents-base/dist/Keys.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js"; import "@ui5/webcomponents-icons/dist/icons/slim-arrow-down.js"; import { isPhone } from "@ui5/webcomponents-base/dist/Device.js"; diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index eb3fbd0a3c71..5dd44ec63708 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -2,7 +2,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; -import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; import { isIE } from "@ui5/webcomponents-base/dist/Device.js"; diff --git a/packages/main/src/themes/Panel.css b/packages/main/src/themes/Panel.css index 3f1141ce777b..9efea36f7eb5 100644 --- a/packages/main/src/themes/Panel.css +++ b/packages/main/src/themes/Panel.css @@ -1,3 +1,5 @@ +@import "./InvisibleTextStyles.css"; + :host(:not([hidden])) { display: block; } diff --git a/packages/main/test/pages/Panel.html b/packages/main/test/pages/Panel.html index eebd79eebb33..f22395dcb840 100644 --- a/packages/main/test/pages/Panel.html +++ b/packages/main/test/pages/Panel.html @@ -187,6 +187,38 @@ +
+ Success + Helpfull message here + + + + + Lorem ipsum! + + + Lorem ipsum dolor sit amet, tamquam invidunt cu sed, unum regione mel ea, quo ea alia novum. Ne qui illud zril + nostrum, vel ea sint dicant postea. Vel ne facete tritani, neglegentur concludaturque sed te. His animal dolorum ut. + Aeterno appareat ei mei, cu sed elit scripserit, an quodsi oportere accusamus quo. Pri ea probo corpora rationibus, + soluta incorrupte ex his. + Mei ei brute cetero, id duo magna aeque torquatos. Quodsi erroribus mediocritatem his ut, ad pri legere iracundia + democritum. Menandri intellegam in mea, ex vero movet qualisque sed. Maiorum verterem perfecto nec ea, est velit + elaboraret consequuntur eu, eam ad reque postea admodum. Ne inimicus convenire pri, doctus vidisse te ius. + Percipitur contentiones in vis, cu vim propriae phaedrum. Has ad magna errem honestatis, duo vero graeco epicurei + no, populo semper sit ne. Vulputate dissentiunt interpretaris ea vis, nec civibus moderatius at. Cu vim stet + dissentias, no vidit saperet indoctum nec, et pro magna prima nobis. Vis consul feugiat qualisque in, regione + persecuti cotidieque id eos, id ius omnesque vituperata. + Pri ex impedit percipit consulatu. Ius iudico feugiat instructior an. Iusto putant eum eu, ubique splendide pri ad, + cu qui salutandi assentior percipitur. At esse ceteros salutandi ius. Te dicam reprehendunt nec, ea discere ponderum + sensibus duo. + Vis cu commodo definiebas, postea dissentias ne vim. Modo homero eos ad. Ut vix equidem temporibus. At duo audire + volumus, id volumus rationibus vim. Sit ne diam volumus. Augue labitur mel cu, an eam omnis causae hendrerit. + + + + +
+ From da1f805066a7a1cf9f1be7beb070e3689363a08e Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 10 Sep 2020 12:27:39 +0300 Subject: [PATCH 2/4] fix failing tests --- packages/base/src/util/AriaLabelHelper.js | 2 +- packages/main/src/Card.hbs | 2 +- packages/main/src/Card.js | 2 +- packages/main/test/specs/Card.spec.js | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/base/src/util/AriaLabelHelper.js b/packages/base/src/util/AriaLabelHelper.js index d96731cb90c7..e5dc45a2c1a0 100644 --- a/packages/base/src/util/AriaLabelHelper.js +++ b/packages/base/src/util/AriaLabelHelper.js @@ -19,7 +19,7 @@ const getEffectiveAriaLabelText = el => { * @param {String} readyIds (Optional) Defines a string of elements ids. The text of these elements will be returned. If used you should provide either el or ownerDocument */ const getAriaLabelledByTexts = (el, ownerDocument, readyIds = "") => { - const ids = readyIds.split(" ") || el.ariaLabelledby.split(" "); + const ids = (readyIds && readyIds.split(" ")) || el.ariaLabelledby.split(" "); const owner = ownerDocument || findNodeOwner(el); let result = ""; diff --git a/packages/main/src/Card.hbs b/packages/main/src/Card.hbs index ec6350518e77..d2970289be24 100644 --- a/packages/main/src/Card.hbs +++ b/packages/main/src/Card.hbs @@ -2,7 +2,7 @@ class="{{classes.main}}" dir="{{effectiveDir}}" role="region" - aria-label="{{ariaLebelText}}" + aria-label="{{ariaLabelText}}" aria-labelledby="{{_id}}-desc {{_id}}-heading"> {{#if hasHeader}}
{ assert.strictEqual(field.getProperty("value"), "3", "The events count should remain 3 as the header is not interactive."); }); - it("Tests aria-label and aria-labelledby", () => { const card1 = browser.$("#textAreaAriaLabel").shadow$(".ui5-card-root"); const card2 = browser.$("#textAreaAriaLabelledBy").shadow$(".ui5-card-root"); From c6d08394aeac5d06f7df2c894e54f9ae5d687cf5 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Mon, 14 Sep 2020 10:37:30 +0300 Subject: [PATCH 3/4] fox comments --- packages/main/src/Panel.js | 6 +++--- packages/main/test/pages/Panel.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/main/src/Panel.js b/packages/main/src/Panel.js index 7d70d21d7d97..0f06d1d0d9bf 100644 --- a/packages/main/src/Panel.js +++ b/packages/main/src/Panel.js @@ -154,7 +154,7 @@ const metadata = { * @private * @since 1.0.0-rc.9 */ - headerAriaLabelledBy: { + headerAriaLabelledby: { type: String, }, @@ -432,10 +432,10 @@ class Panel extends UI5Element { } get headerAriaLabelledByText() { - if (!this.headerAriaLabelledBy) { + if (!this.headerAriaLabelledby) { return; } - return getAriaLabelledByTexts(this.header, findNodeOwner(this), this.headerAriaLabelledBy); + return getAriaLabelledByTexts(this.header, findNodeOwner(this), this.headerAriaLabelledby); } get nonFixedInternalHeader() { diff --git a/packages/main/test/pages/Panel.html b/packages/main/test/pages/Panel.html index f22395dcb840..ee37cc4efdd9 100644 --- a/packages/main/test/pages/Panel.html +++ b/packages/main/test/pages/Panel.html @@ -190,7 +190,7 @@
Success Helpfull message here - + From e09e5558d517d1591ff770a9714be6fc387c56a7 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Fri, 18 Sep 2020 11:47:43 +0300 Subject: [PATCH 4/4] fix linter --- packages/main/src/Panel.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/main/src/Panel.js b/packages/main/src/Panel.js index b93ad92c3074..3f887672f6ce 100644 --- a/packages/main/src/Panel.js +++ b/packages/main/src/Panel.js @@ -11,6 +11,7 @@ import { import { getAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import "@ui5/webcomponents-icons/dist/icons/slim-arrow-right.js"; +import findNodeOwner from "@ui5/webcomponents-base/dist/util/findNodeOwner.js"; import Button from "./Button.js"; import TitleLevel from "./types/TitleLevel.js"; import PanelAccessibleRole from "./types/PanelAccessibleRole.js";