SmarMaker - Documentation
Docs» front» front:themes

Thèmes

Documentation Tailwind CSS v4

SmartMaker utilise TailwindCSS v4 pour la stylisation. Cette version introduit une nouvelle syntaxe CSS-first avec @theme et @layer.

Configuration TailwindCSS 4

Installation

TailwindCSS 4 est intégré via le plugin Vite :

// vite.config.js

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
  ],
});

Point d'entrée CSS

/* src/assets/styles/style.css */

@import "tailwindcss";

@layer theme, base, components;

@import "./theme.css" layer(theme);
@import "./base.css" layer(base);

Définir un thème

Variables CSS avec @theme

/* src/assets/styles/theme.css */

@theme {
  /* Couleurs principales */
  --color-primary: #5fbabf;
  --color-primary-light: #8cd4d8;
  --color-primary-dark: #4a9599;

  --color-secondary: #fc8c8c;
  --color-secondary-light: #fdb5b5;
  --color-secondary-dark: #e67070;

  /* Couleurs sémantiques */
  --color-success: #22c55e;
  --color-warning: #f59e0b;
  --color-error: #ef4444;
  --color-info: #3b82f6;

  /* Couleurs de fond */
  --color-background: #ffffff;
  --color-surface: #f8fafc;
  --color-muted: #f1f5f9;

  /* Couleurs de texte */
  --color-foreground: #0f172a;
  --color-foreground-muted: #64748b;

  /* Espacements customs */
  --spacing-page: 1rem;
  --spacing-card: 1.5rem;

  /* Rayons de bordure */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 1rem;
  --radius-full: 9999px;

  /* Ombres */
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);

  /* Typographie */
  --font-sans: 'Inter', system-ui, sans-serif;
  --font-mono: 'Fira Code', monospace;
}

Utilisation dans les composants

Les variables @theme génèrent automatiquement des classes Tailwind :

<div className="bg-primary text-white">
  Fond primaire
</div>

<div className="text-foreground-muted">
  Texte atténué
</div>

<div className="rounded-lg shadow-md p-card">
  Carte avec espacement
</div>

Styles de base

Reset et règles globales

/* src/assets/styles/base.css */

@layer base {
  * {
    @apply box-border p-0 m-0;
    -webkit-tap-highlight-color: transparent;
  }

  *::-webkit-scrollbar {
    display: none;
  }

  html {
    @apply scroll-smooth antialiased;
  }

  body {
    @apply bg-background text-foreground font-sans;
  }

  /* Focus visible pour accessibilité */
  :focus-visible {
    @apply outline-2 outline-offset-2 outline-primary;
  }

  /* Liens */
  a {
    @apply text-primary hover:text-primary-dark transition-colors;
  }

  /* Inputs */
  input, textarea, select {
    @apply bg-surface border border-gray-200 rounded-md;
    @apply focus:border-primary focus:ring-1 focus:ring-primary;
  }
}

Créer des thèmes multiples

Structure des fichiers

src/assets/
├── styles/
│   ├── style.css           # Point d'entrée
│   ├── theme.css           # Variables par défaut
│   └── base.css            # Règles globales
└── themes/
    ├── light.css           # Thème clair
    └── dark.css            # Thème sombre

Thème clair (défaut)

/* src/assets/themes/light.css */

@theme {
  --color-background: #ffffff;
  --color-surface: #f8fafc;
  --color-foreground: #0f172a;
  --color-foreground-muted: #64748b;
}

Thème sombre

/* src/assets/themes/dark.css */

@theme {
  --color-background: #0f172a;
  --color-surface: #1e293b;
  --color-foreground: #f8fafc;
  --color-foreground-muted: #94a3b8;
}

Chargement dynamique

// src/main.jsx

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

import "./assets/styles/style.css";

// Charger le thème depuis les settings
const theme = localStorage.getItem('theme') || 'light';
import(`./assets/themes/${theme}.css`);

import { App } from "./App";

createRoot(document.getElementById("root")).render(
  <StrictMode>
    <App />
  </StrictMode>
);

Hook useTheme

import { useGlobalStates } from '@cap-rel/smartcommon';
import { useEffect } from 'react';

export const useTheme = () => {
  const [theme, setTheme] = useGlobalStates('settings.theme');

  useEffect(() => {
    // Appliquer le thème au document
    document.documentElement.setAttribute('data-theme', theme);

    // Charger le CSS du thème
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = `/themes/${theme}.css`;
    document.head.appendChild(link);

    return () => {
      document.head.removeChild(link);
    };
  }, [theme]);

  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  return { theme, setTheme, toggleTheme };
};

Composant ThemeToggle

import { useTheme } from '../hooks/useTheme';

const ThemeToggle = () => {
  const { theme, toggleTheme } = useTheme();

  return (
    <button
      onClick={toggleTheme}
      className="p-2 rounded-full bg-surface"
    >
      {theme === 'light' ? '🌙' : '☀️'}
    </button>
  );
};

Variantes de composants

Avec SmartCommon

SmartCommon permet de définir des variantes pour les composants :

// appConfig.js

export const config = {
  components: {
    variants: {
      Button: {
        default: "bg-primary text-white rounded-md px-4 py-2",
        secondary: "bg-secondary text-white rounded-md px-4 py-2",
        outline: "border-2 border-primary text-primary rounded-md px-4 py-2",
        ghost: "text-primary hover:bg-primary/10 rounded-md px-4 py-2",
      },
      Input: {
        default: "bg-surface border border-gray-200 rounded-md p-3",
        filled: "bg-muted border-0 rounded-md p-3",
        underline: "border-b-2 border-gray-200 rounded-none p-3",
      },
    },
  },
};

Utilisation

import { Button, Input } from '@cap-rel/smartcommon';

const MyForm = () => {
  return (
    <form>
      <Input name="email" variant="filled" />
      <Button variant="secondary">Envoyer</Button>
      <Button variant="ghost">Annuler</Button>
    </form>
  );
};

Classes utilitaires personnalisées

Avec @layer components

/* src/assets/styles/components.css */

@layer components {
  .card {
    @apply bg-surface rounded-lg shadow-md p-card;
  }

  .btn {
    @apply inline-flex items-center justify-center;
    @apply px-4 py-2 rounded-md font-medium;
    @apply transition-all duration-200;
    @apply focus:outline-none focus:ring-2 focus:ring-offset-2;
  }

  .btn-primary {
    @apply btn bg-primary text-white;
    @apply hover:bg-primary-dark;
    @apply focus:ring-primary;
  }

  .btn-secondary {
    @apply btn bg-secondary text-white;
    @apply hover:bg-secondary-dark;
    @apply focus:ring-secondary;
  }

  .input {
    @apply w-full px-4 py-3 rounded-md;
    @apply bg-surface border border-gray-200;
    @apply focus:border-primary focus:ring-1 focus:ring-primary;
    @apply placeholder:text-foreground-muted;
  }
}

Dark mode automatique

Avec prefers-color-scheme

/* src/assets/styles/theme.css */

@theme {
  --color-background: #ffffff;
  --color-foreground: #0f172a;
}

@media (prefers-color-scheme: dark) {
  @theme {
    --color-background: #0f172a;
    --color-foreground: #f8fafc;
  }
}

Avec classe CSS

/* Thème par défaut (clair) */
@theme {
  --color-background: #ffffff;
  --color-foreground: #0f172a;
}

/* Thème sombre via classe */
.dark {
  --color-background: #0f172a;
  --color-foreground: #f8fafc;
}
// Toggle dark mode
document.documentElement.classList.toggle('dark');

Conseils

Performance

  • Utilisez @theme pour les variables réutilisées
  • Évitez les classes Tailwind dynamiques (bg-${color})
  • Préférez les variantes de composants

Organisation

  • Un fichier pour les variables (theme.css)
  • Un fichier pour les règles de base (base.css)
  • Un fichier par thème additionnel

Accessibilité

  • Respectez les contrastes WCAG
  • Testez avec prefers-reduced-motion
  • Utilisez focus-visible pour le focus

Voir aussi

  • Configuration - Variantes de composants
  • SmartCommon - Composants disponibles
  • Animations - Transitions de pages
Previous Next

SmarMaker - Documentation
Traductions de cette page:
  • Français
  • Deutsch
  • English
  • Español
  • Italiano
  • Nederlands

Table of Contents

Table des matières

  • Thèmes
    • Configuration TailwindCSS 4
      • Installation
      • Point d'entrée CSS
    • Définir un thème
      • Variables CSS avec @theme
      • Utilisation dans les composants
    • Styles de base
      • Reset et règles globales
    • Créer des thèmes multiples
      • Structure des fichiers
      • Thème clair (défaut)
      • Thème sombre
      • Chargement dynamique
      • Hook useTheme
      • Composant ThemeToggle
    • Variantes de composants
      • Avec SmartCommon
      • Utilisation
    • Classes utilitaires personnalisées
      • Avec @layer components
    • Dark mode automatique
      • Avec prefers-color-scheme
      • Avec classe CSS
    • Conseils
      • Performance
      • Organisation
      • Accessibilité
    • Voir aussi


  • SmartMaker
    • SmartAuth
    • Back (PHP)
      • Mapping Dolibarr
    • Front (React)
      • Configuration
      • SmartCommon
      • Hooks
      • Architecture
      • Composants et pages
      • Routage
      • Requêtes Api
      • Stockage de données
      • Animations
      • Traductions
      • Thèmes
      • PWA
      • Debug
      • Astuces
    • HowTo first app
  • Formations
  • Démonstration
  • Afficher le texte source
  • Anciennes révisions
  • Liens de retour
  • Haut de page
  • S'identifier
front/themes.txt · Dernière modification : 2026/01/11 22:49 de 127.0.0.1