feat: scroll highlighted YAML section into view#703
Open
SurbhiAgarwal1 wants to merge 4 commits into
Open
Conversation
✅ Deploy Preview for otel-ecosystem-explorer ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds auto-scrolling behavior so clicking a configuration section card scrolls the corresponding YAML section into view (when needed), and verifies it via integration tests.
Changes:
- Stub
Element.scrollIntoViewwith a Vitest mock for JSDOM-based integration tests. - Add
YamlCodeBlocklogic to find the active YAML section and scroll it into view when it’s outside the visible container bounds. - Add integration tests covering both “scroll when off-screen” and “don’t scroll when already visible”.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| ecosystem-explorer/src/test/integration/setup.ts | Updates JSDOM test setup to stub scrollIntoView using Vitest mocks. |
| ecosystem-explorer/src/test/integration/configuration-builder-card-clicks.integration.test.tsx | Adds integration tests validating scroll behavior when clicking section cards. |
| ecosystem-explorer/src/features/java-agent/configuration/components/yaml-code-block.tsx | Implements effect-driven scrolling to the active YAML section when it’s not visible. |
Comment on lines
+27
to
+29
| import { vi } from "vitest"; | ||
| if (typeof Element !== "undefined" && !Element.prototype.scrollIntoView) { | ||
| Element.prototype.scrollIntoView = function () {}; | ||
| Element.prototype.scrollIntoView = vi.fn(); |
| // the next initDB() call opens a fresh connection. | ||
| closeDB(); | ||
| }); | ||
| import { vi } from "vitest"; |
Comment on lines
+101
to
+114
| // Mock getBoundingClientRect so the section appears off-screen | ||
| const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect; | ||
| Element.prototype.getBoundingClientRect = function () { | ||
| if (this.tagName === "PRE") { | ||
| return { top: 0, bottom: 500, left: 0, right: 500, width: 500, height: 500, x: 0, y: 0, toJSON: () => {} }; | ||
| } | ||
| if (this.getAttribute("data-yaml-section") === "resource") { | ||
| return { top: 600, bottom: 700, left: 0, right: 500, width: 500, height: 100, x: 0, y: 0, toJSON: () => {} }; | ||
| } | ||
| return originalGetBoundingClientRect.call(this); | ||
| }; | ||
|
|
||
| const scrollIntoViewMock = vi.fn(); | ||
| Element.prototype.scrollIntoView = scrollIntoViewMock; |
| expect(scrollIntoViewMock).toHaveBeenCalledWith({ block: "nearest", behavior: "smooth" }); | ||
| }); | ||
|
|
||
| Element.prototype.getBoundingClientRect = originalGetBoundingClientRect; |
Comment on lines
+52
to
55
| Element.prototype.scrollIntoView = vi.fn(); | ||
| } | ||
|
|
||
| beforeEach(async () => { |
Comment on lines
+102
to
+135
| const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect; | ||
| const originalScrollIntoView = Element.prototype.scrollIntoView; | ||
| const scrollIntoViewMock = vi.fn(); | ||
|
|
||
| Element.prototype.getBoundingClientRect = function () { | ||
| if (this.tagName === "PRE") { | ||
| return { | ||
| top: 0, | ||
| bottom: 500, | ||
| left: 0, | ||
| right: 500, | ||
| width: 500, | ||
| height: 500, | ||
| x: 0, | ||
| y: 0, | ||
| toJSON: () => {}, | ||
| }; | ||
| } | ||
| if (this.getAttribute("data-yaml-section") === "resource") { | ||
| return { | ||
| top: 600, | ||
| bottom: 700, | ||
| left: 0, | ||
| right: 500, | ||
| width: 500, | ||
| height: 100, | ||
| x: 0, | ||
| y: 0, | ||
| toJSON: () => {}, | ||
| }; | ||
| } | ||
| return originalGetBoundingClientRect.call(this); | ||
| }; | ||
| Element.prototype.scrollIntoView = scrollIntoViewMock; |
| const resourceSection = document.querySelector<HTMLElement>('[data-section-key="resource"]'); | ||
| expect(resourceSection).not.toBeNull(); | ||
|
|
||
| // Mock getBoundingClientRect so the section appears off-screen |
| const resourceSection = document.querySelector<HTMLElement>('[data-section-key="resource"]'); | ||
| expect(resourceSection).not.toBeNull(); | ||
|
|
||
| // Mock getBoundingClientRect so the section appears on-screen |
Comment on lines
+93
to
+98
| const isVisible = | ||
| sectionRect.top >= containerRect.top && sectionRect.bottom <= containerRect.bottom; | ||
|
|
||
| if (!isVisible) { | ||
| activeSection.scrollIntoView({ block: "nearest", behavior: "smooth" }); | ||
| } |
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.
What changed
This PR implements an auto-scroll behavior for the YAML preview in the Configuration Builder. When a user interacts with a configuration field, the corresponding highlighted YAML section is now automatically brought into view using
scrollIntoView({ block: "nearest", behavior: "smooth" }). It calculates bounding client rectangles to ensure it only scrolls if the target YAML block is currently off-screen, preventing any unnecessary jumpy behavior.Why
Fixes #682
Right now, highlighting a section that is outside the visible area of the preview container forces the user to manually scroll to find it. This change improves discoverability by automatically scrolling to the active section, providing a smoother editing experience.
How it was tested
Added new tests in
configuration-builder-card-clicks.integration.test.tsxthat mockgetBoundingClientRectandscrollIntoView.scrollIntoViewis triggered correctly when the active YAML block is rendered outside the parent container's visible bounds.scrollIntoViewis NOT triggered when the active YAML block is already visible inside the viewport.Ran all integration tests via Vitest and they passed successfully.
Is this a breaking change?
No.
Special notes for your reviewer
I reused the existing
activePreviewKeylogic introduced in #478 to target the correct[data-yaml-section].Checklist