Back to Articles

Cara Pakai tiptap-docs-kit: Bikin Editor Dokumen ala Word di React

Panduan langkah demi langkah membangun editor dokumen ala Word/Google Docs di React menggunakan @zanwaar/tiptap-docs-kit, lengkap dengan halaman A4, pagination, tabel, gambar, dan styling dokumen.

Tampilan editor dokumen ala Word yang dibangun dengan tiptap-docs-kit

@zanwaar/tiptap-docs-kit adalah extension kit untuk membangun editor dokumen berbasis Tiptap dengan pengalaman seperti word processor (mirip Google Docs atau Microsoft Word). Alih-alih merakit satu per satu extension Tiptap, kit ini membundel kebutuhan umum editor dokumen dalam satu tempat: halaman A4/Letter, page break, pagination otomatis, alignment, warna dan ukuran font, line spacing, gambar yang bisa di-resize, tabel, sampai style dokumen.

Penting dipahami sejak awal: kit ini fokus pada logic Tiptap dan CSS dokumen. UI seperti toolbar, status bar, atau color picker tetap kamu buat sendiri di aplikasi consumer. Jadi tampilan sepenuhnya di tanganmu.

Di tutorial ini kita akan memasang kit-nya di React, membuat editor dokumen, mengaktifkan pagination, lalu menjalankan beberapa command.

Demo dan Sumber

Ingin lihat hasilnya dulu sebelum coding? Coba live demo playground-nya, atau jalankan sendiri dari repo playground-react. Tangkapan layar di bawah memperlihatkan editor dokumen ala Word lengkap dengan toolbar, halaman A4, tabel, dan heading.

Tampilan editor dokumen tiptap-docs-kit

Jalankan playground secara lokal:

git clone https://github.com/zanwaar/playground-react.git
cd playground-react
npm install
npm run dev

1. Instalasi

Kit ini menarget Tiptap v3 (^3.26.1) dan memakai sejumlah package Tiptap sebagai peer dependencies. Untuk proyek React, pasang juga @tiptap/react (binding useEditor dan EditorContent ada di paket ini, bukan di @tiptap/core atau starter-kit, dan kit ini memang dibuat framework-agnostic). Pasang semuanya sekaligus:

npm install @zanwaar/tiptap-docs-kit @tiptap/react @tiptap/core @tiptap/pm @tiptap/starter-kit @tiptap/extension-image @tiptap/extension-table @tiptap/extension-table-cell @tiptap/extension-table-header @tiptap/extension-table-row

2. Membuat Editor Dasar

Gunakan hook useEditor dari @tiptap/react, lalu pasang DocsKit sebagai satu-satunya extension bundle. Untuk isi awal, kit menyediakan helper createBlankWordPageDocument() yang menghasilkan dokumen kosong dengan satu halaman. Jangan lupa import CSS-nya sekali saja di aplikasi.

import { useEditor, EditorContent } from "@tiptap/react";
import { DocsKit, createBlankWordPageDocument } from "@zanwaar/tiptap-docs-kit";
import "@zanwaar/tiptap-docs-kit/style.css";

export function Editor() {
  const editor = useEditor({
    extensions: [DocsKit],
    content: createBlankWordPageDocument(),
    editorProps: {
      attributes: {
        class: "word-editor-document",
      },
    },
  });

  return <EditorContent editor={editor} />;
}

Class word-editor-document penting karena style dokumen (ukuran halaman, font, line height) dikontrol lewat class itu.

3. Mengaktifkan Pagination

Salah satu fitur utama kit ini adalah pagination otomatis ala Word: konten yang melebihi satu halaman akan dipecah ke halaman berikutnya. Untuk mengaktifkannya, panggil bindWordPagePagination pada container scroll editor. Fungsi ini mengembalikan cleanup function, jadi cocok dipasang di dalam useEffect.

import { useEffect, useRef } from "react";
import { EditorContent } from "@tiptap/react";
import type { Editor } from "@tiptap/react";
import { bindWordPagePagination } from "@zanwaar/tiptap-docs-kit";

export function Workspace({ editor }: { editor: Editor | null }) {
  const workspaceRef = useRef<HTMLElement>(null);

  useEffect(() => {
    if (!editor || !workspaceRef.current) return undefined;

    return bindWordPagePagination(editor, workspaceRef.current);
  }, [editor]);

  return (
    <main className="workspace" ref={workspaceRef}>
      <EditorContent editor={editor} />
    </main>
  );
}

4. Menjalankan Command

Kit menambahkan banyak command ke Tiptap. Polanya sama seperti Tiptap pada umumnya: editor.chain().focus().<command>().run(). Berikut command yang paling sering dipakai untuk toolbar.

Pengaturan Halaman

editor.chain().focus().insertPage({ pageType: "body" }).run();
editor.chain().focus().setPageAttrs({ paperSize: "a4", orientation: "portrait", margin: "narrow" }).run();
editor.chain().focus().setPageAttrs({ marginValue: "2cm 1.5cm 1.5cm 1.5cm" }).run();
editor.chain().focus().insertPageBreak().run();
editor.chain().focus().insertWordPageTemplate("cover").run();

Alignment

editor.chain().focus().setTextAlign("left").run();
editor.chain().focus().setTextAlign("center").run();
editor.chain().focus().setTextAlign("right").run();
editor.chain().focus().setTextAlign("justify").run();

Warna, Font, dan Ukuran Teks

editor.chain().focus().setTextColor("#063f81").run();
editor.chain().focus().unsetTextColor().run();
editor.chain().focus().setTextFont("Roboto, Arial, sans-serif").run();
editor.chain().focus().setTextSize("11pt").run();

Line Spacing

editor.chain().focus().setLineSpacing("1.5").run();
editor.chain().focus().unsetLineSpacing().run();
editor.chain().focus().setParagraphSpaceBefore("12pt").run();
editor.chain().focus().setParagraphSpaceAfter("12pt").run();

Gambar

Gambar disisipkan sebagai node image, bisa berupa base64 maupun URL. Lebar gambar bisa diubah dengan menarik handle di pojok kanan bawah, dan tersimpan pada atribut width.

editor.chain().focus().insertContent({ type: "image", attrs: { src, alt: "Gambar" } }).run();

Tabel

editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
editor.chain().focus().insertGrid({ rows: 4, cols: 4 }).run();
editor.chain().focus().addColumnAfter().run();
editor.chain().focus().addRowAfter().run();
editor.chain().focus().deleteColumn().run();
editor.chain().focus().deleteRow().run();
editor.chain().focus().mergeCells().run();
editor.chain().focus().splitCell().run();

Tabel panjang otomatis dipecah antar halaman pada batas row. Kalau tabel punya header row, header-nya akan diulang di tabel lanjutan pada halaman berikutnya.

5. Konfigurasi DocsKit

DocsKit bisa dikonfigurasi per extension lewat .configure(). Set salah satu opsi ke false untuk menonaktifkan extension tersebut.

DocsKit.configure({
  starterKit: {},
  textAlign: { types: ["paragraph", "heading"] },
  textColor: {},
  textFont: {},
  textSize: {},
  paragraphSpacing: { types: ["paragraph", "heading"] },
  table: { resizable: true },
  page: { pasteAsPlainText: true },
  image: { inline: false, allowBase64: true },
});

Contoh menonaktifkan warna teks:

DocsKit.configure({
  textColor: false,
});

6. Menyesuaikan Style Dokumen

Tampilan halaman dikontrol lewat CSS variables pada class .word-editor-document. Kamu bisa override sesuai kebutuhan:

.word-editor-document {
  --word-page-width: 794px;
  --word-page-height: 1123px;
  --word-page-padding: 96px;
  --word-page-text-color: #49454f;
  --word-page-font-family: Roboto, Arial, sans-serif;
  --word-page-font-size: 11pt;
  --word-page-line-height: 1.15;
}

Penutup

Dengan @zanwaar/tiptap-docs-kit, kamu tidak perlu menyusun extension halaman, pagination, tabel, dan styling dokumen dari nol. Cukup pasang DocsKit, beri dokumen awal, aktifkan pagination, lalu bangun toolbar sendiri di atas command yang tersedia.

Untuk contoh implementasi UI lengkap (toolbar, status bar, color picker), coba live demo-nya, lihat kode di repo playground-react, dan repo utama package di github.com/zanwaar/tiptap-docs-kit.

Diskusi proyek? Chat via WhatsApp