---
title: "Chapitre 2 : Navigation"
weight: 540
---

# Chapitre 2 : Navigation

## Navbar

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

### Syntaxe de base

```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

```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 nav = useNavigation();
    const api = useApi();
    const gst = useGlobalStates();

    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();
        nav.navigate('/login');
    };

    return (
        <>
            <Sidebar
                isOpen={isSidebarOpen}
                onClose={() => setIsSidebarOpen(false)}
            >
                {/* En-tête utilisateur */}
                <div className="p-4 border-b">
                    <p className="font-bold">{gst.get('session')?.user?.name}</p>
                    <p className="text-sm text-gray-500">{gst.get('session')?.user?.email}</p>
                </div>

                {/* Menu */}
                <nav className="p-2">
                    {menuItems.map(item => (
                        <button
                            key={item.path}
                            onClick={() => {
                                nav.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

```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 nav = 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={() => nav.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

```javascript
import { useNavigation } from '@cap-rel/smartcommon';

function MyComponent() {
    const nav = useNavigation();

    return (
        <div>
            {/* Navigation vers une route */}
            <button onClick={() => nav.navigate('/products')}>
                Voir les produits
            </button>

            {/* Navigation avec paramètre */}
            <button onClick={() => nav.navigate(`/products/${productId}`)}>
                Détails
            </button>

            {/* Retour arrière */}
            <button onClick={() => nav.navigate(-1)}>
                Retour
            </button>

            {/* Remplacement (pas d'historique) */}
            <button onClick={() => nav.replace('/login').to()}>
                Se connecter
            </button>
        </div>
    );
}
```

## Exemple complet : Layout avec navigation

```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 nav = useNavigation();
    const location = useLocation();
    const api = useApi();
    const gst = useGlobalStates();

    const handleLogout = async () => {
        await api.logout();
        nav.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">{gst.get('session')?.user?.name}</p>
                </div>

                <nav className="flex-1 p-2">
                    <SidebarLink
                        icon={FiHome}
                        label="Accueil"
                        onClick={() => {
                            nav.navigate('/');
                            setSidebarOpen(false);
                        }}
                    />
                    <SidebarLink
                        icon={FiList}
                        label="Produits"
                        onClick={() => {
                            nav.navigate('/products');
                            setSidebarOpen(false);
                        }}
                    />
                    <SidebarLink
                        icon={FiSettings}
                        label="Paramètres"
                        onClick={() => {
                            nav.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={() => nav.navigate('/')}
                />
                <TabbarItem
                    icon={FiList}
                    label="Produits"
                    active={location.pathname.startsWith('/products')}
                    onClick={() => nav.navigate('/products')}
                />
                <TabbarItem
                    icon={FiPlus}
                    label="Nouveau"
                    onClick={() => nav.navigate('/products/new')}
                />
                <TabbarItem
                    icon={FiSettings}
                    label="Paramètres"
                    active={location.pathname === '/settings'}
                    onClick={() => nav.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

```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](/training/module6-smartcommon-composants/mise-en-page) | [Retour au module](/training/module6-smartcommon-composants) | [Chapitre suivant : Formulaires ->](/training/module6-smartcommon-composants/formulaires)
