File size: 4,629 Bytes
eebc40f 6bda4a6 eebc40f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
import { useEffect, useCallback } from 'react';
/**
* Hook pour la navigation aux flèches entre les polices
* Permet de naviguer vers la police la plus proche dans la direction souhaitée
*/
export const useArrowNavigation = (
selectedFont,
fonts,
filter,
searchTerm,
onFontSelect
) => {
// Fonction pour filtrer les polices selon les critères actuels
const getFilteredFonts = useCallback(() => {
if (!fonts || fonts.length === 0) return [];
return fonts.filter(font => {
// Filtrage par famille
const familyMatch = filter === 'all' || font.family === filter;
// Filtrage par recherche
const searchMatch = !searchTerm ||
font.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
font.family.toLowerCase().includes(searchTerm.toLowerCase());
return familyMatch && searchMatch;
});
}, [fonts, filter, searchTerm]);
// NOTE: calculateDistance supprimé car non utilisé
// Fonction pour trouver la police la plus proche dans une direction
const findNearestFontInDirection = useCallback((direction) => {
if (!selectedFont || !onFontSelect) return;
const filteredFonts = getFilteredFonts();
if (filteredFonts.length <= 1) return; // Pas assez de polices pour naviguer
// Trouver la police sélectionnée dans la liste filtrée
const currentFont = filteredFonts.find(font => font.name === selectedFont.name);
if (!currentFont) return;
let bestFont = null;
let bestDistance = Infinity;
// Approche simple : trouver la police la plus proche dans la direction
filteredFonts.forEach(font => {
if (font.name === selectedFont.name) return; // Ignorer la police actuelle
const dx = font.x - currentFont.x;
const dy = font.y - currentFont.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance === 0) return; // Éviter les polices à la même position
let isInDirection = false;
// Vérifier si la police est dans la direction souhaitée (critères simples)
switch (direction) {
case 'ArrowUp':
// Police au-dessus - inversé car les coordonnées semblent inversées
isInDirection = dy > 0 && Math.abs(dx) <= Math.abs(dy) * 2;
break;
case 'ArrowDown':
// Police en-dessous - inversé car les coordonnées semblent inversées
isInDirection = dy < 0 && Math.abs(dx) <= Math.abs(dy) * 2;
break;
case 'ArrowLeft':
// Police à gauche (x plus petit) - accepter un peu de décalage vertical
isInDirection = dx < 0 && Math.abs(dy) <= Math.abs(dx) * 2;
break;
case 'ArrowRight':
// Police à droite (x plus grand) - accepter un peu de décalage vertical
isInDirection = dx > 0 && Math.abs(dy) <= Math.abs(dx) * 2;
break;
default:
return;
}
// Si la police est dans la bonne direction et plus proche que la meilleure actuelle
if (isInDirection && distance < bestDistance) {
bestDistance = distance;
bestFont = font;
}
});
// Sélectionner la police la plus proche trouvée
if (bestFont) {
onFontSelect(bestFont);
}
}, [selectedFont, getFilteredFonts, onFontSelect]);
// Gestionnaire d'événements clavier
const handleKeyDown = useCallback((event) => {
// Vérifier si une police est sélectionnée
if (!selectedFont) return;
// Vérifier si on est dans un champ de saisie
const activeElement = document.activeElement;
if (activeElement && (
activeElement.tagName === 'INPUT' ||
activeElement.tagName === 'TEXTAREA' ||
activeElement.contentEditable === 'true'
)) {
return; // Ne pas intercepter les flèches dans les champs de saisie
}
// Gérer les touches fléchées
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
event.preventDefault(); // Empêcher le scroll de la page
findNearestFontInDirection(event.key);
}
}, [selectedFont, findNearestFontInDirection]);
// Ajouter l'écouteur d'événements
useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [handleKeyDown]);
// Retourner des informations utiles pour le debug
return {
canNavigate: selectedFont && getFilteredFonts().length > 1,
filteredFontsCount: getFilteredFonts().length,
selectedFontName: selectedFont?.name
};
};
|