ComfyCoders TranquilTools
Docs /Laravel Vue FormBuilder
Repository
v1

WYSIWYG Field

A rich text editor field. The editor itself is resolved at runtime from a registry, so the package never imports an editor implementation and your build never inherits one.

use TranquilTools\FormBuilder\Fields\Wysiwyg;

Wysiwyg::make('content')
    ->label('Content')
    ->rules('nullable', 'string')

Registering an editor

An editor key only works once the matching component is registered in your app entrypoint (resources/js/app.ts). Register it once, use it in any form:

import QuillEditor from '@form-builder/wysiwyg/QuillEditor.vue';
import { registerWysiwygEditor } from '@form-builder/wysiwyg/registry';

registerWysiwygEditor('quill', QuillEditor);

Install the engine's own npm packages alongside it:

npm install vue-quilly quill

A field whose editor key is not registered renders a textarea instead of crashing. In development you also get a console.warn naming the missing key and every key that is registered.

Available adapters

Key Engine Licence npm packages Shipped
textarea — — — always available, no registration needed
quill Quill 2 BSD-3-Clause vue-quilly, quill @form-builder/wysiwyg/QuillEditor.vue
hugerte HugeRTE MIT hugerte, @hugerte/hugerte-vue @form-builder/wysiwyg/HugeRteEditor.vue
jodit Jodit 4 MIT jodit @form-builder/wysiwyg/JoditEditor.vue

Any other engine plugs in through the adapter contract. Only permissively licensed engines ship as first-party adapters.

HugeRTE

The community fork of TinyMCE 6, made when TinyMCE 7 moved to GPL. Register it the same way:

import HugeRteEditor from '@form-builder/wysiwyg/HugeRteEditor.vue';

registerWysiwygEditor('hugerte', HugeRteEditor);
npm install hugerte @hugerte/hugerte-vue

The adapter imports the engine, its theme, model, icons, skin and content stylesheet, so nothing is fetched from a CDN and no hugerteScriptSrc is needed.

Plugins are yours to import. The adapter ships none, because which ones a form needs is your decision. A toolbar entry whose plugin was never imported silently takes the whole toolbar down with it, so import each one you configure — next to the registration, before any form renders:

import 'hugerte/plugins/code';
import 'hugerte/plugins/link';
import 'hugerte/plugins/lists';
Wysiwyg::make('article')
    ->editor('hugerte')
    ->options([
        'menubar' => false,
        'plugins' => 'lists link code',
        'toolbar' => 'undo redo | bold italic | bullist numlist | link | code',
    ])

Worth knowing before you commit to it: HugeRTE is maintained by volunteers, its own documentation is still alpha and largely points at the TinyMCE 6 docs, and it cannot take in fixes from TinyMCE 7+ because those are GPL. Sanitizing on the server is what makes that acceptable — see Sanitize on the server.

Jodit

import JoditEditor from '@form-builder/wysiwyg/JoditEditor.vue';

registerWysiwygEditor('jodit', JoditEditor);
npm install jodit

Only the MIT jodit package is supported. jodit-pro and the OEM builds are out of scope: they are separate commercial products under their own terms, and the adapter is written against the free core's API. Jodit needs no Vue wrapper package — it is dependency-free TypeScript and the adapter drives the engine directly.


Choosing an editor

Use a registered editor

Wysiwyg::make('content')
    ->editor('quill')

Use the textarea

Always available, no registration and no npm packages:

Wysiwyg::make('content')
    ->editor('textarea')

The default editor is controlled by config('form-builder.wysiwyg.default-editor'). See Configuration.


Profiles

A profile is a list of features rather than editor options, so a form keeps the same toolbar when you switch editor:

Wysiwyg::make('body')
    ->editor('hugerte')
    ->profile('email')

Profiles live in config('form-builder.wysiwyg.profiles'). email ships with the package (bold, italic, underline, link, list, blockquote) and keeps working with a published config that predates profiles. An unknown profile throws an InvalidArgumentException.

'wysiwyg' => [
    'profiles' => [
        'email' => ['bold', 'italic', 'underline', 'link', 'list', 'blockquote'],
        'notes' => ['bold', 'italic', 'list', 'undo'],
    ],
],

A profile replaces the editor options from editors.<editor>.options in the config. ->options([...]) set on the field still wins: the adapter builds its config from the features first and lays your options over it. Nested objects are merged key by key, so ['modules' => ['clipboard' => [...]]] keeps the profile's Quill toolbar; arrays such as a toolbar list replace the profile's.

Each adapter leaves out what it cannot do. The textarea ignores profiles.

Feature Quill Jodit HugeRTE
bold, italic, underline, strike yes yes yes
link yes yes with hugerte/plugins/link
list (bullets and numbers) yes yes with hugerte/plugins/lists
blockquote yes in the paragraph dropdown yes
heading (H1 to H3) yes in the paragraph dropdown yes (blocks)
code-block yes in the paragraph dropdown (pre) with hugerte/plugins/codesample
align yes, as ql-align-* classes yes yes
indent yes, as ql-indent-* classes yes yes
color (text and background) yes yes yes
image yes yes with hugerte/plugins/image
clean (remove formatting) yes yes yes
undo (undo and redo) no, keyboard only yes yes
source (HTML view) yes, the source button yes with hugerte/plugins/code

Quill also gets a formats whitelist from the profile, so pasted text loses formatting the profile does not offer. HugeRTE plugins have to be imported in your app entrypoint; a feature whose plugin is missing is left out of the toolbar, with a console warning during development. Quill writes alignment and indentation as CSS classes, which mail clients drop, so keep align and indent out of a profile meant for e-mail.


Customizing Quill options

Override the Quill configuration for a specific field:

Wysiwyg::make('summary')
    ->label('Summary')
    ->options([
        'theme' => 'snow',
        'modules' => [
            'toolbar' => [
                ['bold', 'italic', 'underline'],
                [['list' => 'ordered'], ['list' => 'bullet']],
                ['clean'],
            ],
        ],
    ])

Options passed to ->options() replace the defaults from the config file for this field instance.

To set global defaults for all Wysiwyg fields, publish and edit the config file:

php artisan vendor:publish --tag="form-builder-config"

See Configuration → WYSIWYG for the full options reference.

Whatever ->options() contains is handed to the adapter as its config prop without being inspected. Its shape belongs to the engine you registered, not to this package.

Quill themes

The adapter imports quill/dist/quill.snow.css, so the default snow theme works out of the box. Any other theme needs its own stylesheet imported by your application — Quill ships the theme's positioning and tooltip styling in that file, so without it a bubble editor renders an invisible toolbar rather than no toolbar:

import 'quill/dist/quill.bubble.css';
Wysiwyg::make('notes')
    ->editor('quill')
    ->options([
        'theme' => 'bubble',
    ])

Quill source-view button

The bundled Quill adapter appends a button that swaps the editor for a raw HTML textarea. Turn it off per field:

Wysiwyg::make('content')
    ->options([
        'showSourceButton' => false,
    ])