@shane_donnelly/dsi-internal-react-utils
v1.0.0
Published
Librairie de composants et utilitaires React pour les projets front-end de la DSI.
Downloads
1,175
Readme
@shane_donnelly/dsi-internal-react-utils
Librairie de composants et utilitaires React pour les projets front-end de la DSI.
Installation
npm install @shane_donnelly/dsi-internal-react-utils keycloak-jsStyles
L'import du CSS est obligatoire pour charger les styles des composants :
import '@shane_donnelly/dsi-internal-react-utils/style.css'Prérequis
- Un serveur Keycloak configuré avec un realm, un client, et au moins un Identity Provider
Recommandé : utiliser react-router pour éviter de perdre l'état de la page lors des redirections d'authentification.
Modules
Keycloak
Wrapper de simplification pour keycloak-js. KeycloakProvider singleton à la racine, useKeycloakAuth pour accéder à l'état d'auth et déclencher login / logout depuis n'importe quel composant.
Documentation complète du module Keycloak
Chatbot UI
Ensemble de composants React pour créer des interfaces de type chatbot modernes (style ChatGPT / Claude / Gemini). Entièrement indépendant de la logique métier — gère uniquement l'affichage.
Composants disponibles :
| Composant | Description |
|-----------|-------------|
| MarkdownRenderer | Rendu markdown avec bouton copier sur les blocs de code |
| UserMessage | Bulle de message utilisateur avec slots typés optionnels |
| BotMessage | Message bot full-width, extensible via registry |
| SessionHistory | Affichage d'une conversation complète |
| InputBar | Barre d'input avec bouton "+", bouton d'action configurable et slots |
| SessionContainer | Composant tout-en-un : SessionHistory + InputBar |
Système de thème global via setTheme("light" | "dark" | ColorPalette).
Documentation complète du module Chatbot
Exemple complet avec React Router v7 (framework mode)
React Router v7 framework mode utilise app/root.tsx comme layout racine — c'est là que le KeycloakProvider doit être placé.
// app/root.tsx
import { Outlet } from 'react-router';
import { KeycloakProvider } from '@shane_donnelly/dsi-internal-react-utils';
import '@shane_donnelly/dsi-internal-react-utils/style.css';
const keycloakConfig = {
url: 'https://keycloak.example.com',
realm: 'my-realm',
clientId: 'my-frontend',
};
export default function Root() {
return (
<KeycloakProvider config={keycloakConfig} idpHint="oidc" refreshInterval={300}>
<Outlet />
</KeycloakProvider>
);
}// app/routes/profile.tsx
import { useEffect } from 'react';
import { useKeycloakAuth } from '@shane_donnelly/dsi-internal-react-utils';
export default function Profile() {
const { status, user, login, logout } = useKeycloakAuth();
useEffect(() => {
if (status === 'unauthenticated') {
login({ idpHint: 'oidc' });
}
}, [status, login]);
if (status === 'loading' || status === 'unauthenticated') return <p>Chargement...</p>;
if (status === 'error') return <p>Erreur d'authentification.</p>;
return (
<div>
<h1>Bienvenue {user?.name}</h1>
<p>Email : {user?.email}</p>
<button onClick={() => logout({ redirectUri: window.location.origin })}>
Se déconnecter
</button>
</div>
);
}Utiliser le token pour les appels API
import { useKeycloakAuth } from '@shane_donnelly/dsi-internal-react-utils';
function useAuthFetch() {
const { token } = useKeycloakAuth();
return (url: string, options?: RequestInit) =>
fetch(url, {
...options,
headers: {
...options?.headers,
Authorization: `Bearer ${token}`,
},
});
}Accéder à l'instance keycloak-js (usage avancé)
import { useKeycloakAuth } from '@shane_donnelly/dsi-internal-react-utils';
function AdvancedComponent() {
const { keycloak } = useKeycloakAuth();
// Accès direct à l'instance keycloak-js pour des cas spécifiques
console.log(keycloak?.tokenParsed);
}Fonctions utilitaires standalone
Deux fonctions sont disponibles pour manipuler l'instance Keycloak en dehors de React (intercepteurs HTTP, services, etc.) :
import { useKeycloakAuth, logoutKeycloak, refreshTokenKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
// Récupérer l'instance keycloak via useKeycloakAuth()
const { keycloak } = useKeycloakAuth();
// Rafraîchir le token (minValidity en secondes, défaut: 30)
const refreshed = await refreshTokenKeycloak(keycloak!, 60);
const freshToken = keycloak!.token;
// Déconnecter l'utilisateur (redirectUri optionnel, défaut: window.location.origin)
await logoutKeycloak(keycloak!);Exemple dans un intercepteur Axios :
import axios from 'axios';
import { logoutKeycloak, refreshTokenKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
import type Keycloak from 'keycloak-js';
function setupInterceptors(keycloak: Keycloak) {
axios.interceptors.request.use(async (config) => {
await refreshTokenKeycloak(keycloak, 60);
config.headers.Authorization = `Bearer ${keycloak.token}`;
return config;
});
axios.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
await logoutKeycloak(keycloak);
}
return Promise.reject(error);
},
);
}