Skip to content

Commit

Permalink
fix: a11y for feedback section (#560)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
deodorhunter and pnicolli authored Mar 4, 2024
1 parent da10eaa commit f5f907a
Show file tree
Hide file tree
Showing 13 changed files with 277 additions and 147 deletions.
1 change: 1 addition & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions locales/de/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions locales/en/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions locales/es/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions locales/fr/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions locales/it/LC_MESSAGES/volto.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions locales/volto.pot
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
149 changes: 109 additions & 40 deletions src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -9,7 +15,6 @@ import {
Col,
Spinner,
Card,
Button,
CardHeader,
CardBody,
} from 'design-react-kit';
Expand All @@ -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({
Expand Down Expand Up @@ -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',
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -198,6 +236,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
};

const sendFormData = () => {
if (invalidForm) return;
setStep(2);
const data = {
...formData,
Expand All @@ -220,7 +259,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
}

return (
<div className="bg-primary customer-satisfaction">
<section className="bg-primary customer-satisfaction">
<Container>
<Row className="d-flex justify-content-center bg-primary">
<Col className="col-12 col-lg-6">
Expand Down Expand Up @@ -252,15 +291,31 @@ const FeedbackForm = ({ contentType, pathname }) => {
: intl.formatMessage(messages.title)}
</h2>
<div className="rating-container mb-0">
<Rating
<RTRating
name="satisfaction"
value={satisfaction}
// Qui l'implementazione di design react kit sta su con gli stecchini, rifatta
inputs={[
'star1b',
'star2b',
'star3b',
'star4b',
'star5b',
{
name: 'star1b',
value: 1,
},
{
name: 'star2b',
value: 2,
},
{
name: 'star3b',
value: 3,
},
{
name: 'star4b',
value: 4,
},
{
name: 'star5b',
value: 5,
},
]}
aria-controls={
satisfaction > threshold
Expand All @@ -269,7 +324,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
}
className="volto-feedback-rating mb-0"
onChangeRating={changeSatisfaction}
legend=" "
legend={intl.formatMessage(messages.feedback)}
wrapperClassName={'rating'}
/>
</div>
Expand Down Expand Up @@ -300,47 +355,61 @@ const FeedbackForm = ({ contentType, pathname }) => {
/>
<div
className={cx(
'form-step-actions d-flex flex-nowrap w100 justify-content-center button-shadow',
'form-step-actions flex-nowrap w100 justify-content-center button-shadow',
{
'pt-4': satisfaction !== null,
'pt-4 d-flex': satisfaction,
'd-none': !satisfaction,
},
)}
aria-hidden={satisfaction === null}
aria-hidden={!satisfaction}
>
<Button
className="prev-action"
disabled={!!(step - 1)}
onClick={prevStep}
{/* Bug bottoni del kit. Disabled e' settato anche se compare la prop aria-disabled,
quando lo scopo sarebbe continuare a poter usufruire dei focus anche in screen reader.
Per i vedenti, la classe dimmed fa il suo lavoro e disabilita i click/input utente */}
<button
type="button"
outline
color="primary"
onClick={prevStep}
disabled={false}
className={cx(
'me-4 fw-bold btn btn-outline-primary',
{
disabled: step === 0,
},
)}
aria-disabled={!(!invalidForm && step !== 0)}
>
{intl.formatMessage(messages.prev)}
</Button>
</button>

{step !== numberOfSteps - 1 && (
<Button
color="primary"
onClick={nextStep}
className="next-action fw-bold"
disabled={invalidForm}
<button
type="button"
onClick={nextStep}
disabled={false}
aria-disabled={invalidForm}
className={cx('fw-bold btn btn-primary', {
disabled: invalidForm,
})}
>
{intl.formatMessage(messages.next)}
</Button>
</button>
)}
{step === numberOfSteps - 1 && (
<Button
className="next-action fw-bold"
color="primary"
disabled={invalidForm}
type={'button'}
<button
className={cx('fw-bold btn btn-primary', {
disabled: invalidForm,
})}
type="submit"
disabled={false}
aria-disabled={invalidForm}
onClick={sendFormData}
onKeyDown={(e) => {
if (e.key === 'Enter') sendFormData();
if (e.key === 'Enter' && !invalidForm)
sendFormData();
}}
>
{intl.formatMessage(messages.next)}
</Button>
</button>
)}
</div>
</>
Expand Down Expand Up @@ -385,7 +454,7 @@ const FeedbackForm = ({ contentType, pathname }) => {
</Col>
</Row>
</Container>
</div>
</section>
);
};

Expand Down
Loading

0 comments on commit f5f907a

Please sign in to comment.