Skip to content

fix: prevent source setup dropdowns from being clipped by the modal (HDX-4445)#2411

Merged
kodiakhq[bot] merged 2 commits into
mainfrom
claude/hdx-4445-source-form-dropdown-clipping
Jun 3, 2026
Merged

fix: prevent source setup dropdowns from being clipped by the modal (HDX-4445)#2411
kodiakhq[bot] merged 2 commits into
mainfrom
claude/hdx-4445-source-form-dropdown-clipping

Conversation

@teeohhem
Copy link
Copy Markdown
Contributor

@teeohhem teeohhem commented Jun 3, 2026

What & why

In the Configure New Source modal, clicking the Database field opened a dropdown that was clipped at the top edge of the modal — with several databases the list was cut off and the top entries were unreachable (HDX-4445).

Root cause: the Database, Table, and Server Connection pickers set comboboxProps={{ withinPortal: false }}, so their dropdowns were positioned inside the modal's DOM and clipped by the modal's bounds. (maxDropdownHeight already gives the list an internal scrollbar — the problem was purely positional clipping by the modal container.)

Change

  • Flip withinPortal: false → true on the three source-form pickers (DatabaseSelect, DBTableSelect, ConnectionSelect) so their dropdowns render in a portal and escape the modal's clip box. Matches the in-modal precedent in DashboardFiltersModal; true is Mantine v9's default. maxDropdownHeight={280} is kept for the internal scroll.
  • Add a component test (sourceFormPickerDropdowns.test.tsx): mount each picker with a 20-item list and assert (a) all 20 options render (no truncation) and (b) they're portaled out of the picker's own container, so a modal can't clip them. (b) is the regression guard — it fails on withinPortal: false regardless of option count; (a) guards against truncation. Verified red/green.

Note: clipping is a visual overflow effect that doesn't change the DOM or an element's box and isn't measurable in jsdom, so the portal DOM-location is the deterministic signal a component test can assert. (True on-screen visual proof would need a real-browser E2E test.)

Testing

  • make ci-lint ✅ (lint + tsc, all packages)
  • yarn ci:unit ✅ — full app unit suite, incl. the new test
  • Verified red/green: on withinPortal: false all 20 options still render but are nested in the container (clippable) → test fails; on true they're portaled out → test passes.

Closes HDX-4445.

🤖 Generated with Claude Code

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 3, 2026

🦋 Changeset detected

Latest commit: 772c840

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/app Patch
@hyperdx/api Patch
@hyperdx/otel-collector Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment Jun 3, 2026 5:00pm
hyperdx-storybook Ready Ready Preview, Comment Jun 3, 2026 5:00pm

Request Review

@github-actions github-actions Bot added the review/tier-3 Standard — full human review required label Jun 3, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

🔵 Tier 2 — Low Risk

Small, isolated change with no API route or data model modifications.

Why this tier:

  • Standard feature/fix — introduces new logic or modifies core functionality

Additional context: agent branch (claude/hdx-4445-source-form-dropdown-clipping) — change small enough to qualify for Tier 2

Review process: AI review + quick human skim (target: 5–15 min). Reviewer validates AI assessment and checks for domain-specific concerns.
SLA: Resolve within 4 business hours.

Stats
  • Production files changed: 3
  • Production lines changed: 6 (+ 150 in test files, excluded from tier calculation)
  • Branch: claude/hdx-4445-source-form-dropdown-clipping
  • Author: teeohhem

To override this classification, remove the review/tier-2 label and apply a different review/tier-* label. Manual overrides are preserved on subsequent pushes.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

E2E Test Results

All tests passed • 197 passed • 3 skipped • 1280s

Status Count
✅ Passed 197
❌ Failed 0
⚠️ Flaky 2
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Deep Review

The change flips comboboxProps={{ withinPortal: false }} to true on DatabaseSelect, DBTableSelect, and ConnectionSelect, and adds a component test asserting all options render and are portaled out of the picker container. The fix is correct, the portal target resolves to document.body (outside the RTL render container), and the new test is a genuine regression guard — it fails on withinPortal: false because the dropdown then renders inside the picker container.

✅ No critical issues found.

🟡 P2 — recommended

  • packages/app/src/components/SourceSelect.tsx:223SourceSelectControlled defaults to withinPortal: false and is rendered for the correlated source pickers (log/trace/metric/session) inside the same source-setup modal as the three fixed pickers, so those dropdowns remain clippable by the modal's overflow.
    • Fix: Default SourceSelectControlled to a portaled combobox as well, or scope this PR's note to clarify the remaining modal pickers as a tracked follow-up.
    • correctness, maintainability
🔵 P3 nitpicks (1)
  • packages/app/src/components/__tests__/sourceFormPickerDropdowns.test.tsx:119 — Assertion (b) proves the options are absent from the picker container but does not positively assert they live in the document-level portal, so a future change that drops the dropdown entirely could still pass that check (assertion (a) mitigates this).
    • Fix: Optionally assert the options resolve under document.body outside the container to make the portal location explicit.

Reviewers (5): correctness, testing, maintainability, project-standards, kieran-typescript.

Testing gaps: Coverage is jsdom-only by design; actual pixel-level clipping is not assertable without a real-browser E2E test, so the visual fix itself remains unverified by automation.

…HDX-4445)

The Database, Table, and Server Connection pickers in the source setup form used comboboxProps={{ withinPortal: false }}, so their dropdowns rendered inside the modal's DOM and were clipped by its bounds — with many databases the list was cut off at the modal edge. Render the dropdowns in a portal instead so the full list is visible and scrollable.

Adds a component test that mounts each picker with a 20-item list and asserts every option is rendered AND rendered in a portal (outside the picker's own container). The portal check fails if withinPortal is flipped back to false, independent of how many options there are.
@kodiakhq kodiakhq Bot merged commit f95687b into main Jun 3, 2026
19 checks passed
@kodiakhq kodiakhq Bot deleted the claude/hdx-4445-source-form-dropdown-clipping branch June 3, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge review/tier-2 Low risk — AI review + quick human skim

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants