Implement js library in custom widget

I have an app running on Inertia/Vue that I'm considering switching to Filament. My only hangup right now is that this app uses fullcalendar.io and specifically I need to render custom content for the event. I am aware of the fullcalendar plugin and have asked this question on that plugin's server but haven't gotten a response (https://discord.com/channels/883083792112300104/935819320699805737/1133498041144463411)

What I am wondering is if there is any way in Filament/Livewire/Alpine to make use of the content injection functionality offered by fullcalendar (https://fullcalendar.io/docs/content-injection). Using the Vue fullcalendar library, this is trivial because I can simply return a Vue component to the eventContent function since, in the background, fullcalendar is using VDOM (preact).

I realized I can create this HTML in a string in javascript and use the "arg" parameter that provides the calendar event for dynamic content but I am looking for a more elegant way to do this.

Trying to do this in Filament may not be a good fit but want to get some advice before writing off Filament for this project. Thanks
Solution
Okay so I have something like this:

Widget.php
use Filament\Widgets\Widget;
use Illuminate\Support\HtmlString;

class FullCalendarTest extends Widget
{
    protected static bool $isLazy = false;

    protected static string $view = 'filament.widgets.full-calendar-test';

    public $events = [];

    public function mount()
    {
        $this->events = [
            [
                'id' => 'test',
                'title' => 'Brian Kidd Tests',
                'start' => now()->format('Y-m-d'),
                'extendedProps' => [
                    'description' => '<strong>Hello from Filament Discord !</strong>',
                ],
            ],

            [
                'id' => 'test',
                'title' => 'Brian Kidd Tests Urgent',
                'start' => now()->addWeek()->format('Y-m-d'),
                'extendedProps' => [
                    'isUrgent' => true,
                    'description' => '<strong class="text-danger-600">Hello from Filament Discord !</strong>',
                ],
            ],
        ];
    }
}


resources/views/filament/widgets/full-calendar-test.blade.php
<x-filament-widgets::widget>
    <x-filament::section>
        <div id="calendar"></div>
    </x-filament::section>
    <script>
        document.addEventListener('livewire:initialized', () => {

            let calendarEl = document.getElementById('calendar');
            let calendar = new FullCalendar.Calendar(calendarEl, {
                initialView: 'dayGridMonth',
                // @this.events retreive your 'public $events = [];' in your Widget php class
                events: @this.events,

                eventContent: function(arg) {
                    let italicEl = document.createElement('i')

                    if (arg.event.extendedProps.isUrgent) {
                        italicEl.innerHTML = arg.event.extendedProps.description + ' (urgent)'
                    } else {
                        italicEl.innerHTML = arg.event.extendedProps.description
                    }

                    let arrayOfDomNodes = [ italicEl ]
                    return { domNodes: arrayOfDomNodes }
                }
            });
            calendar.render();
        })

    </script>
</x-filament-widgets::widget>


It's not a perfect solution I think, but you have something works 🙂
Was this page helpful?