# Hooks SmartCommon
SmartCommon fournit un ensemble de hooks React pour faciliter le développement d'applications.
## Hooks globaux
Ces hooks utilisent le contexte de l'application et doivent être utilisés à l'intérieur du ''Provider''.
### useApi
Gestion des appels API avec authentification JWT automatique.
```
import { useApi } from '@cap-rel/smartcommon';
const api = useApi();
// Connexion
await api.login({ login, password, rememberMe: true });
// Déconnexion
await api.logout();
// Requête authentifiée
const data = await api.private.get('items').json();
// Requête publique
const info = await api.public.get('public/info').json();
```
Voir [[requetes_api|Requêtes API]] pour plus de détails.
### useGlobalStates
État global avec persistance automatique (localStorage/sessionStorage).
```
import { useGlobalStates } from '@cap-rel/smartcommon';
const gst = useGlobalStates();
// Lire
const user = gst.get('user');
const theme = gst.get('settings.theme');
// Écrire (persistant)
gst.local.set('user', userData);
// Écrire (session uniquement)
gst.session.set('tempData', data);
// Supprimer
gst.unset('user');
// Accès direct aux valeurs
const { user, settings } = gst.values;
```
Voir [[stockage_de_donnees|Stockage de données]] pour plus de détails.
### useNavigation
Utilitaires de navigation pour react-router-dom.
```
import { useNavigation } from '@cap-rel/smartcommon';
const nav = useNavigation();
// Navigation programmatique
nav.navigate('/dashboard');
nav.navigate(-1); // Retour arrière
// Informations de route
const { pathname, search, hash } = nav.location;
// Paramètres d'URL
const { id } = nav.params;
```
### useLibConfig
Accès à la configuration de l'application.
```
import { useLibConfig } from '@cap-rel/smartcommon';
const config = useLibConfig();
console.log(config.debug); // true/false
console.log(config.api); // { prefixUrl, timeout, ... }
```
### useConfirm
Dialogues de confirmation et d'alerte (nécessite ConfirmProvider).
```
import { useConfirm } from '@cap-rel/smartcommon';
const { confirm, alert } = useConfirm();
// Confirmation (retourne true/false)
const handleDelete = async () => {
const ok = await confirm({
type: 'delete', // 'danger' | 'delete' | 'warning' | 'info'
title: 'Supprimer ?',
message: 'Cette action est irréversible.',
detail: item.label, // détail optionnel
confirmText: 'Supprimer',
cancelText: 'Annuler',
});
if (ok) {
await api.del(`items/${item.id}`);
}
};
// Alerte (un seul bouton OK)
await alert({
type: 'info',
title: 'Information',
message: 'Opération terminée avec succès.',
});
```
### usePWAUpdate
Gestion des mises à jour PWA via Service Worker.
```
import { usePWAUpdate } from '@cap-rel/smartcommon';
const { updateAvailable, checkForUpdates, applyUpdate } = usePWAUpdate({
autoReload: false,
checkInterval: 60000,
});
```
Voir [[:03_front:pwa|PWA]] pour plus de détails.
## Hooks locaux
Ces hooks gèrent un état local au composant.
### useStates
Gestion d'état local avec path notation.
```
import { useStates } from '@cap-rel/smartcommon';
const st = useStates({
initialStates: {
count: 0,
user: { name: '', email: '' },
items: []
},
debug: true
});
// Lire
st.get('count'); // 0
st.get('user.name'); // ''
st.get('items[0]'); // undefined
// Écrire
st.set('count', 1);
st.set('user.name', 'John');
st.set('items[]', { id: 1 }); // Push dans le tableau
// Écrire avec fonction
st.set('count', prev => prev + 1);
// Supprimer
st.unset('user.email');
st.unset('items[0]');
// Accès direct
const { count, user, items } = st.values;
```
### useForm
Gestion de formulaires avec état et erreurs.
```
import { useForm } from '@cap-rel/smartcommon';
const form = useForm({
defaultValues: {
name: '',
email: ''
},
debug: true
});
// Lire les valeurs
const name = form.get('values.name');
// Définir un champ avec validation
form.setField({
name: 'email',
value: 'test@example.com',
errors: {
required: { condition: !value },
format: { condition: !isValidEmail(value) }
}
});
// Vérifier les erreurs
const hasEmailError = form.get('errors.email.required');
// Accès direct
const { values, errors, isFormSubmitting, isFormSubmitted } = form;
```
### useDb
Base de données IndexedDB via Dexie avec logging automatique.
```
import { useDb } from '@cap-rel/smartcommon';
const db = useDb({
name: 'myApp',
version: 1,
stores: {
items: 'id++, name, category, createdAt',
categories: 'id++, name'
},
debug: true
});
// CRUD via Dexie
await db.items.add({ name: 'Item 1' });
const all = await db.items.toArray();
await db.items.update(id, { name: 'Updated' });
await db.items.delete(id);
```
Ajoute automatiquement ''createdAt'', ''updatedAt'' et une table ''logs''.
Voir [[stockage_de_donnees|Stockage de données]] pour plus de détails.
Pour un cache API avec stratégies, préférez ''useCachedQuery''. Pour la synchronisation offline, utilisez ''useSyncClient''.
### useCachedQuery
Cache de données avec stratégies réseau/cache.
```
import { useCachedQuery } from '@cap-rel/smartcommon';
const { data, isLoading, isFromCache, isStale, error, refetch, invalidate } = useCachedQuery({
db: dexieInstance, // instance Dexie
store: 'items', // nom du store
key: 'items-list', // clé de cache
fetchFn: () => api.private.get('items').json(), // fonction de fetch
strategy: 'network-first', // 'network-first' | 'cache-first' | 'swr'
ttl: 3600000, // durée de vie du cache (1h)
staleTime: 60000, // seuil de péremption (1min)
enabled: true // activer/désactiver
});
```
Stratégies disponibles :
^ Stratégie ^ Description ^
| ''network-first'' | Réseau en priorité, cache en fallback si erreur |
| ''cache-first'' | Cache en priorité si valide, sinon réseau |
| ''swr'' | Affiche le cache immédiatement, revalide en arrière-plan |
Voir [[stockage_de_donnees|Stockage de données]] pour plus de détails.
### useOnlineStatus
Détection de la connexion réseau avec health check optionnel.
```
import { useOnlineStatus } from '@cap-rel/smartcommon';
const { isOnline, isServerReachable, lastOnline, checkNow } = useOnlineStatus({
healthCheckUrl: '/api/health',
healthCheckInterval: 30000,
stabilityDelay: 2000,
timeout: 5000,
});
```
### useAuthenticatedImage
Chargement d'images authentifiées avec cache IndexedDB.
```
import { useAuthenticatedImage } from '@cap-rel/smartcommon';
const { src, isLoading, isFromCache, error } = useAuthenticatedImage({
db: db.instance, // instance Dexie
url: `/api/users/${id}/photo`,
token: accessToken,
ttl: 86400000, // durée de cache: 24h
staleTime: 3600000, // stale après 1h (refresh en arrière-plan)
placeholder: '/images/default.png',
});
return ;
```
## Hooks utilitaires
### useIntl
Formatage de dates et nombres avec l'API Intl.
```
import { useIntl } from '@cap-rel/smartcommon';
const intl = useIntl();
// Formater une date
const formatted = intl.DateTimeFormat(Date.now());
// "11/01/2025, 14:30:00"
// Avec options personnalisées
const dateOnly = intl.DateTimeFormat(Date.now(), 'fr-FR', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
// "11 janvier 2025"
```
### useAnimation
Gestion d'animations avec Framer Motion.
```
import { useAnimation } from '@cap-rel/smartcommon';
const { start, animations, setAnimations } = useAnimation({
fadeIn: { value: false, state: null },
slideIn: { value: false, state: null }
});
// start devient true après le premier rendu
// Utilisez-le pour déclencher des animations d'entrée
useEffect(() => {
if (start) {
setAnimations(prev => ({
...prev,
fadeIn: { ...prev.fadeIn, state: 'visible' }
}));
}
}, [start]);
```
### useFile
Utilitaires pour la gestion de fichiers.
```
import { useFile } from '@cap-rel/smartcommon';
const { resizeImage } = useFile();
// Redimensionner une image
const handleFileChange = async (e) => {
const file = e.target.files[0];
const base64 = await resizeImage(file, {
maxWidth: 1920,
maxHeight: 1080,
quality: 85
});
console.log(base64); // data:image/jpeg;base64,...
};
```
### useVariantMerger
Fusion de props avec variants de composants (usage interne principalement).
```
import { useVariantMerger } from '@cap-rel/smartcommon';
const MyComponent = (props) => {
const { variantProps, mergeProps, mergeQuickProps, setParams } = useVariantMerger('MyComponent', props);
return (
({
...p,
className: `base-class ${p.className || ''}`
}))}>
{variantProps.children}
);
};
```
^ Propriété ^ Type ^ Description ^
| ''variantProps'' | object | Props fusionnées depuis le thème global + variant + props |
| ''mergeProps'' | function | ''mergeProps(key, fn)'' : fusionne les props d'un élément/sous-composant |
| ''mergeQuickProps'' | function | ''mergeQuickProps(props, keys)'' : extrait un sous-ensemble de variantProps |
| ''setParams'' | function | ''setParams(params)'' : définit des paramètres dynamiques pour les fonctions className |
### useListDnD
Drag and drop pour listes (réordonnancement). Prend en paramètre la fonction ''set'' de ''useStates''.
```
import { useStates, useListDnD } from '@cap-rel/smartcommon';
const st = useStates({
initialStates: {
items: [{ id: 1, label: 'A' }, { id: 2, label: 'B' }],
dragIndex: null,
}
});
const { onDragStart, onDragOver, onDrop } = useListDnD(st.set);
// Utilisation sur chaque élément de liste
{st.get('items').map((item, index) => (
onDragStart(e, 'dragIndex', 'items')}
onDragOver={(e) => onDragOver(e, 'dragIndex', index, 'items', st.get('items'))}
onDrop={() => onDrop('dragIndex')}
>
{item.label}
))}
```
Paramètres des callbacks :
^ Callback ^ Paramètres ^ Description ^
| ''onDragStart'' | ''(e, indexLabel, parent)'' | ''indexLabel'' : clé d'état pour l'index glissé |
| ''onDragOver'' | ''(e, indexLabel, index, listLabel, list)'' | Réordonne la liste en temps réel |
| ''onDrop'' | ''(indexLabel)'' | Réinitialise l'index à null |
### useCalculator
Contrôle programmatique du composant ''Calculator'' (nécessite un ''Calculator'' dans l'arbre de composants).
```
import { useCalculator, Calculator } from '@cap-rel/smartcommon';
const MyComponent = () => {
const { isOpen, open, close, toggle } = useCalculator();
return (
<>
open((result) => console.log('Résultat:', result))}>
Ouvrir la calculatrice
>
);
};
```
^ Propriété ^ Type ^ Description ^
| ''isOpen'' | boolean | État d'ouverture de la calculatrice |
| ''open'' | function | ''open(onResult?)'' : ouvre la calculatrice avec callback optionnel |
| ''close'' | function | Ferme la calculatrice |
| ''toggle'' | function | Bascule l'ouverture/fermeture |
### useWindow
Informations sur la fenêtre du navigateur.
```
import { useWindow } from '@cap-rel/smartcommon';
const { orientation, windowDimension, scroll, darkMode } = useWindow();
// Dimensions
const { w, h } = windowDimension;
// Orientation : 'landscape' | 'portrait'
console.log(orientation);
// Position de scroll
const { x, y } = scroll;
// Mode sombre du système : true | false
console.log(darkMode);
```
### useIsDesktop
Détection responsive desktop/mobile.
```
import { useIsDesktop } from '@cap-rel/smartcommon';
const isDesktop = useIsDesktop();
if (isDesktop) {
return ;
}
return ;
```
### useStatesWorking
Gestion d'état local simplifiée avec paths imbriqués.
```
import { useStatesWorking } from '@cap-rel/smartcommon';
const { states, set, get, unset } = useStatesWorking({
count: 0,
user: { name: '', email: '' }
});
// Lire
get('user.name');
// Écrire (path notation)
set('user.name', 'John');
set('items[0]', { id: 1 });
set('items.[]', newItem); // Push dans le tableau
// Supprimer
unset('user.email');
```
Similaire à ''useStates'' mais avec une API plus directe : les valeurs initiales sont passées directement, sans wrapper ''initialStates''.
### useSyncClient
Synchronisation offline/online avec gestion de conflits.
```
import { useSyncClient } from '@cap-rel/smartcommon';
const sync = useSyncClient({
apiUrl: import.meta.env.VITE_API_URL,
getAccessToken: () => api.accessToken,
scope: ['items', 'categories']
});
// État de connexion
const { isOnline, isServerReachable } = sync;
// État de synchronisation
const { isInitialized, isSyncing, pendingCount, conflictsCount, lastSyncTime, syncError } = sync;
// Opérations CRUD locales (fonctionnent hors-ligne)
await sync.create('items', { ref: 'IT-001', label: 'Item 1' });
await sync.update('items', id, { label: 'Item modifié' });
await sync.remove('items', id);
await sync.upsert('items', { id, label: 'Créer ou modifier' });
// Lecture locale
const item = await sync.getEntity('items', id);
const items = await sync.queryEntities('items', { category: 'A' });
// Synchronisation manuelle
await sync.sync(); // Push + Pull
await sync.push(); // Envoyer les changements locaux
await sync.pull(); // Récupérer les changements serveur
// Gestion des conflits
const conflicts = await sync.getConflicts();
await sync.resolveConflict(conflictId, 'client'); // 'client' | 'server' | mergedData
// Enregistrement de l'appareil
await sync.register({ deviceName: 'Mon téléphone' });
// Réinitialisation
await sync.reset();
```
Voir [[:03_front:synchronisation|Synchronisation]] pour plus de détails.
## Tableau récapitulatif
^ Hook ^ Catégorie ^ Description ^
| ''useApi'' | Global | Appels API avec auth JWT |
| ''useGlobalStates'' | Global | État global persistant |
| ''useNavigation'' | Global | Navigation react-router |
| ''useLibConfig'' | Global | Configuration de l'app |
| ''useConfirm'' | Global | Dialogues de confirmation |
| ''usePWAUpdate'' | Global | Mises à jour PWA |
| ''useStates'' | Local | État local avec path notation |
| ''useStatesWorking'' | Local | État local simplifié avec paths |
| ''useForm'' | Local | Gestion de formulaires |
| ''useCachedQuery'' | Local | Cache de données avec stratégies |
| ''useOnlineStatus'' | Local | Détection connexion réseau |
| ''useAuthenticatedImage'' | Local | Images authentifiées avec cache |
| ''useSyncClient'' | Sync | Synchronisation offline/online |
| ''useIntl'' | Utilitaire | Formatage dates/nombres |
| ''useAnimation'' | Utilitaire | Animations Framer Motion |
| ''useFile'' | Utilitaire | Manipulation de fichiers |
| ''useVariantMerger'' | Utilitaire | Fusion de variants |
| ''useCalculator'' | Utilitaire | Contrôle du composant Calculator |
| ''useListDnD'' | Utilitaire | Drag and drop |
| ''useWindow'' | Utilitaire | Infos fenêtre/orientation/scroll |
| ''useIsDesktop'' | Utilitaire | Détection desktop/mobile |
## Voir aussi
* [[smartcommon|SmartCommon]] - Liste des composants
* [[requetes_api|Requêtes API]] - Documentation détaillée useApi
* [[stockage_de_donnees|Stockage de données]] - Documentation détaillée stockage