Skip to content

#202 — design-2 rich hover cards: model pills, format-badge reconstruction, overrides badge, info tips - #220

Merged
cmbays merged 1 commit into
mainfrom
renderer-202-design2-hover-cards
Jun 11, 2026
Merged

cmbays merged 1 commit into
mainfrom
renderer-202-design2-hover-cards

Conversation

@cmbays

@cmbays cmbays commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

Closes #202

Design-2 integration PR-5: the rich hover layer over the #201 layout, fed by the #200 payload. Template/JS/CSS + tests + goldens only — src/ is zero-diff; templates/report.html, the explore surfaces, fixtures, and the ci.yml/lefthook feature-count lines are untouched.

What landed

  • ensureTip/positionTip/hideTip singletons — three body-appended, viewport-clamped tips (#model-tooltip / #fmt-tooltip / #ov-tooltip, reusing the shipped positionTipNear clamp) shown on mouseenter AND focusin, hidden on mouseleave/focusout. Every trigger is focusable (tabindex=0) with visible text or an aria-label; no native title (the #145 — surface incremental-model unit-test semantics #146 rule). Every interpolated value passes through escapeHtml.
  • Given header: buildGivenTitle renders ref( + .gt-model pill + ) (the given · prefix is dropped; non-ref inputs render verbatim). The pill is a model-tip trigger only when manifest_nodes knows the model (graceful absence). data-input-name retained on the section (test seam).
  • Expected: buildExpectedModelBadge — bar order [model pill][mode badge][row count] with the Diff/File toggle far right (margin-left:auto, matching the Given bars); header fallback when no bar. The #159 — strategy-correct incremental expect-semantics tooltip #161 idempotent clear-list extends to .expected-model-badge (both clear sites: renderExpectedPanel + the unconditional renderForSelectedModel clear).
  • Format badge: shown for ALL formats incl. dict; hover/focus reconstructs the fixture client-side from the existing payload (sql → highlighted SQL; csv → header+rows; dict → YAML list) in a framed mini code-surface. An UNLOADED external fixture has no rows to reconstruct — its badge stays plain (graceful absence, no empty bubble).
  • Overrides badge: overrides · N (N = total keys across groups) in the test badge row when TestPayload.overrides is present; hover/focus shows macros/vars/env_vars groups with key = value rows, values stringified from native scalars.
  • Column tooltips: multi-arg detail strings split into ct-vals/ct-val chips; the ct-detail run + its CSS are retired. Verified against the shipped detail forms (m.f relationships, 0–100 ranges) — single-value details stay one chip. Per-table column_meta sourcing and the th-trigger/no-icon/#col-tooltip contract are unchanged.

Founder mechanism decision (epic #197) — applied as briefed

The incremental-branch mode badge and the prior-model-state this-badge keep the shipped #146 focusable-trigger CSS-bubble mechanism with the pass-2 badge-borne visual styling: the badge itself is the focusable trigger (tabindex=0, aria-label, nested aria-hidden bubble, reveal on :hover/:focus/:focus-visible). The expected panel's separate ⓘ button is retired (the static DAG-hint ⓘ keeps the class). Exactly ONE mechanism per the collision notes — the pass-2's JS info-tip twin for those badges (.has-info-tip/showInfoTip/#info-tooltip) is not ported: its only consumers were these two badges, so porting it would ship dead code. incremental_badges_modes_tooltip_and_this_given was updated deliberately; the LOCKED D4 invariant holds (tooltip rides is_incremental_mode === true, never the this-given proxy, never full-refresh — a new guard additionally pins that the full-refresh badge nests NO bubble). The this-badge tip copy was made strategy-invariant ("exercise the incremental branch", the #159/#161 lesson) rather than the prototype's merge/insert wording.

Discovery answers

  • Tip z-index vs shelf/DataTables: the three singletons are body-appended position:fixed at z-index 90 (the shipped #col-tooltip posture), so they paint above the DAG shelf, the sticky expected panel, and DataTables headers (all in lower in-flow stacking contexts). The badge-borne CSS bubbles sit at z-index 60 absolute within their badge — no clipping ancestor on either badge (given .table-header and the expected header/bar carry no overflow rule; a new headless guard pins the relocated-bar reveal). A live probe on the regenerated playground golden confirmed the 90/90/60 ladder with no occlusion.
  • Format-badge row cap: not needed. The tip clamps at max-height: 22rem with overflow: auto and max-width: min(34rem, 92vw); the largest playground reconstructions scroll cleanly. A row cap would break the faithful-reconstruction promise; the clamp + scroll is sufficient.

Dogfood visibility (regenerated goldens)

  • examples/playground-report.html: 8 ref-pill hover targets, 1 overrides badge (overrides · 1 on test_fct_encounters_incremental_appends_new_encounters), 5 dict format badges — verified live in a browser against the regenerated golden (tips reveal/hide, badge-borne bubbles work).
  • examples/diff-showcase-report.html: ref pills + dict badges present; no overrides badge — its --pr-diff scope excludes the only overrides-bearing playground test. Per the brief I'm reporting this rather than splicing fixtures (tests/fixtures/playground-* untouched).
  • examples/explore/ pages: zero diff (explore embeds neither report.css nor interaction.js).

Gate evidence (run directly in the worktree — lefthook skips in fresh worktrees)

Gate Result
cargo fmt --check clean
cargo clippy --all-targets --locked -- -D warnings exit 0
cargo nextest run --all-targets --locked 1137 passed
cargo test --test bdd 17 features / 128 scenarios / 804 steps passed (no new feature; count untouched)
cargo test --test headless_toggle -- --ignored 44 passed — incl. 2 new #202 guards (rich_hover_cards_model_pill_format_badge_and_overrides, expected_bar_orders_model_pill_mode_badge_rowcount_toggle_far_right), the updated #161/#165 guards, and the re-run 375px stacked guard
cargo test --test headless_zero_egress -- --ignored 5 passed (zero-egress green)
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --locked exit 0
cargo deny check exit 0
Goldens regenerated per the exact ci.yml report recipes; double-render byte-identical (all three); git diff --text -U0 -- examples/ audited — template-only deltas, payload JSON byte-stable, zero root_path/username content
insta intended-only: 1 snapshot (rendered_chrome_jaffle_shop — embeds the template bytes); skeleton snapshot unchanged
crap4rs CI-pinned v0.4.0 (verified installed, not reinstalled), CI-identical recipe (cargo llvm-cov nextest --locked --fail-under-lines 85 → crap4rs --config crap4rs.toml --coverage lcov.info): PASS — 1669 fns, 0 above threshold, worst 23.0

New headless guards

  • ref-pill hover AND keyboard focus reveal the model card (materialized/tags/description/model tests); absent manifest entry ⇒ no trigger class, not focusable
  • format-badge tip reconstructs csv and dict faithfully (exact line assertions); dict column order follows the FixtureTable POD (serde_json sorted-map order — the same order the grid shows)
  • overrides badge count + grouped rows + native-scalar stringification (bool/float/string)
  • all tips hide on focusout; idempotent re-render keeps exactly one expected model pill
  • bar order + toggle-far-right geometry + the relocated badge's bubble revealing from the bar

🤖 Generated with Claude Code


Open in Stage

… reconstruction, overrides badge, info tips (#202)

Three body-appended singleton tips (#model-tooltip / #fmt-tooltip /
#ov-tooltip) on mouseenter AND focusin behind focusable triggers: the
Given header renders ref( + .gt-model pill + ), the Expected panel gains
its model pill (header fallback or fixture-view bar, bar order
[model pill][mode badge][row count] with the Diff/File toggle far
right), the format badge shows for ALL formats incl. dict and
reconstructs the fixture client-side (sql/csv/yaml), and the test badge
row gains the 'overrides . N' badge with grouped key = value rows.

Founder decision (epic #197) applied: the incremental-branch mode badge
and the prior-model-state this-badge keep the #146 focusable-trigger
CSS-bubble mechanism with the pass-2 badge-borne styling - the separate
expected-panel i button is retired, the pass-2's JS info-tip twin for
those badges is not ported (exactly one mechanism), and the LOCKED D4
invariant holds (tooltip rides is_incremental_mode === true, never the
this-given proxy, never full-refresh).

Column-header tooltips: detail strings now render as ct-vals/ct-val
chips (ct-detail retired); per-table column_meta sourcing unchanged.
The #161 idempotent clear-list extends to .expected-model-badge.

Every interpolated tip value passes through escapeHtml (payload strings
are attacker-adjacent YAML). Goldens regenerated (template-only deltas,
payload byte-stable, double-render byte-identical); explore pages
untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@cmbays, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 12 minutes and 27 seconds. Learn how PR review limits work.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 94a8e7b1-85ac-48d2-9c46-7e99c9c40191

📥 Commits

Reviewing files that changed from the base of the PR and between bbcf316 and 18bb052.

⛔ Files ignored due to path filters (1)
  • tests/snapshots/render_integration__rendered_chrome_jaffle_shop.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • examples/diff-showcase-report.html
  • examples/jaffle-shop-report.html
  • examples/playground-report.html
  • templates/interaction.js
  • templates/report.css
  • tests/headless_toggle.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch renderer-202-design2-hover-cards

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ghost

ghost commented Jun 11, 2026

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

📄 Rendered report preview

All golden examples regenerated cleanly.

🟡 Golden examples

Committed to examples/ and byte-identity gated — the canonical reports contributors and consumers browse. Stable across PRs.

Report View Download
diff-showcase-report.html ▶ Open ↗ ⬇ Download
playground-report.html ▶ Open ↗ ⬇ Download
jaffle-shop-report.html ▶ Open ↗ ⬇ Download

🐶 Live dogfood preview

This PR doesn't touch dbt-project/, so there's no live dogfood preview.

▶ Open ↗ opens the report in your browser in one click —
published to this repo's GitHub Pages under /pr-220/.
⬇ Download fetches the same self-contained HTML as a workflow
artifact (auth-gated; works fully offline). Either way the report
makes zero external resource requests.

The Pages preview may take ~1 min to update after this comment
posts. On PRs from forks the Open link is unavailable (read-only
token) — use Download.

Alternative: GitHub CLI
# gh CLI >= 2.63 extracts into ./report-preview-playground/.
gh run download 27326077784 -R breezy-bays-labs/cute-dbt -n report-preview-playground
open report-preview-playground/playground-report.html

Posted by report-preview.yml for 18bb05216134092d70d65e01bb1c817f8dea2e54. Affordance only — never blocks merge.

@cmbays
cmbays merged commit 15e308a into main Jun 11, 2026
33 checks passed
@cmbays
cmbays deleted the renderer-202-design2-hover-cards branch June 11, 2026 05:36
github-actions Bot added a commit that referenced this pull request Jun 11, 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.

feature: design-2 integration PR-5 — rich hover cards: ref()/Expected model pills, format-badge fixture reconstruction, overrides badge, info tips

1 participant