My Jetpack: migrate interstitial Buttons to @wordpress/ui#48489
Conversation
Follow-up to #48414. Replaces the `Button` imports in the product interstitial / pricing-interstitial / more-requests screens with the new `Button` from `@wordpress/ui`. Affects: - `pricing-interstitial.jsx`: free/paid/bundle tier CTAs (`isLoading` → `loading`, `variant="secondary"` → `variant="outline"`, `fullWidth` → small `tier-cta` width:100% class) and the actions-slot "Use license key" CTA. - `product-interstitial.jsx`: the actions-slot "Use license key" CTA. - `jetpack-ai/more-requests.jsx`: the "Contact Us" + "Back" buttons. `href` cases use base-ui's `render={<a/>}` (with `nativeButton={false}`). `@wordpress/ui` Button styles live in `@layer wp-ui-components`, which loses to wp-admin's un-layered `a { color }` rule when rendered as an anchor; a single non-layered rule in `_inc/style.module.scss` re-asserts the button foreground color so anchor-rendered Buttons get the right text color. Also fixes invalid `<a><button/></a>` nesting on the "Back" button by moving react-router's `<Link>` into the Button's `render` prop.
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
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:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
Code Coverage SummaryThis PR did not change code coverage! That could be good or bad, depending on the situation. Everything covered before, and still is? Great! Nothing was covered before? Not so great. 🤷 Full summary · PHP report · JS report Coverage check overridden by
Coverage tests to be added later
|
The non-layered `a[class*="__button"][class*="__is-"] { color: ... }`
override existed to neutralize wp-admin's un-layered `a { color }` rule
beating wp-ui's layered button color when a Button is rendered as an
anchor (`render={<a/>}`). Auditing the actually-reachable interstitials:
- Tier CTAs in pricing-interstitial render as native `<button>` (no
`render` prop wired up on this path), so the cascade-layer issue
doesn't apply.
- The "Use license key" action button is anchor-rendered but uses the
outline variant — wp-admin theme blue vs. wp-ui brand blue is
visually indistinguishable on the white background.
- The only solid-variant anchor Button in the migration lives in
`more-requests.jsx` (`JetpackAIInterstitialMoreRequests`), which has
zero consumers across the repo: no router entry in admin.jsx, no
parent component imports it, and the AI store's `isOverLimit` state
drives in-place notices on the product page rather than mounting the
interstitial. It's unreachable code; the override was protecting a
view that never renders.
Removing the workaround keeps the file in line with other consumer
packages and lets the next layer-aware Button consumer rely on the
upstream cascade rather than a per-package band-aid.
Drop the last 5 migration-relevant @automattic/jetpack-components imports in js-packages/connection. ActionButton's isLoading/displayError/errorMessage behavior is preserved by mapping isLoading -> @wordpress/ui Button's loading prop and rendering the error message as a sibling paragraph with the same jp-action-button__error class. The default error string matches ActionButton's default, so existing tests pass unchanged. Keepers (DecorativeCard, getRedirectUrl, JetpackLogo, PricingCard, TermsOfService) remain on @automattic/jetpack-components; the package dependency stays. Follows #48150 (Publicize), #48489 (My Jetpack interstitials), #49098 (Partner Coupon), and #48909 (CUT migration).
…49099) * Connection: migrate ActionButton, Button, and Text to @wordpress/ui Drop the last 5 migration-relevant @automattic/jetpack-components imports in js-packages/connection. ActionButton's isLoading/displayError/errorMessage behavior is preserved by mapping isLoading -> @wordpress/ui Button's loading prop and rendering the error message as a sibling paragraph with the same jp-action-button__error class. The default error string matches ActionButton's default, so existing tests pass unchanged. Keepers (DecorativeCard, getRedirectUrl, JetpackLogo, PricingCard, TermsOfService) remain on @automattic/jetpack-components; the package dependency stays. Follows #48150 (Publicize), #48489 (My Jetpack interstitials), #49098 (Partner Coupon), and #48909 (CUT migration). * Connection: revert ConnectScreen Basic + RequiredPlan ActionButton migrations These three call sites depend on SCSS rules in `connect-screen/required-plan/style.scss` (lines 46 + 80) and `connect-screen/basic/style.scss` (line 20) that key on the `.jp-action-button--button.components-button` class combination — added by jetpack-components ActionButton and `@wordpress/components` Button. The @wordpress/ui Button doesn't add those classes, so the rules silently stop matching: * RequiredPlan "Get Jetpack Backup" inside PricingCard — lost `width: 100%`, `background: var(--jp-black)`, `color: var(--jp-white)`, padding, border-radius, font-size + font-weight overrides. Rendered as a content-width default-blue `@wordpress/ui` Button instead of the expected full-width black CTA. * RequiredPlan inline "Log in to get started" — lost `display: inline`, `background: inherit`, `text-decoration: underline` text-link treatment. Rendered as a primary-filled rectangular Button inside the otherwise-text paragraph. * Basic "Set up Jetpack" — lost the `.jp-action-button` wrapper + `--button` modifier rules (border-radius, font-weight, responsive max-width). Reverting these three call sites to `ActionButton` preserves the SCSS contract. The connect-button + manage-connection-dialog migrations in this PR stay on `@wordpress/ui` (no SCSS coupling there). A follow-up slice can refactor the SCSS to decouple from the now-internal jetpack class hooks, then re-migrate. * Connection: re-migrate ConnectScreen Basic + RequiredPlan to @wordpress/ui with default styling This supersedes the previous revert (d10b426) and ships the proper @wordpress/ui migration for the three call sites that had been reverted because their SCSS rules were tightly coupled to the old class hooks (`.jp-action-button--button.components-button` and friends). Visual contract follows the user's clarified migration philosophy: default @wordpress/ui Button styling for colors / padding / font-size / border-radius / spinner, with consumer-side SCSS ONLY for structural exceptions (full-width inside the PricingCard, top margin on the basic-screen CTA, responsive max-width). The previous Jetpack-brand overrides (`background: var(--jp-black) !important`, `color: var(--jp-white) !important`) are dropped — WPDS handles those. * **"Get Jetpack Backup" inside PricingCard** (required-plan/visual.jsx): - `@wordpress/ui` Button (default solid + brand), `loading` prop for in-flight feedback (WPDS-styled spinner shows correctly because the button keeps its default chrome). - New stable className `jp-connection__connect-screen__action-button` targeting only `width: 100%` and the vertical rhythm margin. * **"Log in to get started" inline button** (required-plan/visual.jsx): - `@wordpress/ui` Button `variant="unstyled"` styled as an inline text link via SCSS (`.jp-connection__connect-screen__inline-action`). `<button>` element preserves keyboard semantics + a11y; `aria-busy` announces in-flight to screen readers. - `variant="unstyled"` strips Button's own loading visual, so we inject a `@wordpress/components` Spinner via children — matches ActionButton's original "replace label with spinner" behavior. - SCSS aligns the spinner to the prefix-text baseline using `inline-flex` + `align-items: center` + `align-self: baseline`, and zeros out the Spinner's default `5px 11px 0` margin (which existed for the chrome we no longer have). * **"Set up Jetpack" basic CTA** (basic/visual.tsx): - `@wordpress/ui` Button (default solid + brand) + same className hook as RequiredPlan. SCSS keeps only the structural `margin-top: 40px` and the responsive `max-width` breakpoint that goes full-width on mobile. SCSS dead-code removed: * The old `.jp-action-button--button.components-button` selectors at required-plan/style.scss:46 and basic/style.scss:20. * The `.jp-action-button--button.components-button.is-primary` inline-text-link override at required-plan/style.scss:80. * The `.jp-components-spinner__inner / __outer` color overrides at required-plan/style.scss:103. Visually verified in storybook (both Default and Connecting states for the required-plan screen). * Connection: stabilize inline-action width to prevent text-row reflow on loading Adds `min-width: calc(var(--spacing-base) * 8)` and `justify-content: center` to `.jp-connection__connect-screen__inline-action` so the button reserves a fixed minimum width and centers its content. Without this, swapping the children between the (longer) label and the (narrower) spinner during loading caused the surrounding sentence row to reflow visibly. Tracking the user-applied tweak in this commit.
…ui (#49111) Migrates two remaining @automattic/jetpack-components Button consumers in projects/packages/my-jetpack/_inc/components/product-interstitial-modal/: - product-interstitial-modal-cta.tsx: Upgrade CTA Button migrated to @wordpress/ui Button with variant="solid". When an href is provided, renders an anchor via the render={<a />} + nativeButton={false} pattern established in PR #48489. isLoading -> loading. The styles['action-button'] className was a no-op (no .action-button rule in the SCSS module) and has been dropped. - product-interstitial-my-jetpack.tsx: inline AI fair-usage-policy 'Learn more about it here' Button (variant="link") migrated to @wordpress/ui Link with openInNewTab, following the L1b sweep recipe in PR #49109. Refs #48160.
Fixes #
Proposed changes
Follow-up to #48414. Migrates the Button imports in the My Jetpack interstitials away from
@automattic/jetpack-componentsand@wordpress/componentsto the newButtonfrom@wordpress/ui, in line with the broader Jetpack UI Modernization effort.NOTE: disregard the Dolly quotes overlapping with action buttons, that is being worked on #48472
Files touched
pricing-interstitial.jsx— free / paid / bundle tier CTAs and the actions-slot "Use license key" button.product-interstitial.jsx— actions-slot "Use license key" button.jetpack-ai/more-requests.jsx— "Contact Us" + "Back" buttons.Prop migration
@automattic/jetpack-components/@wordpress/components)@wordpress/ui)variant="primary"(default)variant="solid"(default)variant="secondary"variant="outline"isLoading={ … }loading={ … }fullWidthtier-ctawidth:100% classhref={ url }render={ <a href={ url } /> }+nativeButton={ false }<Link to="..."><Button/></Link>(invalid HTML)<Button render={ <Link to="..." /> } />CSS layer workaround
@wordpress/uiButton styles live inside@layer wp-ui-components. wp-admin ships an un-layereda { color: var(--wp-admin-theme-color) }rule which wins over the layered button rule (un-layered styles always beat layered ones), so any Button rendered as an anchor (viarender={<a/>}orrender={<Link/>}) ends up with admin link blue text instead of the button's intended foreground colour — solid-variant buttons in particular render with invisible text (blue on blue).This PR adds a single non-layered rule in
_inc/style.module.scssthat re-asserts--wp-ui-button-foreground-coloron anchor-rendered@wordpress/uiButtons, scoped tobody.jetpack_page_my-jetpack.Drive-bys
more-requests.jsxpreviously rendered as<a><button/></a>(invalid HTML). Moving react-router's<Link>into the Button'srenderprop produces a single, valid<a>element.Related product discussion/links
Does this pull request change what data or activity we track or use?
No. All
onClickanalytics handlers (jetpack_myjetpack_interstitial_license_link_click,jetpack_myjetpack_product_interstitial_back_link_click,jetpack_ai_upgrade_contact_us) are preserved.Testing instructions
/wp-admin/admin.php?page=my-jetpack#/add-*route on a Jetpack-connected site (e.g./add-akismet,/add-security,/add-jetpack-ai).#/add-license./add-akismet,/add-jetpack-ai), confirm the Free / Paid / Bundle tier CTAs render full-width with the right primary/outline treatment.Changelog
packages/my-jetpack— patch / changed entry covers the Button migration.