Componentry: migrate ContextualUpgradeTrigger to @wordpress/ui Notice#48909
Conversation
|
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! Jetpack plugin: The Jetpack plugin has different release cadences depending on the platform:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Social plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Protect plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
Code Coverage SummaryCoverage changed in 1 file.
|
The CUT → Notice migration in social-module-toggle pulled in @wordpress/ui's Tooltip composition, which transitively chains through @wordpress/theme's private-apis. social-admin-page.asset.php now declares wp-theme and wp-private-apis as deps — neither is in WP core, both are polyfilled by wp-build-polyfills. class-social-admin-page.php was enqueuing social-admin-page directly without first registering the polyfills, so the new handles 404'd and the browser threw 'SyntaxError: Unexpected token <' parsing the HTML error page as JS. React tree never mounted, Social e2e times out at the onboarding 'Get Started' button. Pattern matches what videopress / forms / scan / podcast / newsletter / backup already do.
…ess/ui Tooltip The wp-theme polyfill registration approach didn't take effect in publicize's older Assets::register_script pipeline. After diagnosis: no consumer in the codebase has shipped a working @wordpress/ui Tooltip in a non-wp-build plugin yet. Boost (the closest precedent) keeps IconTooltip from jetpack-components for the same reason. Revert the wp-build-polyfills wiring + lockfile regen. Use IconTooltip in social-module-toggle's upgrade Notice. Preserves click-toggle UX from the original CUT tooltipText. IconTooltip migration becomes a separate slice later (item #7 in the shadow analysis priority).
de4324e to
b3ceac3
Compare
…s a11y speak The Notice composition triggers @wordpress/a11y speak() which renders the description text into a visually-hidden .a11y-speak-region in document.body. The existing getByText/queryByText assertions matched both the visible Notice and the speak region, causing 'multiple elements found' on the positive case and 'expected not in document, found' on the negative case (because the speak region persists across jsdom renders). Fix: pass the testing-library ignore option to text queries so they target the visible Notice DOM only. Test-only change; no production code touched.
…#48909) * Componentry: migrate ContextualUpgradeTrigger to @wordpress/ui Notice * Publicize: register wp-build-polyfills before social-admin-page enqueue The CUT → Notice migration in social-module-toggle pulled in @wordpress/ui's Tooltip composition, which transitively chains through @wordpress/theme's private-apis. social-admin-page.asset.php now declares wp-theme and wp-private-apis as deps — neither is in WP core, both are polyfilled by wp-build-polyfills. class-social-admin-page.php was enqueuing social-admin-page directly without first registering the polyfills, so the new handles 404'd and the browser threw 'SyntaxError: Unexpected token <' parsing the HTML error page as JS. React tree never mounted, Social e2e times out at the onboarding 'Get Started' button. Pattern matches what videopress / forms / scan / podcast / newsletter / backup already do. * Lockfile: regenerate consumer composer.lock after publicize wp-build-polyfills dep * Publicize: use IconTooltip from jetpack-components instead of @wordpress/ui Tooltip The wp-theme polyfill registration approach didn't take effect in publicize's older Assets::register_script pipeline. After diagnosis: no consumer in the codebase has shipped a working @wordpress/ui Tooltip in a non-wp-build plugin yet. Boost (the closest precedent) keeps IconTooltip from jetpack-components for the same reason. Revert the wp-build-polyfills wiring + lockfile regen. Use IconTooltip in social-module-toggle's upgrade Notice. Preserves click-toggle UX from the original CUT tooltipText. IconTooltip migration becomes a separate slice later (item #7 in the shadow analysis priority). * Publicize: update social-module-toggle test for @wordpress/ui Notice's a11y speak The Notice composition triggers @wordpress/a11y speak() which renders the description text into a visually-hidden .a11y-speak-region in document.body. The existing getByText/queryByText assertions matched both the visible Notice and the speak region, causing 'multiple elements found' on the positive case and 'expected not in document, found' on the negative case (because the speak region persists across jsdom renders). Fix: pass the testing-library ignore option to text queries so they target the visible Notice DOM only. Test-only change; no production code touched.
…#48909) * Componentry: migrate ContextualUpgradeTrigger to @wordpress/ui Notice * Publicize: register wp-build-polyfills before social-admin-page enqueue The CUT → Notice migration in social-module-toggle pulled in @wordpress/ui's Tooltip composition, which transitively chains through @wordpress/theme's private-apis. social-admin-page.asset.php now declares wp-theme and wp-private-apis as deps — neither is in WP core, both are polyfilled by wp-build-polyfills. class-social-admin-page.php was enqueuing social-admin-page directly without first registering the polyfills, so the new handles 404'd and the browser threw 'SyntaxError: Unexpected token <' parsing the HTML error page as JS. React tree never mounted, Social e2e times out at the onboarding 'Get Started' button. Pattern matches what videopress / forms / scan / podcast / newsletter / backup already do. * Lockfile: regenerate consumer composer.lock after publicize wp-build-polyfills dep * Publicize: use IconTooltip from jetpack-components instead of @wordpress/ui Tooltip The wp-theme polyfill registration approach didn't take effect in publicize's older Assets::register_script pipeline. After diagnosis: no consumer in the codebase has shipped a working @wordpress/ui Tooltip in a non-wp-build plugin yet. Boost (the closest precedent) keeps IconTooltip from jetpack-components for the same reason. Revert the wp-build-polyfills wiring + lockfile regen. Use IconTooltip in social-module-toggle's upgrade Notice. Preserves click-toggle UX from the original CUT tooltipText. IconTooltip migration becomes a separate slice later (item #7 in the shadow analysis priority). * Publicize: update social-module-toggle test for @wordpress/ui Notice's a11y speak The Notice composition triggers @wordpress/a11y speak() which renders the description text into a visually-hidden .a11y-speak-region in document.body. The existing getByText/queryByText assertions matched both the visible Notice and the speak region, causing 'multiple elements found' on the positive case and 'expected not in document, found' on the negative case (because the speak region persists across jsdom renders). Fix: pass the testing-library ignore option to text queries so they target the visible Notice DOM only. Test-only change; no production code touched.
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).
Part of #48160.
Proposed changes
Migrate all 7 in-repo consumers of
ContextualUpgradeTriggeroff@automattic/jetpack-componentsand onto@wordpress/ui'sNoticecomposition. Mark theContextualUpgradeTriggersource as@deprecated(JSDoc only — no API change) following the chip → Badge (#48162) and Status (#48711) precedents. No deletions on the source; npm consumers continue to compile.This is the second slice in the wrapper-first migration plan after Status (#48711). The shadowing analysis identified CUT as the highest impact-per-line wrapper: 44 LOC source, but its migration collapses 6 shadowed
Text+ 2 shadowedButton+ 1 shadowedTitlesites that would otherwise need separate re-touches.Design refresh, not visual parity. The
Noticechrome (rounded, soft-tinted, intent icon at top-left) is intentionally different from the legacy CUT card. This aligns with the broader UI modernization established by #48550 (Search dashboardSimpleNotice→Notice).Per-consumer mapping
plugins/protect(3 sites — co-located helper):src/js/components/threats-list/free-list.jsxsrc/js/routes/scan/scan-footer.jsxsrc/js/routes/firewall/index.jsx<UpgradeNotice>helper atsrc/js/components/upgrade-notice/index.tsx. The helper is a thin shell overNotice.Root+Notice.Description+Notice.Actionsand supports both onClick and href callsites. Following theAdminSectionHero.StatusIndicatorpattern from the Status slice.js-packages/scan(1 site — inline):src/components/threat-modal/threat-fix-details.tsx— inlineNotice.Rootwith anActionButton.packages/videopress(1 site — inline):src/client/admin/components/admin-page/index.tsx— inlineNotice.Rootwith anActionButton. The conditional emptydescriptionshort-circuits cleanly inside the Notice composition.packages/search(1 site — inline):src/dashboard/components/pages/sections/plan-usage-section.jsx— inlineNotice.Rootwith anActionButton. Drops theThemeProviderwrapper (Notice has its own styles).packages/publicize(1 site — inline Notice + IconTooltip):_inc/components/admin-page/toggles/social-module-toggle/index.tsx— only consumer that usedtooltipText. InlineNotice.Rootwith anActionLink, plus anIconTooltipfrom@automattic/jetpack-componentsfor the click-toggle "more details" affordance next to the description. KeepingIconTooltipfrom jetpack-components matches the Boost precedent (plugins/boost/.../page-cache/meta/meta.tsx):@wordpress/uiTooltipchains through@wordpress/themeprivate-apis, which adds awp-themescript handle that the olderAssets::register_scriptpipeline doesn't have polyfill plumbing for.IconTooltipmigration becomes a separate slice later (item Publicize: Add filter to allow plugins to bypass Publicize #7 in the shadow analysis priority).js-packages/components(source —@deprecatedJSDoc only):components/contextual-upgrade-trigger/index.tsx— adds the deprecation block above the export, pointing atNotice. Implementation, styles, stories, and barrel export are unchanged.Test fixtures
packages/search/src/dashboard/components/pages/sections/test/plan-usage-section.test.jsx— replaces the@automattic/jetpack-componentsContextualUpgradeTriggermock with a@wordpress/uiNoticemock that emits the sameupgrade-trigger/upgrade-description/upgrade-ctatestids. All existing assertions pass unchanged.packages/search/tests/js/dashboard/pages/dashboard-page.test.jsx— drops the now-deadContextualUpgradeTriggerentry from the@automattic/jetpack-componentsvirtual mock.Acceptance
grep -rn "from '@automattic/jetpack-components'" projects/ | grep '\bContextualUpgradeTrigger\b'returns zero matches in source files. ✅pnpm jetpack build plugins/protect,pnpm jetpack build packages/videopress --deps,pnpm jetpack build packages/search,pnpm jetpack build packages/publicize,pnpm jetpack build js-packages/scan,pnpm jetpack build js-packages/components. ✅pnpm jetpack test js packages/search,pnpm jetpack test js packages/publicize,pnpm jetpack test js js-packages/scan. ✅jetpack-videopress-pkg/jetpack-search-pkg/jetpack-publicize-pkgare unchanged from trunk). ✅Related product discussion/links
@deprecatedJSDoc precedent.SimpleNotice→@wordpress/uiNotice.js-packages/components/components/chip/index.tsx.Does this pull request change what data or activity we track or use?
No.
Testing instructions
Jetpack → Protect(free plan). The upgrade prompt at the bottom of the page should render as a@wordpress/uiNotice (info intent, rounded, soft-tinted background, info icon, "Upgrade Jetpack Protect now" action button). Click the action — the existing upgrade flow should fire (upgradePlan()viausePlan).Jetpack → Protect → Firewall(free plan). Below the "Automatic firewall protection" toggle, the upgrade prompt should render as a@wordpress/uiNotice. Action button triggers the same upgrade flow.fixedInvalue. The "How to fix it?" panel should show the new Notice with the action button.Jetpack → VideoPresson a site without a VideoPress purchase. The upgrade prompt should render as a Notice with the "Upgrade now to unlock unlimited videos…" action button.Jetpack → Searchon a free Search plan with simulated usage data (overage or near-overage). The plan-usage section should render the upgrade Notice in the appropriate scenario (records, requests, both, or no-overage).Jetpack → Social(or the Jetpack Settings → Sharing tab on a non-WPCOM site without paid Social features). Below the "Automatically share your posts" toggle, the "Unlock advanced sharing options" Notice should render. Click the info icon next to the description — the tooltip with the longer copy should toggle open (click-toggle UX, matching the legacy CUT). Click "Power up Jetpack Social" — it should navigate to the upsell URL.Screenshots
NOTE: the missing screenshots refer to exact same implementation replacements