Skip to content

FormQuill

Rich-text editor wrapper di atas Quill/vue-quilly, dengan image upload dan toolbar konfigurabel.

Bagian dari: vue-saform · Family: Rich Text

FormQuill membungkus Quill jadi component form yang konsisten dengan family lain — label, error state, dan validation pipeline yang sama, meskipun struktur field-nya berbeda (label selalu floated, tidak ada state resting, karena rich-text tidak punya ambiguitas kosong-vs-terisi). Toolbar bisa dikustomisasi penuh, dan upload gambar (lewat toolbar atau paste/drop) diserahkan ke callback uploadImage yang kamu sediakan sendiri — tidak ada asumsi HTTP client atau endpoint tertentu. contentType mendukung HTML string atau Delta object, dua-duanya reaktif lewat v-model.

IMPORTANT

FormQuill diimpor dari subpath terpisah @bpmlib/vue-saform/quill, bukan barrel utama — lihat Installation & Setup untuk peer dependency yang wajib diinstall.


Import

ts
import { FormQuill } from '@bpmlib/vue-saform/quill';
import '@bpmlib/vue-saform/quill.css';

Instalasi: lihat Installation & Setup di halaman utama.


Usage

vue
<script setup lang="ts">
import { ref } from 'vue';
import { FormQuill } from '@bpmlib/vue-saform/quill';
import { required } from '@bpmlib/vue-saform';

const content = ref('');
</script>

<template>
  <FormQuill id="article" v-model="content" label="Isi Artikel" required :validation="required()" />
</template>

API Reference

FormQuill

Cara Penggunaan:

Label selalu tampil di posisi floated (tidak ada state resting) — rich-text field tidak punya ambiguitas kosong-vs-terisi yang layak dianimasikan. disabled/readonly menampilkan ban icon di samping label (bukan di baris input seperti component lain, karena tidak ada baris input terpisah di sini).

Props

NameTypeDefaultDescription
idstring-Id editor, juga dipakai sebagai name. Wajib.
labelstring-Teks label (selalu floated)
contentType'html' | 'delta''html'Shape modelValue/value yang di-emit Lihat selengkapnya
disabledbooleanfalse
readonlybooleanfalseRendering sama seperti disabled (ban icon di samping label)
requiredbooleanfalseBuilt-in rule required(), dicek terhadap plain-text content (bukan raw HTML/Delta)
hasErrorbooleanfalsePaksa visual error state terlepas dari internal validation state
toolbarunknown[]DEFAULT_QUILL_TOOLBARKonfigurasi toolbar container Quill
uploadImage(file: File) => Promise<string>-Handler upload untuk tombol image di toolbar dan paste/drop Lihat selengkapnya
validationValidationInput<unknown>-Custom validation rule(s), jalan bersama built-in required
messagesValidationMessages-Override pesan validasi default, di-shallow-merge
hideValidationbooleanfalseSkip seluruh perhitungan pesan validasi internal
contentType

Menentukan shape modelValue dan value yang di-emit.

NOTE

vue-quilly (dependency internal yang dipakai) selalu bekerja dengan HTML string secara internal — tidak ada mode Delta asli. Saat contentType="delta", FormQuill men-JSON-stringify Delta object jadi string untuk lapisan vue-quilly, lalu JSON-parse kembali sebelum expose ke v-model kamu. Behavior dari sisi consumer tetap sesuai ekspektasi (v-model selalu berupa Delta object), boundary serialisasi ini murni implementasi internal.

Values:

ts
type QuillContentType = 'html' | 'delta';
uploadImage

Backing untuk tombol image toolbar dan paste/drop upload module (imageUploader). Omit untuk membuat fitur upload gambar inert (tombol tetap muncul tapi tidak melakukan apapun).

Signature:

ts
uploadImage: (file: File) => Promise<string>

Parameters:

  • file - File gambar yang dipilih/di-drop/di-paste user

Returns: Promise<string> — URL gambar yang sudah ter-upload, disisipkan ke editor

Contoh:

ts
async function uploadImage(file: File): Promise<string> {
  const formData = new FormData();
  formData.append('image', file);
  const res = await fetch('/api/upload', { method: 'POST', body: formData });
  const { url } = await res.json();
  return url;
}

Use Case: FormQuill tidak mengasumsikan HTTP client atau endpoint backend tertentu — kamu yang mengontrol penuh mekanisme upload-nya.

Model

NameTypeDefaultDescription
v-modelstring | Record<string, unknown> | null''HTML string (contentType="html") atau Delta object (contentType="delta")

Slots

NamePropsDescription
description-Baris deskripsi di bawah field
errors-Baris pesan error custom, menggantikan pesan validasi bawaan

Exposed

NameTypeDescription
validate()() => Promise<boolean>Jalankan validasi, return true jika valid

Contoh:

vue
<FormQuill
  id="content"
  v-model="content"
  label="Konten"
  :upload-image="uploadImage"
  required
/>

Examples

1. Delta Content Type

vue
<script setup lang="ts">
const doc = ref<Record<string, unknown>>({});
</script>

<template>
  <FormQuill id="doc" v-model="doc" content-type="delta" label="Dokumen" />
</template>

2. Custom Toolbar

vue
<FormQuill
  id="comment"
  v-model="comment"
  label="Komentar"
  :toolbar="[['bold', 'italic'], ['link']]"
/>

Styling

Styling sepenuhnya self-contained, dari dist/quill.css (terpisah dari dist/style.css utama) — lihat Import di atas. Component akan tampil fully styled langsung setelah import, tanpa setup tambahan.

CSS Variables

VariableDefaultDescription
--sa-fm-error-list-styledisclist-style-type untuk error list. Sama seperti FormInput