Skip to main content
← Back to Table of Contents

Summary

A specialized input for distributing 100% across multiple segments. Features interactive sliders, numeric inputs, and “locking” capabilities. Commonly used for A/B test traffic allocation, budget distribution, or weighting algorithms.
ClassBjanczak\FilamentFlexFields\Filament\Forms\Components\TrafficSplit
State typearray<int, int> — list of weights summing to 100
Model cast'traffic_weights' => 'array'
FieldTypetraffic-split
Playgroundtraffic-split slug in Flex Fields playground
Default segments3
Default stateEqual split (e.g. [34, 33, 33])

Basic usage

Standard 3-way split

use Bjanczak\FilamentFlexFields\Filament\Forms\Components\TrafficSplit;

TrafficSplit::make('weights')
    ->label('Traffic Allocation')
    ->segmentCount(3)
    ->labels(['Variant A', 'Variant B', 'Control']);

Locked segments

Prevent users from changing specific weights while allowing others to rebalance.
TrafficSplit::make('weights')
    ->segmentCount(4)
    ->lockedSegments([0, 3]); // First and last segments are locked

State & validation

Stored value

The field stores an array of integers. The component automatically ensures that the sum of all integers is exactly 100.
$record->weights; // [50, 25, 25]

Automatic normalization

When the component is hydrated or the segment count changes, it automatically rebalances weights to reach 100%. If a state is invalid (e.g. sums to 90%), it will be normalized to an equal split or adjusted based on locked segments.

Advanced Features

Linking to a Repeater

TrafficSplit can dynamically sync its segment count with a Filament Repeater. This is perfect for split-testing URLs or features where the number of variants is dynamic.
Repeater::make('variants')
    ->schema([
        TextInput::make('url')->required(),
    ])
    ->afterStateUpdated(fn (TrafficSplit $component) => $component->repeaterSyncCallback())
    ->live(),

TrafficSplit::make('allocation')
    ->linkedToRepeater('variants');

Minimum Weight

Ensure no segment falls below a certain percentage (e.g. for statistical significance).
TrafficSplit::make('weights')
    ->minWeight(10); // No slider can go below 10%

Configuration API

All methods accept Closure unless noted.
MethodTypeDefaultDescription
segmentCount(int|Closure $count)Setup3Number of segments (max 5)
minWeight(int|Closure $weight)Setup12Minimum allowed weight per segment
valueThreshold(int|Closure $val)Setup18Visual threshold for label display
variant(string|Closure $variant)Setup'default'Visual variant
labels(array|Closure|null $labels)SetupnullCustom segment labels
lockedSegments(array|Closure $ids)Setup[]Indices of segments to lock
linkedToRepeater(...)SetupSync with a Repeater state path
size(string|Closure $size)Setup'md'sm, md, lg

Real-world examples

A/B Test Configuration

Section::make('Experiment Settings')
    ->schema([
        TextInput::make('name')->required(),
        TrafficSplit::make('traffic_split')
            ->label('Traffic Distribution')
            ->segmentCount(2)
            ->labels(['Original', 'Challenger'])
            ->minWeight(5)
            ->required(),
    ]);

Playground

/admin/flex-fields-playground/traffic-split See Playground for setup.
ComponentWhen to use instead
FlexSliderSingle value selection on a range
TrackSliderRange selection (min/max)
ProgressBarRead-only percentage display

CSS classes (reference)

ClassRole
fff-traffic-splitRoot wrapper
fff-traffic-split__trackThe horizontal slider track
fff-traffic-split__segmentIndividual color segment
fff-traffic-split__handleDraggable divider
fff-traffic-split__inputsGrid of numeric inputs
fff-traffic-split__labelSegment label text
fff-traffic-split__valuePercentage value display