awcodes / filament-tiptap-editor

A Rich Text Editor plugin for Filament Forms.
MIT License
278 stars 77 forks source link

Using a modal action inside a modal containing the editor breaks the editor #380

Closed mxm1070 closed 3 months ago

mxm1070 commented 5 months ago

Filament Version

v3.2.73

Plugin Version

v3.3.3

PHP Version

8.2.18

Problem description

Hey Adam,

I came across a strange interaction in a project. When presenting the TiptapEditor field in a modal, if you cause another modal to spawn such as a hint action, it will break the TiptapEditor field because of this line x-on:close-modal.window="destroyEditor($event)" in tiptap-editor.blade.php.

Here's it in action: https://github.com/awcodes/filament-tiptap-editor/assets/11588575/1b686070-ab1a-4623-9d82-f99ac002ece4

A work around is to add the class curator-panel to the underlying view, but I'm hoping for a more concrete solution that doesn't involve publishing views.

Checkout my example repo and run composer setup if you want to take a quick look.

If you want the real world place where this is happening please see: https://github.com/canyongbs/advisingapp/blob/4a789bbee025f0fa60c55850665f6479cf0e7af3/app-modules/engagement/src/Filament/Resources/EngagementResource/Pages/CreateEngagement.php#L98

Thanks!

Expected behavior

The editor to persist between modal views.

Steps to reproduce

Implement a simple form view and hint action like so:

public static function form(Form $form): Form
{
    return $form
        ->schema([
            Forms\Components\TextInput::make('title')
                ->required()
                ->string()
                ->maxLength(255)
                ->columnSpanFull(),
            TiptapEditor::make('content')
                ->output(TiptapOutput::Json)
                ->required()
                ->columnSpanFull()
                ->hintAction(fn (TiptapEditor $component) => Action::make('loadTemplate')
                    ->form([
                        Forms\Components\Textarea::make('content')
                            ->default('lorem ipsum dolor sit amet')
                            ->columnSpanFull()
                    ])
                    ->action(function (array $data) use ($component) {
                        $component->state($data['content']);
                    }),
                ),
        ]);
}

Reproduction repository

https://github.com/mxm1070/tiptap-editor-example

Relevant log output

No response

awcodes commented 4 months ago

Thanks for the report. Yea. Modals have been a huge headache. I will look into it as soon as I get a chance.

AntoineCrzt commented 4 months ago

Hey, Same issue here with a TipTap inside a CreateAction or an EditAction that open in modals. I cannot add any image for instance. [Warning] Alpine Expression Error: Can't find variable: destroyEditor (livewire.js, line 1123)

Expression: "destroyEditor($event)"

<div wire:ignore ax-load ax-load-src="http://my-dev-journey.test/js/awcodes/tiptap-editor/components/tiptap.js?v=3.2.82.0" class="relative z-0 tiptap-wrapper rounded-md bg-white dark:bg-gray-900 focus-within:ring focus-within:ring-primary-500 focus-within:z-10" x-bind:class="{ 'tiptap-fullscreen': fullScreenMode }" x-data="tiptap({
                        state: $wire.entangle('mountedActionsData.0.content'),
                        statePath: 'mountedActionsData.0.content',
                        tools: JSON.parse('[\u0022heading\u0022,\u0022bullet-list\u0022,\u0022ordered-list\u0022,\u0022checked-list\u0022,\u0022blockquote\u0022,\u0022hr\u0022,\u0022|\u0022,\u0022bold\u0022,\u0022italic\u0022,\u0022strike\u0022,\u0022underline\u0022,\u0022superscript\u0022,\u0022subscript\u0022,\u0022lead\u0022,\u0022small\u0022,\u0022color\u0022,\u0022highlight\u0022,\u0022align-left\u0022,\u0022align-center\u0022,\u0022align-right\u0022,\u0022|\u0022,\u0022link\u0022,\u0022media\u0022,\u0022oembed\u0022,\u0022table\u0022,\u0022grid-builder\u0022,\u0022details\u0022,\u0022|\u0022,\u0022code\u0022,\u0022code-block\u0022,\u0022source\u0022,\u0022blocks\u0022]'),
                        disabled: false,
                        locale: 'fr',
                        floatingMenuTools: JSON.parse('[\u0022media\u0022,\u0022grid-builder\u0022,\u0022details\u0022,\u0022table\u0022,\u0022oembed\u0022,\u0022code-block\u0022,\u0022blocks\u0022]'),
                        placeholder: null,
                        mergeTags: [],
                    })" x-on:click.away="focused = false" x-on:keydown.escape="fullScreenMode = false" x-on:insert-content.window="insertContent($event)" x-on:unset-link.window="$event.detail.statePath === 'mountedActionsData.0.content' ? unsetLink() : null" x-on:update-editor-content.window="updateEditorContent($event)" x-on:refresh-tiptap-editors.window="refreshEditorContent()" x-on:dragged-block.stop="$wire.mountFormComponentAction('mountedActionsData.0.content', 'insertBlock', {
                        type: $event.detail.type,
                        coordinates: $event.detail.coordinates,
                    })" x-on:dragged-merge-tag.stop="insertMergeTag($event)" x-on:insert-block.window="insertBlock($event)" x-on:update-block.window="updateBlock($event)" x-on:open-block-settings.window="openBlockSettings($event)" x-on:delete-block.window="deleteBlock()" x-on:close-modal.window="destroyEditor($event)" x-trap.noscroll="fullScreenMode">…</div>

<div wire:ignore ax-load ax-load-src="http://my-dev-journey.test/js/awcodes/tiptap-editor/components/tiptap.js?v=3.2.82.0" class="relative z-0 tiptap-wrapper rounded-md bg-white dark:bg-gray-900 focus-within:ring focus-within:ring-primary-500 focus-within:z-10" x-bind:class="{ 'tiptap-fullscreen': fullScreenMode }" x-data="tiptap({
                        state: $wire.entangle('mountedActionsData.0.content'),
                        statePath: 'mountedActionsData.0.content',
                        tools: JSON.parse('[\u0022heading\u0022,\u0022bullet-list\u0022,\u0022ordered-list\u0022,\u0022checked-list\u0022,\u0022blockquote\u0022,\u0022hr\u0022,\u0022|\u0022,\u0022bold\u0022,\u0022italic\u0022,\u0022strike\u0022,\u0022underline\u0022,\u0022superscript\u0022,\u0022subscript\u0022,\u0022lead\u0022,\u0022small\u0022,\u0022color\u0022,\u0022highlight\u0022,\u0022align-left\u0022,\u0022align-center\u0022,\u0022align-right\u0022,\u0022|\u0022,\u0022link\u0022,\u0022media\u0022,\u0022oembed\u0022,\u0022table\u0022,\u0022grid-builder\u0022,\u0022details\u0022,\u0022|\u0022,\u0022code\u0022,\u0022code-block\u0022,\u0022source\u0022,\u0022blocks\u0022]'),
                        disabled: false,
                        locale: 'fr',
                        floatingMenuTools: JSON.parse('[\u0022media\u0022,\u0022grid-builder\u0022,\u0022details\u0022,\u0022table\u0022,\u0022oembed\u0022,\u0022code-block\u0022,\u0022blocks\u0022]'),
                        placeholder: null,
                        mergeTags: [],
                    })" x-on:click.away="focused = false" x-on:keydown.escape="fullScreenMode = false" x-on:insert-content.window="insertContent($event)" x-on:unset-link.window="$event.detail.statePath === 'mountedActionsData.0.content' ? unsetLink() : null" x-on:update-editor-content.window="updateEditorContent($event)" x-on:refresh-tiptap-editors.window="refreshEditorContent()" x-on:dragged-block.stop="$wire.mountFormComponentAction('mountedActionsData.0.content', 'insertBlock', {
                        type: $event.detail.type,
                        coordinates: $event.detail.coordinates,
                    })" x-on:dragged-merge-tag.stop="insertMergeTag($event)" x-on:insert-block.window="insertBlock($event)" x-on:update-block.window="updateBlock($event)" x-on:open-block-settings.window="openBlockSettings($event)" x-on:delete-block.window="deleteBlock()" x-on:close-modal.window="destroyEditor($event)" x-trap.noscroll="fullScreenMode">…</div>

After upgrading from v3.2.25 to v3.3.3, the error changed a bit : Alpine Expression Error: undefined is not an object (evaluating 'this.editor().chain')

Expression: "insertContent($event)"

Hard to debug it to be honest

awcodes commented 4 months ago

Hard indeed.

dgoetzit commented 4 months ago

Hello @awcodes! I wanted to follow up to see if this is something you had looked into, or wanted some help resolving. As @mxm1070 mentioned, adding the curator-panel class to the underlying view resolves the issue, but also results in the editor not being destroyed when the modal is closed.

awcodes commented 4 months ago

I'm definitely open to help if you can figure out a way to target and clear while ignoring other modal's close events.

awcodes commented 4 months ago

Update: mostly have this fixed. But need a better way to manage the editors when the modal can have two editors tied to the same root state.

awcodes commented 3 months ago

See if v3.3.7 resolves this for you and let me know.

dgoetzit commented 3 months ago

See if v3.3.7 resolves this for you and let me know.

It looks like this resolves the modal within a modal issue, but seems to re-introduce what you addressed here: https://github.com/awcodes/filament-tiptap-editor/pull/363 as editors within a modal will no longer clear their content on modal close.

awcodes commented 3 months ago

Hmm, they are clearing in my tests. Can you give me a reproduction repo?

awcodes commented 3 months ago

Also make sure to run artisan filament:assets. Maybe you're not getting the updated scripts.

dgoetzit commented 3 months ago

Hey @awcodes! I will try to get you a reproduction repo if I have some time, as the one I am experiencing issues in is a little bit of a lift to get stood up. Perhaps the issue is something specific to our code base and use case, as there is definitely a bit going on https://github.com/canyongbs/advisingapp/blob/main/app-modules/engagement/src/Filament/Resources/EngagementResource/Pages/CreateEngagement.php#L86

Nathan269 commented 3 months ago

I'm also having issues on version 3.3.7. The tiptap editor looks like this within my modal:

Screenshot 2024-06-13 at 13 03 35

When I view my form within my resource and not in the modal, the content displays as expected and contains the tools I have set for the editor.

awcodes commented 3 months ago

I have this modal stuff solved, I think. But it introduced a regression with repeaters and builders. I'm trying to get it solved. Thanks again for your patience.

awcodes commented 3 months ago

Check v3.4.0 and please reopen if you are still having issues.