Skip to content

The repeater becomes a real container - #30

Merged
AllTerrainDeveloper merged 2 commits into
mainfrom
feature/repeater-container
Aug 21, 2026
Merged

AllTerrainDeveloper merged 2 commits into
mainfrom
feature/repeater-container

Conversation

@AllTerrainDeveloper

Copy link
Copy Markdown
Owner

The repeater used to be a summary card that said "set this up in the panel on the right" — and the panel had no way to put fields in it. This makes it a container everywhere it appears.

Builder

  • The canvas draws the repeater as the actual row card the visitor will get: sub-fields render as full live previews inside it, editable in place.
  • Fields drag from the palette into the repeater, from the canvas into it, out of it back to the canvas, and reorder inside it (Alt+arrows work too). Excluded types (nested repeaters, page breaks, files, signatures, totals) fall through to the canvas rather than silently breaking.
  • Sub-fields are selectable with their own inspector — including a crumb ("Inside Attendees — answered once per Attendee") and the exact formula reference to copy. Logic/prefill are hidden on sub-fields because neither has a per-row meaning.
  • The card title is the new itemLabel setting, editable where it sits: type "Attendee" and every front-end card numbers itself.

Front end

  • Every row is a titled card — "Attendee 1", "Attendee 2" — with a header, a named Remove button, role="group" + aria-label, live renumbering on add/remove, and an Add button with real margins that no longer inherits the submit button's width.

Formulas — both engines, held together by the shared fixture table

  • {attendees} → the row count ({attendees} * 15 is per-head pricing).
  • sum( {attendees.age} ) → one argument per row, for sum/avg/min/max as sole argument.
  • {attendees.age} anywhere else → the total across rows (spreading into pow(x, 2) would shift its arguments, so it deliberately doesn't).
  • Priced choices inside a repeater contribute per row; abandoned empty rows count nowhere, agreeing with the sanitiser.
  • The browser recomputes totals live as rows are typed, added, and removed; the formula editor offers repeater chips and previews against two sample rows.

Analytics

  • The repeater's panel reports rows-per-entry (histogram, mean, median).
  • Every sub-field reports as a question of its own — "Attendees · Age" — with choice tallies and numeric summaries pooled across all rows, and honest per-row denominators (of/unit).

Validation

  • Every row's sub-fields validate with the full rule set, named by row: "Attendee 2: Age is required." Plus a minRows floor.

Verified on the 8889 QA site: palette→repeater drag, itemLabel typed on the card, sum({rep.age}) composed by chips previewing 5, and the paired preview window summing 30+12→42.00 live, renumbering on add/remove.

Tests: 353 vitest + 690 PHPUnit green (12 new repeater calc conformance cases run through both engines), PHPCS clean, docs updated.

🤖 Generated with Claude Code

https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp

AllTerrainDeveloper and others added 2 commits August 21, 2026 12:09
The repeater used to be a card that said "set this up in the panel on the
right" — and the panel had no way to put fields in it. Now it is a container
everywhere it appears:

- Builder: the canvas draws the repeater as the row card the visitor will
  get, sub-fields drop into it from the palette, drag in/out/reorder across
  it, and each one is selectable, editable in place, and inspectable. The
  card's title is the new itemLabel setting, editable where it sits.
- Front end: every row is a titled card — "Attendee 1", "Attendee 2" —
  renumbered live, with a header, a named Remove button, and an Add button
  that finally has margins and never inherits the submit button's width.
- Formulas: {attendees} is the row count, sum( {attendees.age} ) spreads one
  argument per row into sum/avg/min/max, and {attendees.age} anywhere else
  is the total across rows. Both engines resolve identically, held to it by
  the shared conformance table.
- Analytics: the repeater's panel reports rows-per-entry, and every
  sub-field reports as a question of its own — choice tallies and numeric
  summaries aggregated across all rows, with honest per-row denominators.
- Validation: each row's sub-fields validate with the full rule set, named
  by row — "Attendee 2: Age is required." — plus a minRows floor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
@AllTerrainDeveloper
AllTerrainDeveloper merged commit 5653153 into main Aug 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant