Last active
March 23, 2025 14:32
-
-
Save SamuelChojnacki/9020fab53fa4acb11cb281507204d1a9 to your computer and use it in GitHub Desktop.
generate react component from json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// render-json.tsx | |
import React from "react"; | |
/** | |
* Interface pour un élément dans la structure JSON | |
*/ | |
interface ElementJson { | |
/** Type d'élément HTML (div, p, span, etc.) */ | |
type: string; | |
/** Attributs HTML et propriétés de l'élément */ | |
attr?: Record<string, string | number | boolean>; | |
/** Contenu texte ou tableau d'éléments enfants */ | |
content?: string | ElementJson[]; | |
/** Enfants du composant (alternative à content) */ | |
children?: ElementJson[]; | |
/** Clé optionnelle pour les listes d'éléments */ | |
key?: string; | |
} | |
/** | |
* Convertit un objet JSON en élément React compatible avec Tailwind CSS | |
* @param json Structure JSON du composant à rendre | |
* @returns Élément React généré | |
*/ | |
export function renderJson(json: ElementJson): React.ReactNode { | |
const { type, attr = {}, content, children, key } = json; | |
// Convertir les attributs HTML en attributs React | |
const reactAttrs: Record<string, any> = { key }; | |
// Traiter tous les attributs | |
const attrKeys = Object.keys(attr); | |
for (const attrName of attrKeys) { | |
const value = attr[attrName]; | |
// Convertir class en className pour React | |
if (attrName === "class") { | |
reactAttrs.className = value; | |
} | |
// Convertir for en htmlFor pour React | |
else if (attrName === "for") { | |
reactAttrs.htmlFor = value; | |
} | |
// Traiter les événements spéciaux (onClick, onChange, etc.) | |
else if (attrName.startsWith("on") && typeof value === "string") { | |
// Ignorer pour l'instant - peut être implémenté avec des gestionnaires d'événements personnalisés | |
// dans une version plus avancée | |
} | |
// Tous les autres attributs passent directement | |
else { | |
reactAttrs[attrName] = value; | |
} | |
} | |
// Préparer les enfants à rendre | |
const childElements: React.ReactNode[] = []; | |
// Si content est une chaîne, c'est le contenu principal | |
if (typeof content === "string") { | |
childElements.push(content); | |
} | |
// Si content est un tableau, traiter récursivement | |
else if (Array.isArray(content)) { | |
for (let index = 0; index < content.length; index++) { | |
const item = content[index]; | |
// Si c'est un élément JSON, le rendre récursivement | |
if (typeof item === "object" && item !== null) { | |
const itemWithKey = { | |
...item, | |
key: item.key || `content-${index}`, | |
}; | |
childElements.push(renderJson(itemWithKey)); | |
} else { | |
// Sinon c'est probablement une chaîne, l'ajouter directement | |
childElements.push(item); | |
} | |
} | |
} | |
// Traiter les enfants après le contenu principal | |
if (Array.isArray(children)) { | |
for (let index = 0; index < children.length; index++) { | |
const child = children[index]; | |
// Ajouter une clé si elle n'existe pas | |
const childWithKey = { | |
...child, | |
key: child.key || `child-${index}`, | |
}; | |
childElements.push(renderJson(childWithKey)); | |
} | |
} | |
// Créer l'élément React avec ses attributs et enfants | |
return React.createElement(type, reactAttrs, ...childElements); | |
} | |
/** | |
* Composant React qui utilise renderJson pour convertir un JSON en élément React | |
*/ | |
const JsonToElement: React.FC<{ json: ElementJson }> = ({ json }) => { | |
return <>{renderJson(json)}</>; | |
}; | |
export default JsonToElement; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment