• Stars
    star
    275
  • Rank 149,357 (Top 3 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 2 years ago
  • Updated 21 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Rich Text Editor plugin for Filament Forms.

Filament Tiptap Editor

A Tiptap integration for Filament Admin/Forms.

tiptap-editor-og

Installation

Install the package via composer

composer require awcodes/filament-tiptap-editor:"^3.0"

In an effort to align with Filament's theming methodology you will need to use a custom theme to use this plugin.

Note If you have not set up a custom theme and are using a Panel follow the instructions in the Filament Docs first. The following applies to both the Panels Package and the standalone Forms package.

  1. Import the plugin's stylesheet and tippy.js stylesheet (if not already included) into your theme's css file.
@import '<path-to-vendor>/awcodes/filament-tiptap-editor/resources/css/plugin.css';
  1. Add the plugin's views to your tailwind.config.js file.
content: [
    ...
    '<path-to-vendor>/awcodes/filament-tiptap-editor/resources/**/*.blade.php',
]
  1. Add the tailwindcss/nesting plugin to your postcss.config.js file.
module.exports = {
    plugins: {
        'tailwindcss/nesting': {},
        tailwindcss: {},
        autoprefixer: {},
    },
}
  1. Rebuild your custom theme.
npm run build

Upgrading from 2.x to 3.x

  1. Output is now set with an Enum, please update your files to use TiptapOutput in all place where you are setting the output, including the config file.
  2. barebone profile setting was renamed to minimal

Usage

The editor extends the default Field class so most other methods available on that class can be used when adding it to a form.

use FilamentTiptapEditor\TiptapEditor;
use FilamentTiptapEditor\Enums\TiptapOutput;

TiptapEditor::make('content')
    ->profile('default|simple|minimal|none|custom')
    ->tools([]) // individual tools to use in the editor, overwrites profile
    ->disk('string') // optional, defaults to config setting
    ->directory('string or Closure returning a string') // optional, defaults to config setting
    ->acceptedFileTypes(['array of file types']) // optional, defaults to config setting
    ->maxFileSize('integer in KB') // optional, defaults to config setting
    ->output(TiptapOutput::Html) // optional, change the format for saved data, default is html
    ->maxContentWidth('5xl')
    ->required();

Rendering content in Blade files

If you are storing your content as JSON then you will likely need to parse the data to HTML for output in Blade files. To help with this there is a helper function tiptap_converter that will convert the data to one of the three supported Tiptap formats.

Styling the output is entirely up to you.

{!! tiptap_converter()->asHTML($post->content) !!}
{!! tiptap_converter()->asJSON($post->content) !!}
{!! tiptap_converter()->asText($post->content) !!}

Table of Contents

If you are using the heading tool in your editor you can also generate a table of contents from the headings in the content. This is done by passing the content to the asHTML() method and setting the toc option to true. You can also pass a maxDepth option to limit the depth of headings to include in the table of contents.

<!-- this will generate links for all headings up to h3 -->
{!! tiptap_converter()->asHTML($post->content, toc: true, maxDepth: 3) !!}

<!-- this will generate a table of contents with headings up to h3 -->
{!! tiptap_converter()->asToc($post->content, maxDepth: 3) !!}

Config

The plugin will work without publishing the config, but should you need to change any of the default settings you can publish the config file with the following Artisan command:

php artisan vendor:publish --tag="filament-tiptap-editor-config"

Profiles / Tools

The package comes with 3 profiles (or toolbars) out of the box. You can also use a pipe | to separate tools into groups. The default profile is the full set of tools.

'profiles' => [
    'default' => [
        'heading', 'bullet-list', 'ordered-list', 'checked-list', 'blockquote', 'hr',
        'bold', 'italic', 'strike', 'underline', 'superscript', 'subscript', 'lead', 'small', 'align-left', 'align-center', 'align-right',
        'link', 'media', 'oembed', 'table', 'grid-builder', 'details',
        'code', 'code-block', 'source',
    ],
    'simple' => [
        'heading', 'hr', 'bullet-list', 'ordered-list', 'checked-list',
        'bold', 'italic', 'lead', 'small',
        'link', 'media',
    ],
    'minimal' => [
        'bold', 'italic', 'link', 'bullet-list', 'ordered-list',
    ],
],

See filament-tiptap-editor.php config file for modifying profiles to add / remove buttons from the editor or to add your own.

Tools can also be added on a per-instance basis by using the ->tools() modifier to overwrite the profile set for the instance. A full list of tools can be found in the filament-tiptap-editor.php config file under the default profile setting.

Media / Images

[
    'accepted_file_types' => ['image/jpeg', 'image/png', 'image/webp', 'image/svg+xml', 'application/pdf'],
    'disk' => 'public',
    'directory' => 'images',
    'visibility' => 'public',
    'preserve_file_names' => false,
    'max_file_size' => 2042,
    'image_crop_aspect_ratio' => null,
    'image_resize_target_width' => null,
    'image_resize_target_height' => null,
]

Output format

Tiptap has 3 different output formats. See: https://tiptap.dev/guide/output

If you want to change the output format that is stored in the database you can change the default config or specify it in each instance.

use FilamentTiptapEditor\Enums\TiptapOutput;

TiptapEditor::make('content')
    ->output(FilamentTiptapEditor\TiptapOutput::Json);

Note If you want to store the editor content as array / json you have to set the database column as longText or json type. And cast it appropriately in your model class.

// in your migration
$table->json('content');

// in your model
protected $casts = [
    'content' => 'json' // or 'array'
];

RTL Support

In order for things like text align to work properly with RTL languages you can switch the direction key in the config to 'rtl'.

// config/filament-tiptap-editor.php
'direction' => 'rtl'

Max Content Width

To adjust the max content width of the editor globally set max_content_width key in the config to one of the tailwind max width sizes or full for full width. This could also be set on a per-instance basis with the ->maxContentWidth() method.

'max_content_width' => 'full'
use FilamentTiptapEditor\TiptapEditor;

TiptapEditor::make('content')
    ->maxContentWidth('3xl');

Overrides

The Link and Media modals are built using Filament Form Component Actions. This means it is easy enough to swap them out with your own implementations.

Link Modal

You may override the default Link modal with your own Action and assign to the link_action key in the config file. Make sure the default name for your action is filament_tiptap_link.

See vendor/awcodes/filament-tiptap-editor/src/Actions/LinkAction.php for implementation.

Media Modal

You may override the default Media modal with your own Action and assign to the media_action key in the config file. Make sure the default name for your action is filament_tiptap_media.

See vendor/awcodes/filament-tiptap-editor/src/Actions/MediaAction.php for implementation.

Initial height of editor field

You can add extra input attributes to the field with the extraInputAttributes() method. This allows you to do things like set the initial height of the editor.

TiptapEditor::make('content')
    ->extraInputAttributes(['style' => 'min-height: 12rem;']),

Bubble and Floating Menus

By default, the editor uses Bubble and Floating menus to help with creating content inline, so you don't have to use the toolbar. If you'd prefer to not use the menus you can disable them on a per-instance basis or globally in the config file.

TiptapEditor::make('content')
    ->disableFloatingMenus()
    ->disableBubbleMenus();
'disable_floating_menus' => true,
'disable_bubble_menus' => true,

You can also provide you own tools to for the floating menu, should you choose. Defaults can be overwritten via the config file.

TiptapEditor::make('content')
    ->floatingMenuTools(['grid-builder', 'media', 'link'])
'floating_menu_tools' => ['media', 'grid-builder', 'details', 'table', 'oembed', 'code-block']

Grid layouts

When using the grid tool, you can customize the available layouts in the dropdown by passing them to the gridLayouts() method:

TiptapEditor::make('content')
    ->gridLayouts([
        'two-columns',
        'three-columns',
        'four-columns',
        'five-columns',
        'fixed-two-columns',
        'fixed-three-columns',
        'fixed-four-columns',
        'fixed-five-columns',
        'asymmetric-left-thirds',
        'asymmetric-right-thirds',
        'asymmetric-left-fourths',
        'asymmetric-right-fourths',
    ]);

Custom Blocks

Note To use custom blocks you must store your content as JSON.

There are 3 components you need to create a custom block for Tiptap Editor.

  • A block class that extends TiptapBlock and defines the settings for the block.
  • A 'preview' blade file
  • A 'rendered' blade file

Creating a custom block

Block class

use FilamentTiptapEditor\TiptapBlock;

class BatmanBlock extends TiptapBlock
{
    public string $preview = 'blocks.previews.batman';

    public string $rendered = 'blocks.rendered.batman';

    public function getFormSchema(): array
    {
        return [
            TextInput::make('name'),
            TextInput::make('color'),
            Select::make('side')
                ->options([
                    'Hero' => 'Hero',
                    'Villain' => 'Villain',
                ])
                ->default('Hero')
        ];
    }
}

Static blocks

If you simply need a placeholder to output a block that doesn't have settings you can simply not provide a getFormSchema method and no modal will be shown and blocks will be directly inserted into the editor.

use FilamentTiptapEditor\TiptapBlock;

class StaticBlock extends TiptapBlock
{
    public string $preview = 'blocks.previews.static';

    public string $rendered = 'blocks.rendered.static';
}

Modal width, slide overs and icons

Note: Currently, icons will only be show on the drag and drop block panel

class BatmanBlock extends TiptapBlock
{
    public string $width = 'xl';
    
    public bool $slideOver = true;
    
    public ?string $icon = 'heroicon-o-film';
}

Preview view

Preview views are just standard blade views. Unfortunately, you cannot use Livewire components in a block preview as they will not work correctly due to the editor having to be wire:ignore.

resources/views/blocks/previews/batman.blade.php

<div class="flex items-center gap-6">
    <div class="text-5xl">
        @php
            echo match($name) {
                'robin' => '🐤',
                'ivy' => '🥀',
                'joker' => '🤡',
                default => '🦇'
            }
        @endphp
    </div>
    <div>
        <p>Name: {{ $name }}</p>
        <p style="color: {{ $color }};">Color: {{ $color }}</p>
        <p>Side: {{ $side ?? 'Good' }}</p>
    </div>
</div>

Rendered view

Rendered views are normal blade files and can also be used to output livewire components with your block data.

resources/views/blocks/rendered/batman.blade.php

<div>
    <livewire:batman-block
        :name="$name"
        :color="$color"
        :side="$side"
    />
</div>

Registering your blocks with the editor

In the register method of a service provider you can add your blocks to the editor via configureUsing.

Note You will also need to add the 'blocks' key where appropriate in your profiles in the tiptap config.

use App\TiptapBlocks\BatmanBlock;
use App\TiptapBlocks\StaticBlock;
use FilamentTiptapEditor\TiptapEditor;

TiptapEditor::configureUsing(function (TiptapEditor $component) {
    $component
        ->blocks([
            BatmanBlock::class,
            StaticBlock::class,
        ]);
});

By default, the drag and drop blocks panel will be open in the editor. If you want to change this you can use the collapseBlocksPanel modifier on the Editor instance or globally with configureUsing.

use App\TiptapBlocks\BatmanBlock;
use App\TiptapBlocks\StaticBlock;
use FilamentTiptapEditor\TiptapEditor;

TiptapEditor::configureUsing(function (TiptapEditor $component) {
    $component
        ->collapseBlocksPanel()
        ->blocks([...]);
});

Merge tags

Merge tags can be used with JSON-based editor content to replace placeholders with dynamic content. Merge tags are defined in the mergeTags() method of the editor instance:

TiptapEditor::make('content')
    ->mergeTags([
        'first_name',
        'last_name',
    ])

To insert a merge tag, the user can either type {{ to open an autocomplete menu, or drag a merge tag into the editor from the "blocks panel". You can remove the tags from the blocks panel using showMergeTagsInBlocksPanel(false):

TiptapEditor::make('content')
    ->mergeTags([...])
    ->showMergeTagsInBlocksPanel(false)

Usage in Standalone Forms Package

If you are using any of the tools that require a modal (e.g. Insert media, Insert video, etc.), make sure to add {{ $this->modal }} to your view after the custom form:

<form wire:submit.prevent="submit">
    {{ $this->form }}

    <button type="submit">
        Save
    </button>
</form>

{{ $this->modal }}

Custom Extensions

You can add your own extensions to the editor by creating the necessary files and adding them to the config file extensions array.

This only support CSS and JS with Vite.

You can read more about custom extensions at https://tiptap.dev/guide/custom-extensions.

JS

First, create a directory for you custom extensions at resources/js/tiptap and add your extension files.

import { Node, mergeAttributes } from "@tiptap/core";

const Hero = Node.create({
    name: "hero",
    ...
})

export default Hero

Next, create at a file at resources/js/tiptap/extensions.js and add the following code.

Note that when adding your extension to the array you must register them a key:array set.

import Hero from "./hero.js";

window.TiptapEditorExtensions = {
    hero: [Hero]
}

CSS

Create a css file for your custom extensions at resources/css/tiptap/extensions.css. All styles should be scoped to the parent class of .tiptap-content.

.tiptap-content {
    .hero-block {
        ...
    }
}

Vite Config

Now you need to add these to your vite.config.js file and run a build to generate the files.

export default defineConfig({
    plugins: [
        laravel({
            input: [
                ...
                'resources/js/tiptap/extensions.js',
                'resources/css/tiptap/extensions.css',
            ],
            refresh: true,
        }),
    ],
});

PHP Parser

You will also need to create a PHP version of your extension in order for the content to be read from the database and rendered in the editor or to your front end display. You are free to create this anywhere in your app, a good place is something like app/TiptapExtensions/YourExtenion.php.

You can read more about the php parsers at https://github.com/ueberdosis/tiptap-php

namespace App\TiptapExtensions;

use Tiptap\Core\Node;

class Hero extends Node
{
    public static $name = 'hero';
    ...
}

Toolbar Button

You will also need to crate a dedicated view for you toolbar button. This should be placed somewhere in your app's resources/views/components directory. You are free to code the buttons as you see fit, but it is recommended to use the plugin's view components for uniformity.

<x-filament-tiptap-editor::button
    label="Hero"
    active="hero"
    action="editor().commands.toggleHero()"
>
    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="currentColor" d="M5 21q-.825 0-1.413-.588T3 19V5q0-.825.588-1.413T5 3h14q.825 0 1.413.588T21 5v14q0 .825-.588 1.413T19 21H5Zm0-2h14v-5H5v5Z"/></svg>
    
    <span class="sr-only">{{ $label }}</span>
</x-filament-tiptap-editor::button>

Registering the Extensions

Finally, you need to register your extensions in the config file and add the new extension to the appropriate profile.

'profiles' => [
    'minimal' => [
        ..., 
        'hero',
    ],
],
'extensions_script' => 'resources/js/tiptap/extensions.js',
'extensions_styles' => 'resources/css/tiptap/extensions.css',
'extensions' => [
    [
        'id' => 'hero',
        'name' => 'Hero',
        'button' => 'tools.hero',
        'parser' => \App\TiptapExtensions\Hero::class,
    ],
],

Versioning

This project follow the Semantic Versioning guidelines.

License

Copyright (c) 2022 Adam Weston and contributors

Licensed under the MIT license, see LICENSE.md for details.

More Repositories

1

filament-curator

A media picker plugin for Filament Panels.
PHP
321
star
2

filament-table-repeater

A modified version of the Filament Forms Repeater to display it as a table.
PHP
199
star
3

filament-quick-create

Plugin for Filament Panels that adds a dropdown menu to the header to quickly create new items.
PHP
165
star
4

overlook

An app overview widget for Filament panels.
PHP
158
star
5

filament-badgeable-column

A custom table column that supports prefixed and suffixed badges to the column content.
PHP
118
star
6

drop-in-action

A form component for Filamentphp allowing actions inside of forms.
PHP
86
star
7

alpine-floating-ui

Add Floating UI functionality to Alpine 3.x components.
JavaScript
79
star
8

filament-sticky-header

A Filament Panels plugin to make headers sticky when scrolling.
PHP
60
star
9

shout

A simple inline contextual notice for Filament forms, basically just a fancy placeholder.
PHP
50
star
10

scribble

PHP
43
star
11

filament-versions

A mostly useless package to display framework versions on Filament panels.
PHP
40
star
12

filament-addons

A set of components / fields to extend Filament Admin.
PHP
30
star
13

light-switch

Plugin to add theme switching (light/dark/system) to the auth pages for Filament Panels.
PHP
29
star
14

filament-extras

PHP
28
star
15

filament-gravatar

Replace Filament's default avatar url provider with one for Gravatar.
PHP
26
star
16

recently

Easily track and access recently viewed records in your filament panels.
PHP
22
star
17

repro

CLI tool for quickly recreating reproduction repos locally.
PHP
18
star
18

preset-color-picker

A color picker field for Filament Forms that uses preset color palettes.
PHP
17
star
19

Matinee

OEmbed field for Filament Panel and Form Builders.
PHP
17
star
20

filament-installer

Filament Admin Panel application installer.
PHP
16
star
21

html-faker

A better html faker.
PHP
13
star
22

trov

A Laravel / Filament starter kit for CMS functionality on websites.
PHP
11
star
23

hydro

CLI for creating new Filament plugins
PHP
9
star
24

filament-plugin-purge

A purge tool to keep your Filament plugin from bloating / duplicating Filament's default styles.
CSS
9
star
25

palette

A color picker field for Filament Forms that uses preset color palettes.
PHP
8
star
26

pounce

A global modal/dialog plugin for Filament.
PHP
7
star
27

filament-sentry

A basic auth scaffolding for Filament utilizing Filament Breezy, Filament Shield and custom User Resources.
PHP
7
star
28

filament-oembed

PHP
6
star
29

sink

A collection of components for Filament.
PHP
6
star
30

curator

PHP
4
star
31

translation-field

A form component for Filament to handle translations at the field / input level.
PHP
3
star
32

postal-codes

This is a package to easily install and use postal codes in your Laravel application from GeoNames.org
PHP
3
star
33

tiptap-demo

Project for testing tiptap functionality
PHP
3
star
34

assistant

A collection of helpers for use in Laravel projects.
PHP
2
star
35

dimmer

Blade
2
star
36

trov-components

A set of components, fields and layouts to extend Filament Admin.
PHP
2
star
37

awcodes-astro

Astro
2
star
38

filament-skins

PHP
2
star
39

gtm

Easy integration of Google Tag Manager into your Laravel application.
PHP
2
star
40

trov-installer

PHP
1
star
41

colors-experiment

PHP
1
star
42

pluginshot

AWcodes Plugin Screenshot Generator
PHP
1
star
43

headings

A Custom Form Component to demo building a standalone Forms Builder plugin for Filament
PHP
1
star
44

laravel-remix

Revert a new Laravel application to Laravel Mix.
PHP
1
star
45

trov-filament

PHP
1
star