1:"$Sreact.fragment"
2:I[70119,["/_next/static/chunks/31d43793a1cb3f9f.js"],"default"]
3:I[39756,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/247eb132b7f7b574.js"],"default"]
4:I[37457,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/247eb132b7f7b574.js"],"default"]
e:I[68027,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/247eb132b7f7b574.js"],"default"]
:HL["/_next/static/chunks/72b91a557eccd659.css","style"]
0:{"P":null,"b":"3j51AZN_4-ufz6TRQsmjK","c":["","blog","principes-ux-applications-web"],"q":"","i":false,"f":[[["",{"children":["blog",{"children":["principes-ux-applications-web",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/72b91a557eccd659.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/31d43793a1cb3f9f.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"fr","children":["$","body",null,{"className":"flex min-h-screen flex-col antialiased","children":[["$","$L2",null,{}],["$","main",null,{"className":"mx-auto w-full max-w-6xl flex-grow content-container my-6 p-8","children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}],["$","footer",null,{"className":"w-full bg-gray-900/95 backdrop-blur-md text-gray-300 py-12 mt-6","children":["$","div",null,{"className":"max-w-6xl mx-auto px-6","children":[["$","div",null,{"className":"grid md:grid-cols-4 gap-8","children":[["$","div",null,{"children":[["$","h3",null,{"className":"text-2xl font-bold text-white mb-4","children":"Tuxyo"}],["$","p",null,{"className":"text-gray-400 mb-4","children":"Des solutions adaptées pour faire grandir votre entreprise"}],["$","div",null,{"className":"flex space-x-4","children":[["$","a",null,{"href":"#","className":"text-gray-400 hover:text-white transition","children":["$","svg",null,{"className":"w-5 h-5","fill":"currentColor","viewBox":"0 0 24 24","children":["$","path",null,{"d":"M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"}]}]}],["$","a",null,{"href":"#","className":"text-gray-400 hover:text-white transition","children":["$","svg",null,{"className":"w-5 h-5","fill":"currentColor","viewBox":"0 0 24 24","children":["$","path",null,{"d":"M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"}]}]}],["$","a",null,{"href":"#","className":"text-gray-400 hover:text-white transition","children":["$","svg",null,{"className":"w-5 h-5","fill":"currentColor","viewBox":"0 0 24 24","children":"$L5"}]}]]}]]}],"$L6","$L7","$L8"]}],"$L9"]}]}]]}]}]]}],{"children":["$La",{"children":["$Lb",{"children":["$Lc",{},null,false,false]},null,false,false]},null,false,false]},null,false,false],"$Ld",false]],"m":"$undefined","G":["$e",[]],"s":false,"S":true}
f:I[22016,["/_next/static/chunks/31d43793a1cb3f9f.js"],""]
33:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/247eb132b7f7b574.js"],"ViewportBoundary"]
35:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/247eb132b7f7b574.js"],"MetadataBoundary"]
36:"$Sreact.suspense"
5:["$","path",null,{"d":"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"}]
6:["$","div",null,{"children":[["$","h4",null,{"className":"font-semibold text-white mb-4","children":"Services"}],["$","ul",null,{"className":"space-y-2 text-sm","children":[["$","li",null,{"children":["$","a",null,{"href":"/services","className":"hover:text-white transition","children":"Développement web"}]}],["$","li",null,{"children":["$","a",null,{"href":"/services","className":"hover:text-white transition","children":"Solutions SaaS"}]}],["$","li",null,{"children":["$","a",null,{"href":"/services","className":"hover:text-white transition","children":"Conseil & Formation"}]}]]}]]}]
7:["$","div",null,{"children":[["$","h4",null,{"className":"font-semibold text-white mb-4","children":"Entreprise"}],["$","ul",null,{"className":"space-y-2 text-sm","children":[["$","li",null,{"children":["$","a",null,{"href":"/about","className":"hover:text-white transition","children":"À propos"}]}],["$","li",null,{"children":["$","a",null,{"href":"/blog","className":"hover:text-white transition","children":"Blog"}]}],["$","li",null,{"children":["$","a",null,{"href":"/contact","className":"hover:text-white transition","children":"Contact"}]}]]}]]}]
8:["$","div",null,{"children":[["$","h4",null,{"className":"font-semibold text-white mb-4","children":"Contact"}],["$","ul",null,{"className":"space-y-2 text-sm","children":["$","li",null,{"className":"flex items-center","children":[["$","svg",null,{"className":"w-4 h-4 mr-2","fill":"none","stroke":"currentColor","viewBox":"0 0 24 24","children":["$","path",null,{"strokeLinecap":"round","strokeLinejoin":"round","strokeWidth":2,"d":"M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"}]}],"contact@tuxyo.com"]}]}]]}]
9:["$","div",null,{"className":"border-t border-gray-800 mt-8 pt-8 text-center text-sm text-gray-400","children":["$","p",null,{"children":["© 2001-",2026," Tuxyo. Tous droits réservés. Version ","0.7.2505"]}]}]
a:["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}]
b:["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}]
10:T503,/* Application de la loi de Fitts en CSS */
/* Boutons d'action principaux - Plus gros, plus faciles à cliquer */
.primary-button {
min-width: 120px;
min-height: 44px; /* Recommandation mobile */
padding: 12px 24px;
font-size: 16px;
border-radius: 6px;
/* Augmentation de la zone de clic */
position: relative;
}
.primary-button::before {
content: '';
position: absolute;
top: -8px;
right: -8px;
bottom: -8px;
left: -8px;
/* Zone de clic étendue invisible */
}
/* Actions secondaires - Plus petites mais toujours accessibles */
.secondary-button {
min-width: 80px;
min-height: 36px;
padding: 8px 16px;
font-size: 14px;
}
/* Éléments fréquemment utilisés - Proches et accessibles */
.frequent-action {
position: sticky;
top: 20px;
right: 20px;
z-index: 100;
}
/* Navigation - Éléments importants en premier */
.main-nav {
display: flex;
justify-content: flex-start; /* Important à gauche */
}
.main-nav .logo {
margin-right: auto; /* Logo toujours accessible */
}
.main-nav .primary-nav {
display: flex;
gap: 8px; /* Proximité des éléments liés */
}
/* Responsive - Adaptation mobile */
@media (max-width: 768px) {
.primary-button {
width: 100%;
min-height: 50px; /* Plus large sur mobile */
}
}c:["$","$1","c",{"children":[["$","article",null,{"className":"max-w-4xl mx-auto","children":[["$","nav",null,{"className":"mb-8","children":["$","div",null,{"className":"flex items-center space-x-2 text-sm text-gray-600","children":[["$","$Lf",null,{"href":"/","className":"hover:text-tuxyoBlue","children":"Accueil"}],["$","span",null,{"children":"/"}],["$","$Lf",null,{"href":"/blog","className":"hover:text-tuxyoBlue","children":"Blog"}],["$","span",null,{"children":"/"}],["$","span",null,{"className":"text-gray-900","children":"Principes UX pour applications web"}]]}]}],["$","header",null,{"className":"mb-12","children":[["$","div",null,{"className":"flex items-center space-x-4 mb-6","children":[["$","span",null,{"className":"px-3 py-1 bg-pink-100 text-pink-700 text-sm font-medium rounded-full","children":"Design"}],["$","div",null,{"className":"flex items-center text-gray-500 text-sm","children":[["$","svg",null,{"className":"w-4 h-4 mr-1","fill":"none","stroke":"currentColor","viewBox":"0 0 24 24","children":["$","path",null,{"strokeLinecap":"round","strokeLinejoin":"round","strokeWidth":2,"d":"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"}]}],"10 min de lecture"]}],["$","span",null,{"className":"text-gray-500 text-sm","children":"14 Octobre 2024"}]]}],["$","h1",null,{"className":"text-4xl md:text-5xl font-bold text-gray-900 mb-6 leading-tight","children":"Principes UX essentiels pour les applications web modernes"}],["$","p",null,{"className":"text-xl text-gray-600 leading-relaxed","children":"Découvrez les fondamentaux de l'expérience utilisateur qui transforment une simple interface en application web intuitive, efficace et agréable à utiliser."}]]}],["$","div",null,{"className":"prose prose-lg max-w-none","children":[["$","h2",null,{"children":"L'UX au cœur du succès des applications web"}],["$","p",null,{"children":"Dans un monde où l'attention des utilisateurs est de plus en plus difficile à capter, l'expérience utilisateur (UX) devient le facteur différenciant principal entre une application qui réussit et une qui échoue. Une bonne UX ne se contente pas d'être \"jolie\" : elle guide intuitivement l'utilisateur vers ses objectifs tout en créant une expérience mémorable et efficace."}],["$","div",null,{"className":"bg-blue-50 p-6 rounded-lg my-6","children":[["$","h3",null,{"className":"text-blue-800 font-semibold mb-2","children":"💡 Impact de l'UX en chiffres"}],["$","ul",null,{"className":"text-blue-700 text-sm space-y-1","children":[["$","li",null,{"children":"• 88% des utilisateurs ne reviendront pas sur un site après une mauvaise expérience"}],["$","li",null,{"children":"• Une bonne UX peut augmenter les taux de conversion jusqu'à 400%"}],["$","li",null,{"children":"• 70% des échecs d'applications sont dus à des problèmes d'utilisabilité"}],["$","li",null,{"children":"• Chaque dollar investi en UX rapporte en moyenne 100$ de ROI"}],["$","li",null,{"children":"• 38% des utilisateurs cesseront d'interagir avec un site au design peu attrayant"}]]}]]}],["$","h2",null,{"children":"Les fondamentaux de l'UX : Lois et principes universels"}],["$","h3",null,{"children":"1. La Loi de Fitts : Optimiser les interactions"}],["$","p",null,{"children":"La loi de Fitts stipule que le temps nécessaire pour atteindre une cible dépend de sa taille et de sa distance. Plus un élément est large et proche, plus il est facile et rapide à atteindre."}],["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$10"}]}],"$L11","$L12","$L13","$L14","$L15","$L16","$L17","$L18","$L19","$L1a","$L1b","$L1c","$L1d","$L1e","$L1f","$L20","$L21","$L22","$L23","$L24","$L25","$L26","$L27","$L28","$L29","$L2a","$L2b","$L2c","$L2d","$L2e","$L2f","$L30"]}],"$L31"]}],null,"$L32"]}]
d:["$","$1","h",{"children":[null,["$","$L33",null,{"children":"$@34"}],["$","div",null,{"hidden":true,"children":["$","$L35",null,{"children":["$","$36",null,{"name":"Next.Metadata","children":"$@37"}]}]}],null]}]
3f:I[97367,["/_next/static/chunks/ff1a16fafef87110.js","/_next/static/chunks/247eb132b7f7b574.js"],"OutletBoundary"]
11:["$","h3",null,{"children":"2. La Loi de Hick : Réduire la complexité des choix"}]
12:["$","p",null,{"children":"Plus vous donnez d'options à un utilisateur, plus il lui faudra de temps pour prendre une décision. Simplifiez les choix pour améliorer la rapidité de décision et réduire la frustration."}]
38:Ta69,// React - Menu de navigation simplifié
function NavigationMenu({ user }) {
// Réduire les options selon le contexte
const getMenuItems = () => {
if (!user) {
return [
{ label: 'Accueil', path: '/' },
{ label: 'À propos', path: '/about' },
{ label: 'Se connecter', path: '/login', primary: true }
];
}
// Menu utilisateur connecté - Max 5-7 items
return [
{ label: 'Dashboard', path: '/dashboard' },
{ label: 'Projets', path: '/projects' },
{ label: 'Messages', path: '/messages' },
{ label: 'Profil', path: '/profile' },
{ label: 'Déconnexion', path: '/logout' }
];
};
return (
{getMenuItems().map(item => (
))}
);
}
// Composant de sélection avec regroupement
function ProductSelector({ products }) {
// Regrouper pour réduire la complexité cognitive
const groupedProducts = products.reduce((groups, product) => {
const category = product.category;
if (!groups[category]) groups[category] = [];
groups[category].push(product);
return groups;
}, {});
return (
{Object.entries(groupedProducts).map(([category, items]) => (
{category}
{items.slice(0, 5).map(product => ( // Limiter à 5 par groupe
))}
))}
);
}
// Progressive disclosure pour réduire la surcharge
function AdvancedSettings({ isExpanded, onToggle }) {
return (
Paramètres
{/* Options de base toujours visibles */}
{/* Options avancées masquées par défaut */}
{isExpanded ? 'Masquer' : 'Options avancées'}
{isExpanded && (
)}
);
}13:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$38"}]}]
14:["$","h3",null,{"children":"3. La Loi de Miller : Limitation de la mémoire de travail"}]
15:["$","p",null,{"children":"L'esprit humain peut garder en mémoire de travail environ 7±2 éléments simultanément. Structurez l'information en chunks de taille appropriée."}]
16:["$","div",null,{"className":"overflow-x-auto","children":["$","table",null,{"className":"min-w-full divide-y divide-gray-200","children":[["$","thead",null,{"className":"bg-gray-50","children":["$","tr",null,{"children":[["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Contexte"}],["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Limite recommandée"}],["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Technique"}],["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Exemple"}]]}]}],["$","tbody",null,{"className":"divide-y divide-gray-200","children":[["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Navigation principale"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"5-7 items"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Regroupement thématique"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Home, Produits, Services, À propos, Contact"}]]}],["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Formulaires"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"5-9 champs par page"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Multi-étapes"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Étape 1: Infos perso, Étape 2: Paiement"}]]}],["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Listes d'options"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"7±2 items"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Recherche + filtrage"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Liste déroulante avec search"}]]}],["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Breadcrumbs"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"3-5 niveaux max"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Hiérarchie logique"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":["Home ",">"," Catégorie ",">"," Produit"]}]]}]]}]]}]}]
17:["$","h2",null,{"children":"Architecture de l'information et navigation"}]
18:["$","h3",null,{"children":"Hiérarchie visuelle et scannabilité"}]
19:["$","p",null,{"children":"Les utilisateurs scannent plus qu'ils ne lisent. Créez une hiérarchie claire qui guide naturellement le regard vers les éléments importants."}]
39:T94f,/* Hiérarchie typographique claire */
.content-hierarchy {
/* Titre principal - Plus gros, plus de contraste */
h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
font-weight: 700;
color: #1a1a1a;
line-height: 1.2;
margin-bottom: 1.5rem;
}
/* Sous-titres - Différenciation progressive */
h2 {
font-size: clamp(1.5rem, 3vw, 2.5rem);
font-weight: 600;
color: #2a2a2a;
margin: 2rem 0 1rem 0;
border-bottom: 2px solid #e5e5e5;
padding-bottom: 0.5rem;
}
h3 {
font-size: clamp(1.25rem, 2vw, 1.75rem);
font-weight: 600;
color: #3a3a3a;
margin: 1.5rem 0 0.75rem 0;
}
/* Corps de texte - Lisibilité optimale */
p {
font-size: 1.1rem;
line-height: 1.7;
color: #4a4a4a;
margin-bottom: 1.25rem;
max-width: 65ch; /* Ligne de lecture optimale */
}
/* Éléments de mise en avant */
.highlight {
background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
background-repeat: no-repeat;
background-size: 100% 0.2em;
background-position: 0 88%;
transition: background-size 0.25s ease-in;
}
.highlight:hover {
background-size: 100% 100%;
}
/* Call-to-action - Maximum de contraste */
.cta {
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
color: white;
font-weight: 600;
padding: 1rem 2rem;
border-radius: 8px;
border: none;
cursor: pointer;
transform: translateY(0);
transition: all 0.2s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.cta:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}
}
/* Layout en F-pattern et Z-pattern */
.f-pattern-layout {
display: grid;
grid-template-areas:
"header header header"
"primary secondary tertiary"
"content content sidebar";
grid-template-columns: 2fr 1fr 1fr;
gap: 2rem;
}
.hero-section {
grid-area: header;
/* Zone de scanning horizontal primaire */
}
.primary-content {
grid-area: primary;
/* Point focal principal */
}
.secondary-content {
grid-area: secondary;
/* Élément de scanning horizontal secondaire */
}
/* Mobile : Z-pattern simplifié */
@media (max-width: 768px) {
.f-pattern-layout {
grid-template-areas:
"header"
"primary"
"secondary"
"content"
"sidebar";
grid-template-columns: 1fr;
}
}1a:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$39"}]}]
1b:["$","h3",null,{"children":"Navigation et wayfinding"}]
1c:["$","p",null,{"children":"Les utilisateurs doivent toujours savoir où ils sont, d'où ils viennent et où ils peuvent aller. Implémentez des systèmes de navigation clairs et cohérents."}]
3a:Tc30,// React - Système de navigation contextuelle
function ContextualNavigation({ currentPath, userRole, breadcrumbs }) {
const [isSearchOpen, setIsSearchOpen] = useState(false);
return (
{/* Breadcrumbs pour l'orientation */}
{/* Navigation principale avec état actif */}
{getNavigationItems(userRole).map(item => (
0}
/>
))}
{/* Recherche contextuelle */}
{/* Indicateur de position dans un workflow */}
{isInWorkflow(currentPath) && (
)}
);
}
// Composant de navigation par étapes
function WorkflowIndicator({ currentStep, totalSteps }) {
return (
{Array.from({ length: totalSteps }, (_, i) => {
const stepNumber = i + 1;
const isComplete = stepNumber < currentStep;
const isCurrent = stepNumber === currentStep;
return (
{stepNumber}
{getStepLabel(stepNumber)}
);
})}
);
}
/* CSS pour la navigation */
.contextual-nav {
position: sticky;
top: 0;
background: white;
border-bottom: 1px solid #e5e7eb;
z-index: 50;
padding: 1rem;
}
.main-nav {
display: flex;
gap: 2rem;
list-style: none;
margin: 0;
padding: 0;
}
.nav-item {
position: relative;
}
.nav-item.active {
color: var(--primary-color);
border-bottom: 2px solid var(--primary-color);
}
.nav-item.active::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
width: 100%;
height: 2px;
background: var(--primary-color);
}
.workflow-indicator {
display: flex;
justify-content: center;
margin: 1rem 0;
gap: 1rem;
}
.step {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem;
border-radius: 6px;
transition: all 0.2s ease;
}
.step.current {
background: var(--primary-color);
color: white;
font-weight: 600;
}
.step.complete {
background: var(--success-color);
color: white;
}
.step.complete .step-number::after {
content: '✓';
margin-left: 0.25rem;
}1d:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$3a"}]}]
1e:["$","h2",null,{"children":"Feedback et états du système"}]
1f:["$","h3",null,{"children":"Communication en temps réel avec l'utilisateur"}]
20:["$","p",null,{"children":"Les utilisateurs doivent toujours comprendre ce qui se passe dans votre application. Implémentez des feedbacks clairs pour tous les états du système."}]
3b:T1114,// React - Système de feedback complet
function FeedbackSystem() {
const [notifications, setNotifications] = useState([]);
const [loadingStates, setLoadingStates] = useState(new Map());
// Hook pour gérer les états de chargement
const useAsyncAction = (actionName) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const execute = async (asyncFunction) => {
setIsLoading(true);
setError(null);
try {
const result = await asyncFunction();
// Feedback de succès
addNotification({
type: 'success',
title: 'Succès',
message: `${actionName} terminé avec succès`,
duration: 3000
});
return result;
} catch (err) {
setError(err);
// Feedback d'erreur
addNotification({
type: 'error',
title: 'Erreur',
message: err.message || `Erreur lors de ${actionName}`,
duration: 5000,
actions: [
{ label: 'Réessayer', action: () => execute(asyncFunction) },
{ label: 'Signaler', action: () => reportError(err) }
]
});
} finally {
setIsLoading(false);
}
};
return { execute, isLoading, error };
};
return { useAsyncAction, notifications, setNotifications };
}
// Composant de notification riche
function Notification({ notification, onDismiss }) {
const { type, title, message, duration, actions } = notification;
useEffect(() => {
if (duration) {
const timer = setTimeout(() => onDismiss(notification.id), duration);
return () => clearTimeout(timer);
}
}, [duration, notification.id, onDismiss]);
return (
{type === 'success' && }
{type === 'error' && }
{type === 'warning' && }
{type === 'info' && }
{title}
{message}
{actions && (
{actions.map((action, index) => (
{action.label}
))}
)}
onDismiss(notification.id)}
aria-label="Fermer la notification"
>
);
}
// États de chargement avec skeleton
function LoadingState({ type = 'content', lines = 3, showAvatar = false }) {
return (
{showAvatar && (
)}
{Array.from({ length: lines }, (_, i) => (
))}
);
}
// États vides avec actions
function EmptyState({
icon,
title,
description,
primaryAction,
secondaryAction
}) {
return (
{icon}
{title}
{description}
{primaryAction && (
{primaryAction.label}
)}
{secondaryAction && (
{secondaryAction.label}
)}
);
}21:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$3b"}]}]
22:["$","h3",null,{"children":"Gestion des erreurs et récupération"}]
3c:T973,// Error Boundary avec récupération gracieuse
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null,
retryCount: 0
};
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
this.setState({
error,
errorInfo
});
// Log de l'erreur pour debugging
console.error('Error boundary caught an error:', error, errorInfo);
// Reporting automatique (optionnel)
if (this.props.reportError) {
this.props.reportError(error, errorInfo);
}
}
handleRetry = () => {
this.setState(prevState => ({
hasError: false,
error: null,
errorInfo: null,
retryCount: prevState.retryCount + 1
}));
}
render() {
if (this.state.hasError) {
return (
Oups, quelque chose s'est mal passé
Une erreur inattendue s'est produite. Nos équipes ont été notifiées.
{this.state.retryCount < 3 && (
Réessayer
)}
Détails techniques
{this.state.error && this.state.error.toString()}
);
}
return this.props.children;
}
}
// Hook pour gestion d'erreurs dans les composants
function useErrorHandler() {
const [error, setError] = useState(null);
const handleError = useCallback((error, context = {}) => {
setError({ error, context, timestamp: Date.now() });
// Log et reporting
console.error('Error handled:', error, context);
}, []);
const clearError = useCallback(() => {
setError(null);
}, []);
const retryLastAction = useCallback(() => {
if (error?.context?.retryFunction) {
clearError();
error.context.retryFunction();
}
}, [error, clearError]);
return {
error,
handleError,
clearError,
retryLastAction
};
}23:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$3c"}]}]
24:["$","h2",null,{"children":"Accessibilité et inclusion"}]
25:["$","h3",null,{"children":"WCAG et bonnes pratiques"}]
26:["$","p",null,{"children":"L'accessibilité n'est pas un \"nice-to-have\", c'est une obligation légale et morale. Intégrez les standards WCAG dès la conception."}]
27:["$","div",null,{"className":"bg-green-50 p-6 rounded-lg my-6","children":[["$","h4",null,{"className":"text-green-800 font-semibold mb-3","children":"✅ Checklist accessibilité essentielle"}],["$","div",null,{"className":"grid md:grid-cols-2 gap-4","children":[["$","div",null,{"children":[["$","h5",null,{"className":"font-medium mb-2 text-green-700","children":"Perceptible"}],["$","ul",null,{"className":"text-sm space-y-1 text-green-600","children":[["$","li",null,{"children":["□ Contraste de couleur ",">","= 4.5:1"]}],["$","li",null,{"children":"□ Texte alternatif pour toutes les images"}],["$","li",null,{"children":"□ Sous-titres pour les vidéos"}],["$","li",null,{"children":"□ Pas uniquement la couleur pour l'info"}],["$","li",null,{"children":"□ Texte redimensionnable jusqu'à 200%"}]]}]]}],["$","div",null,{"children":[["$","h5",null,{"className":"font-medium mb-2 text-green-700","children":"Utilisable"}],["$","ul",null,{"className":"text-sm space-y-1 text-green-600","children":[["$","li",null,{"children":"□ Navigation au clavier complète"}],["$","li",null,{"children":"□ Pas de flashs > 3 par seconde"}],["$","li",null,{"children":"□ Temps suffisant pour lire"}],["$","li",null,{"children":"□ Skip links pour navigation"}],["$","li",null,{"children":"□ Focus visible et logique"}]]}]]}],["$","div",null,{"children":[["$","h5",null,{"className":"font-medium mb-2 text-green-700","children":"Compréhensible"}],["$","ul",null,{"className":"text-sm space-y-1 text-green-600","children":[["$","li",null,{"children":"□ Langue de la page déclarée"}],["$","li",null,{"children":"□ Navigation cohérente"}],["$","li",null,{"children":"□ Étiquettes et instructions claires"}],["$","li",null,{"children":"□ Gestion d'erreurs explicite"}],["$","li",null,{"children":"□ Suggestions d'aide"}]]}]]}],["$","div",null,{"children":[["$","h5",null,{"className":"font-medium mb-2 text-green-700","children":"Robuste"}],["$","ul",null,{"className":"text-sm space-y-1 text-green-600","children":[["$","li",null,{"children":"□ HTML valide et sémantique"}],["$","li",null,{"children":"□ Compatible lecteurs d'écran"}],["$","li",null,{"children":"□ ARIA utilisé correctement"}],["$","li",null,{"children":"□ Fonctionne sans JavaScript"}],["$","li",null,{"children":"□ Support assistive technologies"}]]}]]}]]}]]}]
3d:T1410,// React - Composants accessibles
function AccessibleButton({
children,
onClick,
disabled,
loading,
ariaLabel,
variant = 'primary'
}) {
const buttonRef = useRef(null);
// Gestion du focus pour les modales
useEffect(() => {
if (loading) {
buttonRef.current?.setAttribute('aria-busy', 'true');
} else {
buttonRef.current?.removeAttribute('aria-busy');
}
}, [loading]);
return (
{loading && (
<>
Chargement en cours
>
)}
{children}
);
}
// Formulaire accessible avec validation
function AccessibleForm({ onSubmit, children }) {
const [errors, setErrors] = useState({});
const [touched, setTouched] = useState({});
const validateField = (name, value) => {
// Logique de validation...
return null; // ou message d'erreur
};
return (
);
}
function AccessibleInput({
id,
label,
type = 'text',
required,
error,
helpText,
...props
}) {
const helpId = `${id}-help`;
const errorId = `${id}-error`;
return (
{label}
{required && (
*
)}
{helpText && (
{helpText}
)}
{error && (
{error}
)}
);
}
// Navigation accessible au clavier
function AccessibleModal({ isOpen, onClose, title, children }) {
const modalRef = useRef(null);
const previousFocus = useRef(null);
useEffect(() => {
if (isOpen) {
previousFocus.current = document.activeElement;
modalRef.current?.focus();
// Trap focus dans la modal
const focusableElements = modalRef.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements?.[0];
const lastElement = focusableElements?.[focusableElements.length - 1];
const handleTab = (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === firstElement) {
e.preventDefault();
lastElement?.focus();
} else if (!e.shiftKey && document.activeElement === lastElement) {
e.preventDefault();
firstElement?.focus();
}
}
if (e.key === 'Escape') {
onClose();
}
};
document.addEventListener('keydown', handleTab);
return () => {
document.removeEventListener('keydown', handleTab);
previousFocus.current?.focus();
};
}
}, [isOpen, onClose]);
if (!isOpen) return null;
return (
);
}28:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$3d"}]}]
29:["$","h2",null,{"children":"Tests utilisateurs et métriques UX"}]
2a:["$","h3",null,{"children":"Métriques quantitatives"}]
2b:["$","div",null,{"className":"overflow-x-auto","children":["$","table",null,{"className":"min-w-full divide-y divide-gray-200","children":[["$","thead",null,{"className":"bg-gray-50","children":["$","tr",null,{"children":[["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Métrique"}],["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Objectif"}],["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Outil de mesure"}],["$","th",null,{"className":"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase","children":"Benchmark"}]]}]}],["$","tbody",null,{"className":"divide-y divide-gray-200","children":[["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Task Success Rate"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"% d'utilisateurs qui accomplissent la tâche"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Hotjar, FullStory"}],["$","td",null,{"className":"px-6 py-4 text-sm text-green-600","children":">80%"}]]}],["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Time on Task"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Temps moyen pour accomplir une tâche"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Analytics custom events"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Dépend du contexte"}]]}],["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Error Rate"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"% d'erreurs par session"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Sentry, LogRocket"}],["$","td",null,{"className":"px-6 py-4 text-sm text-green-600","children":"<5%"}]]}],["$","tr",null,{"children":[["$","td",null,{"className":"px-6 py-4 text-sm font-medium text-gray-900","children":"Learnability"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Amélioration performance 2ème utilisation"}],["$","td",null,{"className":"px-6 py-4 text-sm text-gray-600","children":"Tests utilisateurs"}],["$","td",null,{"className":"px-6 py-4 text-sm text-green-600","children":"+20% plus rapide"}]]}]]}]]}]}]
2c:["$","h3",null,{"children":"Tests utilisateurs modulaires"}]
3e:Tea8,// Framework de tests A/B pour l'UX
class UXTestFramework {
constructor(analytics) {
this.analytics = analytics;
this.activeTests = new Map();
this.userSegments = new Map();
}
// Test A/B simple
createABTest(testName, variants, traffic = 0.5) {
const test = {
name: testName,
variants,
traffic,
startDate: new Date(),
participants: new Set()
};
this.activeTests.set(testName, test);
return test;
}
// Assignation d'utilisateur à une variante
getVariant(testName, userId) {
const test = this.activeTests.get(testName);
if (!test) return null;
// Hash stable basé sur userId + testName
const hash = this.hashUserId(userId + testName);
const bucket = hash % 100;
if (bucket < test.traffic * 100) {
const variantIndex = bucket % test.variants.length;
const variant = test.variants[variantIndex];
// Tracking participation
test.participants.add(userId);
this.trackEvent('ab_test_participation', {
testName,
variant: variant.name,
userId
});
return variant;
}
return null;
}
// Métriques d'engagement
trackEngagement(event, data) {
this.analytics.track(event, {
...data,
timestamp: Date.now(),
activeTests: Array.from(this.activeTests.keys())
});
}
// Heatmap tracking
trackMouseMovement(element, eventData) {
const rect = element.getBoundingClientRect();
this.trackEvent('mouse_movement', {
element: element.tagName,
elementId: element.id,
className: element.className,
x: eventData.clientX - rect.left,
y: eventData.clientY - rect.top,
viewport: {
width: window.innerWidth,
height: window.innerHeight
}
});
}
// Funnel tracking
trackFunnelStep(funnelName, step, success, metadata = {}) {
this.trackEvent('funnel_step', {
funnel: funnelName,
step,
success,
metadata,
timestamp: Date.now()
});
}
hashUserId(input) {
let hash = 0;
for (let i = 0; i < input.length; i++) {
const char = input.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32-bit integer
}
return Math.abs(hash);
}
}
// Hook React pour tests UX
function useUXTest(testName, variants) {
const [variant, setVariant] = useState(null);
const [userId] = useState(() => localStorage.getItem('userId') || 'anonymous');
useEffect(() => {
const framework = window.uxTestFramework;
if (framework) {
const assignedVariant = framework.getVariant(testName, userId);
setVariant(assignedVariant);
}
}, [testName, userId]);
const trackConversion = (conversionType, value = 1) => {
if (variant) {
window.uxTestFramework?.trackEvent('conversion', {
testName,
variant: variant.name,
conversionType,
value,
userId
});
}
};
return { variant, trackConversion };
}
// Utilisation dans un composant
function ProductPage() {
const { variant, trackConversion } = useUXTest('button_color', [
{ name: 'blue', color: '#3b82f6' },
{ name: 'green', color: '#10b981' },
{ name: 'red', color: '#ef4444' }
]);
const handlePurchase = () => {
trackConversion('purchase');
// Logique d'achat...
};
const buttonStyle = variant ? { backgroundColor: variant.color } : {};
return (
Produit Awesome
Acheter maintenant
);
}2d:["$","pre",null,{"className":"bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto","children":["$","code",null,{"children":"$3e"}]}]
2e:["$","h2",null,{"children":"Conclusion"}]
2f:["$","p",null,{"children":"L'UX des applications web modernes repose sur une compréhension profonde des utilisateurs et l'application rigoureuse de principes éprouvés. En 2024, une bonne UX doit être accessible, performante, intuitive et adaptée aux nouveaux usages comme la navigation vocale et les interactions gestuelles."}]
30:["$","p",null,{"children":"N'oubliez pas que l'UX est un processus itératif : testez régulièrement avec de vrais utilisateurs, mesurez l'impact de vos décisions et améliorez continuellement. La meilleure interface est celle qui se fait oublier pour laisser place à l'accomplissement fluide des objectifs de l'utilisateur."}]
31:["$","footer",null,{"className":"mt-16 pt-8 border-t border-gray-200","children":["$","div",null,{"className":"flex items-center justify-between","children":[["$","div",null,{"children":[["$","p",null,{"className":"text-sm text-gray-600 mb-2","children":"Publié le 14 Octobre 2024"}],["$","div",null,{"className":"flex items-center space-x-4","children":[["$","span",null,{"className":"text-sm text-gray-500","children":"Partager:"}],["$","a",null,{"href":"#","className":"text-tuxyoBlue hover:text-blue-700","children":"Twitter"}],["$","a",null,{"href":"#","className":"text-tuxyoBlue hover:text-blue-700","children":"LinkedIn"}]]}]]}],["$","$Lf",null,{"href":"/blog","className":"bg-tuxyoBlue text-white px-6 py-2 rounded-lg font-medium hover:bg-blue-700 transition","children":"← Retour au blog"}]]}]}]
32:["$","$L3f",null,{"children":["$","$36",null,{"name":"Next.MetadataOutlet","children":"$@40"}]}]
34:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
37:[["$","title","0",{"children":"Tuxyo - Solutions logicielles expertes"}],["$","meta","1",{"name":"description","content":"Expertise en développement logiciel avec +25 ans d'expérience. Spécialisé en Java, NodeJS, Spring Boot, ReactJS, et solutions Cloud. Architecture et développement de solutions robustes."}]]
40:null