Skip to content

Commit

Permalink
feat: ajout de aria-live sur compteur caractères suggestion (#6379)
Browse files Browse the repository at this point in the history
* feat: ajout de aria-live sur compteur caractères suggestion

* chore: clean

* feat: rgaa liaison entre bouton oui-non et titre

* fix: rgaa gestion des focus

* chore: snap

---------

Co-authored-by: victor <[email protected]>
  • Loading branch information
Viczei and victor authored Dec 19, 2024
1 parent dc52e7e commit 70a216b
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Button } from "@codegouvfr/react-dsfr/Button";
import { Checkbox } from "@codegouvfr/react-dsfr/Checkbox";
import { Input } from "@codegouvfr/react-dsfr/Input";
import { FeedbackActionChoiceValue } from "./tracking";
import { useState } from "react";
import { useEffect, useState } from "react";

const MAX_LENGTH_SUGGESTION = 500;

Expand All @@ -18,6 +18,9 @@ export type FeedbackDataSent = {
};

export const FeedbackContent = (props: Props) => {
const [firstCheckboxRef, setFirstCheckboxRef] =
useState<HTMLInputElement | null>();
const [textAreaRef, setTextAreaRef] = useState<HTMLTextAreaElement | null>();
const [categories, setCategories] = useState<FeedbackActionChoiceValue[]>([]);
const [suggestion, setSuggestion] = useState<string | undefined>(undefined);
const [hasCheckBoxError, setHasCheckBoxError] = useState<boolean>(false);
Expand Down Expand Up @@ -73,6 +76,17 @@ export const FeedbackContent = (props: Props) => {
});
}
};
const charactersCountThresholds = [
400, 300, 200, 100, 50, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
];

useEffect(() => {
if (props.type === "negative") {
firstCheckboxRef?.focus();
} else {
textAreaRef?.focus();
}
});

return (
<>
Expand All @@ -87,6 +101,7 @@ export const FeedbackContent = (props: Props) => {
name: "unclear",
value: "unclear" as FeedbackActionChoiceValue,
onChange: onChangeCategories,
ref: setFirstCheckboxRef,
},
},
{
Expand Down Expand Up @@ -125,6 +140,7 @@ export const FeedbackContent = (props: Props) => {
nativeTextAreaProps={{
onChange: onInputSuggestion,
value: suggestion,
ref: setTextAreaRef,
}}
state={hasSuggestionError ? "error" : "default"}
stateRelatedMessage={errorMessageSuggestion}
Expand All @@ -135,6 +151,13 @@ export const FeedbackContent = (props: Props) => {
"fr-mt-0",
"fr-mb-3w"
)}
aria-live={
charactersCountThresholds.indexOf(remainingCharacters) !== -1
? "polite"
: "off"
}
aria-atomic
data-testid="characterInfo"
>
{`${remainingCharacters} caractère${
remainingCharacters > 1 ? "s" : ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const FeedbackDefault = (props: Props) => {
return (
<div className="fr-grid-row">
<div className="fr-col-12 fr-col-md">
<h2 className={fr.cx("fr-h5", "fr-mb-md-0")}>
<h2 className={fr.cx("fr-h5", "fr-mb-md-0")} id="feedback-title">
Avez-vous trouvé la réponse à votre question ?
</h2>
</div>
Expand All @@ -20,10 +20,16 @@ export const FeedbackDefault = (props: Props) => {
priority="secondary"
className={fr.cx("fr-mr-2w")}
onClick={props.onClickNo}
aria-describedby="feedback-title"
>
Non
</Button>
<Button type="button" priority="secondary" onClick={props.onClickYes}>
<Button
type="button"
priority="secondary"
onClick={props.onClickYes}
aria-describedby="feedback-title"
>
Oui
</Button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { render } from "@testing-library/react";
import React from "react";

import { FeedbackContent } from "../FeedbackContent";
import { UserAction } from "src/common";
import { ui } from "./ui";

describe("<FeedbackContent />", () => {
it("should match snapshot for positive", () => {
Expand All @@ -17,4 +19,16 @@ describe("<FeedbackContent />", () => {
);
expect(container).toMatchSnapshot();
});

it("should warn politely on certain threshold", () => {
render(<FeedbackContent onSubmit={jest.fn} type="positive" />);
const userAction = new UserAction();
expect(ui.characterInfo.get()).toHaveAttribute("aria-atomic");
userAction.setInput(ui.input.get(), "a".repeat(99));
expect(ui.characterInfo.get()).toHaveAttribute("aria-live", "off");
userAction.setInput(ui.input.get(), "a".repeat(100));
expect(ui.characterInfo.get()).toHaveAttribute("aria-live", "polite");
userAction.setInput(ui.input.get(), "a".repeat(101));
expect(ui.characterInfo.get()).toHaveAttribute("aria-live", "off");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ exports[`<FeedbackContent /> should match snapshot for negative 1`] = `
/>
</div>
<p
aria-atomic="true"
aria-live="off"
class="fr-info-text fr-mt-0 fr-mb-3w"
data-testid="characterInfo"
>
500 caractères restants
</p>
Expand Down Expand Up @@ -157,7 +160,10 @@ exports[`<FeedbackContent /> should match snapshot for positive 1`] = `
/>
</div>
<p
aria-atomic="true"
aria-live="off"
class="fr-info-text fr-mt-0 fr-mb-3w"
data-testid="characterInfo"
>
500 caractères restants
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ exports[`<FeedbackDefault /> should match snapshot 1`] = `
>
<h2
class="fr-h5 fr-mb-md-0"
id="feedback-title"
>
Avez-vous trouvé la réponse à votre question ?
</h2>
</div>
<div>
<button
aria-describedby="feedback-title"
class="fr-btn fr-btn--secondary fr-mr-2w"
id="fr-button-:r0:"
type="button"
>
Non
</button>
<button
aria-describedby="feedback-title"
class="fr-btn fr-btn--secondary"
id="fr-button-:r1:"
type="button"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { byLabelText, byTestId } from "testing-library-selector";

export const ui = {
input: byLabelText(/Faire une suggestion pour améliorer cette page/),
characterInfo: byTestId("characterInfo"),
};
Original file line number Diff line number Diff line change
Expand Up @@ -214,19 +214,22 @@ exports[`<LetterModel /> affiche un modèle de document 1`] = `
>
<h2
class="fr-h5 fr-mb-md-0"
id="feedback-title"
>
Avez-vous trouvé la réponse à votre question ?
</h2>
</div>
<div>
<button
aria-describedby="feedback-title"
class="fr-btn fr-btn--secondary fr-mr-2w"
id="fr-button-:r7:"
type="button"
>
Non
</button>
<button
aria-describedby="feedback-title"
class="fr-btn fr-btn--secondary"
id="fr-button-:r8:"
type="button"
Expand Down

0 comments on commit 70a216b

Please sign in to comment.