SmarMaker - Documentation
Docs» 15_training:module6-smartcommon-composants:navigation

Chapitre 2 : Navigation

Navbar

La barre de navigation supérieure. Affiche le titre et des actions.

Syntaxe de base

snippet.javascript
import { Navbar, UpperNavbarItem } from '@cap-rel/smartcommon';
import { FiMenu, FiUser } from 'react-icons/fi';
 
function MyPage() {
    return (
        <>
            <Navbar title="Mon Application">
                <UpperNavbarItem icon={FiMenu} onClick={openMenu} />
                <UpperNavbarItem icon={FiUser} onClick={goToProfile} />
            </Navbar>
            {/* Contenu */}
        </>
    );
}

Props Navbar

Prop Type Description
title string Titre principal
subtitle string Sous-titre optionnel
showBack boolean Afficher le bouton retour
onBack function Callback du bouton retour

Props UpperNavbarItem

Prop Type Description
icon Component Icône react-icons
onClick function Action au clic
badge number Compteur de notification

Sidebar

Menu latéral avec navigation.

Syntaxe

snippet.javascript
import { useState } from 'react';
import { Sidebar, Button } from '@cap-rel/smartcommon';
import { useNavigation, useGlobalStates, useApi } from '@cap-rel/smartcommon';
import { FiHome, FiList, FiSettings, FiLogOut } from 'react-icons/fi';
 
function MainLayout({ children }) {
    const [isSidebarOpen, setIsSidebarOpen] = useState(false);
    const navigate = useNavigation();
    const api = useApi();
    const [session] = useGlobalStates('session');
 
    const menuItems = [
        { icon: FiHome, label: 'Accueil', path: '/' },
        { icon: FiList, label: 'Produits', path: '/products' },
        { icon: FiSettings, label: 'Paramètres', path: '/settings' }
    ];
 
    const handleLogout = async () => {
        await api.logout();
        navigate('/login');
    };
 
    return (
        <>
            <Sidebar
                isOpen={isSidebarOpen}
                onClose={() => setIsSidebarOpen(false)}
            >
                {/* En-tête utilisateur */}
                <div className="p-4 border-b">
                    <p className="font-bold">{session?.user?.name}</p>
                    <p className="text-sm text-gray-500">{session?.user?.email}</p>
                </div>
 
                {/* Menu */}
                <nav className="p-2">
                    {menuItems.map(item => (
                        <button
                            key={item.path}
                            onClick={() => {
                                navigate(item.path);
                                setIsSidebarOpen(false);
                            }}
                            className="flex items-center gap-3 w-full p-3 rounded hover:bg-gray-100"
                        >
                            <item.icon />
                            {item.label}
                        </button>
                    ))}
                </nav>
 
                {/* Déconnexion */}
                <div className="p-4 border-t mt-auto">
                    <Button onClick={handleLogout} variant="outline" className="w-full">
                        <FiLogOut className="mr-2" />
                        Déconnexion
                    </Button>
                </div>
            </Sidebar>
 
            {children}
        </>
    );
}

Props

Prop Type Description
isOpen boolean Contrôle l'affichage
onClose function Callback à la fermeture
position string 'left' ou 'right'

Tabbar

Barre d'onglets en bas de l'écran (navigation mobile).

Syntaxe

snippet.javascript
import { Tabbar, TabbarItem } from '@cap-rel/smartcommon';
import { useNavigation } from '@cap-rel/smartcommon';
import { useLocation } from 'react-router-dom';
import { FiHome, FiSearch, FiShoppingCart, FiUser } from 'react-icons/fi';
 
function AppTabbar() {
    const navigate = useNavigation();
    const location = useLocation();
 
    const tabs = [
        { icon: FiHome, label: 'Accueil', path: '/' },
        { icon: FiSearch, label: 'Recherche', path: '/search' },
        { icon: FiShoppingCart, label: 'Panier', path: '/cart', badge: 3 },
        { icon: FiUser, label: 'Profil', path: '/profile' }
    ];
 
    return (
        <Tabbar>
            {tabs.map(tab => (
                <TabbarItem
                    key={tab.path}
                    icon={tab.icon}
                    label={tab.label}
                    active={location.pathname === tab.path}
                    badge={tab.badge}
                    onClick={() => navigate(tab.path)}
                />
            ))}
        </Tabbar>
    );
}

Props TabbarItem

Prop Type Description
icon Component Icône react-icons
label string Texte sous l'icône
active boolean État sélectionné
badge number Compteur notification
onClick function Action au clic

useNavigation

Hook pour la navigation programmatique.

Syntaxe

snippet.javascript
import { useNavigation } from '@cap-rel/smartcommon';
 
function MyComponent() {
    const navigate = useNavigation();
 
    return (
        <div>
            {/* Navigation vers une route */}
            <button onClick={() => navigate('/products')}>
                Voir les produits
            </button>
 
            {/* Navigation avec paramètre */}
            <button onClick={() => navigate(`/products/${productId}`)}>
                Détails
            </button>
 
            {/* Retour arrière */}
            <button onClick={() => navigate(-1)}>
                Retour
            </button>
 
            {/* Remplacement (pas d'historique) */}
            <button onClick={() => navigate('/login', { replace: true })}>
                Se connecter
            </button>
        </div>
    );
}

Exemple complet : Layout avec navigation

snippet.javascript
// components/layouts/MainLayout/index.jsx
import { useState } from 'react';
import { useLocation } from 'react-router-dom';
import {
    Navbar,
    Sidebar,
    Tabbar,
    TabbarItem,
    UpperNavbarItem
} from '@cap-rel/smartcommon';
import { useNavigation, useGlobalStates, useApi } from '@cap-rel/smartcommon';
import {
    FiMenu,
    FiHome,
    FiList,
    FiPlus,
    FiSettings,
    FiLogOut
} from 'react-icons/fi';
 
export const MainLayout = ({ children, title }) => {
    const [sidebarOpen, setSidebarOpen] = useState(false);
    const navigate = useNavigation();
    const location = useLocation();
    const api = useApi();
    const [session] = useGlobalStates('session');
 
    const handleLogout = async () => {
        await api.logout();
        navigate('/login');
    };
 
    return (
        <div className="min-h-screen flex flex-col">
            {/* Navbar */}
            <Navbar title={title}>
                <UpperNavbarItem
                    icon={FiMenu}
                    onClick={() => setSidebarOpen(true)}
                />
            </Navbar>
 
            {/* Sidebar */}
            <Sidebar
                isOpen={sidebarOpen}
                onClose={() => setSidebarOpen(false)}
            >
                <div className="p-4 border-b">
                    <p className="font-bold">{session?.user?.name}</p>
                </div>
 
                <nav className="flex-1 p-2">
                    <SidebarLink
                        icon={FiHome}
                        label="Accueil"
                        onClick={() => {
                            navigate('/');
                            setSidebarOpen(false);
                        }}
                    />
                    <SidebarLink
                        icon={FiList}
                        label="Produits"
                        onClick={() => {
                            navigate('/products');
                            setSidebarOpen(false);
                        }}
                    />
                    <SidebarLink
                        icon={FiSettings}
                        label="Paramètres"
                        onClick={() => {
                            navigate('/settings');
                            setSidebarOpen(false);
                        }}
                    />
                </nav>
 
                <div className="p-4 border-t">
                    <button
                        onClick={handleLogout}
                        className="flex items-center gap-2 text-red-500"
                    >
                        <FiLogOut /> Déconnexion
                    </button>
                </div>
            </Sidebar>
 
            {/* Contenu principal */}
            <main className="flex-1 pb-16">
                {children}
            </main>
 
            {/* Tabbar */}
            <Tabbar>
                <TabbarItem
                    icon={FiHome}
                    label="Accueil"
                    active={location.pathname === '/'}
                    onClick={() => navigate('/')}
                />
                <TabbarItem
                    icon={FiList}
                    label="Produits"
                    active={location.pathname.startsWith('/products')}
                    onClick={() => navigate('/products')}
                />
                <TabbarItem
                    icon={FiPlus}
                    label="Nouveau"
                    onClick={() => navigate('/products/new')}
                />
                <TabbarItem
                    icon={FiSettings}
                    label="Paramètres"
                    active={location.pathname === '/settings'}
                    onClick={() => navigate('/settings')}
                />
            </Tabbar>
        </div>
    );
};
 
// Composant helper
const SidebarLink = ({ icon: Icon, label, onClick }) => (
    <button
        onClick={onClick}
        className="flex items-center gap-3 w-full p-3 rounded hover:bg-gray-100"
    >
        <Icon />
        {label}
    </button>
);

Utilisation du layout

snippet.javascript
// components/pages/private/ProductsPage/index.jsx
import { MainLayout } from '../../../layouts/MainLayout';
import { Block, List, ListItem } from '@cap-rel/smartcommon';
 
export const ProductsPage = () => {
    const products = [...];
 
    return (
        <MainLayout title="Produits">
            <Block>
                <List>
                    {products.map(p => (
                        <ListItem
                            key={p.id}
                            title={p.label}
                            subtitle={`${p.price} €`}
                        />
                    ))}
                </List>
            </Block>
        </MainLayout>
    );
};

Points clés à retenir

  1. Navbar = barre supérieure avec titre et actions
  2. Sidebar = menu latéral coulissant
  3. Tabbar = navigation par onglets en bas
  4. useNavigation = navigation programmatique
  5. Combiner ces composants dans un Layout réutilisable

← Chapitre précédent | Retour au module | Chapitre suivant : Formulaires →

Previous Next

Made with ❤ by CAP-REL · SmartMaker · GNU AGPL v3+
Code source · Faire un don
SmarMaker - Documentation
Traductions de cette page:
  • Français
  • Deutsch
  • English
  • Español
  • Italiano
  • Nederlands

Table of Contents

Table des matières

  • Chapitre 2 : Navigation
    • Navbar
      • Syntaxe de base
      • Props Navbar
      • Props UpperNavbarItem
    • Sidebar
      • Syntaxe
      • Props
    • Tabbar
      • Syntaxe
      • Props TabbarItem
    • useNavigation
      • Syntaxe
    • Exemple complet : Layout avec navigation
      • Utilisation du layout
    • Points clés à retenir
  • SmartAuth
  • SmartMaker - Back (PHP)
    • Mapping Dolibarr - React
  • SmartMaker - Front (React)
    • Animations de pages
    • Architecture
    • Astuces
    • Calendar
    • Composants et pages
    • Configuration du Provider
    • Debug et Logs
    • Hooks SmartCommon
    • PWA (Progressive Web App)
    • Requêtes API
    • Routage
    • SmartCommon
    • Stockage de données
    • Thèmes
    • Traductions
  • HowTo - Pas à pas - Votre première application
    • Développement PHP (back)
    • Développement React (front)
    • Première étape : Module Builder Dolibarr
    • SmartAuth
    • SmartBoot : Un "squelette" quasiment prêt à l'emploi
  • Formation SmartMaker
    • Module 1 : Fondamentaux JavaScript ES6+
      • Chapitre 1 : Variables et Scope
      • Chapitre 2 : Fonctions
      • Chapitre 3 : Programmation Asynchrone
      • Chapitre 4 : Modules ES6
    • Module 2 : Introduction à React
      • Chapitre 1 : Philosophie React
      • Chapitre 2 : JSX
      • Chapitre 3 : Composants
    • Module 3 : Hooks React Fondamentaux
      • Chapitre 1 : useState
      • Chapitre 2 : useEffect
      • Chapitre 3 : useRef
      • Chapitre 4 : useContext
    • Module 4 : React Avancé
      • Chapitre 1 : useCallback et useMemo
      • Chapitre 2 : Custom Hooks
      • Chapitre 3 : Redux et Redux Toolkit
    • Module 5 : Architecture SmartMaker
      • Chapitre 1 : Structure du projet
      • Chapitre 2 : Configuration
      • Chapitre 3 : Flux de données
    • Module 6 : SmartCommon - Composants
      • Chapitre 1 : Mise en page
      • Chapitre 2 : Navigation
      • Chapitre 3 : Formulaires
      • Chapitre 4 : Affichage
    • Module 7 : SmartCommon - Hooks
      • Chapitre 1 : useApi
      • Chapitre 2 : Gestion d'état
      • Chapitre 3 : Hooks utilitaires
    • Module 8 : Backend API (PHP)
      • Chapitre 1 : Routage
      • Chapitre 2 : Controllers
      • Chapitre 3 : Mappers
      • Extrafields et formulaires dynamiques
    • Module 9 : Intégration complète
      • Chapitre 1 : Backend
      • Chapitre 2 : Frontend
      • Chapitre 3 : Déploiement
    • Module 10 : Fonctionnalités avancées
      • Chapitre 1 : Mode offline
      • Chapitre 2 : Internationalisation (i18n)
      • Chapitre 3 : Autres fonctionnalités
    • Module 11 : Bonnes pratiques
  • Démonstration
  • Start
  • Composants et pages
  • Afficher le texte source
  • Anciennes révisions
  • Liens de retour
  • Haut de page