Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: accessibility improvements #992

9 changes: 6 additions & 3 deletions pages/cadastro/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function SignUpForm() {
{globalErrorMessage && <Flash variant="danger">{globalErrorMessage}</Flash>}

<FormControl id="username">
<FormControl.Label>Nome de usuário</FormControl.Label>
<FormControl.Label id="signup__label-user">Nome de usuário</FormControl.Label>
<TextInput
ref={usernameRef}
onChange={clearErrors}
Expand All @@ -121,6 +121,7 @@ function SignUpForm() {
spellCheck={false}
block={true}
aria-label="Seu nome de usuário"
aria-describedby="signup__label-user"
/>
{errorObject?.key === 'username' && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
Expand All @@ -131,7 +132,7 @@ function SignUpForm() {
)}
</FormControl>
<FormControl id="email">
<FormControl.Label>Email</FormControl.Label>
<FormControl.Label id="signup__label-email">Email</FormControl.Label>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dando uma olhada na documentação do MDN, que tal usarmos o atributo for na label ao invés de id e aria-describedby para vincular a label com o input?

No site a11y-101 tem um caso de uso melhor para o atributo aria-describedby.

Não sou especialista nesses pontos de acessibilidade, então se eu estiver enganado, me avise 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E aí, @Rafatcb ! Tudo bem? Concordo com o que você disse sobre a troca.
No caso, eu havia atribuído o aria-describedby via ID, pois verifiquei que este atributo está sendo gerado automaticamente com valor vazio. (Fiz essa inspeção via plugin WAVE). Ao invés de deixá-lo vazio, atribuí a ele o valor da label.

Entretanto você trouxe um ponto bem pertinente que, de fato, não é este o objetivo dele. Então em relação a vínculo, farei a troca para o FOR como você sugeriu. Obrigado.

<TextInput
ref={emailRef}
onChange={clearErrors}
Expand All @@ -142,6 +143,7 @@ function SignUpForm() {
spellCheck={false}
block={true}
aria-label="Seu email"
aria-describedby="signup__label-email"
/>
{errorObject?.key === 'email' && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
Expand Down Expand Up @@ -170,7 +172,7 @@ function SignUpForm() {
</FormControl>

<FormControl id="password">
<FormControl.Label>Senha</FormControl.Label>
<FormControl.Label id="signup__label-password">Senha</FormControl.Label>
<TextInput
ref={passwordRef}
onChange={clearErrors}
Expand All @@ -184,6 +186,7 @@ function SignUpForm() {
size="large"
block={true}
aria-label="Sua senha"
aria-describedby="signup__label-password"
/>
{capsLockWarningMessage && (
<FormControl.Validation variant="warning">{capsLockWarningMessage}</FormControl.Validation>
Expand Down
6 changes: 4 additions & 2 deletions pages/cadastro/recuperar/[token].public.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function RecoverPasswordForm() {
{globalErrorMessage && <Flash variant="danger">{globalErrorMessage}</Flash>}

<FormControl id="password">
<FormControl.Label>Senha</FormControl.Label>
<FormControl.Label id="recover-token__label-password">Senha</FormControl.Label>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Que tal criar um componente wrapper para o TextInput e o Label para não ter o risco de criar um input sem label vinculado, e também evitar a repetição de código? Eu nunca usei o Primer, então não tenho certeza se faz sentido ter o FormControl.Label dentro do wrapper. Talvez levar todo o FormControl para o componente seja mais interessante.

De qualquer forma, recomendo esperar mais algum comentário antes de implementar o que eu sugeri aqui, caso concorde. Talvez o @aprendendofelipe possa trazer a opinião dele quando estiver com tempo disponível 👍

Fiz uma sugestão parecida no PR #926, porém mais simples e com outra intenção, sem colocar o FormControl.Label no wrapper. Se essa sugestão fizer sentido aqui, o outro PR será afetado também pois usará o componente criado aqui.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Faz sentido para mim sua proposta. O que você acha @aprendendofelipe ?

<TextInput
ref={passwordRef}
onChange={clearErrors}
Expand All @@ -122,6 +122,7 @@ function RecoverPasswordForm() {
size="large"
block={true}
aria-label="Sua senha"
aria-describedby="recover-token__label-password"
/>
{capsLockWarningMessage && (
<FormControl.Validation variant="warning">{capsLockWarningMessage}</FormControl.Validation>
Expand All @@ -135,7 +136,7 @@ function RecoverPasswordForm() {
</FormControl>

<FormControl id="passwordConfirm">
<FormControl.Label>Repita a senha</FormControl.Label>
<FormControl.Label id="recover-token__label-confirm-password">Repita a senha</FormControl.Label>
<TextInput
ref={passwordConfirmRef}
onChange={clearErrors}
Expand All @@ -147,6 +148,7 @@ function RecoverPasswordForm() {
size="large"
block={true}
aria-label="Repita a senha"
aria-describedby="recover-token__label-confirm-password"
/>
{errorObject?.key === 'password_confirm' && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
Expand Down
3 changes: 2 additions & 1 deletion pages/cadastro/recuperar/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function RecoverPasswordForm() {
{globalErrorMessage && <Flash variant="danger">{globalErrorMessage}</Flash>}

<FormControl id="username">
<FormControl.Label>Digite seu usuário ou e-mail</FormControl.Label>
<FormControl.Label id="account-recover__label-user">Digite seu usuário ou e-mail</FormControl.Label>
<TextInput
ref={userInputRef}
onChange={clearErrors}
Expand All @@ -112,6 +112,7 @@ function RecoverPasswordForm() {
spellCheck={false}
block={true}
aria-label="Seu usuário ou e-mail"
aria-describedby="account-recover__label-user"
/>
{['userInput', 'email', 'username'].includes(errorObject?.key) && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
Expand Down
17 changes: 14 additions & 3 deletions pages/interface/components/Content/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,9 @@ function EditMode({ contentObject, setContentObject, setComponentMode, localStor

{!contentObject?.parent_id && (
<FormControl id="title">
<FormControl.Label visuallyHidden>Título</FormControl.Label>
<FormControl.Label visuallyHidden id="content__label-title">
Título
</FormControl.Label>
<TextInput
onChange={handleChange}
onKeyDown={onKeyDown}
Expand All @@ -448,6 +450,7 @@ function EditMode({ contentObject, setContentObject, setComponentMode, localStor
spellCheck={false}
placeholder="Título"
aria-label="Título"
aria-describedby="content__label-title"
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={true}
block={true}
Expand Down Expand Up @@ -480,7 +483,9 @@ function EditMode({ contentObject, setContentObject, setComponentMode, localStor

{!contentObject?.parent_id && (
<FormControl id="source_url">
<FormControl.Label visuallyHidden>Fonte (opcional)</FormControl.Label>
<FormControl.Label visuallyHidden id="content__label-source">
Fonte (opcional)
</FormControl.Label>
<TextInput
onChange={handleChange}
onKeyDown={onKeyDown}
Expand All @@ -491,6 +496,7 @@ function EditMode({ contentObject, setContentObject, setComponentMode, localStor
spellCheck={false}
placeholder="Fonte (opcional)"
aria-label="Fonte (opcional)"
aria-describedby="content__label-source"
block={true}
value={newData.source_url}
/>
Expand All @@ -513,7 +519,12 @@ function EditMode({ contentObject, setContentObject, setComponentMode, localStor
Cancelar
</Button>
)}
<Button variant="primary" type="submit" disabled={isPosting} aria-label="Publicar">
<Button
variant="primary"
type="submit"
disabled={isPosting}
aria-label="Publicar"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Não precisamos de um aria-label aqui, já que o botão tem um texto descritivo.

Referências: a11y-101, MDN

sx={{ background: '#237B3C' }}>
{contentObject?.id ? 'Atualizar' : 'Publicar'}
</Button>
</Box>
Expand Down
5 changes: 3 additions & 2 deletions pages/interface/components/ContentList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export default function ContentList({ contentList, pagination, paginationBasePat
display: 'grid',
gap: '0.5rem',
gridTemplateColumns: 'auto 1fr',
}}>
}}
role={'list'}>
Copy link
Collaborator

@Rafatcb Rafatcb Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conforme comentários do hitmain13:

Suggested change
role={'list'}>
role="list">

<RenderItems />
<EndOfRelevant />
</Box>
Expand Down Expand Up @@ -84,7 +85,7 @@ export default function ContentList({ contentList, pagination, paginationBasePat
{itemCount}.
</Text>
</Box>,
<Box as="article" key={contentObject.id} sx={{ overflow: 'auto' }}>
<Box as="article" key={contentObject.id} sx={{ overflow: 'auto' }} role="listitem">
<Box
sx={{
overflow: 'auto',
Expand Down
3 changes: 2 additions & 1 deletion pages/interface/components/DefaultLayout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export default function DefaultLayout({ children, containerWidth = 'large', meta
flexWrap: 'wrap',
padding: [2, null, null, 4],
paddingTop: [3, null, null, 4],
}}>
}}
as="main">
{children}
</Box>
<Footer
Expand Down
5 changes: 3 additions & 2 deletions pages/interface/components/Footer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export default function Footer(props) {
justifyContent: 'center',
flexWrap: 'wrap-reverse',
gap: 3,
}}>
}}
as="nav">
<Box
sx={{
display: 'flex',
Expand All @@ -28,7 +29,7 @@ export default function Footer(props) {
color: 'fg.subtle',
}}>
<Link href="/" sx={{ color: 'fg.subtle' }}>
<CgTab size={26} />
<CgTab size={26} title="Acessar a página inicial" />
Copy link
Collaborator

@Rafatcb Rafatcb Nov 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 O title não parece ser amigável para tecnologias assistivas. Eu não sabia disso, descobri na documentação do MDN. Vendo o link de referência, algumas sugestões são dadas para melhorar isso. De forma geral, acho que temos três alternativas:

  1. Colocar texto ao lado do ícone;
  2. Usar uma Tooltip, como nas TabCoins/TabCash;
  3. Usar o atributo aria-label.

A 3 me parece fazer mais sentido, mas não posso afirmar isso com certeza.

Edit: no caso da 3, pensei em ficar com ambos atributos: o title e o aria-label.

</Link>
© {new Date().getFullYear()} TabNews
</Box>
Expand Down
3 changes: 2 additions & 1 deletion pages/interface/components/Header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export default function HeaderComponent() {
<Header
sx={{
px: [2, null, null, 3],
}}>
}}
as="header">
<Header.Item>
<HeaderLink href="/">
<CgTab size={32} />
Expand Down
6 changes: 4 additions & 2 deletions pages/login/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function LoginForm() {
Login
</Heading>
<FormControl id="email">
<FormControl.Label>Email</FormControl.Label>
<FormControl.Label id="login__label-email">Email</FormControl.Label>
<TextInput
ref={emailRef}
onChange={clearErrors}
Expand All @@ -115,13 +115,14 @@ function LoginForm() {
spellCheck={false}
block={true}
aria-label="Seu email"
aria-describedby="login__label-email"
/>
{errorObject?.key === 'email' && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
)}
</FormControl>
<FormControl id="password">
<FormControl.Label>Senha</FormControl.Label>
<FormControl.Label id="login__label-password">Senha</FormControl.Label>
<TextInput
ref={passwordRef}
onChange={clearErrors}
Expand All @@ -135,6 +136,7 @@ function LoginForm() {
size="large"
block={true}
aria-label="Sua senha"
aria-describedby="login__label-password"
/>
{capsLockWarningMessage && (
<FormControl.Validation variant="warning">{capsLockWarningMessage}</FormControl.Validation>
Expand Down
9 changes: 6 additions & 3 deletions pages/perfil/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ function EditProfileForm() {
{globalErrorMessage && <Flash variant="danger">{globalErrorMessage}</Flash>}

<FormControl id="username">
<FormControl.Label>Nome de usuário</FormControl.Label>
<FormControl.Label id="profile__label-user">Nome de usuário</FormControl.Label>
<TextInput
ref={usernameRef}
onChange={clearErrors}
Expand All @@ -166,6 +166,7 @@ function EditProfileForm() {
spellCheck={false}
block={true}
aria-label="Seu nome de usuário"
aria-describedby="profile__label-user"
/>
{errorObject?.key === 'username' && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
Expand All @@ -177,7 +178,7 @@ function EditProfileForm() {
</FormControl>

<FormControl id="email" disabled={emailDisabled}>
<FormControl.Label>Email</FormControl.Label>
<FormControl.Label id="profile__label-email">Email</FormControl.Label>
<TextInput
ref={emailRef}
onChange={clearErrors}
Expand All @@ -188,6 +189,7 @@ function EditProfileForm() {
spellCheck={false}
block={true}
aria-label="Seu email"
aria-describedby="profile__label-email"
/>
{errorObject?.key === 'email' && !errorObject?.type && (
<FormControl.Validation variant="error">{errorObject.message}</FormControl.Validation>
Expand Down Expand Up @@ -220,13 +222,14 @@ function EditProfileForm() {
</FormControl>

<FormControl id="notifications">
<FormControl.Label>Receber notificações por email</FormControl.Label>
<FormControl.Label id="profile__notification">Receber notificações por email</FormControl.Label>

<Checkbox
ref={notificationsRef}
onChange={clearErrors}
name="notifications"
aria-label="Você deseja receber notificações?"
aria-describedby="profile__notification"
/>

{errorObject?.key === 'notifications' && (
Expand Down