Componenti React personalizzati
Definisci e usa componenti React personalizzati nei file MDX con rendering lato server, stile Tailwind e accesso ai componenti integrati Jamdesk.
Definisci componenti React personalizzati direttamente nei file MDX. Esporta un componente con funzione freccia in cima al file e usalo inline. I componenti vengono renderizzati lato server in fase di build. Possono usare qualsiasi componente integrato di Jamdesk e classi Tailwind.
Utilizzo di base
Definisci un componente usando export const in cima al file 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.
I nomi dei componenti devono usare PascalCase (iniziare con una lettera maiuscola).
Esempio: scheda hero
Questo esempio usa più prop e classi 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>
Utilizzo dei componenti integrati
I componenti personalizzati possono usare qualsiasi componente integrato di Jamdesk senza import:
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>
Componenti integrati per categoria:
| Categoria | Componenti |
|---|---|
| Callout | Note, Tip, Info, Warning, Check, Danger |
| Layout | Card, Columns, Tabs, Tab, Accordion, Steps, Step, View |
| Media | Frame, Icon, Badge, Tooltip |
| Codice | CodeGroup |
| Documentazione API | ParamField, ResponseField, Expandable |
Limitazioni
- Solo funzioni freccia: usa la sintassi
export const. La sintassiexport functionnon è supportata. - Nessun import: non puoi importare pacchetti esterni o altri file
- Nessun hook: gli hook di React (
useState,useEffect,useRef, ecc.) non sono disponibili. I componenti vengono renderizzati lato server durante la build. Gli hook funzionano solo lato client. Usa i file snippet per i componenti interattivi (vedi la risoluzione dei problemi qui sotto). - Solo lato server: i componenti vengono renderizzati lato server. Nessuna interattività lato client o gestore di eventi
- Solo Tailwind: applica lo stile con le classi di Tailwind CSS. CSS-in-JS non è disponibile
- Sintassi rigorosa: un errore di sintassi in un componente inline fa fallire la build con un messaggio di errore chiaro
- Nomi PascalCase: i nomi dei componenti devono iniziare con una lettera maiuscola e contenere solo lettere e numeri (niente underscore)
Hai bisogno di hook di React? I componenti inline non possono usare useState, useEffect o altri hook. Vengono renderizzati lato server durante la build. Crea un file snippet con la direttiva 'use client' per i componenti che necessitano di stato o effetti (vedi la sezione di risoluzione dei problemi qui sotto).
Best practice
I componenti inline dovrebbero essere presentazionali. Richiedi un componente integrato per la logica complessa.
Costruisci componenti accessibili con elementi HTML appropriati e attributi ARIA.
Visualizza in anteprima la documentazione in locale. Verifica che i componenti vengano renderizzati correttamente anche in modalità scura.
Risoluzione dei problemi
Errore: Expected component 'MyComponent' to be defined
Cause:
- Il nome del componente non usa PascalCase (deve iniziare con una lettera maiuscola)
- Errore di sintassi nella definizione del componente
- Tag o parentesi di chiusura mancanti
Soluzione: Verifica che il tuo export segua questo schema:
export const MyComponent = ({ prop }) => (
<div>{prop}</div>
);Errore: La build fallisce con un riferimento a Babel o alla sintassi JSX
Cause:
- Sintassi JSX non valida nel componente
- Tag o parentesi non chiusi
- Uso di funzionalità JavaScript non supportate
Soluzione: Verifica che il tuo JSX sia valido. Problemi comuni:
- Tutti i tag devono essere chiusi (
<img loading="lazy" />e non<img loading="lazy">) - Usa
classNameinvece diclass - Racchiudi più elementi in un frammento
<>...</>o in un elemento padre
Avviso: Inline component(s) override built-in: Note
Causa: Il tuo componente inline ha lo stesso nome di un componente integrato.
Soluzione: Rinomina il componente per evitare conflitti:
// Instead of: export const Note = ...
export const CustomNote = ({ children }) => (
<div className="my-note">{children}</div>
);Problema: Le classi Tailwind non funzionano
Cause:
- Uso di CSS-in-JS o di oggetti di stile inline (supporto limitato)
- Classe Tailwind non inclusa nella build
Soluzione: Usa le classi di utilità standard di Tailwind. Usa una prop style inline con valori semplici per gli stili personalizzati:
export const Highlight = ({ children }) => (
<span style={{ backgroundColor: '#ffeb3b' }}>{children}</span>
);Problema: Il componente definito con export function non viene renderizzato
Causa: È supportata solo la sintassi export const con funzione freccia.
Soluzione: Converti la funzione in sintassi a funzione freccia:
// Instead of:
export function MyComponent({ prop }) {
return <div>{prop}</div>;
}
// Use:
export const MyComponent = ({ prop }) => (
<div>{prop}</div>
);Problema: Un componente con underscore o caratteri speciali non funziona
Causa: I nomi dei componenti devono essere identificatori PascalCase validi (solo lettere e numeri).
Soluzione: Usa solo lettere e numeri nel nome del componente:
// Instead of: export const Hero_Card = ...
// Instead of: export const my-component = ...
export const HeroCard = ({ title }) => (
<div>{title}</div>
);Errore: ReferenceError: useState is not defined
Causa: Gli hook di React non sono disponibili nei componenti inline. I componenti inline vengono renderizzati lato server durante la build. Gli hook funzionano solo nei componenti React lato client.
Soluzione: Crea un file snippet per i componenti interattivi che necessitano di stato o effetti:
- Crea un file nella tua directory
/snippets(ad esempio/snippets/counter.tsx) - Aggiungi
'use client'in cima al file - Importa e usa il componente nel tuo 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 />