From f5f907a8834ce67fd17c6444a14bb99d3772c292 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini <41484878+deodorhunter@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:57:10 +0100 Subject: [PATCH] fix: a11y for feedback section (#560) * fix: a11y for customer satisfaction section, still small problem with sr announcements * fix: fix some more automated tests issues * fix: changed some logic on satisfaction change, added autofocus on back to first step selected answer * chore: update release.md and translations --------- Co-authored-by: Piero Nicolli --- RELEASE.md | 1 + locales/de/LC_MESSAGES/volto.po | 5 + locales/en/LC_MESSAGES/volto.po | 5 + locales/es/LC_MESSAGES/volto.po | 5 + locales/fr/LC_MESSAGES/volto.po | 5 + locales/it/LC_MESSAGES/volto.po | 5 + locales/volto.pot | 5 + .../CustomerSatisfaction/FeedbackForm.jsx | 149 ++++++++++++----- .../Steps/AnswersStep.jsx | 14 +- .../Steps/CommentsStep.jsx | 8 +- .../Steps/Commons/Rating.jsx | 153 ++++++++---------- .../components/FeedbackForm/Steps/Commons.jsx | 18 ++- .../Components/_customerSatisfaction.scss | 51 +++++- 13 files changed, 277 insertions(+), 147 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 31b235ce1..ff03c492a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -56,6 +56,7 @@ - L'icona per aprire il menu in mobile è ora visibile anche quando l'header del sito è bianca. - La descrizione nelle card per i punti di contatto non mostrano più tutte le iniziali in maiuscolo. - Il colore dei link nel menu mobile è ora accessibile per tutti i temi. +- Migliorata l'accessibilità della sezione dedicata al feedback utente per tutti i contenuti del sito - Rimosso il title dall'immagine di apertura dei contenuti - Rimosso attributo title dall'immagine delle card: card con immagine, persona, blocco link completo, contenuto in evidenza, gallery a griglia, in evidenza - Migliorata l'accessibilità del menu in versione mobile. diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index 66db76294..c2ed42f41 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -2071,6 +2071,11 @@ msgstr "" msgid "feedback_sent" msgstr "" +#: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm +# defaultMessage: Valuta da 1 a 5 stelle +msgid "feedback_stars" +msgstr "" + #: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm # defaultMessage: I ran into technical problems msgid "feedback_technical_problems" diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index cb59baad6..34241408e 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -2056,6 +2056,11 @@ msgstr "" msgid "feedback_sent" msgstr "" +#: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm +# defaultMessage: Valuta da 1 a 5 stelle +msgid "feedback_stars" +msgstr "Rate from 1 to 5 stars" + #: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm # defaultMessage: I ran into technical problems msgid "feedback_technical_problems" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index 8d7c6a2b0..342b7f0ff 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -2065,6 +2065,11 @@ msgstr "" msgid "feedback_sent" msgstr "" +#: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm +# defaultMessage: Valuta da 1 a 5 stelle +msgid "feedback_stars" +msgstr "" + #: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm # defaultMessage: I ran into technical problems msgid "feedback_technical_problems" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index a0ea1f11f..61c9a7bf9 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -2073,6 +2073,11 @@ msgstr "" msgid "feedback_sent" msgstr "" +#: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm +# defaultMessage: Valuta da 1 a 5 stelle +msgid "feedback_stars" +msgstr "" + #: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm # defaultMessage: I ran into technical problems msgid "feedback_technical_problems" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index b1da0afda..de8c40594 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -2056,6 +2056,11 @@ msgstr "Altro" msgid "feedback_sent" msgstr "Il tuo feedback è stato inviato!" +#: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm +# defaultMessage: Valuta da 1 a 5 stelle +msgid "feedback_stars" +msgstr "" + #: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm # defaultMessage: I ran into technical problems msgid "feedback_technical_problems" diff --git a/locales/volto.pot b/locales/volto.pot index b9a0fdaa9..a91fa9b7f 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -2058,6 +2058,11 @@ msgstr "" msgid "feedback_sent" msgstr "" +#: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm +# defaultMessage: Valuta da 1 a 5 stelle +msgid "feedback_stars" +msgstr "" + #: components/ItaliaTheme/CustomerSatisfaction/FeedbackForm # defaultMessage: I ran into technical problems msgid "feedback_technical_problems" diff --git a/src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx b/src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx index cbf73ecd1..6ab1b3741 100644 --- a/src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx +++ b/src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx @@ -1,4 +1,10 @@ -import React, { useState, useEffect, useCallback, useMemo } from 'react'; +import React, { + useState, + useEffect, + useLayoutEffect, + useCallback, + useMemo, +} from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useLocation } from 'react-router-dom'; import { useIntl, defineMessages } from 'react-intl'; @@ -9,7 +15,6 @@ import { Col, Spinner, Card, - Button, CardHeader, CardBody, } from 'design-react-kit'; @@ -25,7 +30,7 @@ import { import cx from 'classnames'; import AnswersStep from './Steps/AnswersStep'; import CommentsStep from './Steps/CommentsStep'; -import Rating from './Steps/Commons/Rating'; +import RTRating from './Steps/Commons/Rating'; import { PropTypes } from 'prop-types'; const messages = defineMessages({ @@ -111,6 +116,10 @@ const messages = defineMessages({ id: 'feedback_other_positive', defaultMessage: 'Other', }, + feedback: { + id: 'feedback_stars', + defaultMessage: 'Valuta da 1 a 5 stelle', + }, error: { id: 'feedback_error', defaultMessage: 'Error', @@ -134,12 +143,11 @@ const FeedbackForm = ({ contentType, pathname }) => { ? window.env.RAZZLE_HONEYPOT_FIELD : process.env.RAZZLE_HONEYPOT_FIELD; - const numberOfSteps = useMemo(() => getNumberOfSteps(), []); + const numberOfSteps = getNumberOfSteps(); const changeSatisfaction = (e) => { setSatisfaction(e); }; - const updateFormData = (field, value) => { if (field === 'comment') { if (value?.length > 200) setInvalidForm(true); @@ -154,12 +162,17 @@ const FeedbackForm = ({ contentType, pathname }) => { [field]: value, }); }; - const getFormFieldValue = (field) => formData?.[field] ?? undefined; - const nextStep = () => setStep(step + 1); + const nextStep = () => { + if (!invalidForm) setStep(step + 1); + }; - const prevStep = () => setStep(step - 1); + const prevStep = () => { + if (!invalidForm && step !== 0) { + setStep(step - 1); + } + }; useEffect(() => { setValidToken(null); @@ -171,6 +184,12 @@ const FeedbackForm = ({ contentType, pathname }) => { }, [path]); useEffect(() => { + const currentVote = getFormFieldValue('vote'); + if ( + (currentVote > threshold && satisfaction < threshold) || + (currentVote < threshold && satisfaction > threshold) + ) + updateFormData('answer', null); updateFormData('vote', satisfaction ?? null); setStep(0); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -182,6 +201,25 @@ const FeedbackForm = ({ contentType, pathname }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [fieldHoney]); + // Motivazioni del focus programmatico + // - su alcuni browser viene dichiarato "object replacement character" ai rerender di react + // che sono inevitabili mentre il focus rimane sul bottone ma non viene detto + // - replichiamo 1:1 il comportamento del secondo step, quando vai avanti hai autofocus sulla + // textarea per i commenti + // - essendo annunciato ora il titolo dello step, l'utente sr sa comunque benissimo dove si trova, + // anzi, il flow di compilazione del form kb+sr e' molto piu' agevole + useEffect(() => { + if (step === 0 && getFormFieldValue('answer')) { + const selectedAnswer = document.getElementById( + `${ + satisfaction > threshold ? 'positive' : 'negative' + }-${getFormFieldValue('answer')}`, + ); + selectedAnswer.focus(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [step]); + const onVerifyCaptcha = useCallback( (token) => { if (satisfaction !== null && !validToken) { @@ -198,6 +236,7 @@ const FeedbackForm = ({ contentType, pathname }) => { }; const sendFormData = () => { + if (invalidForm) return; setStep(2); const data = { ...formData, @@ -220,7 +259,7 @@ const FeedbackForm = ({ contentType, pathname }) => { } return ( -
+
@@ -252,15 +291,31 @@ const FeedbackForm = ({ contentType, pathname }) => { : intl.formatMessage(messages.title)}
- threshold @@ -269,7 +324,7 @@ const FeedbackForm = ({ contentType, pathname }) => { } className="volto-feedback-rating mb-0" onChangeRating={changeSatisfaction} - legend=" " + legend={intl.formatMessage(messages.feedback)} wrapperClassName={'rating'} />
@@ -300,47 +355,61 @@ const FeedbackForm = ({ contentType, pathname }) => { />
- + + {step !== numberOfSteps - 1 && ( - + )} {step === numberOfSteps - 1 && ( - + )}
@@ -385,7 +454,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
-
+ ); }; diff --git a/src/components/ItaliaTheme/CustomerSatisfaction/Steps/AnswersStep.jsx b/src/components/ItaliaTheme/CustomerSatisfaction/Steps/AnswersStep.jsx index a3c737172..bd37d7b9c 100644 --- a/src/components/ItaliaTheme/CustomerSatisfaction/Steps/AnswersStep.jsx +++ b/src/components/ItaliaTheme/CustomerSatisfaction/Steps/AnswersStep.jsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useMemo } from 'react'; import { usePrevious } from '@plone/volto/helpers'; -import { Form, FormGroup, Input, Label } from 'design-react-kit'; +import { Form, FormGroup, Label } from 'design-react-kit'; import { defineMessages } from 'react-intl'; import { FormHeader, @@ -76,6 +76,9 @@ const AnswersStep = ({ step={step + 1} totalSteps={totalSteps} className={'answers-header'} + hidden={ + userFeedback === null || userFeedback < threshold || step !== 0 + } />
@@ -85,14 +88,13 @@ const AnswersStep = ({ key={'positive-' + s} className="border-bottom border-light mb-4" > -