Skip to content

Fix mobile correlation control layout - #2320

Merged
Asherlc merged 1 commit into
mainfrom
issue-2148-mobile-correlation-controls
Jul 29, 2026
Merged

Asherlc merged 1 commit into
mainfrom
issue-2148-mobile-correlation-controls

Conversation

@Asherlc

@Asherlc Asherlc commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • stack correlation metric selectors at narrow web viewports while preserving the desktop row
  • wrap lag choices and move the full comparison sentence below them
  • add a responsive regression test and narrow-viewport Storybook scenario

The audit issue title says mobile, but the reproduced defect is the responsive web surface. Native mobile already uses the intended stacked structure and remains unchanged. A simulator audit was not applicable because the changed surface is web; generating native infrastructure and API/auth state would not validate this defect.

Validation

  • pnpm exec vitest run packages/web/src/pages/CorrelationExplorerPage.test.tsx --project unit (11 passed)
  • pnpm exec vitest run packages/mobile/app/correlation.test.tsx --project mobile (12 passed)
  • pnpm test:changed (18 passed)
  • pnpm typecheck
  • pnpm lint (all gates passed; analytics lint used the workspace-scoped ClickHouse port)
  • pnpm storybook:web:build
  • pnpm storybook:mobile:build

Fixes #2148

Summary by Sourcery

Improve the responsive layout of the correlation controls on the web correlation explorer page to prevent overflow on narrow viewports while preserving the desktop arrangement.

Enhancements:

  • Stack correlation metric selectors in a responsive grid that defaults to a vertical layout on small viewports and preserves the horizontal layout on larger screens.
  • Allow lag option buttons to wrap and place the correlation comparison sentence in its own block below the lag controls to match native structure and improve readability.
  • Add a narrow-viewport Storybook story for the correlation explorer to document and visualize the responsive layout.
  • Refine CorrelationExplorerPage unit tests to assert the new responsive control structure and layout behavior.

Documentation:

  • Add a short implementation plan document describing the responsive correlation controls change, its goals, and validation steps.

Summary by cubic

Stacks the correlation metric selects and wraps lag options on narrow web viewports to prevent overflow, while preserving the desktop row layout. Adds a responsive regression test and a mobile viewport Storybook; fixes #2148.

  • Bug Fixes
    • Switched controls from flex to grid: stacked by default; horizontal at sm with sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]; "vs" hidden on small.
    • Made lag buttons flex-wrap and moved the comparison sentence into its own block below.
    • Native mobile is unchanged.

Written for commit 5bc2430. Summary will update on new commits.

Review in cubic

Keep full metric and lag labels readable at narrow viewports.\n\nRefs #2148
Copilot AI review requested due to automatic review settings July 29, 2026 23:35
@Asherlc Asherlc linked an issue Jul 29, 2026 that may be closed by this pull request
@codereviewbot-ai

Copy link
Copy Markdown

🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews.

@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Asherlc, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Asherlc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 1 minute

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4c11d46b-6371-4a90-a74c-0229fbfde57c

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb9200 and 5bc2430.

📒 Files selected for processing (4)
  • docs/superpowers/plans/2026-07-29-mobile-correlation-controls.md
  • packages/web/src/pages/CorrelationExplorerPage.stories.tsx
  • packages/web/src/pages/CorrelationExplorerPage.test.tsx
  • packages/web/src/pages/CorrelationExplorerPage.tsx

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.

@sourcery-ai

sourcery-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Makes the correlation controls responsive by stacking metric selectors and wrapping lag options on small web viewports, updates tests and Storybook to cover the new layout, and documents the implementation plan.

Flow diagram for responsive correlation controls layout

flowchart LR
  A[Viewport width]
  A -->|< sm| B[Metric controls use grid
stacked X and Y]
  A -->|>= sm| C[Metric controls use grid
row X vs Y]

  B --> D[Lag options in flex
with flex-wrap]
  C --> D

  D --> E[Comparison sentence in
separate block below
lag options]
Loading

File-Level Changes

Change Details Files
Make X/Y metric selectors stack on narrow viewports while preserving the horizontal desktop layout.
  • Remove flex grow from metric select label container to avoid forcing horizontal layout.
  • Change metric controls wrapper from a flex row to a responsive grid that stacks by default and switches to a three-column X / vs / Y layout at the small breakpoint.
  • Hide the inline "vs" label on narrow viewports and show it only from the small breakpoint upward.
packages/web/src/pages/CorrelationExplorerPage.tsx
Make lag controls wrap and move the comparison sentence into its own block for better narrow-viewport behavior.
  • Wrap lag label and buttons with flex-wrap so lag options can flow to multiple lines.
  • Render the formatted correlation comparison sentence in a separate block element below the lag controls instead of inline with them.
  • Keep existing lag selection behavior and visual emphasis while improving layout resilience.
packages/web/src/pages/CorrelationExplorerPage.tsx
Add regression coverage and Storybook support for the responsive correlation controls, and document the implementation plan.
  • Extend CorrelationExplorerPage unit test to assert the responsive grid class on metric controls, flex-wrap on lag options, and structural separation of the comparison sentence.
  • Add a NarrowViewport Storybook story that renders the available scenario with a mobile viewport configuration.
  • Add a documentation plan describing the responsive correlation controls approach, tasks, and relevant references.
packages/web/src/pages/CorrelationExplorerPage.test.tsx
packages/web/src/pages/CorrelationExplorerPage.stories.tsx
docs/superpowers/plans/2026-07-29-mobile-correlation-controls.md

Assessment against linked issues

Issue Objective Addressed Explanation
#2148 Prevent truncation and overlap of correlation controls at narrow (mobile-like) web viewports by changing the layout of metric selectors, lag controls, and the comparison sentence.
#2148 Present the comparison description (e.g., same-day comparison sentence) in a stacked/clearly separated form rather than as an additional flex item in the main controls row.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix responsive web layout for correlation controls

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Stack X/Y metric selectors at narrow web viewports while keeping the desktop row at sm+.
• Allow lag option buttons to wrap and render the comparison sentence on its own line.
• Add a narrow-viewport Storybook scenario and a responsive regression unit test.
Diagram

graph TD
  A["CorrelationExplorerPage.tsx"] --> B["Metric selectors grid"] --> C["Lag controls wrap"] --> D["Comparison sentence below"]
  A --> E["CorrelationExplorerPage.test.tsx"]
  A --> F["CorrelationExplorerPage.stories.tsx"]
  A --> G["Implementation plan doc"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Extract shared CorrelationControls component
  • ➕ Improves reuse and consistency if controls appear in multiple pages
  • ➕ Makes responsive behavior easier to test in isolation
  • ➖ More churn than needed for a single-page fix
  • ➖ Risk of widening scope and introducing regressions elsewhere
2. Use container queries instead of `sm` breakpoint
  • ➕ Layout adapts to actual container width (embeds/sidebars) rather than viewport breakpoint
  • ➕ Often more robust for responsive panels
  • ➖ Requires container-query support and/or additional Tailwind/plugin configuration
  • ➖ Higher complexity than necessary for the reported issue

Recommendation: Current approach is appropriate: Tailwind mobile-first utilities directly address overflow while preserving the desktop row, and the added unit + Storybook coverage reduces regression risk. Consider component extraction only if other pages need the same control block.

Files changed (4) +78 / -29

Bug fix (1) +27 / -25
CorrelationExplorerPage.tsxMake correlation controls mobile-first responsive without desktop regressions +27/-25

Make correlation controls mobile-first responsive without desktop regressions

• Updates metric selectors to use a mobile-first grid that becomes a three-column row at 'sm', hides the inline 'vs' on narrow viewports, and reworks lag controls to wrap with the comparison text moved below for readability.

packages/web/src/pages/CorrelationExplorerPage.tsx

Tests (1) +14 / -4
CorrelationExplorerPage.test.tsxAdd regression assertions for responsive control structure +14/-4

Add regression assertions for responsive control structure

• Updates the unit test to assert the metric controls use the new responsive grid classes, lag controls allow wrapping, and the comparison sentence is in a separate block.

packages/web/src/pages/CorrelationExplorerPage.test.tsx

Documentation (1) +30 / -0
2026-07-29-mobile-correlation-controls.mdDocument responsive correlation controls plan and validation +30/-0

Document responsive correlation controls plan and validation

• Adds an implementation plan describing the responsive web issue, the Tailwind-based layout strategy, and the validation checklist for tests/lint/typecheck/Storybook.

docs/superpowers/plans/2026-07-29-mobile-correlation-controls.md

Other (1) +7 / -0
CorrelationExplorerPage.stories.tsxAdd narrow-viewport Storybook scenario +7/-0

Add narrow-viewport Storybook scenario

• Introduces a 'NarrowViewport' story that sets the default viewport to a mobile preset to visually verify the stacked/wrapping control layout.

packages/web/src/pages/CorrelationExplorerPage.stories.tsx

@github-actions

Copy link
Copy Markdown
Contributor

Storybook previews for e82f2dab are ready:

This comment updates automatically on each PR push.

@Asherlc
Asherlc enabled auto-merge (squash) July 29, 2026 23:42
@Asherlc
Asherlc merged commit 7dc7a9d into main Jul 29, 2026
99 checks passed
@Asherlc
Asherlc deleted the issue-2148-mobile-correlation-controls branch July 29, 2026 23:54
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 167 rules

Grey Divider


Remediation recommended

1. Brittle class substring assertions 🐞 Bug ⚙ Maintainability
Description
The updated CorrelationExplorerPage test asserts layout using className.toContain("grid") /
toContain("flex-wrap"), which can false-pass if only variant-prefixed utilities exist (e.g.
sm:grid, sm:flex-wrap) and therefore doesn’t reliably verify the mobile-first layout.
Code

packages/web/src/pages/CorrelationExplorerPage.test.tsx[R385-392]

+    const xAxisSelect = screen.getByLabelText("X axis");
+    const metricControls = xAxisSelect.parentElement?.parentElement;
+    expect(metricControls?.className).toContain("grid");
+    expect(metricControls?.className).toContain("sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]");
+
+    const sameDayButton = screen.getByRole("button", { name: "Same day" });
+    const lagOptions = sameDayButton.parentElement;
+    expect(lagOptions?.className).toContain("flex-wrap");
Relevance

●●● Strong

Multiple accepted reviews warn against className.toContain Tailwind checks; prefer token-aware
toHaveClass (PRs #2229, #2217).

PR-#2229
PR-#2217

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed test introduced substring checks on className, and the test environment includes
jest-dom matchers that allow exact token assertions (toHaveClass). Past accepted bugs in this
codebase specifically call out this substring/variant-prefix false-positive pattern.

packages/web/src/pages/CorrelationExplorerPage.test.tsx[385-398]
packages/web/test-setup.ts[1-2]
PR-#2281
PR-#2229

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses substring checks on `className` for Tailwind utilities. Substring matching can pass even when the exact class token is missing (e.g., `"grid"` matches `"sm:grid-cols-..."`), weakening the regression coverage for the intended mobile-first classes.

## Issue Context
This repo already loads `@testing-library/jest-dom/vitest`, so `toHaveClass` is available and will assert exact class tokens.

## Fix Focus Areas
- packages/web/src/pages/CorrelationExplorerPage.test.tsx[381-407]
- packages/web/test-setup.ts[1-2]

## Proposed fix
- Replace:
 - `expect(metricControls?.className).toContain("grid")`
 - `expect(lagOptions?.className).toContain("flex-wrap")`

 with token-aware assertions, e.g.:
 - `expect(metricControls).toHaveClass("grid")`
 - `expect(metricControls).toHaveClass("sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]")`
 - `expect(lagOptions).toHaveClass("flex-wrap")`

- Also avoid optional chaining in the assertion target after locating the element; assert it’s non-null first so failures are clearer.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Viewport story ineffective 🐞 Bug ⚙ Maintainability
Description
The new NarrowViewport story sets parameters.viewport.defaultViewport = "mobile1", but the web
Storybook config does not include @storybook/addon-viewport, so the story will render at the
normal preview size and won’t reliably catch narrow-viewport regressions.
Code

packages/web/src/pages/CorrelationExplorerPage.stories.tsx[R226-231]

+export const NarrowViewport: Story = {
+  parameters: {
+    viewport: { defaultViewport: "mobile1" },
+  },
+  render: () => <CorrelationStoryFrame scenario="available" />,
+};
Relevance

● Weak

Repo already merged stories using parameters.viewport.defaultViewport without adding
addon-viewport (PR #2278; Storybook setup PR #686).

PR-#2278
PR-#686

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The story uses a viewport parameter intended for the viewport addon, but the web Storybook
configuration only enables the a11y addon and the web package does not include the viewport addon
dependency, so the viewport setting won’t be applied.

packages/web/src/pages/CorrelationExplorerPage.stories.tsx[226-231]
packages/web/.storybook/main.ts[3-8]
packages/web/package.json[45-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`NarrowViewport` sets Storybook `viewport` parameters, but web Storybook doesn’t have the viewport addon enabled/installed, so the parameter is ignored and the story does not actually validate a narrow layout.

## Issue Context
- The story introduces `viewport: { defaultViewport: "mobile1" }`.
- Web Storybook’s `addons` list does not include `@storybook/addon-viewport`, and `packages/web/package.json` does not declare it.

## Fix Focus Areas
- packages/web/.storybook/main.ts[1-18]
- packages/web/package.json[45-62]
- packages/web/src/pages/CorrelationExplorerPage.stories.tsx[226-231]

## Proposed fix
1. Add `@storybook/addon-viewport` to `packages/web/package.json` devDependencies.
2. Add `"@storybook/addon-viewport"` to the `addons` array in `packages/web/.storybook/main.ts`.
3. (Optional) If you do not want the addon, replace the viewport parameter with an explicit narrow-width wrapper around `CorrelationStoryFrame` (e.g., a container `div` with `style={{ width: 375 }}`) so the story is deterministic without relying on addons.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment on lines +385 to +392
const xAxisSelect = screen.getByLabelText("X axis");
const metricControls = xAxisSelect.parentElement?.parentElement;
expect(metricControls?.className).toContain("grid");
expect(metricControls?.className).toContain("sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]");

const sameDayButton = screen.getByRole("button", { name: "Same day" });
const lagOptions = sameDayButton.parentElement;
expect(lagOptions?.className).toContain("flex-wrap");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Brittle class substring assertions 🐞 Bug ⚙ Maintainability

The updated CorrelationExplorerPage test asserts layout using className.toContain("grid") /
toContain("flex-wrap"), which can false-pass if only variant-prefixed utilities exist (e.g.
sm:grid, sm:flex-wrap) and therefore doesn’t reliably verify the mobile-first layout.
Agent Prompt
## Issue description
The test uses substring checks on `className` for Tailwind utilities. Substring matching can pass even when the exact class token is missing (e.g., `"grid"` matches `"sm:grid-cols-..."`), weakening the regression coverage for the intended mobile-first classes.

## Issue Context
This repo already loads `@testing-library/jest-dom/vitest`, so `toHaveClass` is available and will assert exact class tokens.

## Fix Focus Areas
- packages/web/src/pages/CorrelationExplorerPage.test.tsx[381-407]
- packages/web/test-setup.ts[1-2]

## Proposed fix
- Replace:
  - `expect(metricControls?.className).toContain("grid")`
  - `expect(lagOptions?.className).toContain("flex-wrap")`

  with token-aware assertions, e.g.:
  - `expect(metricControls).toHaveClass("grid")`
  - `expect(metricControls).toHaveClass("sm:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]")`
  - `expect(lagOptions).toHaveClass("flex-wrap")`

- Also avoid optional chaining in the assertion target after locating the element; assert it’s non-null first so failures are clearer.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

[CORR-03] Mobile correlation controls truncate and overlap

2 participants