Partner Coupon: migrate ActionButton to @wordpress/ui#49098
Conversation
Replaces the two ActionButton usages in redeem-partner-coupon-pre-connection and redeem-partner-coupon-post-connection with the new Button from @wordpress/ui, in line with the broader Jetpack UI Modernization effort (#48160). Both call sites only used label + onClick and relied on the default primary variant — the @wordpress/ui Button's default solid variant is the matching primary, so the migration is a straight import + JSX swap with no prop translation. Removes the ActionButton import in this package (2 → 0); the remaining @automattic/jetpack-components imports (getRedirectUrl, JetpackLogo) are unrelated and stay.
|
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. 🤷 |
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.
Part of #48160
Proposed changes
Migrates the two
ActionButtonconsumers in@automattic/jetpack-partner-coupon(redeem-partner-coupon-pre-connection,redeem-partner-coupon-post-connection) to the newButtonfrom@wordpress/ui, in line with the broader Jetpack UI Modernization effort. Follows the pattern established in #48150 (Publicize) and #48489 (My Jetpack interstitials).Brings the partner-coupon package to zero
ActionButtonimports — closing out the leaderboard for this package on that import. Two other@automattic/jetpack-componentsimports remain (getRedirectUrl,JetpackLogo) and are out of scope here; the package dep stays.Props mapping
Both call sites used
ActionButtonminimally — onlylabel(the visible text) andonClick, defaulting to the primary variant. The@wordpress/uiButton's defaultsolidvariant is the matching primary, so:ActionButtonprop@wordpress/uiButton equivalentlabel="…"onClick={…}onClick={…}variant(default"primary")No translation needed for
isLoading,isDisabled,displayError,errorMessage,isExternalLink,customClass,loadingText— none were used at either call site.Files changed
redeem-partner-coupon-pre-connection/index.jsx— "Redeem {product}" CTA inside<ConnectScreen>(rendered only whenconnectionStatus.hasConnectedOwneris true).redeem-partner-coupon-post-connection/index.jsx— "Redeem {product}" CTA in the post-connection redemption flow (sits next to the "Remind me later" plain button).package.json— drops the implicit ActionButton dep, adds@wordpress/uiat0.11.0(matching the version pinned by my-jetpack, publicize, etc.).pnpm-lock.yaml— workspace import block for partner-coupon now resolves@wordpress/ui.Related product discussion/links
Does this pull request change what data or activity we track or use?
No.
Testing instructions
The partner-coupon flow is a deep integration that surfaces when a user lands on a Jetpack admin page with a
partnerCouponquery parameter and a matching partner record. Spot-checks I'd suggest reviewers run:pnpm jetpack build js-packages/partner-coupon— builds clean.cd projects/js-packages/partner-coupon && pnpm run test— all 22 existing tests pass;getByRole( 'button', { name: ... } )still matches the new@wordpress/uiButton since it renders an accessible button with the same accessible name.hasConnectedOwner === truebranch of<ConnectScreen>)If a visual reviewer can capture before/after of the redemption banner, please drop them on this PR — happy to update the body with the URLs.