Correctifs RGAA (#2416)
* fix: id et for manquants, role img sur svg * feat: Ajoute une confirmation sur le bouton de suppression des données * fix: Ajoute un id et un label sur le champ select caché * fix: Ajoute id et label * fix: Corrige title * fix: Hierarchie titrepull/2428/head
parent
be031035f6
commit
5dff6b1fa2
|
@ -44,7 +44,8 @@ export default function ChiffreAffairesActivitéMixte({
|
|||
}, [dispatch])
|
||||
|
||||
return (
|
||||
<fieldset aria-label={t("Chiffre d'affaires")}>
|
||||
<fieldset>
|
||||
<legend className="sr-only">{t("Chiffre d'affaires")}</legend>
|
||||
<SimulationGoal
|
||||
appear={false}
|
||||
onUpdateSituation={clearChiffreAffaireMixte}
|
||||
|
|
|
@ -28,6 +28,8 @@ export default function SearchButton() {
|
|||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
aria-hidden
|
||||
role="img"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="square"
|
||||
|
|
|
@ -152,14 +152,21 @@ export default function AnswerList({ onClose, children }: AnswerListProps) {
|
|||
<Body>
|
||||
Les réponses liées à l'entreprise sont automatiquement
|
||||
sauvegardées d'une simulation à l'autre.{' '}
|
||||
<Link
|
||||
onPress={() => {
|
||||
<PopoverConfirm
|
||||
small
|
||||
trigger={(buttonProps) => (
|
||||
<Link {...buttonProps}>
|
||||
<Trans>Supprimer les données sauvegardées.</Trans>{' '}
|
||||
</Link>
|
||||
)}
|
||||
onConfirm={() => {
|
||||
dispatch(resetSimulation())
|
||||
dispatch(resetCompany())
|
||||
}}
|
||||
>
|
||||
<Trans>Supprimer les données sauvegardées.</Trans>{' '}
|
||||
</Link>
|
||||
title={t(
|
||||
'Attention, vos données sauvegardées seront supprimées de manière définitive.'
|
||||
)}
|
||||
></PopoverConfirm>
|
||||
</Body>
|
||||
</Message>
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
} from '@/design-system'
|
||||
import { Item, Select } from '@/design-system/field/Select'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { H4 } from '@/design-system/typography/heading'
|
||||
import { H3, H4 } from '@/design-system/typography/heading'
|
||||
|
||||
import { ExplicableRule } from './Explicable'
|
||||
import { InputProps } from './RuleInput'
|
||||
|
@ -174,12 +174,16 @@ function RadioChoice<Names extends string = DottedName>({
|
|||
) ? null : 'children' in node ? (
|
||||
<div
|
||||
role="group"
|
||||
aria-labelledby={node.dottedName + '-legend'}
|
||||
aria-labelledby={
|
||||
node.dottedName.replace(/\s|\./g, '') + '-legend'
|
||||
}
|
||||
css={`
|
||||
margin-top: -1rem;
|
||||
`}
|
||||
>
|
||||
<H4 id={node.dottedName + '-legend'}>{node.title}</H4>
|
||||
<H4 as={H3} id={node.dottedName + '-legend'}>
|
||||
{node.title}
|
||||
</H4>
|
||||
<Spacing lg />
|
||||
<StyledSubRadioGroup>
|
||||
<RadioChoice
|
||||
|
@ -212,6 +216,10 @@ function RadioChoice<Names extends string = DottedName>({
|
|||
rootDottedName,
|
||||
node.dottedName
|
||||
)}'`}
|
||||
id={`radio-input-${relativeDottedName(
|
||||
rootDottedName,
|
||||
node.dottedName
|
||||
).replace(/\s|\./g, '')}`}
|
||||
>
|
||||
{node.title}{' '}
|
||||
{node.rawNode.icônes && <Emoji emoji={node.rawNode.icônes} />}
|
||||
|
@ -264,11 +272,19 @@ export function OuiNonInput<Names extends string = DottedName>(
|
|||
value={currentSelection ?? undefined}
|
||||
>
|
||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus */}
|
||||
<Radio value="oui" autoFocus={props.autoFocus && defaultValue === 'oui'}>
|
||||
<Radio
|
||||
value="oui"
|
||||
id={`input-oui-${props.id || ''}`}
|
||||
autoFocus={props.autoFocus && defaultValue === 'oui'}
|
||||
>
|
||||
<Trans>Oui</Trans>
|
||||
</Radio>
|
||||
{/* eslint-disable-next-line jsx-a11y/no-autofocus */}
|
||||
<Radio value="non" autoFocus={props.autoFocus && defaultValue === 'non'}>
|
||||
<Radio
|
||||
value="non"
|
||||
id={`input-non-${props.id || ''}`}
|
||||
autoFocus={props.autoFocus && defaultValue === 'non'}
|
||||
>
|
||||
<Trans>Non</Trans>
|
||||
</Radio>
|
||||
</ToggleGroup>
|
||||
|
|
|
@ -115,6 +115,11 @@ export default function Conversation({
|
|||
</H3>
|
||||
</div>
|
||||
<fieldset>
|
||||
<legend className="sr-only">
|
||||
{t(
|
||||
'Répondez à quelques questions additionnelles afin de préciser votre résultat.'
|
||||
)}
|
||||
</legend>
|
||||
<RuleInput
|
||||
dottedName={currentQuestion}
|
||||
onChange={onChange}
|
||||
|
@ -127,6 +132,7 @@ export default function Conversation({
|
|||
<button
|
||||
aria-hidden
|
||||
className="sr-only"
|
||||
aria-label={t('Valider')}
|
||||
type="submit"
|
||||
tabIndex={-1}
|
||||
/>
|
||||
|
|
|
@ -19,6 +19,8 @@ export const SearchBox = connectSearchBox(
|
|||
'recherche-globale.placeholder',
|
||||
'Mot-clé ou acronyme (ex : CSG)'
|
||||
)}
|
||||
aria-label={t('Rechercher une règle de calcul dans la documentation')}
|
||||
id="input-recherche-globale"
|
||||
isSearchStalled={isSearchStalled}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
@ -34,7 +34,13 @@ export default function ButtonHelp({
|
|||
{...buttonProps}
|
||||
{...props}
|
||||
>
|
||||
<CircleIcon aria-hidden width="24" height="24" viewBox="0 0 24 24">
|
||||
<CircleIcon
|
||||
aria-hidden
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
role="img"
|
||||
>
|
||||
{type === 'info' ? (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
|
|
|
@ -15,12 +15,12 @@ type RadioProps = AriaRadioProps & {
|
|||
}
|
||||
|
||||
export function Radio(props: RadioProps) {
|
||||
const { hideRadio, children } = props
|
||||
const { hideRadio, children, id } = props
|
||||
|
||||
return (
|
||||
<RadioSkeleton role="radio" aria-atomic {...props}>
|
||||
{!hideRadio && <RadioPoint />}
|
||||
<LabelBody as="span" $hideRadio={hideRadio}>
|
||||
<LabelBody as="span" for={id} $hideRadio={hideRadio}>
|
||||
{children}
|
||||
</LabelBody>
|
||||
</RadioSkeleton>
|
||||
|
@ -28,7 +28,7 @@ export function Radio(props: RadioProps) {
|
|||
}
|
||||
|
||||
export const RadioSkeleton = (props: RadioProps) => {
|
||||
const { hideRadio, ...ariaProps } = props
|
||||
const { hideRadio, id, ...ariaProps } = props
|
||||
const { children } = ariaProps
|
||||
const state = useContext(RadioContext)
|
||||
if (!state) {
|
||||
|
@ -39,8 +39,8 @@ export const RadioSkeleton = (props: RadioProps) => {
|
|||
const { inputProps } = useRadio(ariaProps, state, ref)
|
||||
|
||||
return (
|
||||
<Label $hideRadio={hideRadio} className={props.className}>
|
||||
<InputRadio {...inputProps} className="sr-only" ref={ref} />
|
||||
<Label $hideRadio={hideRadio} for={id} className={props.className}>
|
||||
<InputRadio {...inputProps} className="sr-only" ref={ref} id={id} />
|
||||
<VisibleRadio>{children}</VisibleRadio>
|
||||
</Label>
|
||||
)
|
||||
|
@ -53,7 +53,7 @@ export const RadioPoint = ({ className }: { className?: string }) => (
|
|||
</RadioButton>
|
||||
)
|
||||
|
||||
const Label = styled.label<{ $hideRadio?: boolean }>`
|
||||
const Label = styled.label<{ $hideRadio?: boolean; for?: string }>`
|
||||
${({ $hideRadio }) =>
|
||||
$hideRadio &&
|
||||
css`
|
||||
|
@ -129,7 +129,7 @@ export const VisibleRadio = styled.span`
|
|||
}
|
||||
`
|
||||
|
||||
export const LabelBody = styled(Body)<{ $hideRadio?: boolean }>`
|
||||
export const LabelBody = styled(Body)<{ $hideRadio?: boolean; for?: string }>`
|
||||
margin: ${({ theme }) => theme.spacings.xs} 0px;
|
||||
margin-left: ${({ theme }) => theme.spacings.xxs};
|
||||
${({ $hideRadio }) =>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import styled, { css } from 'styled-components'
|
||||
|
||||
import { CarretDown } from '@/design-system/icons/carret-down'
|
||||
import { omit } from '@/utils'
|
||||
|
||||
import { ListBox } from './ListBox'
|
||||
import { Popover } from './PopOver'
|
||||
|
@ -225,6 +226,17 @@ export function Select<T extends Record<string, unknown>>(
|
|||
})
|
||||
}, [])
|
||||
|
||||
// Fix : Asqatasun détecte 2 violations au niveau du hidden select
|
||||
// pas moyen d'accéder aux props de manière plus propre rapidement
|
||||
useEffect(() => {
|
||||
const selectInput = wrapperRef?.current?.querySelector('input')
|
||||
|
||||
if (selectInput) {
|
||||
selectInput.setAttribute('id', buttonProps.id || '')
|
||||
selectInput.setAttribute('aria-label', 'Hidden select input')
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
ref={wrapperRef}
|
||||
|
@ -244,7 +256,7 @@ export function Select<T extends Record<string, unknown>>(
|
|||
</Label>
|
||||
)}
|
||||
<Button
|
||||
{...mergeProps(buttonProps, focusProps)}
|
||||
{...mergeProps(omit(buttonProps, 'id'), focusProps)}
|
||||
ref={ref}
|
||||
isFocusVisible={isFocusVisible}
|
||||
>
|
||||
|
|
|
@ -49,7 +49,7 @@ export default function PopoverConfirm({
|
|||
<Button
|
||||
onPress={() => {
|
||||
closePopover()
|
||||
onConfirm()
|
||||
setTimeout(() => onConfirm())
|
||||
}}
|
||||
>
|
||||
{confirmLabel}
|
||||
|
|
|
@ -31,14 +31,11 @@ export default function Créer() {
|
|||
<TrackPage name="accueil" />
|
||||
<Meta
|
||||
page="créer"
|
||||
title="Créer"
|
||||
title={t('créer.titre', 'Créer une entreprise')}
|
||||
description="Créer une entreprise"
|
||||
ogImage={créerSvg}
|
||||
/>
|
||||
|
||||
<DefaultHelmet>
|
||||
<title>{t('créer.titre', 'Créer une entreprise')}</title>
|
||||
</DefaultHelmet>
|
||||
<PageHeader
|
||||
titre={<Trans i18nKey="créer.titre">Créer une entreprise</Trans>}
|
||||
picture={créerSvg}
|
||||
|
|
|
@ -32,13 +32,10 @@ export default function Simulateurs() {
|
|||
<TrackPage chapter1="simulateurs" name="accueil" />
|
||||
<Meta
|
||||
page="simulateurs"
|
||||
title="simulateurs"
|
||||
title={titre}
|
||||
description="Tous les simulateurs sur ce site sont maintenus à jour avec les dernières évolutions législatives."
|
||||
ogImage={simulatorSvg}
|
||||
/>
|
||||
<DefaultHelmet>
|
||||
<title>{titre}</title>
|
||||
</DefaultHelmet>
|
||||
<PageHeader titre={titre} picture={simulatorSvg}>
|
||||
<Intro>
|
||||
<Trans i18nKey="pages.simulateurs.accueil.header">
|
||||
|
|
|
@ -490,6 +490,7 @@ function SimulateursChoice(props: {
|
|||
}}
|
||||
defaultSelectedKey={props.value}
|
||||
label={'Sélectionner la fonctionnalité'}
|
||||
id="simulator-choice-input"
|
||||
>
|
||||
{[
|
||||
<Item key={''} textValue="Tout le site">
|
||||
|
|
|
@ -2,7 +2,6 @@ import { utils } from 'publicodes'
|
|||
import { Trans, useTranslation } from 'react-i18next'
|
||||
|
||||
import Value, { Condition } from '@/components/EngineValue'
|
||||
import RuleLink from '@/components/RuleLink'
|
||||
import { FromTop } from '@/components/ui/animate'
|
||||
import Emoji from '@/components/utils/Emoji'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
|
@ -80,14 +79,12 @@ export default function ResultatsSimples() {
|
|||
</Condition>{' '}
|
||||
</H3>
|
||||
<Intro>
|
||||
<RuleLink dottedName={r.dottedName}>
|
||||
<Value
|
||||
expression={r.dottedName}
|
||||
displayedUnit="€"
|
||||
unit="€/an"
|
||||
precision={0}
|
||||
/>
|
||||
</RuleLink>
|
||||
<Value
|
||||
expression={r.dottedName}
|
||||
displayedUnit="€"
|
||||
unit="€/an"
|
||||
precision={0}
|
||||
/>
|
||||
</Intro>
|
||||
|
||||
{r.rawNode.description && (
|
||||
|
|
Loading…
Reference in New Issue