Skip to content

Premium Analytics: add a per-section header with title and date controls - #50894

Merged
retrofox merged 11 commits into
trunkfrom
add/pa-section-header
Jul 30, 2026
Merged

retrofox merged 11 commits into
trunkfrom
add/pa-section-header

Conversation

@retrofox

@retrofox retrofox commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes

The SectionHeader component

A new SectionHeader in the internal ui package. The left half anchors the section: the title (heading-2xl, rendered as an h2 under the breadcrumb h1) plus an optional subtitle.

The right half is a slot. The consumer mounts the date controls there, so the component stays purely presentational and owns no date state.

Storybook stories cover the two instances from the design: rolling presets with comparison, and the year surface.

Before
image

After
image

Dashboard wiring

Each section panel now renders the header, with the title coming from the section registry's label. DateFiltersPanel moves from above the panels into the header's controls slot.

Only the active panel mounts, so there is still a single live instance of the filters.

The subtitle is intentionally absent for now. WOOA7S-1824 adds the formatter that derives it from the applied date configuration.

Scroll moves to the page content

The section panel no longer owns a scroll container. The page content scrolls instead, so the section tabs scroll away with it.

This is the groundwork for pinning the header below the page header, tracked in WOOA7S-1825.

A responsive fix on the way

The filters' responsive measurement now targets the full header row instead of a content-sized wrapper.

Before this change, the compact layout could latch on the first shrink and never disengage when space returned.

Related product discussion/links

Linear umbrella: WOOA7S-1793, consistent title and date selection component.

Follow-ups filed: WOOA7S-1824 (dynamic subtitle) and WOOA7S-1825 (sticky header).

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

No.

Testing instructions

Setup

Build the package with jetpack build packages/premium-analytics --deps, then open the dashboard at wp-admin/admin.php?page=jetpack-premium-analytics.

The header

Each section (Traffic, Insights, Subscribers) renders its title above the widgets, with the date filters aligned to the end of the same row.

The page header keeps the "Analytics" breadcrumb, and the previous page-level subtitle is gone. The section subtitle is absent until WOOA7S-1824 lands.

Scrolling

Scroll the page. The section tabs scroll away with the content, since the page content is the scroll container now.

Screen.Recording.2026-07-29.at.9.30.43.AM.mov

Responsive

Shrink the viewport below ~600px so the presets collapse into the compact select, then widen it again.

The preset pills must return. Before this PR, the compact layout could stay latched.

Storybook

Run cd projects/js-packages/storybook && pnpm run storybook:dev and check Packages/Premium Analytics/UI/SectionHeader.

image

@retrofox
retrofox requested a review from a team July 29, 2026 08:16
@retrofox
retrofox requested a review from a team as a code owner July 29, 2026 08:16
@retrofox retrofox added Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Status] Needs Review This PR is ready for review. labels Jul 29, 2026
@retrofox retrofox self-assigned this 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 add/pa-section-header branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack add/pa-section-header
bin/jetpack-downloader test jetpack-mu-wpcom-plugin add/pa-section-header

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

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!

@jp-launch-control

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

Copy link
Copy Markdown

Code Coverage Summary

2 files are newly checked for coverage.

File Coverage
projects/packages/premium-analytics/packages/ui/src/section-header/section-header.tsx 1/1 (100.00%) 💚
projects/packages/premium-analytics/packages/ui/src/section-header/index.ts 0/0 (—%) 🤷

Full summary · PHP report · JS report

@retrofox
retrofox force-pushed the add/pa-section-header branch from b781db2 to 8c3c0cb Compare July 29, 2026 11:29

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

Really like the shape of this! 👍

I just noticed a few things while poking at this, and most of them seems because the responsive measurement now that it lives inside the tab panels. I've added a few inline comments.

value={ section.slug }
className={ styles.content }
>
<div ref={ setContainerElement } className={ styles.sectionHeader }>

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 wonder if we should make each panel have its own container state?

Right now, all panels share setContainerElement. When switching tabs, the old panel can clear the ref after the new panel sets it, leaving containerElement as null. The filters then measure document.body instead of the actual row. Since the body is much wider, the filters may incorrectly stay in the wide layout.

Screen.Recording.2026-07-30.at.10.49.24.AM.mov

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.

I wonder if we should make each panel have its own container state?

This is a good question. The composition between SectionHeader and the tabs doesn't look very good. I'll take a look.

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.

Confirmed, and it happens on every tab switch. Base UI defers the outgoing panel's unmount by a frame, so the incoming panel sets the ref and the old one nulls it right after. The filters then measure document.body, around 208px wider than the real row, which keeps the presets wide between roughly 600 and 810px.

#50906 removes containerElement altogether and has the panel measure its own root, so the shared ref stops existing. The two PRs already conflict in stage.tsx and that is the resolution. What it does not cover is that SectionHeader's controls slot is a shrink-to-fit flex item, so a self-measuring panel would read its own content instead of the row. Tracked in WOOA7S-1837.

*/
export function SectionHeader( { title, subtitle, children }: SectionHeaderProps ) {
return (
<Stack direction="row" align="flex-start" justify="space-between">

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.

Worth adding a gap here? Stack doesn't set one, so a long translated title can end up right up against the date controls.

Image

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.

Yes, 👍 . This will be addressed in a follow-up.

>
<div ref={ setContainerElement } className={ styles.sectionHeader }>
<SectionHeader title={ section.label }>
<DateFiltersPanel { ...dateFilters } containerElement={ containerElement } />

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.

The container used to mean "how much room do the filters have, but now the title also uses part of this container, so the filters may see 700px even though they only have 500px and incorrectly stay in the wide layout. Should the measured slot have a stable allocated width?

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.

Same as before. Those controls will change soon, so I'd like to address that in a follow-up. For instance, this PR #50906

@@ -12,7 +12,7 @@
.content {

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 noticed that in mobile view, or on a tall screen, the sticky header may scroll away once we pass the first screen of widgets.

Screen.Recording.2026-07-30.at.10.46.01.AM.mov

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.

yes, same comment as the previous ones. Let's address it in a follow-up. I don't want to introduce too many changes in this PR

chihsuan
chihsuan previously approved these changes Jul 30, 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.

Let's iterate on another PR. 🚢

Copy link
Copy Markdown
Contributor Author

Thanks. We have a few issues that address these tasks.

@retrofox
retrofox requested a review from a team July 30, 2026 08:16
@retrofox
retrofox merged commit 23c627c into trunk Jul 30, 2026
80 checks passed
@retrofox
retrofox deleted the add/pa-section-header branch July 30, 2026 11:53
@github-actions github-actions Bot removed the [Status] Needs Review This PR is ready for review. label Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Changes to an existing feature — removing, adding, or changing parts of it [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