Reddot UI Library

Docs
useMediaQuery

useMediaQuery

Hook personnalisé pour détecter les changements de media queries CSS

Installation

$npx shadcn@latest add https://reddot.dottools.xyz/r/use-media-query.json

Utilisation

import { useMediaQuery } from '@/hooks/use-media-query';
 
function ResponsiveComponent() {
  // Détecte si l'écran est en mode mobile
  const isMobile = useMediaQuery('(max-width: 768px)');
  
  // Détecte si l'utilisateur préfère le mode sombre
  const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
  
  // Détecte l'orientation de l'écran
  const isLandscape = useMediaQuery('(orientation: landscape)');
 
  return (
    <div>
      <p>Mode mobile: {isMobile ? 'Oui' : 'Non'}</p>
      <p>Préfère le mode sombre: {prefersDark ? 'Oui' : 'Non'}</p>
      <p>Orientation paysage: {isLandscape ? 'Oui' : 'Non'}</p>
    </div>
  );
}

API

const matches = useMediaQuery(query, options?);

Paramètres

  • query - La media query CSS à surveiller (string)
  • options - Options de configuration (optionnel)
    • defaultValue - Valeur par défaut retournée côté serveur (boolean, défaut: false)
    • initializeWithValue - Initialise avec la valeur actuelle de la media query (boolean, défaut: true)

Retour

  • matches - Valeur booléenne indiquant si la media query correspond actuellement

Exemples

Détection de la taille d'écran

function BreakpointExample() {
  const isSmall = useMediaQuery('(max-width: 640px)');
  const isMedium = useMediaQuery('(min-width: 641px) and (max-width: 1024px)');
  const isLarge = useMediaQuery('(min-width: 1025px)');
 
  return (
    <div>
      {isSmall && <p>Écran petit</p>}
      {isMedium && <p>Écran moyen</p>}
      {isLarge && <p>Écran large</p>}
    </div>
  );
}

Préférences système

function SystemPreferences() {
  const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
  const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');
 
  return (
    <div className={prefersDark ? 'dark' : 'light'}>
      {prefersReducedMotion && <p>Animations réduites</p>}
    </div>
  );
}

Configuration côté serveur

function ServerSideExample() {
  // Définit une valeur par défaut pour le rendu côté serveur
  const isMobile = useMediaQuery('(max-width: 768px)', {
    defaultValue: false,
    initializeWithValue: false
  });
 
  return <div>{isMobile ? 'Mobile' : 'Desktop'}</div>;
}

Fonctionnalités

  • Détecte automatiquement les changements de media queries CSS
  • Compatible avec le rendu côté serveur (SSR)
  • Utilise useIsomorphicLayoutEffect pour éviter les problèmes d'hydratation
  • Support des anciens navigateurs Safari avec les méthodes addListener/removeListener
  • Réagit en temps réel aux changements de taille d'écran, orientation, et préférences système
  • Configuration flexible avec valeurs par défaut personnalisables

Exemple avancé

import { useMediaQuery } from '@/registry/hooks/use-media-query';
 
function AdaptiveInterface() {
  const isMobile = useMediaQuery('(max-width: 768px)');
  const isTablet = useMediaQuery('(min-width: 769px) and (max-width: 1024px)');
  const isDesktop = useMediaQuery('(min-width: 1025px)');
  const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
  const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');
  const isLandscape = useMediaQuery('(orientation: landscape)');
 
  const getLayoutClass = () => {
    if (isMobile) return 'mobile-layout';
    if (isTablet) return 'tablet-layout';
    return 'desktop-layout';
  };
 
  return (
    <div 
      className={`
        ${getLayoutClass()}
        ${prefersDark ? 'dark-theme' : 'light-theme'}
        ${prefersReducedMotion ? 'reduced-motion' : ''}
        ${isLandscape ? 'landscape' : 'portrait'}
      `}
    >
      <header>
        {isMobile ? (
          <MobileNavigation />
        ) : (
          <DesktopNavigation />
        )}
      </header>
      
      <main>
        {isDesktop && <Sidebar />}
        <Content 
          columns={isMobile ? 1 : isTablet ? 2 : 3}
          animations={!prefersReducedMotion}
        />
      </main>
      
      <footer>
        <ResponsiveFooter device={isMobile ? 'mobile' : 'desktop'} />
      </footer>
    </div>
  );
}

Notes techniques

  • Performance : Le hook utilise l'API native matchMedia pour une détection optimisée
  • Mémoire : Les event listeners sont automatiquement nettoyés lors du démontage du composant
  • SSR : Compatible avec Next.js, Gatsby et autres frameworks SSR grâce à useIsomorphicLayoutEffect
  • Hydratation : Évite les erreurs d'hydratation en gérant correctement les différences client/serveur
  • Navigateurs : Support complet des navigateurs modernes avec fallback pour Safari < 14
  • Réactivité : Met à jour automatiquement l'état lors des changements de media query