O latim pode não estar correto, mas essa sua acessibilidade no seu formulário multi-etapas pode também não estar!
Mas por que, se eu adicionei todas as propriedades de acessibilidade corretamente!?
Creio que seu formulário multi-etapas troca de "página" usando condicionamento de estados, certo? Se sim, você pode ter um problema com a ordem de acessibilidade do leitor de tela.
Perceba no vídeo acima que o leitor de tela não voltou ao topo pra ler os campos do segundo formulário, mas continuou no botão "Next" e seu próximo índice de leitura foi o botão "Back"
Por que isso acontece?
O leitor de tela não sabe que você trocou de "página" e continua lendo o que está na tela, por isso ele não volta ao topo pra ler os campos do segundo formulário, pois apenas o conteúdo foi alterado, mas não a rota, então ele não sabe que deve voltar ao topo.
Como corrigir?
Provavelmente seu código deve seguir uma estrutura parecida com essa:
import React, { useState } from "react";
import { Text, View } from "react-native";
const StepperForm = () => {
const [stepIndex, setStepIndex] = useState(0);
const handleNext = () => {
setStepIndex(stepIndex + 1);
};
return (
<View>
{stepIndex === 0 && (
<View>
<Text>Formulário Nº 001</Text>
</View>
)}
{stepIndex === 1 && (
<View>
<Text>Formulário Nº 002</Text>
</View>
)}
<Button onPress={handleNext} title="Next" />
</View>
);
};
Talvez não com todos os formulários na mesma tela, mas esse é só um exemplo básico.
Precisamos fazer com que o foco do leitor de tela vá para o título do formulário, para isso podemos usar a função setAccessibilityFocus presente no módulo AccessibilityInfo do React Native.
Mas perceba que esta função não recebe uma referência a ser focada, mas sim uma tag numérica, essa tag é um identificador nativo que conseguiremos a partir da referência do componente, usando o método findNodeHandle
do React Native.
Esse eu vou ficar devendo o link porque não tem na documentação nada falando especificamente sobre essa função
Juntando os dois, a gente consegue criar o seguinte código:
const node = findNodeHandle(titleRef.current);
if (node) {
AccessibilityInfo.setAccessibilityFocus(node);
}
Aqui é necessário fazer a verificação se o node
existe, pois se você tentar focá-lo sem que o mesmo exista, você receberá um erro.
Agora que sabemos como focar, usaremos o useEffect
pra executar o foco sempre que formulário for trocado, ficando assim:
import React, { useState, useEffect, useRef } from "react";
import { Text, View } from "react-native";
import { AccessibilityInfo, findNodeHandle } from "react-native";
const StepperForm = () => {
const [stepIndex, setStepIndex] = useState(0);
const titleRef = useRef(null);
useEffect(() => {
const node = findNodeHandle(titleRef.current);
if (node) {
AccessibilityInfo.setAccessibilityFocus(node);
}
}, [stepIndex]);
const handleNext = () => {
setStepIndex(stepIndex + 1);
};
// template removido para simplificar o exemplo
};
Agora você só precisa escolher onde colocar a referência titleRef
onde quiser que seja levado o foco do leitor de tela, como o título do formulário, e não se esqueça! Para que o AccessibilityInfo.setAccessibilityFocus
funcione você precisa obrigatoriamente colocar a propriedade accessible
no componente que receberá o foco!
<View ref={titleRef} accessible>
<Text>
Formulário Nº 001
</Text>
</View>
Eis o resultado!
E por que não criar um hook?
Pra ficar ainda mais simples e poder utilizar esse comportamento em qualquer outra tela multi-etapas que você tiver, vamos criar um hook!
import { useState, useEffect, useRef } from "react";
import { AccessibilityInfo, findNodeHandle } from "react-native";
const useStepper = () => {
const [stepIndex, setStepIndex] = useState(0);
const focusRef = useRef(null);
useEffect(() => {
const node = findNodeHandle(focusRef.current);
if (node) {
AccessibilityInfo.setAccessibilityFocus(node);
}
}, [stepIndex]);
const handleNext = () => {
setStepIndex(stepIndex + 1);
};
const handlePrevious = () => {
setStepIndex(stepIndex - 1);
};
return {
focusRef,
stepIndex,
handleNext,
handlePrevious,
};
};
Pronto, agora só usar!
import React from "react";
import { Text, View } from "react-native";
import { useStepper } from "./useStepper";
const StepperForm = () => {
const { focusRef, stepIndex, handleNext, handlePrevious } = useStepper();
return (
<View>
{stepIndex === 0 && (
<View ref={focusRef} accessible>
<Text>
Formulário Nº 001
</Text>
</View>
)}
{stepIndex === 1 && (
<View ref={focusRef} accessible>
<Text>
Formulário Nº 002
</Text>
</View>
)}
<Button onPress={handleNext} title="Próximo" />
<Button onPress={handlePrevious} title="Anterior" />
</View>
);
};
Top comments (0)