wikimedica-disease-search/app/src/util.js

91 lines
2.4 KiB
JavaScript
Raw Normal View History

import {useState, useEffect} from 'react';
/**
* Hook permettant dobtenir des résultats asynchrones.
*
* @param initial Valeur initiale lorsque la promesse na pas répondu.
* @param func Fonction renvoyant une promesse.
* @param ...args Arguments à passer à `func` qui sont susceptibles de changer.
* @return Résultats de la promesse.
*/
export const useAsync = (initial, func, ...args) =>
{
const [results, setResults] = useState(initial);
useEffect(() =>
{
const fetcher = async () =>
{
setResults(await func(...args));
};
fetcher();
}, args);
return results;
};
/**
* Crée un état composé dune liste et dun élément ayant le focus dans cette
* liste. À la modification de la liste ou de lindice de lélément ayant le
2019-12-04 23:16:27 +00:00
* focus, la contrainte suivante est imposée:
*
* si la liste nest pas vide, focus [0, taille de la liste].
* sinon, focus = 0.
*
* @return Objet contenant la liste, lindice de lélément ayant le focus ainsi
* que des fonctions de modification.
*/
export const useFocusableList = () =>
{
const [list, setList] = useState([]);
const [focus, setFocus] = useState(0);
return {
list,
focus,
/**
* Modifie la liste et sassure que lélément ayant le focus est
* toujours dans sa plage de valeurs possibles.
*
* @param nextList Nouvelle liste.
*/
setList(nextList)
{
setList(nextList);
2019-12-04 23:16:27 +00:00
setFocus(
nextList.length === 0
? 0
: Math.min(nextList.length - 1, focus)
);
},
/**
* Modifie lélément ayant le focus en imposant les contraintes
* dintégrité.
*
* @param nextFocus Indice du nouvel élément ayant le focus.
*/
setFocus(nextFocus)
{
const itemCount = list.length;
if (itemCount === 0)
{
// Sur la liste vide, on ne peut pas changer le focus
return;
}
// Ramène une valeur négative dans les positifs
while (nextFocus < 0) { nextFocus += itemCount; }
// Ramène une valeur trop grande à lintérieur de la liste
nextFocus = nextFocus % itemCount;
setFocus(nextFocus);
}
};
};