Skip to content

Premium Analytics: measure the date presets instead of guessing a breakpoint - #50906

Merged
retrofox merged 22 commits into
trunkfrom
update/date-controls-responsive-labels
Aug 4, 2026
Merged

retrofox merged 22 commits into
trunkfrom
update/date-controls-responsive-labels

Conversation

@retrofox

@retrofox retrofox commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Fixes WOOA7S-1816
Part of WOOA7S-1793

What?

The date range presets now shorten their labels before collapsing into a select, and both switches are decided by measuring the active language's own labels rather than comparing the container against a fixed width.

Implements WOOA7S-1816, on the measurements from WOOA7S-1817. Design: Eder's p1785208001025929-slack-C06FSDTSN82, "Responsive format".

Also included, because they surfaced while measuring:

  • The custom-range trigger truncates a long label instead of wrapping it.
  • DateFiltersPanel measures itself, so containerElement is gone from 12 call sites.

Why?

The panel collapsed its presets into a select below a fixed 600px. That number was picked against English, and English is the shortest case. Measured through CoreText at the pill's real type settings, across the 15 locales that translate all four preset labels:

locale preset group vs English
ru 572px 1.49x
nl 526px 1.37x
cs 525px 1.36x
de 478px 1.24x
en 385px baseline
ko 304px 0.79x

German is not the worst case, it is seventh. CJK is narrower than English. Russian is the outlier, and the whole row needs 694px there against 470px in English.

Two consequences. A fixed threshold is wrong for almost every language, by up to 225px. And collapsing straight to a select was throwing away a click for no reason: abbreviated labels fit in a fraction of the room, so the select only becomes necessary far below where it used to fire.

Counting characters would not have found this. Последние 7 дней is 1.45x English by character count but 1.69x by rendered width.

How?

PresetLabelMode (full / abbreviated / select) replaces the isCompact boolean. isCompact survives only as labelMode === 'select', for the popover and the compact CSS.

PresetRowProbe renders the preset row twice off-screen, once per label form, inert and at max-content, and reports both natural widths. Measured in the DOM rather than computed, because the width depends on the font resolved for the locale's script, the button padding tokens, and the group's borders — reproducing that in JS would be a second implementation of the same layout, free to drift.

It renders both forms unconditionally. This is the load-bearing detail: measuring the live row oscillates, since shortening the labels shrinks it, the full labels then look like they fit, and back again.

resolvePresetLabelMode( availableWidth, rowWidths ) is a pure function picking the longest form that fits. There is no threshold constant left. WIDE_CALENDAR_CONTAINER_THRESHOLD stays one on purpose: the calendar's content is two month grids, whose width does not follow the locale's strings.

The abbreviations are _x() strings with translator context, not truncations. Last 24H and 7D are English initials; without context a translator leaves them in English and a Russian reader sees 7D.

flex-wrap: nowrap on the rolling group, now that shortening happens before overflow. That also retires an artifact: the group's hairline dividers are drawn with > * + *, which knows nothing about row breaks, so a wrapped row's first pill painted a border on top of the group's own frame. Scoped to that group rather than the shared mixin, since the year surface has no abbreviated form to fall back on yet.

Self-measurement

Every one of the ten page consumers wrapped the panel in a div and handed it back as containerElement, so the value was always the panel's own width. The panel now observes its own root. The two ReportParamsField copies also lose a document.querySelector( '.next-admin-layout__surface' ) workaround that existed only to feed the prop, and whose upstream fix (WOOA7S-1008) was cancelled.

Net effect on the call sites: 137 lines removed, 32 added.

Testing

Storybook: cd projects/js-packages/storybook && pnpm run storybook:dev, then Packages / Premium Analytics / UI / DateFiltersPanel.

TranslatedRussian, TranslatedDutch and TranslatedGerman install real WordPress.org language packs through setLocaleData, so labels come from the actual __() path. Each renders the bar at 960 / 782 / 600 / 360 / 280px plus a resizable container.

  1. Russian at 600px shows Last 24H 7D 30D 12M. On trunk it wraps to two rows.
  2. English (DashboardFilters) at 600px keeps full labels. Same width, different tier, because the boundary is measured per locale.
  3. Drag the resizable container across both boundaries. It should settle in one state at each width, never flicker between two.
  4. 280px shows the custom trigger truncated with an ellipsis. On trunk it breaks mid-word across three lines.
  5. All five rungs should show no wrapped preset row and no doubled divider at the left edge of a second row.

Also worth a pass in wp-admin on the dashboard, a report page, and post detail, since all three lost their wrapper ref: narrow the browser and confirm the presets shorten and then collapse.

Automated: pnpm run test in projects/packages/premium-analytics (199 suites, 1395 tests), plus pnpm run typecheck.

Follow-ups

  • Real translations for the abbreviations. The tiers hold regardless, but until the packs carry Last 24H and friends, non-English users see English initials in the middle tier. Tracked on WOOA7S-1817.
  • The probe's measurement is not unit tested: jsdom performs no layout, so getBoundingClientRect() returns 0, the probe bails, and the panel stays in full for the whole suite. The decision function and the label rendering are covered; the measurement is verified visually. Worth knowing before trusting a green run on this component.
  • DateYearFilter still takes containerElement. Its panel lands in WOOA7S-1815, which should give it the same treatment.
  • The year surface keeps flex-wrap: wrap because it has no abbreviated form. Revisit with WOOA7S-1815.
  • WOOA7S-1818: All time orphans the existing All-time translation over a hyphen, and Custom needs _x() context — the French pack returns "Lien" for the bare msgid.

retrofox added 8 commits July 29, 2026 08:34
russian, dutch and german through real language packs at four container widths
translated separately with context, not truncations of the full label
replaces the fixed 600px compact threshold, which was wrong for every language
own element so the ellipsis can engage; adds a 280px story rung
the fixed widths cannot show whether a boundary settles or flickers
drops containerElement from 12 call sites; every one passed its own wrapper
extracts it from the panel; jsdom has no layout, so the probe stays visual
resolves three report pages where trunk added table deltas next to the removed containerElement
@retrofox
retrofox requested a review from a team July 29, 2026 17:21
@retrofox
retrofox requested a review from a team as a code owner July 29, 2026 17:21
@retrofox retrofox self-assigned this Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • 🔴 Add a "[Status]" label (In Progress, Needs Review, ...).
  • 🔴 Add testing instructions.
  • 🔴 Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


🔴 Action required: Please include detailed testing steps, explaining how to test your change, like so:

## Testing instructions:

* Go to '..'
*

🔴 Action required: We would recommend that you add a section to the PR description to specify whether this PR includes any changes to data or privacy, like so:

## Does this pull request change what data or activity we track or use?

My PR adds *x* and *y*.

Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@github-actions github-actions Bot added the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack or WordPress.com Site Helper), and enable the update/date-controls-responsive-labels branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack update/date-controls-responsive-labels
bin/jetpack-downloader test jetpack-mu-wpcom-plugin update/date-controls-responsive-labels

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@jp-launch-control

jp-launch-control Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Code Coverage Summary

Coverage changed in 19 files. Only the first 5 are listed here.

File Coverage Δ% Δ Uncovered
projects/packages/premium-analytics/packages/ui/src/date-filters-panel/date-filters-panel.tsx 0/45 (0.00%) 0.00% 15 💔
projects/packages/premium-analytics/packages/datetime/src/presets/primary.ts 69/69 (100.00%) 0.00% 0 💚
projects/packages/premium-analytics/packages/ui/src/date-range-filter/date-range-filter.tsx 9/9 (100.00%) 0.00% 0 💚
projects/packages/premium-analytics/packages/ui/src/date-range-layout.ts 6/6 (100.00%) 0.00% 0 💚
projects/packages/premium-analytics/packages/ui/src/date-range-quick-presets/date-range-quick-presets.tsx 17/20 (85.00%) 1.67% 0 💚

1 file is newly checked for coverage.

File Coverage
projects/packages/premium-analytics/packages/ui/src/date-filters-panel/preset-row-probe.tsx 1/30 (3.33%) 💔

Full summary · PHP report · JS report

If appropriate, add one of these labels to override the failing coverage check: Covered by non-unit tests Use to ignore the Code coverage requirement check when E2Es or other non-unit tests cover the code Coverage tests to be added later Use to ignore the Code coverage requirement check when tests will be added in a follow-up PR I don't care about code coverage for this PR Use this label to ignore the check for insufficient code coveage.

kangzj
kangzj previously approved these changes Jul 31, 2026

@kangzj kangzj 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.

Reviewed the diff, ran jp test js packages/premium-analytics (199 suites, green), pnpm run typecheck, and eslint on the changed files — all clean.

Also verified the responsive behavior live in Storybook. Russian at 600px collapses to the abbreviated tier (Last 24H 7D 30D 12M) exactly as described, confirming the per-locale measurement is doing what the PR claims rather than a fixed breakpoint:

Image

One non-blocking nit: the pre-existing CompactLayout story (English @ 360px, untouched by this PR) still carries the docblock "quick presets collapse to the compact select, like mobile layouts." With the new three-tier model, English at 360px now renders the abbreviated pill tier, not the select — the comment (and the story) no longer demonstrate what the name promises:

Image

Worth a follow-up to either narrow the story's width or update its description so it still exercises the select tier. Doesn't block — everything else checks out.

retrofox added 2 commits July 31, 2026 10:29
keeps trunk's section header layout; its story still fed the removed containerElement
360px lands on the abbreviated tier, not the select
@retrofox retrofox added [Status] Needs Review This PR is ready for review. and removed [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. labels Jul 31, 2026
@github-actions github-actions Bot added [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. and removed [Status] Needs Review This PR is ready for review. labels Jul 31, 2026
retrofox added 2 commits July 31, 2026 16:42
memoizes the probe, floors the measured width, drops a redundant measure pass
a shrink-to-fit slot made the panel measure its content and never shorten
chihsuan

This comment was marked as off-topic.

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great work! @retrofox Overall looks good.

One thing I noticed: the probe and the real trigger can end up measuring two different labels.

After selecting and applying a custom range, clicking a preset pill does not change the custom-range trigger back to “Custom”. It continues to display the previously applied date range.

Also, the probe measures the shorter “Custom” label. This leaves roughly 90px of width unaccounted for, causing the UI to overlap or overflow.

See recording below:

Screen.Recording.2026-08-03.at.1.03.59.PM.mov

the remembered range desynced the probe, which only ever sees props
@retrofox

retrofox commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review, Chi.

After selecting and applying a custom range, clicking a preset pill does not change the custom-range trigger back to “Custom”. It continues to display the previously applied date range.

This is intentional. I defined it this way in case the user wants to switch back to the last custom date range. I think it can be a valid use case. We can change the behavior if we consider it confusing, though.

intentional: it is the way back to the last custom range
the probe reproduces the trigger's label, so it cannot be popover state
@retrofox

retrofox commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

The probe and the trigger already shared the label helper.

What they did not share was one of its inputs: the trigger kept rememberedCustomRange in local state inside DateRangePopover, while the probe re-derived it from props, where it returns to null as soon as the applied preset stops being custom.

So after applying a custom range and clicking a preset, the trigger rendered the formatted range and the probe resolved to "Custom". That is your 90px apporx.

DateFiltersPanel now owns the remembered range and passes it down. The probe can only see props, so local state in the popover was invisible to it by construction. One source, no drift. Two tests pin the range arriving as a prop.

Worth knowing when you retest: the probe now measures the wide label whenever a custom range is remembered, so the presets shorten earlier and stay shortened after switching back to a preset.

That is the measurement being accurate, not a regression.

chihsuan
chihsuan previously approved these changes Aug 3, 2026

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it can be a valid use case. We can change the behavior if we consider it confusing, though.

Thanks for clarifying! It may be worth checking with @ederrengifo, as the behavior appears to be different on the demo site. Agreed we can update it in a follow-up if needed.

Worth knowing when you retest: the probe now measures the wide label whenever a custom range is remembered, so the presets shorten earlier and stay shortened after switching back to a preset.

Thanks, tested well now. LGTM! 🚀

dognose24
dognose24 previously approved these changes Aug 3, 2026

@dognose24 dognose24 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.

Approving — I went through the probe design, the resolver, and the stories, and this is excellent work. Verified along the way:

  • The unconditional double-render probe is the right answer to the oscillation problem, and the rounding directions pair correctly (probe ceils demand, panel floors supply — conservative on both sides, so sub-pixel jitter can't flip the mode).
  • resolvePresetLabelMode's tests are a model: the every-tier-reachable set test and the monotonicity property (including the degenerate abbreviated > full widths) pin exactly the failure modes a boundary-only suite would miss.
  • No stray MOBILE_CONTAINER_WIDTH_THRESHOLD references remain; isCompact survives only as labelMode === 'select'.
  • The abbreviated pills carrying the full label as aria-label, and the whole group switching together, are both the right calls.
  • Spot-checked the call-site cleanup: all the removed containerElement wrappers were indeed passing the panel's own immediate wrapper back.

One finding from testing the storybook stories, worth addressing here since this PR is what makes it reachable:

The custom trigger's font size still hangs on a fixed viewport breakpoint. .date-filters-panel-button gets max(md, 16px) below a @media (min-width: 600px) query (pre-existing, date-range-popover/date-range-filter.scss). On trunk that mismatch was unreachable in the app: the container is always narrower than the viewport, so below 600px viewport the panel was already in select mode and 16px matched the select. With the middle tier, full/abbreviated pills now survive into that zone — e.g. viewport 599px with the panel at ~560px keeps full 13px pills next to a 16px trigger. (In storybook it flips when the canvas iframe crosses 600px — around a 900px outer viewport with the sidebar open.)

Suggestion, in the spirit of the rest of this PR — key it to the panel's measured state instead of the viewport, and the media query goes away:

.date-filters-panel-button {
	font-size: var(--wpds-typography-font-size-md);
}

.date-filters-panel.is-compact .date-filters-panel-button {
	font-size: max(var(--wpds-typography-font-size-md), 16px);
}

The trigger then matches the pills whenever it shares the row with them, and matches the 16px select exactly when the row collapses — which also retires the last width constant this PR's own rationale argues against. Fine as a fast-follow if you'd rather keep this PR frozen.

Screenshots

Viewport 600px — abbreviated pills and the Custom trigger aligned at 13px

截圖 2026-08-04 凌晨12 05 40

Viewport 599px — the media query fires: Custom jumps to 16px beside the 13px pills

截圖 2026-08-04 凌晨12 05 58

Viewport 462px — select mode; both dropdowns at 16px, where the sizes align again

截圖 2026-08-04 凌晨12 09 18

clean; trunk's changes land in the locations report, away from the date controls
a 600px viewport query left a 16px trigger beside 13px pills
@retrofox
retrofox dismissed stale reviews from dognose24 and chihsuan via 2c618e8 August 3, 2026 17:34
@retrofox

retrofox commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, folks. We'll continue polishing the implementation in follow-ups. Thanks for your review 🙇‍♂️

@retrofox
retrofox merged commit 46a621b into trunk Aug 4, 2026
76 of 78 checks passed
@retrofox
retrofox deleted the update/date-controls-responsive-labels branch August 4, 2026 07:23
@github-actions github-actions Bot added [Status] UI Changes Add this to PRs that change the UI so documentation can be updated. and removed [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. labels Aug 4, 2026
dognose24 added a commit that referenced this pull request Aug 4, 2026
…ment panel

Conflicts were the #50964 externals refactor against the video-detail
stage/summary-card imports (resolved to the externals convention) and the
date-filters panel, taken wholly from trunk — this branch's net change to
packages/ui is zero since 'Drop the header date-filter half', and trunk's
WOOA7S-1817 content-measurement rework is what that deferral was waiting for.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dognose24 added a commit that referenced this pull request Aug 7, 2026
…mparison from its widgets (#51082)

* Premium Analytics: post detail parity — overflow fixes, timezone, no comparison

Applies to the post/email detail page the fixes proven on the video
detail page: the breadcrumb/summary overflow bugs (contain: inline-size
plus the breadcrumbs-slot shrink shim), aspect-ratio: 1 so the boot
shell's img reset cannot squash the featured image, post-views bucket
keys parsed as site-local calendar dates (parseSiteDateTime, UTC-12
regression test), and block-size nits.

The page's design has no period-over-period comparison: the post-views
and email-time-series widgets drop their comparison series, the route
normalizes comparison params away, and DateFiltersPanel gains a minimal
showComparison prop so the Compare control hides at the existing
fixed-bar call site.

Moving the panel onto the summary's title row (per the mock) is
deferred until the preset measurement rework lands (WOOA7S-1816) — it
would collide head-on, the same reason the video-detail PR dropped its
filters row. Rebased onto trunk accordingly: nothing here depends on
the video-detail branch anymore.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Pass comparison params through the post-detail route

Mirror the video-detail review outcome (#50970): the page renders no
comparison and its widgets ignore the params, but the breadcrumb's
dashboard link reads the URL state back out, so stripping them lost the
user's comparison settings on a Dashboard → Post → Dashboard round trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Premium Analytics: align comparison pass-through comments with the route contract

* Strip comparison params from injected widget reportParams and drop the parseISO fallback

Per review: the page-wide no-comparison invariant now holds by
construction — usePostDetailTabs injects comparison-stripped
reportParams (via the new omitComparisonReportParams helper) into every
layout entry, so comparison-capable widgets like UTM insights and
highlights can no longer render deltas from URL state. The URL keeps
the comparison params for the breadcrumb round trip.

Also remove the parseISO fallback in use-post-views: bucket dates come
from format(start, 'yyyy-MM-dd') so parseSiteDateTime cannot fail, and
the fallback would silently reintroduce the browser-local day shift;
an unparseable bucket now drops the point instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Premium Analytics: restore the video detail date filters and strip comparison from its widgets

WOOA7S-1816: the date filter presets were dropped from the video detail
page in #50970 because they collided with the preset-measurement rework;
now that #50906 has landed, restore them using the same construction as
post detail (DateFiltersPanel with showComparison=false, fixed above the
scroll container).

Also port the comparison-strip construction from #50971: inject
omitComparisonReportParams()-stripped reportParams into every layout
entry so comparison-capable widgets (highlights) cannot render deltas
from URL state, while the URL keeps the params for the breadcrumb round
trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Record the crypto-js deprecation in pnpm-lock.yaml

The npm registry marked crypto-js@4.2.0 deprecated after this lock was
written, so the lock check's fresh resolution now expects the
deprecation note. Registry-metadata drift only; no dependency change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Clarify that the video detail comparison strip is defensive

All three current video-detail widgets already ignore comparison params
in their own query mapping; the injection exists so the page-wide
invariant holds by construction (matching post detail) rather than
relying on each widget. Adjust the code comment and changelog wording
accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Put the date filter presets on the summary title row per the mocks

One header row per the design mocks: title left, presets right,
vertically centered. The summary grows into free space and absorbs the
squeeze down to a 400px floor (title ellipsis); its inline-size
containment keeps a long title from wrapping the row.

Known rough edge, deferred to #51088: the panel self-measures its root,
which in this shrink-to-fit slot always sees its own content width — so
the presets keep their full layout and narrow rows degrade poorly. The
external-measurement wiring (containerElement / reservedInlineSize)
ships there to keep this PR free of shared-component changes beyond the
already-reviewed showComparison prop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Put the video detail date filter presets on the summary title row

Same composition as post detail: one header row, title left and presets
right, 400px summary floor with inline-size containment. The panel's
step-down on narrow rows needs external measurement and ships
separately (#51088).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Drop the route-level breadcrumb shim in favor of the component-owned fix

Superseded by #51085: the ':has(> nav)' rule targets StatsBreadcrumbs'
display:contents trail wrapper (no box for min-inline-size to act on)
and the nav rule is covered by the component stylesheet. Tracked
upstream as WordPress/gutenberg#81297.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Drop the video detail route-level breadcrumb shim in favor of #51085

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: retrigger checks — workflow runs were never created for the previous push

* ci: retrigger checks — workflow runs were never created for the previous push

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
dognose24 added a commit that referenced this pull request Aug 10, 2026
… with a reserved share (#51088)

* Premium Analytics: let DateFiltersPanel measure an external container with a reserved share

Two props for hosts that place the panel in a shrink-to-fit slot, such
as a detail page's header row shared with the summary title:

- containerElement: measure the given element instead of the panel's own
  root. #50906 removed external measurement because every caller then
  passed its immediate wrapper, making it a no-op; in a shrink-to-fit
  slot the root's width follows the panel's own content, so
  self-measurement can neither collapse the layout when narrow nor
  expand it back when widened.
- reservedInlineSize: inline space in the measured container never
  available to the panel (a title's minimum share). Subtracted before
  resolving the layout, so the panel steps down while its row-mates
  still have their minimum.

Consumers land in #50971 (post detail) and #51082 (video detail); those
branches carry identical copies of this change until it merges.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Wire the header-row measurement into both detail pages

With #50971 / #51082 merged, connect the stages to the new props: each
header row gets a ref, and the panel measures it with the summary's
reserved share (400px floor + 16px gap + 24px step-down buffer)
subtracted — restoring the narrow-row degradation (full → abbreviated →
compact) that shipped as a known rough edge in those PRs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Update the wrap comments for the dropped preset select mode

Since #51094 the panel's smallest layout is abbreviated pills — there is
no compact dropdown to collapse into.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Drop a stray blank line left by the trunk merge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Premium Analytics [Status] UI Changes Add this to PRs that change the UI so documentation can be updated.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants