feat(skills): Add migrate-container-queries skill#162
Conversation
Guide for migrating viewport media queries (@media, useMedia) to container queries in Sentry's frontend. Encodes the refactor-first ladder (prefer Container/Flex/Grid primitives, fall back to @container), the breakpoints-vs-container scale mismatch, and the container-type guidance. Registered in README, .claude/settings.json, and the claude-settings-audit allowlist.
…-query skill Make the "convert to the nearest container scale" rule explicit (round the element's real rendered width to the closest container token, never reuse the breakpoint key), surface "always do a visual check" prominently up top and in the checklist, and trim density by collapsing redundant examples. Add SPEC.md for the maintenance contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…laim global.tsx only sets container-type on #modal-portal (for portaled content outside the app tree), not a root container. The real app-content query container is ContentStack (#main) in organizationLayout, which wraps the routed Outlet. topBar has its own.
Default rung 3 to useResponsivePropValue (with useContainerBreakpoint as the raw-key fallback), reframe the container-type section as default-then-how with the concrete ContentStack/#main ancestor, and drop the trace-PR references from the runtime file. Align the checklist wording. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert rung 3 to useContainerBreakpoint() (the documented container-scoped useMedia replacement), complete both token tables from the story (container scale to 5xl, screen scale to 2xl) and split them so keys aren't read across rows, and route genuine viewport-width cases to screen: responsive keys instead of useMedia. Add the Seer-sidebar drag as a concrete visual-check technique and cite the story as an authoritative source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Correct the scale rule to map the OLD breakpoint's pixel value to the nearest container token (breakpoints.sm 800px -> container.xl 768px; rung-2 example 992px -> 3xl 1024px), replacing the earlier element-width framing that contradicted the examples. Merge the duplicated container-type paragraphs and cut the checklist down to verification-only gotchas so the four rungs aren't restated three times. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the oblique "don't read across a row" note with a direct caps directive naming the actual error: map by pixel value, not by key (breakpoints.sm does not become container.sm). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the unclear "never reused the breakpoint key" wording with a concrete by-name example (breakpoints.sm -> container.xl, not container.sm) and align the rule sentence to say "same name" instead of "matching key". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cut boilerplate and SKILL.md-duplicating sections (trigger context, runtime contract, reference architecture, validation, template source lists) down to intent, the settled constraints, sources, limitations, and maintenance. 72 -> 37 lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tent Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| // New | ||
| import {Flex} from '@sentry/scraps/layout'; | ||
| <Flex direction={{xs: 'column', sm: 'row'}} gap="md"> | ||
| ``` |
There was a problem hiding this comment.
Bug: The Rung 1 migration example incorrectly maps breakpoints.sm to container.sm. It should map by pixel value to the nearest container breakpoint, container.xl.
Severity: MEDIUM
Suggested Fix
Update the example to reflect the correct mapping based on pixel values. The code direction={{xs: 'column', sm: 'row'}} should be changed to direction={{zero: 'column', xl: 'row'}} to correctly map the original breakpoints.sm (800px) to the nearest container breakpoint (container.xl at 768px).
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: skills/migrate-container-queries/SKILL.md#L72-L75
Potential issue: The Rung 1 migration example in the documentation incorrectly maps a
viewport breakpoint to a container breakpoint. It maps `breakpoints.sm` (800px) to the
`sm` container key, which corresponds to 512px. This contradicts the guide's own rule to
map by pixel value, not by key name. The correct mapping for the original 800px
breakpoint is `container.xl` (768px). This incorrect example could lead developers to
introduce responsive bugs into their components.
Did we get this right? 👍 / 👎 to inform future reviews.
| const breakpoint = useContainerBreakpoint(); // 'zero' | '3xs' | ... | '5xl' | ||
| const isNarrow = breakpoint === 'zero'; | ||
| ``` |
There was a problem hiding this comment.
Bug: The useMedia migration example incorrectly replaces a max-width: 800px check with breakpoint === 'zero', which is only true below 320px, inverting the responsive logic.
Severity: MEDIUM
Suggested Fix
The example should be corrected to check if the current container breakpoint is below the equivalent of the original 800px viewport breakpoint. The logic should check if the active breakpoint is smaller than 'xl' (768px), which is the nearest container token to the original 800px boundary.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: skills/migrate-container-queries/SKILL.md#L98-L100
Potential issue: The Rung 3 example for migrating `useMedia` incorrectly replaces a
check for screen width less than 800px (`useMedia('(max-width: breakpoints.sm)')`) with
a check for `breakpoint === 'zero'`. The `'zero'` container breakpoint only applies when
the container width is less than 320px. This fundamentally changes the responsive logic,
causing the `isNarrow` condition to be `false` for most realistic container sizes,
whereas it was previously `true` for a wide range of widths up to 800px.
Did we get this right? 👍 / 👎 to inform future reviews.
|
@priscilawebdev since this is
|
Omg! That is very true. thank you! |
Adds the
migrate-container-queriesskill guiding the migration of viewport media queries (@media,useMedia) to container queries in Sentry's frontend, backing the Design Engineering container-query migration project (DE-1368). It's a single inlineSKILL.mdplus aSPEC.mdmaintenance contract.