fix(NotchGrid): guarantee distinct panels never overlap at gap=0#323
Closed
I-am-nothing wants to merge 5 commits into
Closed
fix(NotchGrid): guarantee distinct panels never overlap at gap=0#323I-am-nothing wants to merge 5 commits into
I-am-nothing wants to merge 5 commits into
Conversation
Two unrelated components (different keys, no shared groupKey, different themes) placed on touching cells rendered with their outlines overlapping by 2*panelBleed px — the later-painted panel cutting up into the one above — because panelBleed dilates every outline outward and gap=0 applies no counter-erosion. Grouping was correct (they stayed two separate chromes); the defect was purely in outline geometry (grid-outline erosion = gap/2 - bleed going negative with no inter-component protection). NotchGrid now caps each component's outward bleed at half the empty space to its nearest distinct neighbour and forces a small seam when a neighbour is flush, so distinct components always stay visually separated regardless of the gap prop. Well-separated layouts keep the full panelBleed unchanged. Bump 0.5.17; add regression test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
|
Storybook Preview: https://mirrorstack-ai.github.io/web-ui-kit/pr/323/ |
…t a fixed px MIN_COMPONENT_SEP was a flat 2px, imperceptible at typical block sizes and not what "leave a gap between distinct panels" actually needs. Replaced with MIN_COMPONENT_SEP_FRACTION (0.25 of one cell), so the guaranteed seam scales with the grid's live block size the same way callers already reason about spacing in cell/tile units.
Replace the per-component bleed-capping/eroding approach (computeComponentOutlines) with a position nudge (computeComponentNudges): distinct touching components get pushed apart by enough to cancel their bleed's outward dilation plus the desired MIN_COMPONENT_SEP_FRACTION seam, applied to where each component renders (its wrapper's left/top, the same mechanism already used for drag offsets) rather than varying its gap/panelBleed. Every component's own outline shape is now identical regardless of its neighbors — only its position shifts. Strengthened the regression test to also assert each panel's own outline dimensions are unchanged (proving the fix is position-only), and fixed the nudge magnitude to account for panelBleed's full outward reach (previously only offset by half the target seam, which undershot when panelBleed was nonzero).
…ound race agentBodyH started at 0 and was only ever set by ResizeObserver's own callback, which the spec requires to fire asynchronously — even for the very first observation. That left a real (if usually brief) window on every sidebar open where windowBodyHeight was omitted from AgentSidebarHeader, so the transparent body (which depends entirely on the header's single-shape fill reaching down over it) rendered with no background at all until the async callback landed. Switch the effect to useLayoutEffect and seed agentBodyH synchronously via getBoundingClientRect() before attaching the observer, so the very first paint already has a real height. The observer still owns every subsequent resize (drag, viewport changes, content growth) — this only closes the initial gap.
Reflects the NotchGrid position-nudge fix (gap=0 + panelBleed distinct-panel overlap) as a minor rather than patch — the fix changed the resolved geometry of any component that touches a distinct neighbor, not just an edge case.
5 tasks
Contributor
Author
|
Superseded by #325 — this branch picked up an unrelated commit from a concurrent session that now conflicts with main (main merged a different version of the same AppShell fix via #324). #325 is a clean cherry-pick of just the NotchGrid + version-bump commits off current main. Branch kept on origin, not deleted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In an app-overview NotchGrid (web-applications), two UNRELATED right-column panels — Summary (filled/secondary) and Manage (filled/tertiary), different keys, no shared `groupKey` — rendered with their outlines stuck together: Manage's top cutting up into Summary's bottom.
Root cause (verified by reproduction, not assumption)
Two distinct panels placed on touching cells with `gap={0}` + `panelBleed={4}` render outlines that overlap by `2·panelBleed` = 8px. `grid-outline.ts` computes `erosion = gap/2 − bleed`; at `gap=0` that is `−panelBleed` (net outward dilation), and nothing in the kit guarantees separation between distinct components. Manage paints after Summary → its dilated top overlaps Summary's dilated bottom.
Ruled out — the 8-connected grouping merge. `findConnectedComponents` does merge touching placements, but `groupComponents` buckets by `groupKey` first, and a panel with `subItems` gets its own key as `groupKey` (NotchGrid.tsx:749). Verified via the real render path: distinct-keyed touching panels stay two separate chromes (2 ``), so the "joined shape" was overlapping-but-separate outlines, not a real mask merge.
Fix
`NotchGrid` now derives per-component outline geometry (`computeComponentOutlines`): each component's outward `panelBleed` is capped at half the empty pixel space to its nearest distinct neighbour, and a flush neighbour forces a small inward seam (`MIN_COMPONENT_SEP`). Distinct components stay visually separated regardless of the `gap` prop; well-separated layouts keep the full `panelBleed` unchanged (only kicks in for default `panelBleed=0` never).
Tests
Bumps to 0.5.17 (patch, pre-1.0) paired with the `release` label.
🤖 Generated with Claude Code