Repository navigation
Description
Not blocking: javaabu/form-builder ships the field itself. This issue proposes moving it into stencil once the API settles, so other packages can use it.
stencil has no repeater, and form-builder needs repeating groups. So form-builder implements one as a stencil Field: Javaabu\FormBuilder\Stencil\Repeater (source). It's tested with both drivers.
Repeater::make('references')
->schema(fn (string $row) => [ // $row is the row's state path: references.0
TextInput::make('name')->required(),
Select::make('relationship')->options([...]),
TextInput::make('other')->visibleWhen("{$row}.relationship", 'other'),
])
->minRows(1)->maxRows(3)->addLabel(__('Add a reference'))->rowLabel(__('Reference :number'));How it works
-
State and rows. The state is a list of rows. Each row is a
GroupwithstatePath('{key}')under the repeater, so names come out asreferences[0][name]and rules asreferences.0.name. The array schema is deep-copied per row, or a closure is called with the row's path. -
Validation and dehydration. The rows' fields aren't in
Form::getFields(), because how many there are depends on the state, andgetFields()is cached beforefill().Repeater::getFlatFields()returns[]. The repeater merges its rows' rules, attributes (with the row label, e.g. "Name (Reference 2)") and messages, and dehydrates its rows itself. Conditions use absolute paths, soisHiddenByConditionsandisDisabledByConditionswork per row. -
Finding fields.
EntryForm::getField()(form-builder'sFormsubclass) also finds row fields by full path, so condition selectors resolve inside rows. Moving this intoForm::getField()would make it work for any form. -
Rendering. The node's props carry:
minRows,maxRows,addLabel,removeLabel,rowLabel(with:number)rowKeysandnextRowrowPlaceholder(__ROW__)template: a JSON node of an empty row, with__ROW__in names, ids and selectors
The Blade view renders the rows plus a
<template>row, and a small script copies it with the next row number. The React component (FormBuilderRepeater) does the same withrowFromTemplate().
What upstreaming would need
RepeaterinJavaabu\Stencil\Fields, arepeaterBlade view, and a React component inbuiltInComponents.- Optionally,
Form::getField()resolving row fields, andForm::getFields()exposing them once the state is known. - The template and placeholder documented in the JSON format (
docs/advanced-usage/json-format.md).
Once stencil has it, form-builder would switch to it and keep a class alias.
Activity
n4ff4h commentedon Nov 6, 2026
Orchestrator note: deferring this to after v1.0. form-builder ships its own repeater, so nothing is blocked; moving it into stencil is a refactor for a later minor release.