Maison  >  Article  >  interface Web  >  Composants accessibles : Pagination

Composants accessibles : Pagination

Barbara Streisand
Barbara Streisandoriginal
2024-11-03 00:46:03854parcourir

Aujourd'hui, nous allons voir comment créer une pagination de toutes pièces et la rendre accessible et réutilisable. J'espère que cela vous aidera et laissez-moi vos commentaires à la fin du post !

Github : https://github.com/micaavigliano/accessible-pagination
Projet : https://accessible-pagination.vercel.app/

Hook personnalisé pour récupérer des données

const useFetch = <T,>(url: string, currentPage: number = 0, pageSize: number = 20) => {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<boolean>(false);

  useEffect(() => {
    const fetchData = async() => {
      setLoading(true);
      setError(false);

      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error('network response failed')
        }
        const result: T = await response.json() as T;
        setData(result)
      } catch (error) {
        setError(true)
      } finally {
        setLoading(false);
      }
    };

    fetchData()
  }, [url, currentPage, pageSize]);

  return {
    data,
    loading,
    error,
  }
};
  1. Nous allons générer un hook personnalisé avec un type générique. Cela nous permettra de préciser le type de données attendues lors de l'utilisation de ce hook
  2. Attendons 3 paramètres. Un pour url où on va récupérer les données, currentPage qui est la page où nous sommes et par défaut c'est 0 et pageSize qui est le numéro d'éléments que nous allons avoir par page et par défaut il est de 20 (vous pouvez modifier cette valeur).
  3. Dans notre état const [data, setData] = useState(nul); Nous lui passons le type générique T car comme nous l'utilisons pour différentes demandes de données, nous nous attendrons à différents types de données.

Pagination

Pour qu'une page soit accessible nous devons prendre en compte les points suivants :

  • Le focus doit se déplacer à travers tous les éléments interactifs de la page et avoir un indicateur visible
  • pour garantir une bonne interaction avec les lecteurs d'écran, nous devons utiliser correctement les régions, les propriétés et les états
  • La page doit être regroupée dans une balise et contenir un aria-label qui l'identifie comme une page en soi.
  • Chaque élément de la pagination doit contenir un aria-setsize et un aria-pointset. Maintenant, à quoi servent-ils ? Eh bien, aria-setsize est utilisé pour calculer le nombre total d'éléments dans la liste de pagination. Le lecteur d'écran l'annoncera comme suit :

Componentes accesibles: Paginación

aria-pointset est utilisé pour calculer la position de l'élément parmi tous les éléments de la page. Le lecteur d'écran l'annoncera comme suit :

Componentes accesibles: Paginación

  • Chaque élément doit avoir un aria-label pour pouvoir identifier à quelle page nous allons accéder si nous cliquons sur ce bouton.
  • Avoir des boutons pour accéder à l'élément suivant/précédent et chacun de ces boutons doit avoir son étiquette aria correspondante
  • Si notre pagination contient des points de suspension, elle doit être correctement marquée avec un aria-label
  • Chaque fois que nous allons sur une nouvelle page, le lecteur d'écran doit annoncer sur quelle page nous nous trouvons et combien de nouveaux éléments il y a comme suit.

Componentes accesibles: Paginación

Pour y arriver, nous allons le coder comme suit :

const useFetch = <T,>(url: string, currentPage: number = 0, pageSize: number = 20) => {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<boolean>(false);

  useEffect(() => {
    const fetchData = async() => {
      setLoading(true);
      setError(false);

      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error('network response failed')
        }
        const result: T = await response.json() as T;
        setData(result)
      } catch (error) {
        setError(true)
      } finally {
        setLoading(false);
      }
    };

    fetchData()
  }, [url, currentPage, pageSize]);

  return {
    data,
    loading,
    error,
  }
};

Lorsque la page cesse de se charger, nous définirons un nouveau message avec notre page actuelle et la longueur du nouveau tableau que nous chargeons.

Maintenant oui ! Voyons comment le code est structuré dans le fichier pagination.tsx

Le composant nécessitera cinq accessoires

const [statusMessage, setStatusMessage] = useState<string>("");

useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
    if (!loading) {
      setStatusMessage(`Page ${currentPage} loaded. Displaying ${data?.near_earth_objects.length || 0} items.`);
    }
  }, [currentPage, loading]);
  • currentPage fera référence à la page actuelle. Nous allons gérer cela en étant dans le composant où nous voulons utiliser la pagination comme suit : const [currentPage, setCurrentPage] = useState(1);
  • totalPages fait référence au nombre total d'éléments à afficher que contient l'API
  • .
  • nextPage cette fonction nous permettra d'aller à la page suivante et de mettre à jour notre état currentPage comme suit :
interface PaginationProps {
  currentPage: number;
  totalPages: number;
  nextPage: () => void;
  prevPage: () => void;
  goToPage: (page: number) => void;
}
  • prevPage cette fonction nous permettra d'aller à la page précédente à notre page actuelle et de mettre à jour notre état currentPage
const handlePageChange = (newPage: number) => {
    setCurrentPage(newPage); 
  };

  const nextPage = () => {
    if (currentPage < totalPages) {
      handlePageChange(currentPage + 1);
    }
  };
  • goToPage cette fonction aura besoin d'un paramètre numérique et c'est la fonction que devra avoir chaque élément pour pouvoir aller à la page souhaitée. Faisons en sorte que cela fonctionne comme suit :
const prevPage = () => {
    if (currentPage > 1) {
      handlePageChange(currentPage - 1);
    }
  };

Pour que notre pagination prenne vie, nous avons besoin d'une étape de plus, créer le tableau que nous allons itérer dans notre liste ! Pour cela nous devons suivre les étapes suivantes :

  1. Créez une fonction, dans ce cas je l'appellerai getPageNumbers
  2. Créez des variables pour le premier et le dernier élément de la liste.
  3. Créez une variable pour les points de suspension sur le côté gauche. Par ma propre décision, mes points de suspension vont être situés après le quatrième élément de la liste.
  4. Créez une variable pour les points de suspension sur le côté droit. Par ma propre décision, mes points de suspension seront placés avant trois éléments de la liste.
  5. Créez une fonction qui renvoie un tableau où 5 éléments sont toujours centrés, la page actuelle, deux éléments précédents et deux éléments suivants. Si nécessaire, nous exclurons la première et la dernière page const pagesAroundCurrent = [currentPage - 2, currentPage - 1, currentPage, currentPage 1, currentPage 2].filter(page => page > firstPage && page < lastPage);
  6. Pour notre dernière variable, nous allons créer un tableau qui contient toutes les variables créées précédemment.
  7. Enfin, nous allons filtrer les éléments nuls et renvoyer le tableau.

Ce tableau est celui que nous allons parcourir pour obtenir la liste des éléments de notre page comme suit :

const useFetch = <T,>(url: string, currentPage: number = 0, pageSize: number = 20) => {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<boolean>(false);

  useEffect(() => {
    const fetchData = async() => {
      setLoading(true);
      setError(false);

      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error('network response failed')
        }
        const result: T = await response.json() as T;
        setData(result)
      } catch (error) {
        setError(true)
      } finally {
        setLoading(false);
      }
    };

    fetchData()
  }, [url, currentPage, pageSize]);

  return {
    data,
    loading,
    error,
  }
};

Et voici comment réaliser une pagination réutilisable et accessible ! Personnellement, j'ai appris à créer une page à partir de zéro car j'ai dû l'implémenter en live coding. J'espère que mon expérience vous sera utile pour votre carrière et que vous pourrez l'implémenter et même l'améliorer !

Salutations,
Mica<3

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn