Skip to content

feat(sliders): support interpolation on merged/banner header tables#61

Merged
IanMayo merged 2 commits into
mainfrom
claude/table-interpolation-merged-headers-uvfyc1
Jul 3, 2026
Merged

feat(sliders): support interpolation on merged/banner header tables#61
IanMayo merged 2 commits into
mainfrom
claude/table-interpolation-merged-headers-uvfyc1

Conversation

@IanMayo

@IanMayo IanMayo commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Speed-vs-length matrix tables commonly draw a merged banner above the numeric column headers. Two author permutations are now supported:

  1. Full-width banner — a single <th colspan="N">Length Overall (m)</th> row above the Speed Knots | 10 | 20 | … header row.
  2. Rowspan corner — a <th rowspan="2">Speed Knots</th> corner beside a <th colspan="N"> banner, with the numeric length headers on the leaf row below.

Previously the canonical addressing layer treated the first header row as the column header. The banner (or the collapsed column count it produced) hid the numeric axis, so the table read as not suitable and the interpolation (slider) enrichment was never offered — exactly the "extra header cell will probably prevent that" case reported.

What changed

Header resolution now peels off leading banner/grouping rows and returns the leaf column-header row that aligns 1:1 with the data columns. A new occupancy-aware (colspan + rowspan) column reader handles the rowspan corner, which shifts the leaf cells right. The fix threads through every consumer of the header model:

  • core/table-grid.tsresolveHeader (banner peel) + headerRows, sourceHeaderColumns, dataHeaderCells, sourceColumnMatrix.
  • core/type-detection.ts / ui/toggle-injector.ts — flatten a multi-row header by logical column so suitability + column typing see the real numeric columns instead of a collapsed banner.
  • ui/header-utils.ts — place per-column lozenges on the leaf headers, the corner slider lozenge on the true corner, and row lozenges on the body rows.
  • enrichments/slider-injection.ts — read axis headers via dataHeaderCells; inject the row-slider header cell into the top header row spanning the whole block so the gutter lines up with the body.

Every banner-aware branch is gated on headerRows(table).length > 1, so single-row-header tables are byte-identical — no behaviour change for the common case.

Testing

  • src/core/__tests__/table-grid.test.ts — leaf-row resolution + dataHeaderCells for both permutations, no-<thead> banner, and a plain single-row equivalence check.
  • src/enrichments/__tests__/slider.test.tsbuildAxisBinding for both permutations, end-to-end dual-axis slider creation + interpolation on a rowspan-corner table, and clean injection teardown.
  • src/ui/__tests__/toggle-injector.banner-header.test.ts — drives the real activation path and asserts the enabled slider lozenge appears for both permutations, plus byte-identical activate→deactivate teardown.

Full jsdom unit suite: 731 passing (94 files). tsc --noEmit clean; vite build clean. The Storybook browser project + Playwright e2e couldn't run in this environment (Playwright browser-build version mismatch), so those weren't exercised here.

Notes / follow-ups

  • The lozenge-mount fix places the corner slider affordance correctly; broader per-column sort/filter/heatmap behaviour on multi-row-header tables is offered but not exhaustively re-validated for exotic combinations (e.g. banner header + virtual columns, which fall back to source-only column typing).
  • A demo page for the merged-header pattern could be added under demo/ if useful for visual verification.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EvweKwJZVqe5rWL8bF6ogS


Generated by Claude Code

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🧹 PR preview for #61 has been removed.

github-actions Bot pushed a commit that referenced this pull request Jul 3, 2026
@codacy-production

codacy-production Bot commented Jul 3, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 53 complexity · 2 duplication

Metric Results
Complexity 53
Duplication 2

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

claude added 2 commits July 3, 2026 12:29
A speed-vs-length matrix table often draws a merged banner above the
numeric column headers — either a single full-width `<th colspan=N>`
title, or a `<th rowspan=2>` corner label beside a colspan banner. The
canonical addressing layer treated the FIRST header row as the column
header, so the banner (or the collapsed column count it produced) hid
the numeric axis: the table read as unsuitable and the interpolation
(slider) enrichment was never offered.

Teach the header resolution to peel off leading banner/grouping rows and
return the LEAF column-header row, and add an occupancy-aware
(colspan + rowspan) column reader so a rowspan corner that shifts the
leaf cells right is handled. The change threads through every consumer
of the header model:

- table-grid: `resolveHeader` (banner peel), `headerRows`,
  `sourceHeaderColumns`, `dataHeaderCells`, `sourceColumnMatrix`.
- type-detection / toggle-injector: flatten a multi-row header by
  logical column for suitability + column typing.
- header-utils: place per-column lozenges on the leaf headers and the
  corner slider lozenge on the true corner; row lozenges on body rows.
- slider-injection: read axis headers via `dataHeaderCells`; inject the
  row-slider header cell into the top header row spanning the block.

All banner-aware paths are gated on `headerRows(table).length > 1`, so
single-row-header tables are byte-identical. Adds unit coverage for both
author permutations at the addressing, axis-binding, and full-activation
(lozenge mounts) levels, plus injection teardown.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EvweKwJZVqe5rWL8bF6ogS
A speed-vs-length matrix page demonstrating both authored header
permutations now supported by the sliders enrichment:

  1. a full-width `<th colspan=N>` banner above the numeric column
     headers, and
  2. a `<th rowspan=2>` corner label beside a `<th colspan=N>` banner
     (leaf row is all length headers, shifted right).

The tables are generated before the bundle loads so Grid-Sight sees a
complete table at init. Registered in the demo nav and on the landing
page. Verified in a headless browser: both tables are detected as
suitable, offer an enabled sliders lozenge, and inject both axis sliders
for bilinear interpolation.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EvweKwJZVqe5rWL8bF6ogS
@IanMayo IanMayo force-pushed the claude/table-interpolation-merged-headers-uvfyc1 branch from 0089159 to c3a1050 Compare July 3, 2026 12:31
github-actions Bot pushed a commit that referenced this pull request Jul 3, 2026
@IanMayo IanMayo merged commit ff627b0 into main Jul 3, 2026
4 checks passed
@IanMayo IanMayo deleted the claude/table-interpolation-merged-headers-uvfyc1 branch July 3, 2026 15:00
github-actions Bot added a commit that referenced this pull request Jul 3, 2026
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.

2 participants