Components
TiptapEditor
Editor WYSIWYG rich-text basato su Tiptap con toolbar integrata e output configurabile in HTML, JSON o Markdown.
Panoramica
TiptapEditor è un editor rich-text basato su Tiptap con caricamento lazy delle dipendenze. Fornisce una toolbar integrata per la formattazione testo e supporta tre formati di output: HTML, JSON e Markdown.
Funzionalità della toolbar:
- H2 — Intestazione livello 2
- Grassetto —
**testo** - Corsivo —
*testo* - Lista puntata — Elenco non ordinato
- Lista numerata — Elenco ordinato
- Citazione — Blockquote
Le dipendenze Tiptap vengono caricate in modo asincrono al mount del componente; durante il caricamento viene mostrato un indicatore di stato.
Sicurezza: L'output HTML non è sanitizzato. Se si utilizza
v-htmlper renderizzare il contenuto, sanitizzare con DOMPurify per prevenire XSS.
Casi d'uso tipici: descrizioni prodotti, contenuti articoli, note tecniche, documentazione interna, messaggi con formattazione.
Anteprima live
Prerequisiti
Installare le peer dependencies:
npm install @tiptap/vue-3 @tiptap/starter-kit
# Opzionale, per output Markdown avanzato:
npm install turndown
Utilizzo nello schema
const schema = [{
name: 'descrizione',
type: 'tiptap',
label: 'Descrizione prodotto',
props: {
outputFormat: 'html',
placeholder: 'Inserisci una descrizione dettagliata...',
}
}, {
name: 'contenutoJson',
type: 'tiptap',
label: 'Contenuto strutturato',
props: {
outputFormat: 'json',
}
}, {
name: 'readme',
type: 'tiptap',
label: 'README',
props: {
outputFormat: 'markdown',
helperText: 'Il contenuto sarà convertito in Markdown',
}
}]
Utilizzo diretto
<TiptapEditor
v-model="contenutoArticolo"
output-format="html"
label="Contenuto articolo"
placeholder="Scrivi il tuo articolo..."
/>
Output JSON (per salvataggio strutturato)
<TiptapEditor
v-model="documentoJson"
output-format="json"
label="Documento"
helper-text="Il contenuto viene salvato come JSON strutturato"
/>
Output Markdown
<TiptapEditor
v-model="readmeContent"
output-format="markdown"
label="Note tecniche"
/>
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
modelValue | string | '' | Contenuto dell'editor (v-model); formato dipende da outputFormat |
label | string | — | Etichetta del campo |
helperText | string | — | Testo di supporto sotto il campo |
error | string | — | Messaggio di errore (attiva stato invalid) |
disabled | boolean | false | Disabilita l'editor e i pulsanti toolbar |
invalid | boolean | false | Attiva visivamente lo stato di errore |
outputFormat | 'html' | 'json' | 'markdown' | 'html' | Formato del valore emesso da update:modelValue |
placeholder | string | — | Testo placeholder nell'area di testo |
Eventi
| Evento | Payload | Descrizione |
|---|---|---|
update:modelValue | string | Contenuto aggiornato nel formato specificato da outputFormat |
Note sui formati di output
| Formato | Tipo valore | Note |
|---|---|---|
'html' | Stringa HTML | Sanitizzare prima di usare con v-html |
'json' | Stringa JSON | JSON.stringify() del documento Tiptap; usare JSON.parse() per leggere |
'markdown' | Stringa Markdown | Conversione semplice; per Markdown completo installare turndown |
Validazione suggerita
import { z } from 'zod'
const schema = z.object({
// HTML: verifica che non sia vuoto o solo tag vuoti
descrizione: z.string()
.min(1, 'La descrizione è obbligatoria')
.refine(
html => html.replace(/<[^>]+>/g, '').trim().length > 0,
'La descrizione non può essere vuota'
),
// JSON: verifica struttura valida
contenutoJson: z.string()
.refine(str => {
try { JSON.parse(str); return true } catch { return false }
}, 'Formato JSON non valido'),
})