From 0463e49e08c5e1b12c0259715cc20af3581a4531 Mon Sep 17 00:00:00 2001 From: Florian Kellner Date: Wed, 21 Feb 2024 16:44:24 +0100 Subject: [PATCH] geosolutions-it#10158: tooltip enhancer adds 'aria-label' with l10n Modify tooltip enhancer to also provide `aria-label`-property to wrapped objects (most commonly glyph-only buttons). Does localization on a best-effort basis, trying to unwrap messages passed in as tooltip prop. On Behalf of DB Systel --- .../misc/enhancers/__tests__/tooltip-test.jsx | 18 ++++++++++ .../components/misc/enhancers/tooltip.jsx | 34 ++++++++++++++----- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/web/client/components/misc/enhancers/__tests__/tooltip-test.jsx b/web/client/components/misc/enhancers/__tests__/tooltip-test.jsx index 8b90da7b92..4f5eb54663 100644 --- a/web/client/components/misc/enhancers/__tests__/tooltip-test.jsx +++ b/web/client/components/misc/enhancers/__tests__/tooltip-test.jsx @@ -12,6 +12,13 @@ import React from 'react'; import ReactDOM from 'react-dom'; import tooltip from '../tooltip'; import { Button } from 'react-bootstrap'; +import Message from "../../../I18N/HTML"; +import Localized from "../../../I18N/Localized"; + +const messages = { + "testMsg": "my message" +}; + describe("tooltip enhancer", () => { beforeEach((done) => { document.body.innerHTML = '
'; @@ -38,5 +45,16 @@ describe("tooltip enhancer", () => { el.click(); expect(el.getAttribute('aria-describedby')).toExist(); }); + it('adds an aria-label property with localized content', () => { + const CMP = tooltip(Button); + const tip = ; + ReactDOM.render( + + TEXT + , document.getElementById("container")); + const el = document.getElementById("text-cmp"); + expect(el).toExist(); + expect(el.getAttribute('aria-label')).toBe('my message'); + }); }); diff --git a/web/client/components/misc/enhancers/tooltip.jsx b/web/client/components/misc/enhancers/tooltip.jsx index 3a6403c194..bf0c958512 100644 --- a/web/client/components/misc/enhancers/tooltip.jsx +++ b/web/client/components/misc/enhancers/tooltip.jsx @@ -15,11 +15,15 @@ import { omit } from 'lodash'; /** * Tooltip enhancer. Enhances an object adding a tooltip (with i18n support). - * It is applied only if props contains `tooltip` or `tooltipId`. It have to be applied to a React (functional) component + * It is applied only if props contains `tooltip` or `tooltipId`. It has to be applied to a React (functional) component. + * The tooltip text will also be added as `aria-label` prop to the object in order to increase a11y. + * Note that if you add an i18n `Message` as a tooltip, it will be reconstructed around the tooltip so that its + * text is also available in the `aria-label` property. Passing other `node`s as tooltips is strongly discouraged, + * since it will result in an `[object Object]` `aria-label` which will help nobody. * @type {function} * @name tooltip * @memberof components.misc.enhancers - * @prop {string|node} [tooltip] if present will add the tooltip. This is the full tooltip content + * @prop {string|node} [tooltip] if present will add the tooltip. This is the full tooltip content. * @prop {string} [tooltipId] if present will show a localized tooltip using the tooltipId as msgId * @prop {string} [tooltipPosition="top"] * @prop {string} tooltipTrigger see react overlay trigger @@ -32,12 +36,26 @@ import { omit } from 'lodash'; */ export default branch( ({tooltip, tooltipId} = {}) => tooltip || tooltipId, - (Wrapped) => ({tooltip, tooltipId, tooltipPosition = "top", tooltipTrigger, keyProp, idDropDown, args, ...props} = {}) => ({tooltipId ? : tooltip}}>), + (Wrapped) => ({tooltip, tooltipId, tooltipPosition = "top", tooltipTrigger, keyProp, idDropDown, args, ...props} = {}) => + (tooltipId || (tooltip.props && tooltip.props.msgId) // this is not DRY, but constructing the within the OverlayTrigger prevents it from working + ? + { (msg) => {msg}}> + } + + : {tooltipId ? : tooltip}}> + ), // avoid to pass non needed props (Wrapped) => (props) => {props.children} );