Dokumentacja
KodifyEditor to headless, oparty na Reactcie edytor drag & drop. Jeden uniwersalny stan JSON zasila trzy renderery: stron WWW, maili HTML i dokumentów PDF.
Chcesz najpierw zobaczyć go w akcji? Otwórz interaktywne demo edytora →
Instalacja
Zainstaluj rdzeń oraz wybrane buildery przez swój menedżer pakietów. Zalecamy pnpm.
# rdzeń + builder stron
pnpm add @kodifyeditor/core @kodifyeditor/web
# opcjonalnie: maile i dokumenty
pnpm add @kodifyeditor/email @kodifyeditor/documentSzybki start
Owiń aplikację w EditorProvider i zamontuj wybrany builder. To wszystko, czego potrzeba, by uruchomić edytor.
import { EditorProvider } from '@kodifyeditor/core'
import { PageBuilder } from '@kodifyeditor/web'
export default function App() {
return (
<EditorProvider initialState={{ root: [] }}>
<PageBuilder />
</EditorProvider>
)
}Stan dokumentu
Cała treść jest reprezentowana jako serializowalne drzewo węzłów. Pojedynczy węzeł (BlockNode) ma stałą, przewidywalną strukturę:
export type BlockNode = {
id: string // unikalny identyfikator (nanoid)
type: string // 'text' | 'button' | 'section' …
props: Record<string, any> // treść, style, kolory
children?: BlockNode[] // dla kontenerów (sekcja, kolumny)
}
export type EditorState = {
root: BlockNode[]
}Ponieważ stan to czysty JSON, możesz go zapisać w bazie danych, wersjonować, walidować schematem i renderować po stronie serwera — bez żadnej dodatkowej warstwy.
Pola węzła
| Pole | Typ | Opis |
|---|---|---|
| id | string | Unikalny identyfikator generowany przy tworzeniu klocka. |
| type | string | Klucz typu klocka — decyduje, który renderer go obsłuży. |
| props | Record | Dowolne właściwości edytowalne w inspectorze. |
| children | BlockNode[]? | Dzieci dla klocków kontenerowych. Pominięte dla liści. |
Renderery
Ten sam stan przepuszczasz przez różne renderery zależnie od celu. Każdy generuje kod dopasowany do swojego medium.
import { WebRenderer } from '@kodifyeditor/web'
import { EmailRenderer } from '@kodifyeditor/email'
import { PdfRenderer } from '@kodifyeditor/document'
// 1. Strona WWW → semantyczny HTML
const page = WebRenderer.toHtml(state)
// 2. E-mail → tabele HTML + inline CSS (Outlook-safe)
const email = EmailRenderer.toHtml(state)
// 3. Dokument → plik PDF ze zmiennymi
const pdf = await PdfRenderer.toPdf(state, { data })Zmienne dynamiczne
W dowolnym polu tekstowym możesz użyć składni {{ klucz }}. Podczas renderowania silnik interpolacji podstawia wartości z przekazanego obiektu data.
const html = WebRenderer.toHtml(state, {
data: {
clientName: 'Jan Kowalski',
invoiceNumber: 'FV/2026/05/0042',
items: [
{ name: 'Licencja Pro', qty: 1, price: 2400 },
],
},
})Klocek dyn-table mapuje tablicę {{ items }} na wiersze — idealny do pozycji faktury. W trybie Podgląd tagi zamieniają się na realne wartości.
Własne klocki
Zarejestruj dowolny komponent React jako klocek za pomocą defineBlock. Określasz typ, edytowalne pola i funkcję renderującą — to Twój markup i Twoje style.
import { defineBlock } from '@kodifyeditor/core'
export const Callout = defineBlock({
type: 'callout',
label: 'Callout',
defaultProps: { text: 'Uwaga!', tone: 'info' },
fields: {
text: { type: 'text' },
tone: { type: 'select', options: ['info', 'warn'] },
},
render: ({ text, tone }) => (
<div className={`callout callout--${tone}`}>{text}</div>
),
})Referencja API
useEditorState()
Hook zwracający aktualny stan oraz akcje do jego modyfikacji. Dostępny wewnątrz EditorProvider.
| Zwraca | Sygnatura | Opis |
|---|---|---|
| state | EditorState | Aktualne drzewo dokumentu. |
| addBlock | (type, parentId?, index?) | Dodaje nowy klocek danego typu. |
| moveBlock | (id, parentId, index) | Przenosi klocek w drzewie. |
| updateProps | (id, partial) | Aktualizuje właściwości klocka. |
| removeBlock | (id) | Usuwa klocek wraz z dziećmi. |
| undo / redo | () => void | Cofnij / ponów ostatnią zmianę. |