The Native-First, High-Performance Markdown Plugin for JavaScript
Markdown text editor plugin that transforms a native textarea into a full editing suite. WYSIWYG and plain Markdown modes, live preview, RTL support, dark mode. Works with Django, HTMX, Laravel, React, and any stack.
The Philosophy: "Native-First"
Most editors break the standard web workflow. MarkdownEditor embraces it.
Because it sits directly on top of a <textarea>, you don't need to learn a new way to handle data.
- No Data Binding Needed: Works with
<form method="POST">out of the box - Standard Access: Use
document.getElementById('editor').valuejust like a normal input. - Backend Agnostic: Works with any backend (Python, Node.js, PHP, etc.) just like a normal form field
Key Features
🖼️ Advanced Image Upload (SEO Optimized)
Don't bloat your database with heavy Base64 strings. Configure our API to upload images directly to your server or S3 bucket. The editor receives the URL, keeping your Markdown files light and your site's SEO ranking high.
🔀 Hybrid & Plain Modes
Give your users the best of both worlds. Switch between a Visual (WYSIWYG) Hybrid mode for easy formatting and a Plain Markdown mode for distraction-free, raw syntax editing.
🌍 Global-Ready with RTL Support
Full native support for Right-to-Left (RTL) languages. Perfect for projects requiring Arabic, Urdu, or Farsi support with automatic text-direction alignment.
⚡ Performance at Scale
- Lightweight: A tiny ~116KB footprint that won't slow down your page load
- Large Document Support: Optimized to handle thousands of lines of text without input lag or browser freezing
- Smart Rendering: Debounced preview updates, cached style calculations, and conflict-free keyboard handling between list continuation and indentation — so Tab and Enter always do exactly one thing
♿ Accessible by Default
Full ARIA support is built in and requires no extra configuration. The toolbar is a proper role="toolbar" landmark, the preview pane is a labelled role="region", all SVG icons are hidden from screen readers, the preview toggle exposes its on/off state via aria-pressed, and disabled toolbar buttons use both disabled and aria-disabled so assistive technology is never misled. Modals return focus to the triggering button when closed.
🛡️ Zero CSS Conflicts
All editor styles are fully scoped to the .markdown-editor-wrapper element. Tailwind's global preflight (element resets for h1–h6, a, button, etc.) is excluded, so the editor can live alongside Bootstrap, Tailwind, or any other CSS framework on the same page without breaking a single style.
🔒 XSS Safe Preview
The rendered preview is sanitized via DOMPurify before being written to the DOM. Script tags, inline event handlers, and malicious URLs in crafted markdown input are stripped automatically — no configuration required.
Markdown Editor Demo
Quick Implementation
1. Installation
You can install it using NPM, import the JavaScript file directly, or use a CDN for rapid deployment.
Install via NPM
npm install markdown-text-editor |
Using a CDN
Alternatifnya, sertakan tautan CDN berikut dalam HTML Anda
<script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> |
2. Struktur HTML
Cukup tempatkan <textarea> di dalam formulir standar Anda. Tidak diperlukan pembungkus khusus.
1 2 3 4 | <form action="/api/save" method="POST"> <textarea id="markdown-editor" name="content"># Hello World</textarea> <button type="submit">Save Content</button> </form> |
3. Impor JS dan CSS dan inisialisasi plugin pada elemen textarea Anda
1 2 3 4 5 6 | import MarkdownEditor from "markdown-text-editor"; const editor = new MarkdownEditor('#markdown-editor', { placeholder: 'Write your markdown...', toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'], }); |
4. Konfigurasi & Kustomisasi
Anda dapat sepenuhnya menyesuaikan perilaku dan antarmuka editor dengan meneruskan objek options. Jika Anda menghilangkan opsi, nilai default akan digunakan.
| Milik | Jenis | Bawaan | Purpose |
|---|---|---|---|
mode |
string |
'plain' |
Mengatur tampilan awal. Gunakan 'hybrid' untuk pengalaman WYSIWYG atau 'plain' untuk sintaksis mentah. |
placeholder |
string |
'Write...' |
Teks ditampilkan saat editor kosong. |
toolbar |
array |
[...] |
Menentukan alat mana yang muncul dan dalam urutan apa. |
footer |
false | object |
semua terlihat | Mengontrol bilah status yang ditampilkan di bawah editor. Setel ke false untuk menyembunyikannya sepenuhnya, atau teruskan objek untuk mengubah statistik individual. |
theme |
string |
diwariskan | Menetapkan tema editor secara eksplisit ('light', 'dark', 'snowberry', 'darkberry'). Jika dihilangkan, editor akan mewarisi data-theme dari elemen leluhur terdekat atau <textarea> itu sendiri. |
minHeight |
number |
200 |
Tinggi minimum dalam piksel yang akan diperkecil oleh editor ketika kontennya pendek. Pasangkan dengan maxHeight untuk menyetel rentang pertumbuhan otomatis. |
maxHeight |
number |
500 |
Tinggi maksimum dalam piksel yang dapat ditingkatkan editor dalam mode non-layar penuh. Setelah konten melebihi ketinggian ini, bilah gulir akan muncul di dalam editor. Editor juga memiliki pegangan tarik sehingga pengguna dapat mengubah ukurannya secara manual melebihi batas ini. |
onChange |
function |
undefined |
Callback diaktifkan pada setiap perubahan konten — pengetikan, tindakan toolbar, undo/redo, dan kelanjutan daftar. Menerima string penurunan harga saat ini sebagai satu-satunya argumennya. |
🛠 Kustomisasi Bilah Alat
Bilah alatnya bersifat modular. Anda dapat menciptakan pengalaman minimal atau power suite berfitur lengkap dengan memodifikasi array.
Alat yang Tersedia
| Kategori | Kunci Alat |
|---|---|
| Typography | heading, bold, italic, strikethrough, blockquote |
| Daftar | ul (peluru), ol (bernomor), checklist |
| Kode | code (sebaris), codeblock (blok berpagar) |
| Sisipan | hr (aturan horisontal), table (templat tabel) |
| Media | link, image |
| Mengedit | undo, redo, indent, outdent |
| Melihat | preview |
💡 Kiat Penerapan:
- Pengurutan ulang: Tombol muncul sesuai urutan yang Anda cantumkan dalam larik
- Menghapus: Cukup hilangkan kunci apa pun (seperti
gambar) dari array untuk menonaktifkan fitur tersebut sepenuhnya bagi pengguna - Pengganti Asli: Jika Anda tidak memberikan
placeholderdi JS, plugin akan secara otomatis menggunakan atributplaceholderdari<textarea>HTML Anda
📊 Catatan Kaki (Bilah Status)
Footer berada di bawah editor dan menampilkan baris, kolom kursor, jumlah karakter dokumen, dan jumlah kata opsional — semuanya diperbarui secara real-time. Ini terlihat secara default dan setiap stat dapat diubah secara independen.
| Kunci | Jenis | Bawaan | Keterangan |
|---|---|---|---|
line |
boolean |
true |
Tampilkan nomor baris saat ini. |
col |
boolean |
true |
Tampilkan nomor kolom saat ini. |
chars |
boolean |
true |
Tampilkan jumlah karakter total. |
words |
boolean |
false |
Tunjukkan jumlah kata total. Nonaktif secara default — setel ke true untuk mengaktifkan. |
Contoh Penggunaan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Default — line, col, and chars visible new MarkdownEditor('#editor'); // Disable the footer entirely new MarkdownEditor('#editor', { footer: false }); // Hide only character count new MarkdownEditor('#editor', { footer: { chars: false } }); // Hide line and column, keep character count new MarkdownEditor('#editor', { footer: { line: false, col: false } }); // Show only line number new MarkdownEditor('#editor', { footer: { col: false, chars: false } }); // Enable word count alongside the defaults new MarkdownEditor('#editor', { footer: { words: true } }); // Show word count only new MarkdownEditor('#editor', { footer: { line: false, col: false, chars: false, words: true } }); |
5. Mendapatkan, Mengatur, dan Mengirimkan Konten
Salah satu kekuatan inti MarkdownEditor adalah menjaga <textarea> tetap tersinkronisasi dengan sempurna. Baik Anda menggunakan kerangka kerja JavaScript modern atau backend tradisional seperti Django, PHP, atau Laravel, alur kerjanya tetap sederhana dan asli.
1. Cara Asli (Disarankan)
Karena editor menyempurnakan area teks standar, Anda dapat menggunakan metode DOM yang sudah dikenal. Ini adalah cara tercepat untuk berinteraksi dengan data Anda tanpa mempelajari API baru.
1 2 3 4 5 | // Retrieve content via ID const markdown = document.getElementById('markdown-editor').value; // Set content via ID (The editor UI updates automatically) document.getElementById('markdown-editor').value = "# New Heading Content"; |
2. Menggunakan Referensi Variabel
Jika Anda memiliki referensi ke elemen textarea, Anda dapat menggunakannya secara langsung — tidak diperlukan API khusus perpustakaan.
1 2 3 4 5 6 7 | const textarea = document.getElementById('markdown-editor'); // Retrieve content const markdown = textarea.value; // Set content (the editor UI reflects this immediately) textarea.value = "## Updated via JS"; |
3. Menetapkan dan membaca konten
Cara yang disarankan untuk menyetel konten awal adalah langsung di HTML <textarea> — ini bekerja secara alami dengan setiap kerangka backend (Django, Laravel, Rails, PHP, dll.) dan editor merendernya secara otomatis di init.
1 2 | <!-- Recommended: set content server-side --> <textarea id="markdown-editor"># Hello World</textarea> |
Untuk membaca atau memperbarui konten saat runtime, gunakan nilai textarea asli. Panggil editor.render() setelah pembaruan untuk menyegarkan pratinjau dan lapisan hibrid.
1 2 3 4 5 6 7 8 | const textarea = document.getElementById('markdown-editor'); // Read const markdown = textarea.value; // Update at runtime textarea.value = '# New content'; editor.render(); |
4. Menghancurkan editor — destroy()
Panggil editor.destroy() untuk menghapus pembungkus DOM editor dan mengembalikan <textarea> asli ke posisinya dalam dokumen. Berguna dalam aplikasi satu halaman saat melepas tampilan.
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor'); // Remove the editor and restore the plain textarea editor.destroy(); |
React terhadap perubahan dengan onChange
Teruskan callback onChange untuk mendapatkan notifikasi setiap ada perubahan konten. Menerima string penurunan harga saat ini.
1 2 3 4 5 | const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { console.log('Content changed:', value.length, 'characters'); } }); |
Simpan otomatis draf dengan localStorage
Gunakan onChange untuk menyimpan draf pada setiap penekanan tombol. Pulihkan dengan mengisi terlebih dahulu area teks sebelum menginisialisasi editor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const DRAFT_KEY = 'my-page-draft'; // Restore saved draft before init (only if textarea starts empty) const textarea = document.getElementById('markdown-editor'); const saved = localStorage.getItem(DRAFT_KEY); if (saved && !textarea.value) textarea.value = saved; // Save on every change const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { localStorage.setItem(DRAFT_KEY, value); } }); // Clear draft after successful form submission document.querySelector('form').addEventListener('submit', () => { localStorage.removeItem(DRAFT_KEY); }); |
4. Pengiriman Formulir Otomatis yang Mudah
Karena MarkdownEditor dibangun langsung pada <textarea> asli, ia kompatibel dengan setiap kerangka backend (Django, Laravel, PHP, Ruby on Rails, dll.) langsung dari kotaknya.
Di sinilah filosofi “Pribumi-Pertama” bersinar. Anda tidak perlu menyinkronkan data secara manual sebelum mengirimkan formulir. Browser memperlakukan editor persis seperti kolom input standar.
1 2 3 4 5 6 7 8 9 10 11 12 | <form method="POST" action="/api/submit"> <textarea id="markdown-editor" name="content" class="h-48" rows="5"> # Initial Content </textarea> <button type="submit">Submit to Server</button> </form> <script> // Just initialize it. That's it. new MarkdownEditor('#markdown-editor'); </script> |
Catatan: Inisialisasi plugin MarkdownEditor wajib dilakukan
Cukup gunakan <form> HTML standar. Atribut name pada textarea adalah apa yang akan digunakan server Anda untuk mengidentifikasi konten.
🚀 Mengapa ini merupakan Game-Changer untuk Backend
Karena editor mempertahankan perilaku <textarea> asli, server Anda menangani data sebagai string standar. Tidak diperlukan logika tambahan—tidak ada preventDefault() dan tidak ada konstruksi FormData manual.
💡 Mengapa ini disebut "Fitur Pembunuh":
Kebanyakan editor (seperti Quill, Editor.js, simpleMDE, easyMDE) menyimpan data dalam struktur JSON yang kompleks. Jika pengembang menggunakannya, mereka harus menulis ulang skema database dan logika renderingnya.
Dengan MarkdownEditor, pengembang dapat mengambil situs web lama, mengganti <textarea> biasa dengan editor Anda, dan backend bahkan tidak mengetahui perubahannya. Itu hanya menerima teks mentah yang sama seperti biasanya, tetapi pengguna mendapatkan pengalaman 10x lebih baik.
| Kerangka / Bahasa | Cara mengakses konten penurunan harga |
|---|---|
| PHP | $_POST['content'] |
| Django | request.POST.get('content') |
| Node.js (Express) | req.body.content |
| Laravel | $request->input('content') |
| Ruby on Rails | params[:content] |
Opsi Konfigurasi
🖼️ Unggah gambar tingkat lanjut
Menangani unggahan gambar secara asli—daripada mengandalkan string Base64 yang lambat dan banyak memori—merupakan kemenangan yang signifikan baik untuk performa maupun SEO.
Opsi Konfigurasi
Alat gambar mendukung konfigurasi fileInput untuk menangani unggahan server langsung.
accept: Menentukan array format gambar yang diperbolehkan (misalnya, 'webp', 'avif')uploadUrl: Tentukan titik akhir backend tempat objekFileakan dikirim melaluiPOSTparams: Objek opsional untuk mengirim data tambahan (seperti token CSRF, ID pengguna, atau nama folder) bersama file gambar
Contoh penggunaan (Konfigurasi Lengkap)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const options = { placeholder: 'Start writing...', toolbar: [ 'link', { image: { fileInput: { accept: ['webp', 'avif'], // restrict the image upload format uploadUrl: '/api/upload', // Your upload endpoint params: { _token: 'your_csrf_token_here', // Essential for Laravel/Django folder: 'blog_posts' } }, // Supports boolean: true/false OR object: { required: true } altInput: { required: true } } }, 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
📡 Detail Integrasi Server
1. Permintaan
Editor mengirimkan permintaan POST sebagai multipart/form-data. Secara default, ini mencakup:
image_file: Objek file sebenarnyaimage_alt: Teks alternatif yang dimasukkan oleh pengguna- ...ditambah data khusus apa pun yang ditentukan dalam objek
params
2. Respon yang Diperlukan
Untuk mengonfirmasi keberhasilan upload dan menyisipkan gambar ke editor, server Anda harus mengembalikan struktur JSON berikut:
1 2 3 4 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp" } |
Catatan: Pastikan Anda menggunakan kunci image_path untuk URL gambar yang diunggah.
Validasi Teks Alt Gambar (altInput)
Untuk memastikan konten Anda tetap dapat diakses dan SEO-friendly, MarkdownEditor menerapkan validasi teks alternatif secara default. Anda dapat mengonfigurasi perilaku ini menggunakan singkatan boolean atau objek detail.
- Perilaku Default: Jika
altInputtidak ditentukan, defaultnya adalah{ diperlukan: true } - Terapkan Aksesibilitas: Pengguna akan dilarang menyisipkan gambar sampai deskripsi alternatif diberikan
Contoh Konfigurasi:
1. Default (Tidak perlu konfigurasi)
1 2 3 4 | // Alt text is REQUIRED by default image: { fileInput: { uploadUrl: '/api/upload' } } |
2. Singkatan (Nonaktifkan Validasi)
Jika Anda ingin mengizinkan gambar tanpa deskripsi, cukup setel boolean ke false.
1 2 3 | image: { altInput: false // Users can now skip the alt text field } |
3. Berbasis objek (Eksplisit)
1 2 3 4 5 | image: { altInput: { required: false // Disables alt text validation — users can skip the alt field } } |
Penggunaan Gambar Standar (Tanpa fileInput):
Jika fileInput tidak dikonfigurasi, editor akan menggunakan modal sederhana berbasis URL secara default. Ini ideal jika sebagian besar pengguna Anda terhubung ke host gambar eksternal.
1 2 3 4 5 6 7 8 | const options = { toolbar: [ 'link', 'image', 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
💡 Mengapa menggunakan params?
Dalam kerangka kerja seperti Laravel atau Django, Anda tidak dapat mengunggah berkas tanpa token CSRF. Dengan menambahkan _token ke objek params, permintaan Anda akan melewati middleware keamanan backend dengan lancar, mempertahankan filosofi "Zero Logic" untuk pengontrol sisi server Anda.
🔀 Mode Pengeditan
MarkdownEditor menawarkan dua cara berbeda untuk menulis dan memformat konten Anda. Anda dapat beralih antara tampilan tradisional yang berfokus pada sintaksis atau pengalaman modern yang mengutamakan visual.
Konfigurasi
Anda dapat menentukan mode awal menggunakan properti mode selama inisialisasi.
plain(Default): Lingkungan penurunan harga yang bersih dan berkinerja tinggi tempat sintaksis (seperti**bold**atau# heading) terlihat. Ideal untuk pengembang dan penganut penurunan hargahibrida: Pengalaman yang terinspirasi WYSIWYG yang menampilkan pemformatan (Tebal, Miring, Judul) secara real-time saat Anda mengetik, sambil tetap mempertahankan struktur penurunan harga yang mendasarinya.
Pelaksanaan:
1 2 3 4 5 6 7 8 9 10 11 12 | // Default initialization (Plain Mode) new MarkdownEditor('#markdown-editor'); // Explicit Plain Mode new MarkdownEditor('#markdown-editor', { mode: 'plain' }); // Hybrid (Visual) Mode new MarkdownEditor('#markdown-editor', { mode: 'hybrid' }); |
Pratinjau Mode Hibrid dan Biasa:
Hybrid Mode
Pemformatan visual ditampilkan secara real-time saat Anda mengetik.
Mode Biasa (Default)
Berfokus pada sintaks penurunan harga mentah untuk pengalaman yang ringan.
| Konfigurasi | Properti / Alat | Keterangan |
|---|---|---|
| Objek pilihan | placeholder |
Menetapkan teks placeholder untuk textarea (opsional, karena Anda juga dapat menggunakan atribut textarea HTML standar) |
mode: 'hybrid' |
Memungkinkan pengalaman yang terinspirasi WYSIWYG yang menampilkan pemformatan (tebal, miring, judul) secara real-time saat Anda mengetik | |
toolbar: Menentukan alat manayang muncul di toolbar dan urutannya. |
heading |
Membuka tarik-turun untuk memilih tingkat judul H1–H6 |
bold |
Mengaktifkan pemformatan teks tebal. | |
italic |
Mengaktifkan pemformatan teks miring. | |
strikethrough |
Memungkinkan teks dicoret. | |
ol |
(Daftar Terurut): Mengubah teks menjadi format daftar bernomor. | |
ul |
(Daftar Tidak Berurutan): Mengubah teks menjadi daftar poin-poin. | |
checklist |
Menambahkan kotak centang ke teks Anda, sehingga cocok untuk tugas, daftar tugas, atau melacak status penyelesaian. | |
blockquote |
Sorot teks yang dikutip atau ditekankan. | |
code |
Membungkus teks yang dipilih dalam satu backtick untuk kode sebaris. Mengklik lagi akan menghapus backticks. | |
codeblock |
Membungkus teks yang dipilih dalam blok kode berpagar triple-backtick. Mengklik lagi akan menghilangkan pagar. | |
hr |
Menyisipkan aturan horizontal --- pada posisi kursor pada barisnya sendiri. |
|
table |
Menyisipkan templat tabel penurunan harga 2x3 awal pada posisi kursor. | |
image |
Memungkinkan Anda menyisipkan gambar melalui sintaks penurunan harga. | |
link |
Memungkinkan Anda menambahkan hyperlink ke teks Anda. | |
undo |
Untuk membalikkan perubahan terakhir. | |
redo |
Untuk menerapkan kembali perubahan terakhir yang dibatalkan. | |
indent |
Untuk meningkatkan tingkat lekukan. | |
outdent |
Untuk mengurangi tingkat lekukan. | |
preview |
Mengalihkan pratinjau layar penuh berdampingan. Kotak centang di panel pratinjau dapat diklik dan memperbarui sumber penurunan harga secara instan. Tekan Escape untuk keluar dari layar penuh. | |
| Fitur pengunggahan gambar tingkat lanjut: Memungkinkan konfigurasi pengunggahan gambar ke server Anda sendiri dan menyetel jalur gambar melalui API. Ini meningkatkan kinerja dan SEO. |
fileInput |
accept: Kumpulan jenis file gambar yang diperbolehkan (misalnya 'webp', 'avif').uploadUrl: Titik akhir backend tempat file dikirim melalui POST.params: Objek opsional untuk data tambahan (token CSRF, ID pengguna, nama folder)
|
altInput |
wajib: salah: Menonaktifkan validasi input teks alternatif (standarnya adalah benar) |
⌨️ Pintasan Papan Ketik
Tindakan pemformatan umum dapat dipicu langsung dari keyboard tanpa menyentuh toolbar. Setiap pintasan juga ditampilkan di tooltip tombol toolbar yang sesuai.
| Jalan pintas | Tindakan |
|---|---|
Ctrl + B / ⌘ B |
Alihkan Tebal |
Ctrl + I / ⌘ I |
Alihkan Miring |
Ctrl + K / ⌘ K |
Sisipkan Tautan |
Ctrl + ` / ⌘ ` |
Alihkan Kode sebaris |
Ctrl + Shift + S / ⌘ ⇧ S |
Alihkan |
Ctrl + Z / ⌘ Z |
Membuka |
Ctrl + Shift + Z / ⌘ ⇧ Z |
Mengulangi |
Tab |
Indentasi baris yang dipilih |
Shift + Tab |
Garis yang dipilih keluar |
Ctrl + F / ⌘ F |
Buka panel Temukan |
Ctrl + H / ⌘ H |
Buka panel Temukan & Ganti |
Escape |
Tutup panel Temukan / Keluar dari pratinjau layar penuh |
🔍 Temukan & Mengganti
Panel temukan dan ganti bawaan tersedia di dalam editor — tidak diperlukan ekstensi browser atau alat terpisah.
- Tekan
Ctrl + F(atau⌘ F) untuk membuka panel Temukan - Tekan
Ctrl + H(atau⌘ H) untuk membuka Temukan & Ganti panel - Penelusuran tidak peka huruf besar-kecil dan menampilkan penghitung pertandingan langsung (misalnya 3 dari 12)
- Navigasikan kecocokan dengan tombol ▲ / ▼ atau
Enter/Shift + Enter - Ganti menggantikan kecocokan yang disorot saat ini; Ganti Semua menggantikan setiap kejadian sekaligus
- Tekan
Escapeuntuk menutup panel dan mengembalikan fokus ke editor
Panel mengapung di sudut kanan atas area konten editor dan tidak mengganggu penulisan.
🌙 Tema
MarkdownEditor secara otomatis mewarisi temanya dari halaman sekitarnya — tidak diperlukan konfigurasi. Editor membaca data-theme dari leluhur terdekat saat inisialisasi, sehingga tetap sinkron dengan tema situs Anda.
Bagaimana tema diselesaikan (urutan prioritas)
- Opsi
tema— penggantian eksplisit yang diteruskan pada objek opsi data-themepada<textarea>— disetel langsung pada elemendata-themepada leluhur mana pun — mis.<html>,<body>, atau pembungkus<div>
Tema yang tersedia
'light' (default), 'dark', 'snowberry', 'darkberry'
Opsi 1 — mewarisi dari <html> atau leluhur mana pun (konfigurasi nol)
1 2 3 4 5 6 | <html data-theme="dark"> ... <textarea id="markdown-editor"></textarea> <script> new MarkdownEditor('#markdown-editor'); // picks up dark automatically </script> |
Opsi 2 — atur data-theme langsung di <textarea>
1 2 3 4 | <textarea id="markdown-editor" data-theme="dark"></textarea> <script> new MarkdownEditor('#markdown-editor'); </script> |
Opsi 3 — opsi tema eksplisit (mengganti semuanya)
1 2 3 | new MarkdownEditor('#markdown-editor', { theme: 'dark' }); |
🎨 Tema Khusus melalui Variabel CSS
Anda dapat sepenuhnya menyesuaikan tampilan editor dengan mengganti variabel CSS-nya pada elemen .markdown-editor-wrapper atau pemilih [data-theme] mana pun. Semua warna menggunakan ruang warna OKLCH untuk hasil yang seragam.
| Variabel | Purpose | Standar ringan | Defaultnya gelap |
|---|---|---|---|
--color-base |
Latar belakang penyunting | oklch(100% 0 0) |
oklch(10.9% 0 0) |
--color-on-base |
Warna teks utama | oklch(22% 0 0) |
oklch(98% 0 0) |
--color-primary |
Aksen utama (bilah alat aktif, tautan) | oklch(51.1% .262 277) |
oklch(66.4% .184 286) |
--color-on-primary |
Teks pada permukaan berwarna primer | oklch(96.2% .018 272) |
oklch(10% .01 270) |
--color-secondary |
Aksen sekunder | oklch(59.1% .293 323) |
oklch(65% .18 220) |
--color-accent |
Aksen highlight (kode sebaris, miring) | oklch(54.1% .281 293) |
oklch(75% .18 50) |
--color-neutral |
Permukaan netral (batas, pemisah) | oklch(15% 0 0) |
oklch(85% 0 0) |
--color-error |
Warna status kesalahan | oklch(57.7% .245 27) |
oklch(60% .22 30) |
--border-radius |
Pembulatan sudut bingkai editor | 0.25rem |
|
Contoh tema khusus
Ganti variabel apa pun di .markdown-editor-wrapper setelah editor menginisialisasi, atau tentukan blok [data-theme] khusus di stylesheet Anda:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* Override individual variables */ .markdown-editor-wrapper { --color-primary: oklch(60% 0.2 30); /* orange accent */ --border-radius: 0.5rem; } /* Or define a full custom theme */ [data-theme="brand"] .markdown-editor-wrapper, .markdown-editor-wrapper[data-theme="brand"] { --color-base: oklch(15% 0.01 250); --color-on-base: oklch(95% 0 0); --color-primary: oklch(65% 0.22 145); /* green */ --color-on-primary: oklch(10% 0 0); --color-accent: oklch(75% 0.18 60); --color-neutral: oklch(80% 0 0); --border-radius: 0.75rem; } |
new MarkdownEditor('#markdown-editor', { theme: 'brand' }); |
- Pratinjau Waktu Nyata: Lihat penurunan harga yang ditampilkan secara instan saat Anda mengetik.
- Penyorotan Sintaks: Peningkatan keterbacaan dengan kode yang jelas dan format penurunan harga.
- Integrasi Mudah: Integrasikan secara lancar ke dalam proyek web apa pun dengan penyiapan minimal.
- Bilah Alat yang Dapat Disesuaikan: Konfigurasikan dan susun ulang opsi bilah alat secara dinamis seperti huruf tebal, miring, dan lainnya.
Fitur
🔌 Integrasi Formulir Asli
Bekerja persis seperti <textarea> standar. Tidak ada API yang rumit—cukup gunakan atribut value atau name. Ini "hanya berfungsi" dengan pengiriman formulir HTML standar di PHP, Django, atau Node.js.
🖼️ Unggah Gambar Tingkat Lanjut
Konfigurasikan unggahan server asli melalui API. Hindari string Base64 yang berat untuk memastikan pemuatan halaman lebih cepat dan SEO unggul dengan menghosting gambar di CDN Anda sendiri.
🔀 Hybrid & Plain Modes
Beralih antara pengalaman Hybrid (WYSIWYG) untuk pengeditan visual atau mode Penurunan Harga Biasa untuk nuansa pengkodean tradisional.
🚀 Performa Tinggi
Paket kecil ~116 KB yang dioptimalkan untuk "Konten Berat". Menangani dokumen berukuran besar dan file besar tanpa jeda input atau penurunan kinerja.
🌍 Dukungan RTL bawaan
Dukungan asli untuk bahasa Kanan-Kiri seperti Arab, Urdu, dan Farsi. Sempurna untuk membangun aplikasi yang dapat diakses secara global.
🌙 Tema Adaptif
Termasuk dukungan Mode Gelap otomatis. Ini disinkronkan dengan pengaturan sistem Anda atau perpustakaan Frutjam UI untuk pengalaman visual yang lancar.
📝 Pengeditan Cerdas
Kelanjutan daftar otomatis gaya GitHub untuk daftar terurut, daftar tak terurut, dan daftar periksa — tekan Enter dan editor melanjutkan polanya. Kotak centang di panel pratinjau dapat diklik dan langsung disinkronkan kembali ke sumber penurunan harga.
📱 Sepenuhnya Responsif
UI yang lancar dan mengutamakan seluler yang beradaptasi sempurna dengan desktop, tablet, dan ponsel cerdas untuk mengedit saat bepergian.
📦 Dukungan Universal
Kompatibel dengan ESM, UMD, CommonJS, dan IIFE. Berfungsi langsung melalui CDN (<script src>), npm, atau bundler apa pun (Vite, webpack, Rollup) — tidak memerlukan konfigurasi tambahan.
♿ Accessible by Default
Dukungan penuh ARIA bawaan — landmark toolbar, wilayah pratinjau berlabel, tombol ramah pembaca layar, aria-pressed pada tombol pratinjau, disabled dan aria-disabled pada alat yang tidak aktif, dan memperbaiki pemulihan fokus ketika modals ditutup.
🛡️ Zero CSS Conflicts
Gaya editor sepenuhnya tercakup dalam .markdown-editor-wrapper. Pra-penerbangan global Tailwind dikecualikan sehingga editor dapat bekerja dengan aman bersama Bootstrap, Tailwind, atau kerangka kerja lainnya tanpa merusak gayanya.
⌨️ Pintasan Papan Ketik
Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+`, Ctrl+Shift+S — tindakan pemformatan umum tanpa menyentuh mouse. Setiap pintasan ditampilkan di tooltip tombol toolbar.
🔍 Temukan & Mengganti
Tekan Ctrl+F untuk mencari atau Ctrl+H untuk membuka cari & mengganti. Pencarian tidak peka huruf besar-kecil dengan penghitung pencocokan langsung, navigasi berikutnya/sebelumnya, penggantian tunggal, dan penggantian semua — tanpa meninggalkan editor.
Contoh Konfigurasi Lengkap
Gunakan contoh komprehensif ini untuk menginisialisasi MarkdownEditor dengan semua fitur utama, termasuk pengurutan toolbar khusus dan penanganan unggahan gambar tingkat lanjut.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | const editor = new MarkdownEditor('#markdown-editor', { mode: 'hybrid', placeholder: 'Start writing...', footer: { line: true, col: true, chars: true, words: true, }, onChange(value) { console.log('Content updated:', value.length, 'characters'); }, toolbar: [ 'heading', 'bold', 'italic', 'strikethrough', 'blockquote', 'ul', 'ol', 'checklist', 'code', 'codeblock', 'hr', 'table', { image: { fileInput: { accept: ['webp', 'avif', 'png'], uploadUrl: '/api/upload' } } }, 'link', 'undo', 'redo', 'indent', 'outdent', 'preview' ], }); // Read content natively const markdown = document.getElementById('markdown-editor').value; // Update content programmatically (dispatch input to keep preview in sync) // const ta = document.getElementById('markdown-editor'); // ta.value = '# New content'; // ta.dispatchEvent(new Event('input', { bubbles: true })); // destroy() when the view unmounts (SPAs) // editor.destroy(); |