Skip to content

Premium Analytics: let DateFiltersPanel measure an external container with a reserved share - #51088

Merged
dognose24 merged 6 commits into
trunkfrom
add/premium-analytics-date-filters-external-measure
Aug 10, 2026
Merged

dognose24 merged 6 commits into
trunkfrom
add/premium-analytics-date-filters-external-measure

Conversation

@dognose24

@dognose24 dognose24 commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes

Completes the detail-page date filter work from #50971 / #51082: the panel's responsive layout now measures the header row instead of itself, restoring the narrow-row degradation those PRs shipped without (a known, documented rough edge there).

  1. DateFiltersPanel.containerElement — measure the given element for the responsive layout instead of the panel's own root. Premium Analytics: measure the date presets instead of guessing a breakpoint #50906 removed external measurement because every caller at the time passed its immediate wrapper, so the number was always the panel's own width and the prop bought nothing. The detail pages introduce the case the removal assumed away: the panel sits in a shrink-to-fit slot (the header row it shares with the summary title), where the root's width follows the panel's own content — self-measurement becomes self-fulfilling in both directions (it can neither collapse the layout when the row narrows nor expand it back when the row widens).
  2. DateFiltersPanel.reservedInlineSize — inline space in the measured container never available to the panel. Subtracted before resolving the layout, so the panel steps down while its row-mates still hold their minimum instead of squeezing the title out first.
  3. Stage wiring for both detail pages — each header row gets a ref passed as containerElement, with reservedInlineSize = 440 (the summary's 400px floor + 16px row gap + a 24px buffer so the layout steps down before the wrap threshold — layout wraps synchronously while the measured flip lags a frame, so equal thresholds would flash a wrapped row at every boundary).

Both props default to the previous behavior, so other callers are untouched.

Related product discussion/links

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

No.

Testing instructions

  1. Build packages/premium-analytics + plugins/premium-analytics and open a post or video detail page.
  2. Narrow the window: the title ellipsizes down to its 400px block floor first, then the presets abbreviate (7D/30D…) — the panel's smallest layout since Premium Analytics: make date comparison an additive control #51094 dropped the select fallback — all on one row; widening restores each step. Before this PR the presets sit stuck in the abbreviated form no matter how wide the window is — self-measurement can never see more room than the row already uses. (Before Premium Analytics: make date comparison an additive control #51094's rework the same root cause showed its other face: stuck full-size and overflowing.)
  3. At phone widths the abbreviated pills wrap to their own line below the summary.
  4. The dashboard's date filters (self-measuring callers) behave unchanged.
  5. pnpm run test in projects/packages/premium-analytics.

Screencasts

Before

2026-08-08.1.22.23.mov

After

2026-08-08.1.09.10.mov

🤖 Generated with Claude Code

… 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>
@dognose24
dognose24 requested a review from a team August 6, 2026 09:09
@dognose24
dognose24 requested a review from a team as a code owner August 6, 2026 09:09
@dognose24 dognose24 added the [Status] Needs Review This PR is ready for review. label Aug 6, 2026
@dognose24 dognose24 self-assigned this Aug 6, 2026
@dognose24
dognose24 requested a review from chihsuan August 6, 2026 09:10
@github-actions

github-actions Bot commented Aug 6, 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 add/premium-analytics-date-filters-external-measure branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack add/premium-analytics-date-filters-external-measure
bin/jetpack-downloader test jetpack-mu-wpcom-plugin add/premium-analytics-date-filters-external-measure

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

@github-actions

github-actions Bot commented Aug 6, 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 🤖


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!

@dognose24 dognose24 closed this Aug 6, 2026
@github-actions github-actions Bot removed the [Status] Needs Review This PR is ready for review. label Aug 6, 2026
@jp-launch-control

jp-launch-control Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

Code Coverage Summary

No summary data is available for parent commit 4fa25b3, so cannot calculate coverage changes. 😴

If that commit is a feature branch rather than a trunk commit, this is expected. Otherwise, this should be updated once coverage for 4fa25b3 is available.

Full summary · PHP report · JS report

dognose24 added a commit that referenced this pull request Aug 6, 2026
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>
dognose24 added a commit that referenced this pull request Aug 6, 2026
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>
@dognose24 dognose24 reopened this Aug 6, 2026
@dognose24 dognose24 added the [Status] Needs Review This PR is ready for review. label Aug 6, 2026
dognose24 added a commit that referenced this pull request Aug 7, 2026
…resets, no comparison (#50971)

* 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>

* 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>

* 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>

* 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>

* 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 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 and others added 3 commits August 7, 2026 21:39
# Conflicts:
#	projects/packages/premium-analytics/packages/ui/src/date-filters-panel/date-filters-panel.tsx
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>
…s-date-filters-external-measure

# Conflicts:
#	projects/packages/premium-analytics/packages/ui/src/date-filters-panel/date-filters-panel.tsx
@dognose24
dognose24 requested a review from a team as a code owner August 7, 2026 17:03
dognose24 and others added 2 commits August 8, 2026 01:11
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>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
{ ...dateFilters }
showComparison={ false }
containerElement={ headerElement }
reservedInlineSize={ HEADER_RESERVED_INLINE_SIZE }

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.

I think we should try to avoid using constants in this process. The component should automatically adapt to its space without hardcoding values.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed — the ideal end state is the panel adapting without any hand-fed number. The 440 exists because the row-mate's floor lives in CSS where the panel can't see it, so for now the comment keeps the three values in sync. Converging these headers on SectionHeader (grid) as you suggest would let us drop the constant entirely — happy to pick that up as the follow-up. Thanks for the review!

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

LGTM.

containerElement / reservedInlineSize work well for this flex-hosted slot.

The hand-synced 440 constant is fine as a transitional cost, given the "keep the three in sync" comment already guards it.

Flagging that IMO the plan of record is converging these headers on SectionHeader (grid-hosted, intrinsic measuring), so let's treat these as a bridge API: no new callers, and they retire with the migration.

@dognose24
dognose24 merged commit 03b07bf into trunk Aug 10, 2026
114 of 117 checks passed
@dognose24
dognose24 deleted the add/premium-analytics-date-filters-external-measure branch August 10, 2026 05:51
@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 Review This PR is ready for review. labels Aug 10, 2026
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.

2 participants