janczakb/filament-flex-fields

68 Filament v5 form components with unified design system, lazy CSS/JS, optional JSON custom fields, layout primitives, and built-in Playground — one plugin for modern Laravel admin forms.
197 29
Install
composer require janczakb/filament-flex-fields
Latest Version:v2.7.0
PHP:^8.3
License:proprietary
Last Updated:Jun 21, 2026
Links: GitHub  ·  Packagist
Maintainer: janczakb

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.


Quick start

First-time install:

composer require janczakb/filament-flex-fields
php artisan filament:assets

Register 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.


Upgrading

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/.

Standard upgrade (Packagist)

composer update janczakb/filament-flex-fields
php artisan filament:assets

That is the full required workflow for most apps.

Path repository (monorepo / local package)

composer update janczakb/filament-flex-fields
php artisan filament:assets

If 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.

Automate asset sync (recommended)

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.

What you usually do not need on upgrade

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)

After upgrading in the browser

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.

Version-specific notes

Read CHANGELOG.md for breaking changes, new config keys, and migration steps for a given release.


Why Flex Fields?

Who it's for

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.

At a glance

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

What's inside

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.

  1. Lean corecore.css (~20 KB): tokens and hint chrome only.
  2. Conditional critical preloadteleported-menu at HEAD_END only when a dropdown field is on the page (FlexFieldStylesheetQueue::needsTeleportedMenu()). Hold-confirm preloads per action via @push in hold-confirm.blade.php, not globally.
  3. Per-component bundles — queued when the field renders, deduped per request via FlexFieldStylesheetQueue / FlexFieldAlpineQueue. Alpine entries register once; manifest chunks load on demand.
  4. Head deliveryemit-assets pushes <link> / modulepreload via @stack('styles') on full pages; Livewire partials emit inline asset batches.
  5. SPA injectorflex-field-asset-injector.js loads missing lazy CSS/JS on morph and navigation, with FOUC prevention inside Filament modals.
  6. Lazy Alpine mount — heavy fields defer x-data init until x-intersect (see lazy-alpine-mount Blade 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.


Table of contents


Screenshots


Custom Components (68)

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.

Text & input (13)

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

Number & range (6)

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)

Choice & selection (14)

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
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

Date & time (11)

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

Media, color & location (12)

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

Rating (1)

Component Description
RatingField Star rating input

Layout & display — schemas (9)

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.

Table columns (3)

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.


Use cases

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

Requirements

Dependency Version
PHP 8.3+
Laravel 11+
Filament 5.x (filament/filament ^5.0)

Optional integrations (see composer.jsonsuggest):

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

Installation

Already ran Quick start? Jump to Setup. For version bumps, see Upgrading. Below: Packagist install, monorepo path repo, and optional Composer automation.

Composer (Packagist)

composer require janczakb/filament-flex-fields
php artisan filament:assets

Composer (path repository — monorepo)

{
    "repositories": [
        {
            "type": "path",
            "url": "packages/filament-flex-fields"
        }
    ],
    "require": {
        "janczakb/filament-flex-fields": "@dev"
    }
}
composer require janczakb/filament-flex-fields:@dev
php artisan filament:assets

Auto-discovered via composer.jsonextra.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"
    ]
}

Setup

1. Register the plugin

use Bjanczak\FilamentFlexFields\FilamentFlexFieldsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel->plugin(FilamentFlexFieldsPlugin::make());
}

2. Publish configuration (optional)

php artisan vendor:publish --tag=filament-flex-fields-config

3. Publish translations (optional)

Built-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-translations

Files 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.

Translation files

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:

  1. timezones.php override (Europe/Warsaw → key Europe__Warsaw)
  2. PHP Intl for the active locale (requires ext-intl)
  3. Humanized IANA identifier (America/New_YorkNew 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.

Adding a new locale

  1. Copy the structure from vendor/janczakb/filament-flex-fields/resources/lang/en/.
  2. Create lang/vendor/filament-flex-fields/{locale}/ with the files you need (default.php is usually enough to start).
  3. Add timezones.php only for manual timezone wording overrides.
  4. Set app.locale / Filament panel locale to your new locale.

You do not need to register anything else — filament-flex-fields::… lines resolve automatically.

Updating translations after a plugin upgrade

You usually do not need to re-publish translations when you update the package.

Laravel loads translations in two layers:

  1. Built-in files from the package (resources/lang inside the plugin)
  2. Your overrides from lang/vendor/filament-flex-fields/ merged on top with array_replace_recursive

That means:

  • New keys added in a new plugin version appear automatically, even if your published default.php is 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 Intl by 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.

4. Mapbox geocoding (MapPicker & AddressAutocomplete)

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=60

Proxy routes use web + auth middleware by default (config/filament-flex-fields.phpmapbox.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.

5. Flex field audit trail (enabled by default)

# Enabled by default — set false to disable
FLEX_FIELDS_AUDIT_ENABLED=true
FLEX_FIELDS_AUDIT_COLUMN=flex_field_audit

HasFlexFields records value changes (user, timestamp, field key, old/new snapshot) in the configured JSON column.

6. Flex fields on a model (optional)

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.


Quick usage

Standalone form components

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.

Schema / display components

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…
]);

Playground

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=false

Example slugs: matrix-choice, choice-cards, tags-field, title-slug-field, phone-field, file-upload, item-card-group, progress-circle.


Documentation

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

FAQ

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.


Development

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 Pint

Rebuild assets after changing resources/css/ or resources/js/.

npm run check:budgets   # CI bundle size guard (reads resources/dist/bundle-metrics.json)

Performance-first assets

This is the technical reference for Lazy assets & shared chunks above.

CSS delivery pipeline

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-fieldtimezone-fieldflex-time-segments).

JavaScript delivery pipeline

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

Bundle inventory & CI

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) 27.6 (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.4 (gzip 6.9) + deps 72.5
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) 30.6 (gzip 6.4) + deps 72.5
FlexTextInput 10.6 (gzip 3.2) + flex-dropdown-coordinator 1.7 (gzip 0.8) + emoji 19.7 (gzip 6.2) lazy 42.2 (gzip 7.7) + deps 24.5
TagsField 3.1 (gzip 1.1) 25.4 (gzip 5.7) + deps 69.5
RatingField 0.7 (gzip 0.3) 27.5 (gzip 6.1)
SwitchField Alpine inline 46.1 (gzip 8)
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) 33.8 (gzip 6.8) + deps 168
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) 31.6 (gzip 7) + deps 56.8
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.1 (gzip 13.2) + deps 30.2

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.