Démo interactive
21 templates à charger dans l'éditeur
Article de blog
Titre, intro, liste à puces, blockquote et section code. Structure éditoriale classique.
Newsletter mensuelle
Header coloré, mise en page 2 colonnes (contenu + sidebar chiffres), bouton CTA.
Pipeline CI/CD
Flowchart LR complet : lint → tests → build → Docker → staging → approval → prod.
Flux Auth OAuth2
Diagramme de séquence : Frontend → API Gateway → Auth Service → Redis Cache.
Planning Gantt Q2
Roadmap 4 sprints avec tâches done/active/à venir et milestone de release.
Grille Pricing
3 colonnes flexbox (Starter / Pro / Enterprise) avec tarifs, features et CTA différenciés.
Rapport Dashboard
KPIs en 4 colonnes, pie chart sources de trafic, tableau top pages avec métriques.
Documentation API
Référence technique avec blocs code, tableau de props, notes blockquote et exemples.
Workflow commande
State diagram du cycle de vie e-commerce : panier → paiement → expédition → retour.
Schéma BDD SaaS
Diagramme ER multi-tenant : Organization → Workspace → Project + Users + AuditLog.
Menu gastronomique
Carte élégante avec photos Unsplash, entrées / plats / desserts, mise en page colonnes.
Bistrot parisien
Carte brasserie avec formule du jour, tableau de prix, galerie desserts et photos.
Physique — Équations fondamentales
E=mc², équation de Schrödinger, équations de Maxwell. Formules en mode bloc et inline.
Mathématiques — Analyse
Série de Taylor, intégrale de Gauss, formule d'Euler. Mix bloc / inline dans le texte.
Statistiques & Machine Learning
Distribution normale, régression linéaire, gradient descent — avec formules et explications.
Architecture microservices
Schéma d'architecture avec API Gateway, services, bases de données et queues de messages.
Wireframe landing page
Maquette basse fidélité avec header, hero, features, pricing et footer.
Mind map — Stratégie produit
Carte mentale avec branches : Vision, Roadmap, Personas, KPIs, Risques.
User flow — Onboarding
Parcours utilisateur de l'inscription à l'activation du compte, avec décisions et étapes.
Board Kanban Sprint
Tableau Kanban avec colonnes Todo / In Progress / Review / Done et cartes de tâches.
Sushi Bar japonais
Menu épuré dark-mode avec plateaux, ramen, photos de plats et section livraison.
Flux facturation électronique
Cycle de vie complet d'une facture : création, validation, envoi, paiement, relance — diagramme Mermaid interactif.
Processus commande B2B
Séquence complète Client → Commercial → ERP → Entrepôt → Logistique avec échanges de messages et validations.
Pipeline livraison e-commerce
Flux de traitement d'une commande en ligne : panier, paiement, préparation, expédition, livraison, retour.
Analyse de signal — Mix complet
Transformée de Fourier en KaTeX, pipeline FFT en Mermaid et signal sinusoïdal dessiné en SVG natif.
Carte de visite numérique
Profil dev avec 3 QR codes générés à la volée — site web, GitHub, npm. Éditable en un clic.
Presets toolbar — reconfigurer l'éditeur à la volée
Chaque preset correspond à une configuration toolbar utilisée dans l'ERP Adliss.
🚀 Installation
npm install @synapxlab/wysiwyg
yarn add @synapxlab/wysiwyg
Modules optionnels :
# Diagrammes Mermaid
npm install mermaid
# Formules mathématiques KaTeX
npm install katex
# Dessins Excalidraw (nécessite React 18)
npm install @excalidraw/excalidraw react react-dom --legacy-peer-deps
Ou via CDN (ESM) :
<script type="module">
import { WysiwygEditor } from 'https://cdn.jsdelivr.net/npm/@synapxlab/wysiwyg/dist/wysiwyg.es.js';
import 'https://cdn.jsdelivr.net/npm/@synapxlab/wysiwyg/dist/style.css';
</script>
⚡ Démarrage rapide
import { WysiwygEditor } from '@synapxlab/wysiwyg';
import '@synapxlab/wysiwyg/style.css';
const editor = new WysiwygEditor({
upload: async (file) => {
const fd = new FormData();
fd.append('file', file);
return (await (await fetch('/upload', { method:'POST', body:fd })).json()).url;
},
});
document.getElementById('app').appendChild(editor.el);
editor.setValue('<p>Bonjour <strong>monde</strong></p>');
editor.onChange = () => console.log(editor.getValue());
const { WysiwygEditor } = require('@synapxlab/wysiwyg');
const editor = new WysiwygEditor();
document.getElementById('app').appendChild(editor.el);
🔧 Options toolbar
Tous les groupes sont activés par défaut. Passez false pour désactiver.
new WysiwygEditor({
toolbar: { mermaid: true, math: true, draw: true, excalidraw: true, twig: false }, // opt-in
wordCount: true,
upload: async (file: File) => 'https://…/url.jpg',
mermaid: mermaidInstance, // requis si toolbar.mermaid: true
katex: katexInstance, // requis si toolbar.math: true
excalidraw: { Excalidraw, exportToSvg, React, ReactDOM }, // requis si toolbar.excalidraw: true
});
{
source, formatHtml, history, fullscreen,
lists, align, direction,
link, image, table, grid,
heading, font, textColor,
blockquote, divider, specialChars,
mermaid, // opt-in — passer opts.mermaid aussi
math, // opt-in — passer opts.katex aussi
draw, // opt-in — éditeur vectoriel natif, zéro dépendance
excalidraw, // opt-in — passer opts.excalidraw aussi
twig, // opt-in — 27 snippets Twig prêts
}
🎯 Intention de sortie (HTML / PDF)
L'option intent: 'html' | 'pdf' de WysiwygOptions indique à l'éditeur l'usage auquel le résultat de getValue() est destiné.
intent: 'pdf'optimise le HTML pour wkhtmltopdf, dompdf et mPDF : les tableaux utilisent des largeurs figées en centimètres avectable-layout:fixed, les conteneurs de défilement responsive sont retirés et la propriété CSSvertical-alignest aussi écrite dans l'attribut HTMLvalign, pour les moteurs qui ignorent parfois ce style sur les cellules.intent: 'html', valeur par défaut, enveloppe les tableaux à largeur fixe dans un conteneur à défilement horizontal pour préserver un affichage responsive dans le navigateur, puis nettoie les attributs parasites superflus.
Sécurité Twig : le code Twig présent dans le contenu — {% %} et {{ }} — n'est jamais transformé ni altéré par la normalisation, quelle que soit l'intention choisie.
editor.getRawValue() retourne le HTML brut, sans aucune normalisation d'intention. Utilisez-le pour sauvegarder une version source indépendante du rendu final.
Pour une normalisation manuelle hors de l'éditeur, le package exporte applyIntent(html, intent), normalizeForPdf(html), normalizeForHtml(html) et le type WysiwygIntent.
import {
WysiwygEditor,
applyIntent,
normalizeForPdf,
normalizeForHtml,
} from '@synapxlab/wysiwyg';
import type { WysiwygIntent } from '@synapxlab/wysiwyg';
const editor = new WysiwygEditor({ intent: 'pdf' });
const pdfHtml = editor.getValue(); // HTML normalisé pour le PDF
const sourceHtml = editor.getRawValue(); // HTML brut
const intent: WysiwygIntent = 'pdf';
const manualPdf = applyIntent(sourceHtml, intent);
const pdfOnly = normalizeForPdf(sourceHtml);
const htmlOnly = normalizeForHtml(sourceHtml);
🧰 Presets
WYSI_PRESETS est un dictionnaire de configurations de toolbar prêtes à l'emploi, conçues pour les cas d'usage courants :
product— fiches produit e-commerce, avec un formatage minimal : texte, gras, italique, liens et listes.mini— éditeur ultra-léger pour les libellés et descriptions courtes.small— usage rédactionnel courant, avec un bon compromis entre légèreté et fonctionnalités.bill— facturation et sortie PDF, avec tableaux et mise en page figée.pdf— documents PDF complets, notamment les contrats, devis et rapports, avec une toolbar riche orientée impression.entity— templates Twig pour les entités métier d'un ERP ou CRM : variables, boucles et conditions.full— toutes les fonctionnalités activées, sans restriction.
resolvePreset(nom, surcharges?) retourne un objet WysiwygOptions prêt à fournir au constructeur et fusionne le preset choisi avec les surcharges optionnelles. Pour une configuration très ciblée, toolbarOnly(...clés) construit un WysiwygToolbarConfig qui n'active que les groupes indiqués.
import {
WysiwygEditor,
WYSI_PRESETS,
resolvePreset,
toolbarOnly,
} from '@synapxlab/wysiwyg';
const editor = new WysiwygEditor(
resolvePreset('pdf', { statusbarLabel: 'Devis' }),
);
const customToolbar = toolbarOnly('bold', 'italic', 'link');
console.log(WYSI_PRESETS.pdf, customToolbar);
📖 API publique
editor.getValue(): string // HTML courant
editor.setValue(html: string) // Injecter du contenu
editor.focus(): void // Placer le curseur
editor.onChange?: () => void // Appelé à chaque modif
editor.el: HTMLElement // Élément racine à monter
Note : editor.el doit être monté dans le DOM avant d'appeler setValue().
Types TypeScript
import type { WysiwygOptions, WysiwygToolbarConfig } from '@synapxlab/wysiwyg';
🧩 Mermaid (opt-in)
Injectez votre propre instance Mermaid v10+. Zéro impact bundle si non utilisé.
import mermaid from 'mermaid';
mermaid.initialize({ startOnLoad: false });
new WysiwygEditor({ mermaid, toolbar: { mermaid: true } });
- Flowchart, sequence, gantt, pie, stateDiagram, erDiagram
- Cliquez un diagramme existant pour le ré-éditer
- Erreurs affichées inline dans la modale
- Blocs
```mermaid```dans le source HTML strippés automatiquement
∑ KaTeX — Formules mathématiques (opt-in)
Injectez votre propre instance KaTeX. Zéro impact bundle si non utilisé. Chargez le CSS KaTeX séparément.
import katex from 'katex';
import 'katex/dist/katex.min.css';
new WysiwygEditor({ katex, toolbar: { math: true } });
- Cliquez le bouton Σ → saisissez la formule LaTeX (ex.
\frac{a}{b}) - Mode bloc (centré,
$$...$$) ou mode inline (dans le texte,$...$) - Les délimiteurs
$$...$$/$...$sont retirés automatiquement - Cliquez une formule existante → rouvre la modale avec le code pré-rempli
- Stocké sous
<div|span class="be-math" data-math-code="...">
🖊️ Éditeur vectoriel natif (opt-in)
Dessinez et annotez directement dans le contenu. L'éditeur SVG est désormais un package autonome — installez-le séparément puis injectez-le comme dépendance.
Installation
npm install @synapxlab/draw
Intégration
import { WysiwygEditor } from '@synapxlab/wysiwyg';
import { DrawEditor } from '@synapxlab/draw';
import '@synapxlab/draw/style.css';
new WysiwygEditor({
draw: DrawEditor,
toolbar: { draw: true },
});
- 7 outils — sélection, crayon, rectangle, ellipse, ligne, flèche, texte multiligne
- Sélection → 8 poignées de redimensionnement + rotation libre
- Support tactile — fonctionne sur tablette et mobile
- Double-clic sur un texte → édition en place
- Panneau propriétés : couleur, arrière-plan, style texte, transparence, z-order
- Annuler
Ctrl+Z, supprimerSuppr - Clic sur un dessin inséré → panneau style + bouton Modifier le dessin
▣ QR Code (opt-in)
Insérez et modifiez des QR codes SVG directement dans le contenu — couleurs, taille, correction d'erreur. Basé sur @synapxlab/qrcode, zéro dépendance runtime.
Installation
npm install @synapxlab/qrcode
Intégration
import { WysiwygEditor } from '@synapxlab/wysiwyg';
import { QRCode } from '@synapxlab/qrcode';
new WysiwygEditor({
qrcode: QRCode,
toolbar: { qrcode: true },
});
- Génération SVG inline — retaillable à l'infini, zéro canvas
- Couleur des modules, couleur de fond, marge, niveau de correction L/M/Q/H
- Clic sur un QR inséré → modale de modification (toutes les options)
- Données stockées en
data-qr-*— re-générables côté serveur
🔊 Lecture audio
Le bouton de toolbar audio, actif par défaut, lit à voix haute la sélection courante ou, si aucun texte n'est sélectionné, l'ensemble du contenu de l'éditeur. Un second clic arrête immédiatement la lecture en cours.
Le bouton est automatiquement masqué lorsque l'API Web Speech Synthesis n'est pas disponible dans le navigateur : aucune configuration de compatibilité n'est nécessaire. L'option lang accepte un code de langue BCP 47, par exemple fr-FR ou en-US, afin de forcer la langue de synthèse.
La classe exportée SpeechReader peut aussi être utilisée indépendamment de l'éditeur. Elle expose speak(texte), stop(), toggle(texte), l'événement onStateChange et la méthode statique SpeechReader.isSupported().
import { WysiwygEditor, SpeechReader } from '@synapxlab/wysiwyg';
const editor = new WysiwygEditor({
lang: 'fr-FR',
toolbar: { audio: true },
});
if (SpeechReader.isSupported()) {
const reader = new SpeechReader();
reader.onStateChange = (isSpeaking) => console.log(isSpeaking);
reader.speak('Bonjour depuis SynapxLab.');
reader.toggle('Un second appel bascule entre lecture et arrêt.');
reader.stop();
}
🌿 Twig snippets (opt-in)
Activez le panneau de snippets Twig pour insérer rapidement des variables, structures et filtres dans le contenu. Les snippets sont insérés en texte brut — traités nativement par votre moteur Twig côté serveur.
new WysiwygEditor({
toolbar: { twig: true },
});
- Cliquez le bouton { } → panneau latéral avec snippets groupés par catégorie
- 6 catégories intégrées : Variable, Structure, Filtre, Client, Facture, Système
- Coloration syntaxique Twig en mode source (variables
{{ }}et blocs{% %}) - Snippets personnalisés injectables via
twigSnippets: [ { cat, label, code } ]
Variables & structures
Accès aux données du contexte, conditions et boucles :
{{ customer.company }} {# Société #}
{{ invoice.date|date('d/m/Y') }} {# Date formatée #}
{{ invoice.total_ttc|number_format(2, ',', ' ') }} €
{% if invoice.status == 'PAID' %}
Facture réglée ✓
{% else %}
En attente de paiement
{% endif %}
{% for line in invoice.lines %}
{{ line.label }} — {{ line.qty }} × {{ line.unit_price }} €
{% endfor %}
Filtres natifs Twig
{{ texte|upper }} {# MAJUSCULES #}
{{ texte|lower }} {# minuscules #}
{{ texte|nl2br }} {# Sauts de ligne →
#}
{{ variable|default('N/A') }} {# Valeur par défaut #}
{{ tableau|length }} {# Nombre d'éléments #}
{{ date|date('d/m/Y') }} {# Format date #}
{{ nombre|number_format(2,',',' ') }} {# 1 234,56 #}
Filtres d'extension Twig personnalisés
Injectez vos propres filtres métier via twigSnippets — ils restent dans votre projet et ne sont pas embarqués dans le package :
{# Montant en lettres → "MILLE DEUX CENTS EUROS" #}
{{ invoice.total_ttc|asLetters }}
{# Date en lettres → "le 24 mars 2026" #}
{{ invoice.date|asLetters }}
{# Expressions de date dynamiques résolues à l'exécution #}
{{ "Rapport de {{mount/year}}"|dateExpression(invoice.date) }}
{# → "Rapport de Mars 2026" #}
{# Traduction de valeurs BDD (DRAFT, PAID, BANK_TRANSFER…) #}
{{ "Statut : {{status}}"|Expression('status', invoice.status) }}
{# → "Statut : Payé" #}
{# JSON sécurisé pour attributs HTML #}
{# Traduction i18n #}
{{ __('invoice.title') }}
Injection de snippets personnalisés
Passez vos filtres métier via l'option twigSnippets — chaque entrée a une catégorie, un libellé et le code à insérer :
new WysiwygEditor({
toolbar: { twig: true },
twigSnippets: [
{ cat: 'Mon ERP', label: '|asLetters', code: 'montant en lettres' },
{ cat: 'Mon ERP', label: '|dateExpression', code: 'expression de date' },
{ cat: 'Mon ERP', label: '|jsonAttr', code: 'json pour attribut HTML' },
],
});
🎨 Thème CSS vars
Toutes les couleurs dans des variables CSS scopées à .be-wysiwyg.
.be-wysiwyg {
--be-primary: #4f46e5;
--be-bg: #f8f9fa;
--be-surface: #ffffff;
--be-border: #e5e7eb;
--be-text: #111827;
--be-radius: 6px;
--be-font: system-ui, sans-serif;
--be-font-mono: 'Courier New', monospace;
}
.be-wysiwyg {
--be-primary: #6366f1;
--be-bg: #0f172a;
--be-surface: #1e293b;
--be-border: #334155;
--be-text: #f1f5f9;
}
🧩 Addons WordPress & PrestaShop
Un plugin WordPress et un module PrestaShop prêts à l'emploi sont disponibles dans le dossier addons/ du dépôt GitHub @synapxlab/wysiwyg. Ils permettent d'intégrer l'éditeur sans écrire de JavaScript.
La commande suivante génère les deux archives ZIP prêtes à installer :
npm run package:addons
Dans le HTML, ajoutez la classe synapxlab-wysiwyg à un <textarea>. L'addon le détecte automatiquement et instancie l'éditeur à sa place. Les attributs data-preset, data-intent, data-height et data-label règlent respectivement le preset, l'intention html ou pdf, la hauteur en pixels et le libellé de la barre de statut.
<textarea
class="synapxlab-wysiwyg"
data-preset="pdf"
data-intent="pdf"
data-height="520"
data-label="Devis"
></textarea>
Site sans bundler : le bundle IIFE dist/wysiwyg.global.js expose directement l'éditeur sous window.SynapxWysiwyg après son chargement avec une simple balise <script>.
👁 Rendu final
Le bouton Afficher sous l'éditeur ouvre une modale qui affiche le HTML généré en rendu final,
encapsulé dans un conteneur .wysiwyg_view.
Ce rendu correspond à un affichage dans une page HTML classique — identique à ce que produirait
$twig->createTemplate($html) côté serveur.
- ✅ Typographie complète : titres, paragraphes, listes, blockquote, code
- ✅ Tableaux avec zebra-stripes
- ✅ Diagrammes Mermaid (SVG inline)
- ✅ Formules KaTeX (HTML déjà rendu + CSS chargé)
- ✅ QR codes (SVG inline)
- ✅ Dessins vectoriels (SVG inline)
- ✅ Grilles flexbox et mises en page multi-colonnes
Pour intégrer le rendu dans votre projet, ajoutez la classe .wysiwyg_view sur le conteneur
qui reçoit le HTML, et chargez le CSS KaTeX si des formules mathématiques sont présentes.
<div class="wysiwyg_view">
</div>
// PHP
$twig->createTemplate($html);
🌐 Compatibilité
- ✅ Navigateurs modernes (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)
- ✅ Node.js ≥ 18 (SSR : importez, n'instanciez pas côté serveur)
- ✅ React, Vue, Angular, Svelte — montez
editor.eldans un ref/onMount - ✅ Vite, Webpack, Rollup, ESBuild
- ❌ IE11 non supporté
Licence
MIT — Utilisez, modifiez, redistribuez librement.
Code source : github.com/synapxLab/wysiwyg