Releases Covered: v4.13 - v4.15 & v5.8 - v5.10
The past three minor releases of Filament have brought a massive number of improvements to the way that you build applications with Filament. From UX improvements in our Rich Editor to optimizing load times for large forms, there are a ton of new tools you can use to make a big difference to your users!
We have a lot to cover here, so we're going to take a look at the team's favorite highlights from these releases. As always, though, you can find the full changelogs on Github if you want to dig a little deeper into the specifics.
#Updates to the Rich Editor
The team has given a lot of love to the Rich Editor component over the past few releases, and for good reason! Filament's Rich Editor component is built to be flexible, able to handle everything from the usual rich text all the way to building with custom blocks, and today, we've added even more ways to use it for your specific needs.
First, let's talk about those custom blocks. If you've never used them before, they're a great solution for letting your users piece together prebuilt blocks to make dynamic content or even full web pages. However, prior to these latest releases, once you've got a large number of blocks to choose from, things can get a bit unwieldy.
As of these recent updates, though, now the Rich Editor gives you more ways to customize and organize the block-picking experience. Blocks can now provide their own descriptive icons through the getIcon() method, you can now arrange blocks in a grid with the customBlocksGrid() method, and users can even search through blocks dynamically with the searchableCustomBlocks() method. One small detail I find particularly useful when it comes to searching through the custom blocks is that you can search for the name of a block's group rather than the block itself to show all blocks in that group! All of these new organizational methods should help your users find what they are looking for more quickly and easily than ever, especially as the list of blocks continues to grow!
Second, the team has added some updates to long Rich Editor documents as well by way of the stickyToolbar() and stickyPanels(). These methods keep the toolbar and the custom block and merge tag panels within easy reach while users scroll. Sticky panels apply when the editor is wide enough to display them beside the content; in narrower editors, the panels scroll normally.
Lastly, the team has added some new controls to help you manage grids more easily within your Rich Editor! These controls let users add columns to symmetrical grids, delete individual columns and their content, or remove the grid layout altogether! When you remove a full grid with these new tools, the content stays so your users can return to a regular layout without risk of losing everything they've written.
For a list of all Rich Editor configuration options, take a look at our Rich Editor documentation!
A big thank you to @imliam and @danharrin for their contributions here!
#Deferred form content
In addition to giving some love and care to the Rich Editor form field, Filament has also given some attention to those long forms that can crop up in our applications. We're all probably aware of the previous issue here: when loading a form in Filament, by default, form content inside collapsed sections, inactive tabs, and later wizard steps is still rendered when the page loads. Practically, this means that even form fields that are housed inside of a collapsed section that may or may not ever be interacted with by a user all still contribute to increasing the form's overall load and render time.
Nowhere is this more apparent than in long Repeater lists where, for a given Repeater, your user might only interact with a handful of items while the form insists on rendering every single field.
Now, however, thanks to the new deferLoading() Schema method, you can selectively tell Filament to defer rendering a given Schema and all of its child components until it enters the viewport! That means a collapsed section, an inactive tab, or a later wizard step can all wait to render until the user actually reaches it, giving your page a snappier and more responsive render time, especially on those longer forms.
For example, assume you have an ArticleResource that includes publishing settings. These settings are hardly ever viewed or changed after their initial setup, so they're a perfect candidate for deferred loading! Setting up deferred loading for this section is as easy as adding that deferLoading() method and a key() method to the schema definition like so:
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
Section::make('Publishing settings')
->key('publishingSettings')
->collapsed()
->schema(
Schema::make()
->components([
TextInput::make('slug'),
DateTimePicker::make('published_at')
->label('Published at'),
])
->deferLoading(),
)
With this, the child schema inherits the section's unique key. Once loaded, the child schema then stays loaded for the lifetime of the Livewire component, deferring the rendering work but ensuring that any loaded fields retain their intended Livewire interactivity once loaded!
You can find more details in the schema documentation for more information and specifics on how to implement deferred loading in your own applications!
Bonus update!
There's one nice quality-of-life update that I wanted to sneak in here because it's not big enough for an entire section on its own, but it helps improve the perceived performance of your application by your users.
Filament has now added a loadingSkeleton() method for tables that will, when enabled, cover the current records in a table with a loading skeleton while sorting, filtering, searching, or paging through results. This ensures that the table keeps its shape with the headers and pagination remaining visible while the background query runs to retrieve the relevant set of results.
This change won't make a slow query faster, but it gives users a visual indicator that their request is being processed correctly and that the application hasn't broken!
A big thank you to @KianAcquoy and @danharrin for their contributions here!
#Multi-factor challenges are available everywhere!
Sometimes, a user signing in is only the first place you want them to verify their identity with a multi-factor challenge. For example, you may want to put the user through this heightened security challenge when they're deleting important records or updating crucial application configurations!
Previously, the only way to do this in Filament was to implement the multi-factor challenge yourself, which didn't feel great considering there has been a baked-in multi-factor challenge for the Filament log in page for a while now.
Now, thanks to the new MultiFactorChallenge class, Filament's challenge components are now reusable across your entire application and not just stuck on the login page. You can use the built-in provider picker and challenge fields in your own flow as well as latching into the existing hooks for features such as sending an email code.
These challenges use your current or default Filament panel's configured providers. Your flow must check hasEnabledProviders() immediately before validation, apply the challenge's rate-limiter helpers, and call getState() on the schema to validate the code. An empty challenge schema validates successfully, so the enabled-provider check is essential. You must also authorize the protected operation separately.
For more details when building one of these multi-factor flows, check out the multi-factor authentication documentation for more important details on how this system works.
A big thank you to @webard for your contributions here!
#A handful of UX accessibility improvements
In the past few minor versions, the Filament team has released a handful of improvements to UX improvements across the Filament ecosystem. Here are a few of the team's favorites in rapid fire mode:
- Chart widgets now expose a
getChartAssistiveContent()method that allows developers to supply a text summary or structured alternative (ex: a table of values) to be made available to screen readers while remaining visually hidden on the page. - Common form controls now connect their helper text and validation errors to the relevant inputs to give screen readers more useful context while filling out forms.
- Loading state changes help focused controls remain in place during Livewire requests so keyboard users can continue where they left off prior to the request.
- Toast notifications now pause their countdown while hovered or focused, allowing users more time to read the message and interact with its actions.
Big thanks to @danharrin for his contributions!
#Development & testing tools
Finally, the Filament team has added some new tools to help you while you build and test your Filament applications!
One addition that the team has made now allows you to generate more realistic content in factories with the new filamentRichContent() and filamentMarkdown() methods. These methods return fluent builders that let you add headings, lists, tables, and other structured content. Finish with toHtml() or toArray() for rich content, or toString() for Markdown, to get realistic factory data rather than another paragraph of placeholder text.
Additionally, the team has added importer and exporter test helpers which let you exercise row handling and inspect action submissions more directly in your tests without having to run the entire queued workflow for every single assertion.
A huge thank you to @danharrin for his contributions here!
#Thank you!
As always, the Filament team wants to thank everyone for contributing features, reporting issues, and giving us great feedback to help move Filament forward! The project wouldn't be where it is today without the incredible Filament community.
Give these new features a try, and if you want to learn more about any of the new features that were mentioned (or ones that were skipped), take a look at the official changelogs on Github!