Composants React personnalisés
Créez des composants React personnalisés dans les fichiers MDX, avec rendu côté serveur, style Tailwind et accès aux composants Jamdesk intégrés.
Définissez des composants React personnalisés directement dans vos fichiers MDX. Exportez un composant sous forme de fonction fléchée en haut du fichier, puis utilisez-le en ligne. Les composants sont rendus côté serveur au moment du build, avec accès à tous les composants intégrés de Jamdesk et aux classes Tailwind.
Utilisation de base
Définissez un composant à l'aide d'export const en haut de votre fichier MDX :
export const Highlight = ({ children, color }) => (
<span style={{ backgroundColor: color, padding: '0.2em 0.4em', borderRadius: '4px' }}>
{children}
</span>
);
This text has a <Highlight color="#ffeb3b">yellow highlight</Highlight> in it.
Les noms de composants doivent utiliser le PascalCase (commencer par une majuscule).
Exemple : carte Hero
Voici un exemple plus complexe avec plusieurs props et classes Tailwind :
export const HeroCard = ({ title, description, href, icon }) => (
<a
href={href}
className="group block p-6 rounded-lg border border-gray-200 hover:border-blue-500 transition-colors"
>
<div className="flex items-center gap-3 mb-2">
<Icon icon={icon} />
<h3 className="font-semibold text-lg">{title}</h3>
</div>
<p className="text-gray-600">{description}</p>
</a>
);
<div className="grid grid-cols-2 gap-4">
<HeroCard
title="Getting started"
description="Learn the basics"
href="/quickstart"
icon="rocket"
/>
<HeroCard
title="Components"
description="Explore available components"
href="/components/overview"
icon="puzzle-piece"
/>
</div>
Utilisation des composants intégrés
Vos composants personnalisés ont accès à tous les composants intégrés de Jamdesk. Aucun import n'est nécessaire :
export const FeatureCard = ({ title, children }) => (
<Card title={title} icon="star">
{children}
<Tip>This tip is inside a custom component!</Tip>
</Card>
);
<FeatureCard title="My Feature">
<Note>Notes work inside custom components too!</Note>
</FeatureCard>
Composants intégrés par catégorie :
| Catégorie | Composants |
|---|---|
| Encadrés | Note, Tip, Info, Warning, Check, Danger |
| Mise en page | Card, Columns, Tabs, Tab, Accordion, Steps, Step, View |
| Médias | Frame, Icon, Badge, Tooltip |
| Code | CodeGroup |
| Documentation API | ParamField, ResponseField, Expandable |
Limitations
- Fonctions fléchées uniquement : utilisez la syntaxe
export const. La syntaxeexport functionn'est pas prise en charge. - Aucun import : vous ne pouvez pas importer de packages externes ou d'autres fichiers
- Aucun hook : les hooks React (
useState,useEffect,useRef, etc.) ne sont pas disponibles. Les composants sont rendus côté serveur pendant le build, et les hooks ne fonctionnent que côté client. Pour des composants interactifs, utilisez plutôt des fichiers snippet (voir le dépannage ci-dessous). - Côté serveur uniquement : les composants sont rendus sur le serveur ; aucune interactivité côté client ni gestionnaire d'événements
- Tailwind uniquement : utilisez des classes Tailwind CSS pour le style ; le CSS-in-JS n'est pas disponible
- Syntaxe stricte : les erreurs de syntaxe dans les composants inline feront échouer le build avec un message d'erreur clair
- Noms en PascalCase : les noms de composants doivent commencer par une majuscule et ne contenir que des lettres et des chiffres (pas de tirets bas)
Besoin des hooks React ? Les composants inline ne peuvent pas utiliser useState, useEffect ou d'autres hooks, car ils sont rendus sur le serveur pendant le build. Pour des composants interactifs nécessitant un état ou des effets, créez un fichier snippet avec la directive 'use client' (voir la section de dépannage ci-dessous).
Bonnes pratiques
Les composants inline doivent être présentationnels. Pour une logique complexe, demandez un composant intégré.
Assurez-vous que vos composants sont accessibles grâce à des éléments HTML appropriés et des attributs ARIA.
Prévisualisez votre documentation en local pour vérifier que les composants s'affichent correctement en mode clair et en mode sombre.
Dépannage
Erreur : Expected component 'MyComponent' to be defined
Causes :
- Le nom du composant n'utilise pas le PascalCase (doit commencer par une majuscule)
- Erreur de syntaxe dans la définition du composant
- Balise de fermeture ou parenthèse manquante
Solution : vérifiez que votre export suit ce modèle :
export const MyComponent = ({ prop }) => (
<div>{prop}</div>
);Erreur : le build échoue en mentionnant une syntaxe Babel ou JSX
Causes :
- Syntaxe JSX invalide dans votre composant
- Balises ou parenthèses non fermées
- Utilisation de fonctionnalités JavaScript non prises en charge
Solution : vérifiez que votre JSX est valide. Problèmes courants :
- Toutes les balises doivent être fermées (
<img loading="lazy" />et non<img loading="lazy">) - Utilisez
classNameau lieu declass - Enveloppez plusieurs éléments dans un fragment
<>...</>ou un élément parent
Avertissement : Inline component(s) override built-in: Note
Cause : votre composant inline porte le même nom qu'un composant intégré.
Solution : renommez votre composant pour éviter les conflits :
// Instead of: export const Note = ...
export const CustomNote = ({ children }) => (
<div className="my-note">{children}</div>
);Problème : les classes Tailwind ne fonctionnent pas
Causes :
- Utilisation de CSS-in-JS ou d'objets de style inline (support limité)
- Classe Tailwind non incluse dans le build
Solution : utilisez les classes utilitaires Tailwind standard. Pour des styles personnalisés, utilisez la prop style inline avec des valeurs simples :
export const Highlight = ({ children }) => (
<span style={{ backgroundColor: '#ffeb3b' }}>{children}</span>
);Problème : un composant défini avec export function ne s'affiche pas
Cause : seule la syntaxe de fonction fléchée export const est prise en charge.
Solution : convertissez votre fonction en syntaxe de fonction fléchée :
// Instead of:
export function MyComponent({ prop }) {
return <div>{prop}</div>;
}
// Use:
export const MyComponent = ({ prop }) => (
<div>{prop}</div>
);Problème : un composant avec des tirets bas ou des caractères spéciaux ne fonctionne pas
Cause : les noms de composants doivent être des identifiants PascalCase valides (lettres et chiffres uniquement).
Solution : utilisez uniquement des lettres et des chiffres dans le nom de votre composant :
// Instead of: export const Hero_Card = ...
// Instead of: export const my-component = ...
export const HeroCard = ({ title }) => (
<div>{title}</div>
);Erreur : ReferenceError: useState is not defined
Cause : les hooks React ne sont pas disponibles dans les composants inline. Les composants inline sont rendus côté serveur pendant le processus de build, et les hooks ne fonctionnent que dans les composants React côté client.
Solution : pour des composants interactifs nécessitant un état ou des effets, créez plutôt un fichier snippet :
- Créez un fichier dans votre répertoire
/snippets(par exemple,/snippets/counter.tsx) - Ajoutez
'use client'en haut du fichier - Importez-le et utilisez-le dans votre MDX
'use client';
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
}import { Counter } from '/snippets/counter';
<Counter />