Sayap
Jenis huruf bawaanJarak


NABI NOTE

Penyunting WYSIWYG sumber terbuka


NABI NOTE adalah penyunting WYSIWYG sumber terbuka yang memisahkan fungsi seperti format, perataan, tabel, dan unggahan dari inti menjadi modul mandiri bernama wing. Pengembang dapat memilih wing yang diperlukan dan menghubungkan wing buatan sendiri. Ditulis dengan JavaScript murni, ia dapat digunakan bersama React, Vue, maupun kerangka kerja lain. Pada halaman tanpa lingkungan build, pustaka CDN dapat langsung digunakan. Format dokumennya sendiri, NABI TREE, dapat diubah menjadi HTML bahkan di lingkungan Node.js tanpa DOM peramban. Dokumen masukan dirapikan mengikuti aturan yang terdaftar, sedangkan saat membuat HTML teks dan atribut di-escape serta alamat tautan diperiksa. Wing buatan sendiri dan data dari server tetap perlu ditinjau sesuai kebijakan keamanan aplikasi. Variabel CSS dan tata letak berbasis rem memudahkan pengaturan tema serta ukuran, termasuk mode gelap dan font untuk berbagai bahasa. Pengurutan tabel, riwayat lokal, dan pekerjaan dokumen berbantuan AI juga berada pada satu model dokumen.


Jenis huruf

Keluarga tanpa serif (bawaan), serif, lebar tetap, dan tulisan tangan menyediakan fon cadangan untuk berbagai bahasa. Jika fon yang sesuai dengan keluarga pilihan tidak tersedia, fon bawaan browser akan digunakan. Halaman yang memuat editor menentukan jenis huruf bawaannya.


Di bawah ini setiap keluarga ditunjukkan dalam berbagai bahasa.


산세리프 · ゴシック体 · 无衬线 · Serifenlos · Sans empattement · Sin serifa · Sem serifa · Без засечек · بلا زخارف · सैन्स सेरिफ़ · স্যান্স সেরিফ · سانس سیرف · Tanpa serif · بدون سریف · सॅन्स सेरिफ · Không chân · శాన్స్ సెరిఫ్ · Mara seref · Sans serif · Bila serif · சான்ஸ் செரிஃப் · ไร้เชิง · Senza grazie


세리프 · 明朝体 · 衬线 · Serif · Avec empattement · Con serifa · Com serifa · С засечками · بزخارف · सेरिफ़ · সেরিফ · سیرف · Berserif · سریف · सेरिफ · Có chân · సెరిఫ్ · Mai seref · Yenye serif · செரிஃப் · มีเชิง · Con grazie


고정폭 · 等幅 · 等宽 · Dicktengleich · Chasse fixe · Monoespaciada · Monoespaçada · Моноширинный · ثابت العرض · मोनोस्पेस · মনোস্পেস · یکساں چوڑائی · Lebar tetap · تک‌فاصله · Đơn cách · మోనోస్పేస్ · Tazara ɗaya · Eş aralıklı · Nafasi moja · ஒற்றையகலம் · ความกว้างคงที่ · Monospaziato · Monospace


필기체 · 筆記体 · 手写体 · Schreibschrift · Cursive · Cursiva · Рукописный · خط اليد · हस्तलिपि · হস্তলিপি · رواں خط · Tulisan tangan · دست‌نویس · हस्ताक्षर · Chữ viết tay · చేతిరాత · Rubutun hannu · El yazısı · Mwandiko · கையெழுத்து · ลายมือ · Corsivo



Ukuran huruf

Sangat kecil

Kecil

Besar

Sangat besar



Judul

Di baris kosong ketik # lalu tekan spasi — seketika menjadi judul.

H1

H2

H3

H4

H5
H6



Tebal · Miring · Garis bawah · Coret

Tebal miring garis bawah coret dapat diterapkan bersama pada karakter yang sama.

Bisa juga ditumpuk.

Superskrip dan subskrip

Luasnya 3,5 m2, dan catatan kaki ditulis seperti ini1

Air itu H2O.



Warna teks · Stabilo

Paletnya dipilih agar tetap terbaca baik di mode terang maupun gelap.

Warna teks Hijau · Koral · Ungu · Ambar · Biru

Stabilo Kuning · Hijau · Sian · Merah muda · Ungu · Jingga



Tautan

Masukkan alamat, maka jadilah tautan.

Anda dapat memakai URL http:// dan https:// serta jalur di situs yang sama yang diawali . atau /. Alamat seperti javascript: tidak diizinkan.

Misalnya ketik https://nabi.saro.me lalu tekan spasi atau Enter — ia berubah sendiri, seperti terlihat di sini.

Cara membuka tautan

Dokumen hanya menyimpan alamat tautan; halaman yang menampilkan dokumen menentukan cara tautan dibuka.

Tautan lampiran

Berkas selain gambar tetap tersimpan sebagai tautan lampiran seperti contoh di bawah.

Lampiran disimpan sebagai tautan di dalam dokumen.



Perataan

Rata kiri

Rata tengah

Rata kanan

Perataan tidak dapat diterapkan pada judul.



Daftar

Daftar berbutir

Di baris kosong ketik - lalu tekan spasi — seketika menjadi daftar berbutir.

  • Ini sebuah butir

    • Tab / Shift+Tab untuk menjorokkan dan mengembalikan.

Daftar bernomor

Di baris kosong ketik 1. lalu tekan spasi — jadilah daftar bernomor.

  1. Pertama

  2. Kedua

  3. Ketiga

Daftar centang

Di baris kosong ketik [ ] atau [x] lalu tekan spasi — jadilah daftar centang.

  • Yang ini sudah dikerjakan.

  • Yang ini belum.



Tabel

Sel dapat memuat beberapa paragraf dan blok, dengan warna latar untuk membedakan isinya. Coba edit langsung teks dan gambar pada tabel berikut.

Materi

Catatan kerja

Gambar dan keterangannya dalam satu sel.

Paragraf yang fleksibel

Tekan Enter untuk membuat paragraf baru, atau Shift+Enter untuk mengganti baris dalam paragraf yang sama.

  • Mengubah latar sel

  • Mengindentasi daftar dengan Tab

  • Memilih beberapa sel dan menerapkan warna yang sama

Klik untuk melihat tips pengeditan

Sel juga dapat memuat blok lipat, kutipan, kode, dan video.

Penggabungan sel mempertahankan isi setiap sel sesuai urutan.

Klik di dalam sel untuk menampilkan warna latar serta alat baris dan kolom. Pilih beberapa sel untuk mengubah warna dan perataannya sekaligus. Untuk menempatkan seluruh tabel, pilih “Pilih tabel”, lalu gunakan alat perataan.

Tabel berwarna atau berisi beberapa blok tetap disimpan sebagai HTML meskipun disimpan dalam Markdown.

Warna latar sel

Semua warna latar sel yang didukung ditampilkan di sini. Klik sel untuk mengubah warnanya, atau pilih “Bawaan” pada alat properti untuk menghapus latarnya.

Kuning

yellow

Hijau

green

Biru muda

cyan

Merah muda

pink

Ungu

purple

Oranye

orange

Pengurutan kolom

Pratinjau lalu tekan kepala kolom Stok dan Harga satu per satu.

Model

Stok

Harga

Berat

NB-7

1,200

349

1.2 kg

NB-9

20,000

99

0.9 kg

NB-12

3,500

1,299

1.4 kg

NB-80

900

8,900

2.1 kg

NB-100

Belum ditentukan

12,999

2.4 kg

Harga hanya berisi nilai angka, sehingga kolom diurutkan secara numerik.

Stok berisi angka dan teks, sehingga kolom diurutkan sebagai rangkaian karakter.



Garis pemisah

Ketik --- lalu tekan Enter — berubah menjadi garis pemisah.




Gambar

Lebarnya bisa diatur dari 30% sampai 100%, dan bisa diletakkan di kiri, tengah, atau kanan.



Area mengambang

Sekilas

Area pendukung kecil untuk teks, gambar, dan tabel.

Penempatan

Kanan

Lebar maksimum

40%

Gunakan area mengambang untuk menaruh penjelasan tambahan atau materi kecil di samping teks utama. Pada dokumen yang lebar, teks ini mengalir di samping area. Klik di dalamnya untuk mengedit teks dan menyisipkan gambar atau tabel pada editor yang sama.

Letakkan kursor di dalam area untuk membuka alat propertinya. Ganti penempatan kiri atau kanan, lalu pilih lebar maksimum 20, 30, 40, atau 50% yang sesuai dengan teks. Tabel dan gambar yang ditempel juga tetap berada di dalam area.

Anda juga dapat membungkus paragraf yang dipilih dalam sebuah area. Tombol pelepas di samping lebar membiarkan isinya tetap di dokumen utama. Pratinjau menyembunyikan garis putus-putus pengeditan; pada dokumen sempit atau saat dicetak, semuanya tersusun satu kolom.


YouTube



Unggah

Cobalah seret gambar atau berkas ke atas penyunting.

Demo ini tidak mengirim berkas ke server sungguhan. Hubungkan pengunggah di aplikasi Anda untuk menyimpannya di server.

Setelah membuka pemilih gambar atau memulai unggahan, memindahkan kursor saja tetap menyisipkan di posisi awal. Mengedit dokumen saat menunggu membatalkan penyisipan dan menampilkan pemberitahuan. Progres dan hasil unggahan yang dimulai di dalam sel juga tetap berada di sel tersebut.



Kutipan

Di baris kosong ketik > lalu tekan spasi — jadilah kotak kutipan.

Ia boleh menempati beberapa baris.



Kode

Di baris kosong ketik ``` lalu tekan spasi atau Enter — jadilah kotak kode.

Tulis sekalian bahasanya, seperti ```java, lalu spasi atau Enter — kotaknya memakai bahasa itu.

import { createNabiWith, defaultWings } from 'nabi-note'

const { nabi } = createNabiWith(defaultWings)
const html = nabi.getHtml()



Lipatan

Lipatan terdiri dari judul dan isi.

Anda bisa menentukan apakah ia disimpan dalam keadaan tertutup atau terbuka.



Bilah alat

Alat judul, format teks, perataan, daftar, penyisipan, dan dokumen dikelompokkan. Desktop menampilkan alat lengkap, sedangkan seluler menyediakan alat cepat dan palet lengkap. Properti tabel atau area mengambang yang dipilih muncul di bawah bilah alat.


Pintasan

Tekan Shift dua kali dengan cepat untuk memilih alat dengan papan ketik. Jelajahi bilah alat yang terbuka di desktop atau palet lengkap di seluler. Gunakan Tab untuk berpindah grup, tombol panah untuk memilih alat, dan Enter untuk menjalankannya.

Di akhir blok kutipan, kode, atau blok lipat, tekan Enter dua kali dengan cepat untuk keluar. Interval bawaan penekanan ganda adalah 180ms.



Format otomatis

Contoh

Tombol

Hasil

#

Spasi

Judul

-

Spasi

Daftar berbutir

1.

Spasi

Daftar bernomor

[ ] · [x]

Spasi

Daftar centang

>

Spasi

Kutipan

``` · ```ts

Spasi · Enter

Kotak kode

---

Enter

Garis pemisah

https://…

Spasi · Enter

Tautan



Fungsi keluaran

Fungsi

Hasil

getHtml()

HTML

getJson()

JSON



Berjalan tanpa DOM

Mengubah NABI TREE menjadi HTML tidak memerlukan DOM.

Server (Node.js) juga dapat membaca NABI TREE yang tersimpan dan menghasilkan HTML dengan aturan yang sama.


Ramah ponsel

  • UI seluler — Menata alat pengeditan sesuai lebar layar.

  • Penyesuaian papan ketik seluler — Menyesuaikan tinggi area pengeditan saat papan ketik terbuka.

  • Ukuran fleksibel — Menggunakan satuan rem untuk tata letak utama agar menyesuaikan pembesaran dan pengecilan.

  • Berbagai bahasa — Anda dapat mengatur locale dan jenis huruf sesuai bahasa serta arah teks.


Penyesuaian

  • Sayap buatan sendiri — jika membutuhkan fitur, Anda dapat membuat dan menghubungkannya sendiri.

  • CSS buatan sendiri — sesuaikan warna utama, sudut, dan jarak dengan token --nabi-* untuk mode terang dan gelap.

  • Sumber terbuka — kode sumber dibagikan di GitHub dan dikembangkan bersama.


Lihat dokumentasi → nabi.saro.me

HTMLMemuat editor…
JSONnabi-treeMemuat editor…
Pasang
npm install nabi-note
Kode
import {
  createLocale, createNabiWith, mountSurface, mountToolbar,
  mountContextToolbar, mountHints, watchSettle, makeTranslator,
  defaultWings, mountUpload, mountUploadView, browserFileStore,
  mountFile, mountViewTools, browserHistoryStorage, mountLocalHistory,
  openHistoryPanel,
} from 'nabi-note'
import { mountDiffWing } from 'nabi-note/diff'
import { mountOutline } from 'nabi-note/viewer'

// The box that asks — without it the core answers "no" to everything (plug in your own)
const ask = { message: (t: string) => alert(t), confirm: (t: string) => confirm(t) }

const selected = [
  ...defaultWings,
]
const locale = createLocale('id')
const { nabi, registry } = createNabiWith(selected, { ask, locale })

// Bring your own highlighter (Prism, highlight.js, Shiki, …) — the wing stays as it is
// and only the attach is swapped (`makeCodeAttach` ships from the same door)
// { ...codeWing, attach: makeCodeAttach({ highlight: (source, lang) => [{ text: source }] }) }

const root = document.querySelector('.nabi')!
const content = document.querySelector('.nabi-content')!

const view = mountUploadView({ nabi, surface: content, locale })
const upload = mountUpload({
  nabi, root: content, locale,
  // your upload goes here — report progress with task.onProgress(0–100)
  uploader: async (task) => ({ uri: 'https://cdn.example/uploaded' }),
  extensions: ['png', 'jpg', 'pdf'], maxFileSize: 10 * 1024 * 1024,
  onStart: (tasks) => view.start(tasks),
  onProgress: (id, percent) => view.progress(id, percent),
  onSettle: () => view.settle(),
  onDone: () => view.done(),
})
const file = mountFile({ nabi, registry, store: browserFileStore(document), locale, name: () => 'note' })
const history = mountLocalHistory({ nabi, storage: browserHistoryStorage(window) })
const diff = mountDiffWing({ nabi, registry, surface: content, locale })

// The locale also sets the direction — Arabic and Urdu run right to left
mountSurface({ nabi, registry, root: content, locale, fileSink: upload.take })

const trigger = document.createElement('button')
trigger.type = 'button'
trigger.textContent = makeTranslator(locale).t('outline')
trigger.style.cssText = 'position:fixed;right:1rem;bottom:1rem;z-index:1000'
root.append(trigger)
const outline = mountOutline(content, {
  trigger, locale,
  scrollContainer: () => root.classList.contains('is-fullscreen') ? root : window,
  onChange: ({ items, activeIndex, available, open }) => {
    trigger.hidden = !available
    trigger.setAttribute("aria-expanded", String(open))
  },
})
trigger.onclick = () => outline.toggle()
// Call outline.unmount() when removing the editor

const settle = watchSettle(document, { surface: content })
const shared = { nabi, registry, surface: content, settle, locale }
// A tool that needs a panel comes back to the host — without this the button is dead
const toolbar = mountToolbar({
  ...shared, root: document.querySelector('#toolbar')!,
  file,
  onFiles: upload.take,
  onHost: (w) => {
    if (w === 'diff') { diff.open(); return }
    if (w !== 'localHistory') return
    openHistoryPanel({
      history, surface: content, locale, sessionId: history.sessionId,
      render: (record) => createNabiWith(selected, { doc: JSON.parse(record.body) }).nabi.getHtml(),
    })
  },
})
const context = mountContextToolbar({ ...shared, root: document.querySelector('#context')! })
mountHints({ toolbar, context, root, surface: content })
// The preview and fullscreen buttons — they stand their own box at the end of the row
mountViewTools({ ...shared, root, container: document.querySelector('#toolbar')! })

// on every change — hook up your own code here
// nabi.onChange(() => user_callback(nabi.getHtml()))

// Call from your language selector. Content and editing history stay intact.
// locale.setLocale('ko')