Filament v5 · Laravel admin forms · 68 custom components · one design system
Replace a patchwork of field plugins with one cohesive form layer — lazy assets, optional JSON custom fields, built-in Playground.
Pre-built CSS/JS · no Node.js in production · standalone fields or dynamic schemas · full per-component docs
Filament Flex Fields is a Filament v5 plugin for Laravel admin panels: 68 custom form components, a unified --fff-* design system, and an optional JSON custom-field layer (no EAV, no per-attribute migrations). Use any field standalone, or wire schemas through FlexFieldFormBuilder + HasFlexFields.
First-time install:
composer require janczakb/filament-flex-fields
php artisan filament:assetsRegister the plugin on your Filament panel:
use Bjanczak\FilamentFlexFields\FilamentFlexFieldsPlugin;
public function panel(Panel $panel): Panel
{
return $panel->plugin(FilamentFlexFieldsPlugin::make());
}Then drop any component into a form — e.g. MatrixChoiceField::make('priorities'). Full install options (path repo, config, translations): Installation. Already installed? See Upgrading below.
When a new version is released, update the package and sync Filament assets into public/. You do not need Node.js, npm, or npm run build in your Laravel app — the plugin ships pre-built CSS/JS in resources/dist/.
composer update janczakb/filament-flex-fields
php artisan filament:assetsThat is the full required workflow for most apps.
composer update janczakb/filament-flex-fields
php artisan filament:assetsIf you develop the package itself, rebuild assets inside the package first (npm run build in packages/filament-flex-fields/), then run the commands above in the host app.
Add this to your host app composer.json so filament:assets runs after every composer install / composer update:
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi",
"@php artisan filament:assets --ansi"
]
}With that hook in place, composer update janczakb/filament-flex-fields alone is enough.
| Step | Needed? |
|---|---|
npm install / npm run build in the host app |
No — assets are pre-built in the package |
php artisan vendor:publish --tag=filament-flex-fields-config |
No — unless CHANGELOG documents a new config key you want to set |
php artisan vendor:publish --tag=filament-flex-fields-translations |
No — see Updating translations after a plugin upgrade |
php artisan optimize:clear |
Only if the panel still serves stale CSS/JS after filament:assets (rare) |
If a field looks unstyled after deploy, hard-refresh the Filament panel (Cmd+Shift+R / Ctrl+Shift+R) once so the browser drops cached asset URLs.
Read CHANGELOG.md for breaking changes, new config keys, and migration steps for a given release.
Teams building Filament v5 backends that need more than native inputs — CRM custom attributes, CMS page builders, SaaS onboarding, marketplaces with configurable product fields, or any admin UI that should look and behave like one product, not ten plugins stitched together.
| Flex Fields | Typical approach | |
|---|---|---|
| Scope | 68 fields, layouts, and table columns — one package | Many single-purpose Filament plugins |
| Design | One --fff-* system — sizes, focus, menus, dark mode |
Mixed UI from unrelated packages |
| Flexibility | Standalone fields or dynamic JSON on models — same components | Usually one mode only |
| Depth | Validation, formatting, and interaction built in — not thin wrappers | Basic inputs; edge cases left to you |
| Performance | Lazy per-field CSS/JS in <head>, shared chunks, pre-built dist/ — no npm in your app |
Global bundles or consumer-side builds |
| DX | Playground for every component + dedicated doc per field | Trial-and-error per plugin |
68 components — 56 form fields, 9 layout/schema pieces, 3 table columns, plus HoldConfirmAction. Matrix grids, slugs, translatable groups, media, ratings, signatures, layouts — full list.
One design system — shared sm / md / lg sizes, --fff-* tokens, glass searchable menus, dark mode, consistent focus rings.
Lazy assets — each field loads only its CSS/JS; heavy libraries share chunks and preload once per page. Pre-built resources/dist/ means no Node.js or Vite in your Laravel project.
Asset pipeline (technical)
- Lean core —
core.css(~20 KB): tokens and hint chrome only. - Conditional critical preload —
teleported-menuatHEAD_ENDonly when a dropdown field is on the page (FlexFieldStylesheetQueue::needsTeleportedMenu()). Hold-confirm preloads per action via@pushinhold-confirm.blade.php, not globally. - Per-component bundles — queued when the field renders, deduped per request via
FlexFieldStylesheetQueue/FlexFieldAlpineQueue. Alpine entries register once; manifest chunks load on demand. - Head delivery —
emit-assetspushes<link>/modulepreloadvia@stack('styles')on full pages; Livewire partials emit inline asset batches. - SPA injector —
flex-field-asset-injector.jsloads missing lazy CSS/JS on morph and navigation, with FOUC prevention inside Filament modals. - Lazy Alpine mount — heavy fields defer
x-datainit untilx-intersect(seelazy-alpine-mountBlade component).
See Performance-first assets for classes, manifest, and bundle metrics.
JSON custom fields — define schemas in PHP config or FlexFieldSchemaRegistry, store values in one JSON column via HasFlexFields. FlexFieldFormBuilder renders live Filament forms. Ideal for CMS, tenant settings, and CRM-style attributes. Options: config/filament-flex-fields.php.
Playground & docs — local preview of all 68 components; every field documented in docs/ with methods, validation, and examples.
- Quick start
- Upgrading
- Why Flex Fields?
- Screenshots
- Custom Components (68)
- Use cases
- Requirements
- Installation
- Setup
- Quick usage
- Playground
- Documentation
- FAQ
- Development
Every item below is a custom class shipped by this package — own Blade views, CSS, and configuration API. This list does not include native Filament fields (TextInput, TagsInput, Repeater, etc.) used only as passthrough inside FlexFieldFormBuilder.
Full API for each component: docs/index.md.
| Component | Description |
|---|---|
FlexTextInput |
Enhanced text input — speech dictation, emoji picker, password strength, clearable |
FlexTextareaField |
Animated autosizing textarea with character counter |
FlexRichEditor |
JSON-first rich editor — responsive images, limits, fullscreen, autosave, optional Spatie |
PhoneField |
International phone input with libphonenumber validation |
CountryField |
Searchable country picker with flags |
TimezoneField |
IANA timezone picker with UTC offset display |
LinkPreviewField |
URL input with live Open Graph preview card (horizontal, vertical, or full-width layouts) |
BarcodeScannerField |
Barcode/QR input — Filament modal camera scanner, format whitelist, EAN/UPC checksum, hybrid BarcodeDetector + ZXing, torch & front/back switch, iOS-safe preview (v2.6.0) |
SocialLinksField |
Social profile links — platform picker, URL validation, custom platforms, reorder |
SlugField |
Slug input with permalink preview, uniqueness, regenerate/copy actions |
TitleSlugField |
Title + slug pair with live URL preview and optional Spatie Sluggable |
AddressAutocompleteField |
Mapbox-powered address search with structured storage |
FlexVerificationCode |
OTP / 2FA verification code input with grouping |
| Component | Description |
|---|---|
NumberStepper |
+/- numeric stepper control |
CurrencyField |
Multi-currency money input with locale-aware formatting |
FlexSlider |
Styled range slider with value display |
TrackSlider |
Track-style slider — single value, percentage, or min/max range |
PriceRangeField |
Dual-handle price filter with histogram |
TrafficSplit |
Weighted segment split control (A/B-style traffic allocation) |
| Component | Description |
|---|---|
SwitchField |
Animated toggle switch with row/inline layouts |
CellSwitch |
Compact SwitchField variant for table cells |
SegmentControl |
Segmented button control |
ChoiceCards |
Rich card-based radio selection |
ChoiceCheckboxCards |
Rich card-based multi-select |
FlexChecklist |
Animated checklist with icons and descriptions |
FlexRadiolist |
Animated radio list with icons and descriptions |
MatrixChoiceField |
Survey / configurator matrix grid — radio or checkbox per row |
FlexMatrixTable |
Advanced matrix grid with full Filament components inside cells |
SelectField |
Rich select with avatars, badges, and descriptions |
UserSelect |
User picker with avatar stacks and verification badges |
DualListboxField |
Two-panel reorderable transfer list |
TagsField |
Tag input — pills below the field with inline remove buttons |
IconPickerField |
Searchable blade-icons picker with lazy SVG rendering, virtual scroll, and paginated search (v2.7.0) |
FlexSpatieTagsField |
Spatie Tags integration for TagsField |
| Component | Description |
|---|---|
FlexDateField |
Segmented date input without calendar popover |
FlexDatePicker |
Date picker with calendar popover |
FlexTimeField |
Segmented time input (12h / 24h, seconds optional) |
FlexTimeSegmentsField |
Dropdown time picker (hour / minute columns, HH:MM) |
ScheduleField |
Weekly opening-hours editor — day toggles, slots, breaks, copy-to-weekdays, timezone |
FlexDateTimePicker |
Combined date + time picker |
FlexDateRangeField |
Start/end date range |
FlexDurationField |
Duration input (hours / minutes) |
FlexTimeRangeField |
Start/end time range |
FlexMonthPicker |
Month picker |
FlexYearPicker |
Year picker |
| Component | Description |
|---|---|
ColorSwatchField |
Preset color swatch picker |
FlexColorPickerField |
Advanced color picker with grid and eyedropper |
FlexFileUpload |
Styled file upload with webcam capture, URL import, and security presets (v2.6.1) |
FlexImageUpload |
Image upload with processing options |
FlexSpatieMediaLibraryFileUpload |
Spatie Media Library upload integration |
VideoField |
Video URL / player with YouTube support |
AudioField |
Audio URL / player with waveform |
VoiceNoteRecorderField |
In-browser voice recorder — waveform, local playback, deferred or immediate upload |
MapPickerField |
Interactive map pin picker with draggable marker and address autofill |
SignatureField |
Canvas signature pad |
CreditCardField |
Card preview with Luhn validation and CVV flip |
CellSlider |
Compact TrackSlider variant for table cells |
| Component | Description |
|---|---|
RatingField |
Star rating input |
| Component | Description |
|---|---|
SegmentTabs |
Tabbed segment navigation for forms |
TranslatableFields |
Locale tabs wrapping any fields (JSON or Spatie Translatable) |
TranslatableTabs |
Legacy alias for TranslatableFields |
ItemCard |
Single settings-style card row |
ItemCardGroup |
Polished card-based settings group |
ItemCardStack |
Stacked card layout for profile / settings pages |
CoverCard |
Hero cover card for tabbed editors |
ProgressBar |
Linear, pill, or segment progress bar |
ProgressCircle |
Circular or semicircle progress indicator |
Ready-made layout recipes: Form layout patterns.
| Component | Description |
|---|---|
UserColumn |
Avatar + name/email display with hover card |
RatingColumn |
Star rating display in Filament tables |
IconColumn |
Blade-icons display for IconPickerField values (v2.7.0) |
Total: 68 custom components (56 form fields + 9 layout/schema + 3 table columns). HoldConfirmAction (press-and-hold Filament actions) is documented in the playground but not counted in the 68.
| Scenario | Recommended components |
|---|---|
| CRM / SaaS custom attributes | JSON flex fields + PhoneField, CountryField, UserSelect |
| CMS / page builder | TitleSlugField, TranslatableFields, FlexFileUpload, FlexImageUpload |
| Product configurator | MatrixChoiceField, ChoiceCards, PriceRangeField, ColorSwatchField |
| Surveys & assessments | MatrixChoiceField, FlexRadiolist, RatingField |
| SaaS onboarding | ChoiceCards, SegmentTabs, CoverCard, ProgressCircle |
| E-commerce filters | PriceRangeField, TrackSlider, DualListboxField |
| User profile settings | ItemCardGroup, PhoneField, TimezoneField, SignatureField |
| Payment forms | CreditCardField, FlexVerificationCode |
| Location services | MapPickerField, AddressAutocompleteField |
| A/B configuration | TrafficSplit, SegmentControl |
| Dependency | Version |
|---|---|
| PHP | 8.3+ |
| Laravel | 11+ |
| Filament | 5.x (filament/filament ^5.0) |
Optional integrations (see composer.json → suggest):
| Package | Used for |
|---|---|
spatie/laravel-sluggable |
Model-based slug generation in SlugField |
spatie/laravel-translatable |
JSON translation storage for translatable titles |
spatie/laravel-medialibrary |
FlexSpatieMediaLibraryFileUpload |
filament/spatie-laravel-media-library-plugin |
Filament base class for media upload |
spatie/laravel-tags |
FlexSpatieTagsField — sync tags on models using HasTags |
Already ran Quick start? Jump to Setup. For version bumps, see Upgrading. Below: Packagist install, monorepo path repo, and optional Composer automation.
composer require janczakb/filament-flex-fields
php artisan filament:assets{
"repositories": [
{
"type": "path",
"url": "packages/filament-flex-fields"
}
],
"require": {
"janczakb/filament-flex-fields": "@dev"
}
}composer require janczakb/filament-flex-fields:@dev
php artisan filament:assetsAuto-discovered via composer.json → extra.laravel.providers.
Asset sync on every Composer run — optional but recommended; see Automate asset sync in Upgrading.
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi",
"@php artisan filament:assets --ansi"
]
}use Bjanczak\FilamentFlexFields\FilamentFlexFieldsPlugin;
public function panel(Panel $panel): Panel
{
return $panel->plugin(FilamentFlexFieldsPlugin::make());
}php artisan vendor:publish --tag=filament-flex-fields-configBuilt-in locales ship with the package (en, pl). Publish them only when you need to customize strings in your app:
php artisan vendor:publish --tag=filament-flex-fields-translationsFiles are copied to:
lang/vendor/filament-flex-fields/
├── en/
│ ├── default.php
│ ├── countries.php
│ ├── currencies.php
│ └── timezones.php
└── pl/
├── default.php
├── countries.php
└── timezones.php
Why lang/vendor/? Laravel resolves package translation overrides only from lang/vendor/{namespace}/ (see FileLoader::loadNamespaceOverrides). A flat path such as lang/filament-flex-fields/ is not picked up for __('filament-flex-fields::...') unless you add custom loader logic. The vendor segment here is Laravel’s convention for published package lang files — it is not Composer’s vendor/ directory.
| File | Purpose |
|---|---|
default.php |
UI labels (placeholders, buttons, validation copy, search hints) |
countries.php |
Country names for CountryField / PhoneField |
currencies.php |
Currency names for CurrencyField |
timezones.php |
Optional timezone name overrides for TimezoneField |
Timezone names resolve in this order:
timezones.phpoverride (Europe/Warsaw→ keyEurope__Warsaw)- PHP
Intlfor the active locale (requiresext-intl) - Humanized IANA identifier (
America/New_York→New York)
The field renders {name} (UTC±HH:MM) — only the name uses the chain above; offset is computed at runtime. You usually do not need to publish timezones.php unless you want custom wording.
Example override:
// lang/vendor/filament-flex-fields/pl/timezones.php
return [
'Europe__Warsaw' => 'Warszawa',
];Without publishing, the package uses its bundled translations automatically.
- Copy the structure from
vendor/janczakb/filament-flex-fields/resources/lang/en/. - Create
lang/vendor/filament-flex-fields/{locale}/with the files you need (default.phpis usually enough to start). - Add
timezones.phponly for manual timezone wording overrides. - Set
app.locale/ Filament panel locale to your new locale.
You do not need to register anything else — filament-flex-fields::… lines resolve automatically.
You usually do not need to re-publish translations when you update the package.
Laravel loads translations in two layers:
- Built-in files from the package (
resources/langinside the plugin) - Your overrides from
lang/vendor/filament-flex-fields/merged on top witharray_replace_recursive
That means:
- New keys added in a new plugin version appear automatically, even if your published
default.phpis older and does not contain them yet. - Keys you customized in
lang/vendor/...keep your wording. - Keys you never published/overrode always follow the latest built-in package text.
- Timezone list labels follow PHP
Intlby default, so new IANA zones work without updating lang files.
Recommended workflow
| Situation | What to do |
|---|---|
| You never published translations | Run composer update only — new keys work out of the box |
| You customized a few strings | Keep your lang/vendor/... files; do not re-publish with --force |
| You want to customize a new key from an upgrade | Copy that key from vendor/janczakb/filament-flex-fields/resources/lang/{locale}/ into your published file |
| You need new country/currency keys in a published file | Diff package countries.php / currencies.php and append only missing keys to your copy |
| You want custom timezone wording | Add only those zones to published timezones.php |
Re-run vendor:publish --tag=filament-flex-fields-translations only when you want a fresh file template. Avoid --force unless you intend to overwrite your edits.
Set MAPBOX_ACCESS_TOKEN in .env. By default use_server_proxy is true — geocoding requests go through authenticated Laravel routes so the token never ships to the browser for search/reverse geocode:
MAPBOX_ACCESS_TOKEN=pk.…
FLEX_FIELDS_MAPBOX_SERVER_PROXY=true
FLEX_FIELDS_MAPBOX_CACHE_TTL=3600
FLEX_FIELDS_MAPBOX_RATE_LIMIT=60Proxy routes use web + auth middleware by default (config/filament-flex-fields.php → mapbox.proxy_middleware). Disable the proxy only when you intentionally expose a public Mapbox token client-side.
Field API highlights: searchTypes(), language(), minSearchLength(), searchDebounce(), streetAddressesOnly(). See MapPickerField and AddressAutocompleteField.
# Enabled by default — set false to disable
FLEX_FIELDS_AUDIT_ENABLED=true
FLEX_FIELDS_AUDIT_COLUMN=flex_field_auditHasFlexFields records value changes (user, timestamp, field key, old/new snapshot) in the configured JSON column.
use Bjanczak\FilamentFlexFields\Concerns\HasFlexFields;
class Product extends Model
{
use HasFlexFields;
protected $casts = [
'flex_field_values' => 'array',
];
}Define schemas in config/filament-flex-fields.php or FlexFieldSchemaRegistry, then build with FlexFieldFormBuilder.
use Bjanczak\FilamentFlexFields\Filament\Forms\Components\ChoiceCards;
use Bjanczak\FilamentFlexFields\Filament\Forms\Components\MatrixChoiceField;
use Bjanczak\FilamentFlexFields\Filament\Forms\Components\PhoneField;
use Bjanczak\FilamentFlexFields\Filament\Forms\Components\TitleSlugField;
ChoiceCards::make('plan')
->options(['basic' => 'Basic', 'pro' => 'Pro'])
->required();
MatrixChoiceField::make('priorities')
->mode('checkbox')
->rows(['dark_mode' => 'Dark mode', 'csv_export' => 'CSV export'])
->matrixColumns(['low' => 'Low', 'medium' => 'Medium', 'high' => 'High'])
->disableCellWhen('csv_export', 'high', 'dark_mode', 'high');
PhoneField::make('phone')->defaultCountry('PL');
TitleSlugField::make('title', 'slug')
->permalinkPreview()
->slugUnique();Full API for every option: docs/index.md.
use Bjanczak\FilamentFlexFields\Filament\Schemas\Components\ItemCardGroup;
use Bjanczak\FilamentFlexFields\Filament\Schemas\Components\ProgressCircle;
ProgressCircle::make()
->value(72)
->displayValue('72%')
->variant('semicircle');
ItemCardGroup::make([
// Polished card-based settings rows…
]);A dev UI page previews every custom component.
| Setting | Env variable | Default |
|---|---|---|
| Plugin enabled | FLEX_FIELDS_ENABLED |
true |
| Playground | FLEX_FIELDS_PLAYGROUND |
true when APP_ENV=local |
| Nav group | FLEX_FIELDS_PLAYGROUND_NAV_GROUP |
Settings & Tools |
| Nav sort | FLEX_FIELDS_PLAYGROUND_NAV_SORT |
91 |
FLEX_FIELDS_PLAYGROUND=falseExample slugs: matrix-choice, choice-cards, tags-field, title-slug-field, phone-field, file-upload, item-card-group, progress-circle.
| Document | Contents |
|---|---|
| docs/index.md | Complete per-component API — every method, option, validation rule, config key, and example |
| docs/shared-concepts.md | Asset pipeline, overlay coordinator, wire:ignore + Livewire sync patterns |
| CHANGELOG.md | Version history and release notes |
| config/filament-flex-fields.php | Schemas, UI defaults, playground, Mapbox, audit |
Why choose Flex Fields over multiple Filament field plugins? One design system, one asset pipeline, one Playground, and 68 components that work together — standalone or as dynamic JSON attributes. You avoid conflicting CSS, duplicate JS, and inconsistent field APIs.
Do I need Node.js to use this package?
No. Pre-built CSS/JS are committed to resources/dist/. Node is only needed when developing the package itself.
How does asset loading work? Each component loads its own CSS/JS on demand. Shared libraries are split into cached chunks and loaded once per page. See Development → Performance-first assets.
Can I use components without the JSON flex-field system?
Yes. Import any component directly into Filament forms — the JSON column and HasFlexFields trait are optional.
How many components are included? 68 custom UI classes with own views and CSS — listed in Custom Components (68).
Does it work with Filament v4? No — this package targets Filament v5 only.
Is Spatie required?
No. Sluggable, Translatable, and Media Library integrations are optional composer suggest packages.
Where is the Matrix Choice / survey grid?
MatrixChoiceField — radio or checkbox mode, per-row validation, reactive disableCellWhen() / disableRowWhen(). See docs/matrixchoicefield.md.
Główna instrukcja dla osób piszących kod pakietu (CSS/JS, FlexFieldStylesheetQueue, współdzielenie bundle'i, antywzorce): DEVELOPMENT.md.
composer install
composer test # Pest — 99+ PHP tests
composer analyse # PHPStan
npm install
npm run build # CSS + JS → resources/dist/
npm run test:js # Node unit tests
npm run test:e2e # Playwright playground tests (requires FLEX_FIELDS_PLAYGROUND_URL)
composer format # Laravel PintRebuild assets after changing resources/css/ or resources/js/.
npm run check:budgets # CI bundle size guard (reads resources/dist/bundle-metrics.json)This is the technical reference for Lazy assets & shared chunks above.
| Step | Class / file | Role |
|---|---|---|
| 1 | Field blade @include(…load-stylesheet) |
Registers needed bundles when the field is on the page |
| 2 | FlexFieldStylesheetQueue / FlexFieldAlpineQueue |
Request-scoped dedup — 5× ChoiceCards → 1× choice-cards.css |
| 3 | emit-assets (via load-stylesheet) |
Full-page: @push('styles') into <head>; Livewire partial: inline <link> / modulepreload batches |
| 4 | queued-stylesheets render hook |
Flushes any remaining pending() queues at STYLES_AFTER and BODY_END |
| 5 | Filament @stack('styles') in layout/base.blade.php |
Renders pushed links in <head> before content paint |
| 6 | flex-field-asset-injector.js |
SPA/morph: loads missing lazy assets, dedupes hrefs, prevents modal FOUC |
| 7 | loadedOnRequest() on Filament CSS assets |
Prevents unused bundles from auto-loading via @filamentStyles |
Dependency order is declared in FlexFieldAssets::STYLESHEET_DEPENDENCIES and resolved depth-first in stylesheetsFor() (e.g. schedule-field → timezone-field → flex-time-segments).
| Step | Class / file | Role |
|---|---|---|
| 1 | x-load + thin {component}.js entry |
Alpine factory only — heavy libs in shared chunks |
| 2 | esbuild splitting: true + semantic chunk names |
flex-fields-phone-lib-*, flex-fields-emoji-*, … |
| 3 | alpine-manifest.json |
Maps each field → chunk list for preload |
| 4 | FlexFieldAlpineQueue |
Dedup modulepreload in <head> — one fetch per chunk per request |
| 5 | flex-field-asset-injector.js |
Loads missing chunks from morph batches; in-flight promise cache prevents duplicate fetches |
| 6 | Dynamic import() where possible |
e.g. libphonenumber, emoji picker — parse cost deferred until interaction |
npm run build writes resources/dist/bundle-metrics.json (raw + gzip KB per file). Core CSS stays lean; component CSS/JS load lazily through the pipeline above.
npm run build # CSS + JS → resources/dist/
npm run check:budgets # fail if any bundle exceeds limits| Field / component | JS (KB) | CSS (KB) |
|---|---|---|
| core (always) | — | 28 (gzip 6) |
| PhoneField | 5.9 (gzip 1.9) + virtualized-list 7.3 (gzip 2.5) + select-menu 5.4 (gzip 1.9) + theme-utils 0.4 (gzip 0.3) + flex-dropdown-coordinator 1.7 (gzip 0.8) + phone-lib 185 (gzip 43.3) | 34.7 (gzip 6.9) + deps 73.2 |
| CountryField | 3.9 (gzip 1.4) + virtualized-list 7.3 (gzip 2.5) + select-menu 5.4 (gzip 1.9) + theme-utils 0.4 (gzip 0.3) + flex-dropdown-coordinator 1.7 (gzip 0.8) | 31 (gzip 6.5) + deps 73.2 |
| FlexTextInput | 10.6 (gzip 3.2) + flex-dropdown-coordinator 1.7 (gzip 0.8) + emoji 19.7 (gzip 6.2) lazy | 42.6 (gzip 7.8) + deps 24.9 |
| TagsField | 3.1 (gzip 1.1) | 25.8 (gzip 5.7) + deps 70.3 |
| RatingField | 0.7 (gzip 0.3) | 27.9 (gzip 6.1) |
| SwitchField | Alpine inline | 46.5 (gzip 8.1) |
| UserSelect | 14.6 (gzip 4.8) + select-menu 5.4 (gzip 1.9) + theme-utils 0.4 (gzip 0.3) + flex-dropdown-coordinator 1.7 (gzip 0.8) | 34.4 (gzip 6.9) + deps 169.7 |
| MapPickerField | 9.3 (gzip 2.9) + mapbox 6.1 (gzip 2.3) + select-menu 5.4 (gzip 1.9) + flex-dropdown-coordinator 1.7 (gzip 0.8) + theme-utils 0.4 (gzip 0.3) | 32.2 (gzip 7) + deps 57.6 |
| SelectField | 14.6 (gzip 4.8) + select-menu 5.4 (gzip 1.9) + theme-utils 0.4 (gzip 0.3) + flex-dropdown-coordinator 1.7 (gzip 0.8) | 84.6 (gzip 13.2) + deps 30.6 |
Sample bundles (10 of 56 production CSS files). Full per-file metrics — every component, shared chunk, and gzip size — live in resources/dist/bundle-metrics.json (regenerated on npm run build). JS = entry + preloaded chunks from alpine-manifest.json; CSS + deps = declared stylesheet dependencies.
See LICENSE for license details.
Made with ❤️ by Bartłomiej Janczak
































