Skip to content

Remove groups: every row moves on its own - #99

Merged
grunion-ai merged 1 commit into
mainfrom
remove-groups
Sep 16, 2026
Merged

grunion-ai merged 1 commit into
mainfrom
remove-groups

Conversation

@grunion-ai

Copy link
Copy Markdown
Owner

What changed

group leaves decklet. A row no longer carries a link to another row, so every text box, tile, bar, node and chip selects, drags, nudges and deletes on its own.

Surface What went
Model contract the group prop — validate errors on it: "group is gone — every row moves on its own"
Engine (template.html) grp(), the marquee's group expansion, the .gbox union outline and its CSS
Layout library the slot-level group on kpi tiles, cards, callouts, logo plates, team photos, process steps, timeline events and the cta button (the catalogue's own shelf name, group: 'modern', is a different thing and stays)
lib/chart.mjs the shared id a chart's expansion wore
lib/diagram.mjs the ids nodes, edges, zones, ticks and the note wore

create strips a group a model written against an older skill still carries, so such a deck still builds, minus the dead link.

Multi-row moves are unchanged and belong to the human: ⌘-click adds a row, a marquee takes what it contains, arrows nudge the lot, and the selection is gone at the next click.

Why

Kyle, 2026-09-15: a text box that cannot be moved away from the box beside it is the wrong object. The link complicated every edit — a press anywhere on a card took the whole card, and taking one row back needed a modifier.

The one non-obvious consequence

The gap gate used a shared group as a collision exemption, and the library leaned on it in two places. Both now rest on geometry:

  • Containment is judged on what the model declares. A text row with no stated height is contained by a painted box when its origin and its declared sides sit inside it — a card holds its own copy even when the line-count estimate runs past the card's bottom edge. That overflow is the text-fit gate's business, and verify measures the real glyphs in a browser.
  • Two text rows inside ONE painted box, apart only on an estimate — a stat over its label on a kpi tile — are the card's interior, not a collision. A pair that overlaps on an axis both rows declare still fails, as before.

validate --strict stays clean across the library, the 99 templates and the examples.

Verification

  • npm test346 pass, 0 fail, 0 skipped (baseline on main: 342 pass, 0 fail).
  • npm run verify:deckVERIFY PASS, all 12 slides.
  • deck.html, library.html, library-speaker.html and library-reading.html rebuilt from the new engine.

New and rewritten gates:

  • test/group.test.mjs is the gate for the absence: the prop rejected, create stripping it, no library slot carrying one, charts and figures emitting none, the engine free of grp/.gbox, plus a live Chromium proof that a card's tile drags alone while its text rows stay, that a text row drags out of its card, and that a marquee still takes what it contains.
  • test/diagram.test.mjs reads a figure's parts back out of the rows themselves: a zone is a dashed over:1 box, a node is a row with an id, an edge is a run of line rows closed by to.
  • test/editor.test.mjs, test/gate.test.mjs, test/layouts.test.mjs, test/templates.test.mjs, test/icons.test.mjs and test/chart.test.mjs updated to the new contract.

🤖 Generated with Claude Code

A `group` string made several rows one unit in the editor — a press on a
kpi tile took its value, its label and its delta chip; a marquee that
caught one member took the rest; the selection drew a dashed box round
the union. Kyle's ruling: a text box that cannot be moved away from the
box beside it is the wrong object, and the link cost more in editing
than it ever paid in dragging.

The prop leaves the contract (validate names it), the engine (grp(), the
marquee's expansion, the .gbox outline), the library's composite slots,
and what chart rows and diagramSlide() emit. create strips a `group` an
older model still carries, so such a deck still builds. Multi-row moves
are unchanged and are the human's: ⌘-click, a marquee, arrow nudge.

The gap gate keeps the two cases groups were waving through, on geometry
instead of a link: containment is judged on what the model declares (a
card holds its copy even when the line-count estimate overflows it), and
two text rows inside ONE painted box that are apart only on an estimate
are the card's interior, not a collision. A pair overlapping on an axis
both rows declare still fails.

npm test: 346 pass, 0 fail, 0 skipped. verify:deck: VERIFY PASS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@grunion-ai
grunion-ai merged commit 88f5461 into main Sep 16, 2026
1 check passed
@grunion-ai
grunion-ai deleted the remove-groups branch September 16, 2026 04:34
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