diff --git a/projects/js-packages/components/changelog/change-migrate-cut-wp-ui b/projects/js-packages/components/changelog/change-migrate-cut-wp-ui new file mode 100644 index 000000000000..ec760138cee1 --- /dev/null +++ b/projects/js-packages/components/changelog/change-migrate-cut-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Mark ContextualUpgradeTrigger as @deprecated. Use Notice from @wordpress/ui instead. The implementation is unchanged. diff --git a/projects/js-packages/components/components/contextual-upgrade-trigger/index.tsx b/projects/js-packages/components/components/contextual-upgrade-trigger/index.tsx index 2c43bd797ed2..ecd0f75f1ba9 100644 --- a/projects/js-packages/components/components/contextual-upgrade-trigger/index.tsx +++ b/projects/js-packages/components/components/contextual-upgrade-trigger/index.tsx @@ -6,6 +6,21 @@ import styles from './style.module.scss'; import { CutBaseProps } from './types.ts'; import type { FC } from 'react'; +/** + * ContextualUpgradeTrigger component. + * + * @deprecated Use `Notice` from `@wordpress/ui` instead. Compose with `Notice.Root` (`intent="info"`), `Notice.Description` for the body, and `Notice.Actions` + `Notice.ActionLink` / `Notice.ActionButton` for the CTA. See https://github.com/Automattic/jetpack/issues/48160 for migration guidance. + * + * @param props - The component properties. + * @param props.description - The body copy describing the upgrade context. + * @param props.cta - The CTA label. + * @param props.onClick - Click handler when rendered as a button. + * @param props.href - When provided, renders as an anchor instead of a button. + * @param props.openInNewTab - Whether to open the link in a new tab. + * @param props.className - Optional class for the root element. + * @param props.tooltipText - Optional tooltip body shown next to the description. + * @return The rendered upgrade trigger. + */ const ContextualUpgradeTrigger: FC< CutBaseProps > = ( { description, cta, diff --git a/projects/js-packages/scan/changelog/change-migrate-cut-wp-ui b/projects/js-packages/scan/changelog/change-migrate-cut-wp-ui new file mode 100644 index 000000000000..b25b23aae75c --- /dev/null +++ b/projects/js-packages/scan/changelog/change-migrate-cut-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Replace internal ContextualUpgradeTrigger upgrade prompts with @wordpress/ui Notice composition. Internal refactor with a Notice-style visual refresh. diff --git a/projects/js-packages/scan/src/components/threat-modal/threat-fix-details.tsx b/projects/js-packages/scan/src/components/threat-modal/threat-fix-details.tsx index eb5a2b00d9ef..466f6490bad3 100644 --- a/projects/js-packages/scan/src/components/threat-modal/threat-fix-details.tsx +++ b/projects/js-packages/scan/src/components/threat-modal/threat-fix-details.tsx @@ -1,5 +1,6 @@ -import { ContextualUpgradeTrigger, Text } from '@automattic/jetpack-components'; +import { Text } from '@automattic/jetpack-components'; import { __, sprintf } from '@wordpress/i18n'; +import { Notice } from '@wordpress/ui'; import { useMemo, useContext } from 'react'; import { getFixerDescription } from '@automattic/jetpack-scan'; import { ThreatModalContext } from './index.tsx'; @@ -48,14 +49,16 @@ const ThreatFixDetails = (): JSX.Element => { { title } { fix } { handleUpgradeClick && ( - + + + { __( 'Looking for advanced scan results and one-click fixes?', 'jetpack-scan' ) } + + + + { __( 'Upgrade Jetpack now', 'jetpack-scan' ) } + + + ) } ); diff --git a/projects/packages/publicize/_inc/components/admin-page/test/social-module-toggle.test.jsx b/projects/packages/publicize/_inc/components/admin-page/test/social-module-toggle.test.jsx index e1a065361d64..2f10b52ecfa3 100644 --- a/projects/packages/publicize/_inc/components/admin-page/test/social-module-toggle.test.jsx +++ b/projects/packages/publicize/_inc/components/admin-page/test/social-module-toggle.test.jsx @@ -16,6 +16,11 @@ describe( 'SocialModuleToggle', () => { clearMockedScriptData(); } ); + // @wordpress/ui Notice triggers @wordpress/a11y speak() which renders the + // same description text into a visually-hidden .a11y-speak-region. Exclude + // that region from text queries so the assertions target the visible Notice. + const ignoreA11ySpeak = { ignore: 'script, style, .a11y-speak-region' }; + it( 'should render connection management component by default', () => { render( ); @@ -25,7 +30,9 @@ describe( 'SocialModuleToggle', () => { it( 'should show upgrade trigger when no paid features', () => { render( ); - expect( screen.getByText( /Unlock advanced sharing options/i ) ).toBeInTheDocument(); + expect( + screen.getByText( /Unlock advanced sharing options/i, ignoreA11ySpeak ) + ).toBeInTheDocument(); } ); it( 'should not show upgrade trigger with paid features', () => { @@ -40,6 +47,8 @@ describe( 'SocialModuleToggle', () => { } ); render( ); - expect( screen.queryByText( /Unlock advanced sharing options/i ) ).not.toBeInTheDocument(); + expect( + screen.queryByText( /Unlock advanced sharing options/i, ignoreA11ySpeak ) + ).not.toBeInTheDocument(); } ); } ); diff --git a/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/index.tsx b/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/index.tsx index 186e89b5e69e..e5d1aa3cca0b 100644 --- a/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/index.tsx +++ b/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/index.tsx @@ -1,5 +1,5 @@ import { - ContextualUpgradeTrigger, + IconTooltip, Text, getRedirectUrl, useBreakpointMatch, @@ -7,7 +7,7 @@ import { import { getScriptData, isWpcomPlatformSite } from '@automattic/jetpack-script-data'; import { useSelect, useDispatch } from '@wordpress/data'; import { __, _x } from '@wordpress/i18n'; -import { Link } from '@wordpress/ui'; +import { Link, Notice } from '@wordpress/ui'; import clsx from 'clsx'; import { useCallback } from 'react'; import { store as socialStore } from '../../../../social-store'; @@ -93,19 +93,29 @@ const SocialModuleToggle: FC = () => { { ! isWpcomPlatformSite() && ! hasSocialPaidFeatures() ? ( - + + + { __( 'Unlock advanced sharing options', 'jetpack-publicize-pkg' ) }{ ' ' } + + + { __( + 'Share custom images and videos that capture attention, use our powerful Social Image Generator to create stunning visuals, and access priority support for expert help whenever you need it.', + 'jetpack-publicize-pkg' + ) } + + + + + + { __( 'Power up Jetpack Social', 'jetpack-publicize-pkg' ) } + + + ) : null } { isModuleEnabled && } { renderConnectionManagement() } diff --git a/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/styles.module.scss b/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/styles.module.scss index 39ab329a136b..38a2437035f5 100644 --- a/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/styles.module.scss +++ b/projects/packages/publicize/_inc/components/admin-page/toggles/social-module-toggle/styles.module.scss @@ -44,3 +44,4 @@ .learn { text-wrap: nowrap; } + diff --git a/projects/packages/publicize/changelog/change-migrate-cut-wp-ui b/projects/packages/publicize/changelog/change-migrate-cut-wp-ui new file mode 100644 index 000000000000..b25b23aae75c --- /dev/null +++ b/projects/packages/publicize/changelog/change-migrate-cut-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Replace internal ContextualUpgradeTrigger upgrade prompts with @wordpress/ui Notice composition. Internal refactor with a Notice-style visual refresh. diff --git a/projects/packages/search/changelog/change-migrate-cut-wp-ui b/projects/packages/search/changelog/change-migrate-cut-wp-ui new file mode 100644 index 000000000000..b25b23aae75c --- /dev/null +++ b/projects/packages/search/changelog/change-migrate-cut-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Replace internal ContextualUpgradeTrigger upgrade prompts with @wordpress/ui Notice composition. Internal refactor with a Notice-style visual refresh. diff --git a/projects/packages/search/src/dashboard/components/pages/sections/plan-usage-section.jsx b/projects/packages/search/src/dashboard/components/pages/sections/plan-usage-section.jsx index 51ea85ecedb3..149081c6843e 100644 --- a/projects/packages/search/src/dashboard/components/pages/sections/plan-usage-section.jsx +++ b/projects/packages/search/src/dashboard/components/pages/sections/plan-usage-section.jsx @@ -1,7 +1,6 @@ -import { ContextualUpgradeTrigger, ThemeProvider } from '@automattic/jetpack-components'; import { createInterpolateElement } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; -import { Link } from '@wordpress/ui'; +import { Link, Notice } from '@wordpress/ui'; import { useState, useCallback, useMemo } from 'react'; import DonutMeterContainer, { formatNumber } from '../../donut-meter-container'; import PlanSummary from './plan-summary'; @@ -300,17 +299,17 @@ const getUpgradeMessages = () => { }; const UpgradeTrigger = ( { upgradeMessage, ctaCallback } ) => { - // const upgradeMessage = type && getUpgradeMessages()[ type ]; - const triggerData = upgradeMessage && { ...upgradeMessage, onClick: ctaCallback }; + if ( ! upgradeMessage ) { + return null; + } return ( - <> - { triggerData && ( - - - - ) } - + + { upgradeMessage.description } + + { upgradeMessage.cta } + + ); }; diff --git a/projects/packages/search/src/dashboard/components/pages/sections/test/plan-usage-section.test.jsx b/projects/packages/search/src/dashboard/components/pages/sections/test/plan-usage-section.test.jsx index 6bfc782d8f10..66f887120bdc 100644 --- a/projects/packages/search/src/dashboard/components/pages/sections/test/plan-usage-section.test.jsx +++ b/projects/packages/search/src/dashboard/components/pages/sections/test/plan-usage-section.test.jsx @@ -1,18 +1,18 @@ import { render, screen } from '@testing-library/react'; import PlanUsageSection from '../plan-usage-section'; -jest.mock( '@automattic/jetpack-components', () => ( { - ContextualUpgradeTrigger: ( { description, cta } ) => ( -
- { description } - { cta } -
- ), - ThemeProvider: ( { children } ) => <>{ children }, -} ) ); - jest.mock( '@wordpress/ui', () => ( { Link: ( { children, href } ) => { children }, + Notice: { + Root: ( { children } ) =>
{ children }
, + Description: ( { children } ) => { children }, + Actions: ( { children } ) =>
{ children }
, + ActionButton: ( { children, onClick } ) => ( + + ), + }, } ) ); jest.mock( '../../../donut-meter-container', () => { diff --git a/projects/packages/search/tests/js/dashboard/pages/dashboard-page.test.jsx b/projects/packages/search/tests/js/dashboard/pages/dashboard-page.test.jsx index 2007a5cf78f0..e5b983735cd7 100644 --- a/projects/packages/search/tests/js/dashboard/pages/dashboard-page.test.jsx +++ b/projects/packages/search/tests/js/dashboard/pages/dashboard-page.test.jsx @@ -8,7 +8,6 @@ jest.mock( Button: ( { children, ...rest } ) => , Container: ( { children } ) =>
{ children }
, Col: ( { children } ) =>
{ children }
, - ContextualUpgradeTrigger: ( { children } ) =>
{ children }
, DonutMeter: () =>
, Gridicon: () => , IconTooltip: ( { children } ) =>
{ children }
, diff --git a/projects/packages/videopress/changelog/change-migrate-cut-wp-ui b/projects/packages/videopress/changelog/change-migrate-cut-wp-ui new file mode 100644 index 000000000000..b25b23aae75c --- /dev/null +++ b/projects/packages/videopress/changelog/change-migrate-cut-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Replace internal ContextualUpgradeTrigger upgrade prompts with @wordpress/ui Notice composition. Internal refactor with a Notice-style visual refresh. diff --git a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx index 3e8f9272b994..ea63b60545ec 100644 --- a/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/admin-page/index.tsx @@ -10,7 +10,6 @@ import { Button, Col, useBreakpointMatch, - ContextualUpgradeTrigger, } from '@automattic/jetpack-components'; import { useProductCheckoutWorkflow, @@ -19,6 +18,7 @@ import { } from '@automattic/jetpack-connection'; import { FormFileUpload } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { Notice } from '@wordpress/ui'; import clsx from 'clsx'; import { useState } from 'react'; /** @@ -246,11 +246,11 @@ const UpgradeTrigger = ( { hasUsedVideo = false }: { hasUsedVideo: boolean } ) = ); return ( - + + { description && { description } } + + { cta } + + ); }; diff --git a/projects/plugins/protect/changelog/change-migrate-cut-wp-ui b/projects/plugins/protect/changelog/change-migrate-cut-wp-ui new file mode 100644 index 000000000000..b25b23aae75c --- /dev/null +++ b/projects/plugins/protect/changelog/change-migrate-cut-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Replace internal ContextualUpgradeTrigger upgrade prompts with @wordpress/ui Notice composition. Internal refactor with a Notice-style visual refresh. diff --git a/projects/plugins/protect/src/js/components/threats-list/free-list.jsx b/projects/plugins/protect/src/js/components/threats-list/free-list.jsx index 76cde0a0e02b..68e220ccfe81 100644 --- a/projects/plugins/protect/src/js/components/threats-list/free-list.jsx +++ b/projects/plugins/protect/src/js/components/threats-list/free-list.jsx @@ -1,9 +1,10 @@ -import { Text, Button, ContextualUpgradeTrigger } from '@automattic/jetpack-components'; +import { Text, Button } from '@automattic/jetpack-components'; import { __, sprintf } from '@wordpress/i18n'; import { useCallback } from 'react'; import useAnalyticsTracks from '../../hooks/use-analytics-tracks'; import usePlan from '../../hooks/use-plan'; import FreeAccordion, { FreeAccordionItem } from '../free-accordion'; +import UpgradeNotice from '../upgrade-notice'; import Pagination from './pagination'; import styles from './styles.module.scss'; @@ -65,7 +66,7 @@ const ThreatAccordionItem = ( { sprintf( __( 'Update to %1$s %2$s', 'jetpack-protect' ), name, fixedIn ) } - ; + /** + * Optional href. When set, renders an ActionLink instead of an ActionButton. + */ + href?: string; + /** + * Whether to open the link in a new tab. Only applies when `href` is set. + */ + openInNewTab?: boolean; + /** + * Forwarded to the underlying Notice.Root for layout overrides. + */ + className?: string; +} + +/** + * Package-local upgrade-notice helper, built on `@wordpress/ui` `Notice`. + * + * Wraps the `Notice.Root` + `Notice.Description` + `Notice.Actions` composition so the + * three Protect upgrade-trigger sites stay terse. Replaces the deprecated + * `ContextualUpgradeTrigger` from `@automattic/jetpack-components`. + * + * @param props - Component properties. + * @param props.description - Body copy describing the upgrade context. + * @param props.cta - CTA label for the action. + * @param props.onClick - Click handler for the CTA (used when `href` is unset). + * @param props.href - Optional href. When set, renders an ActionLink. + * @param props.openInNewTab - Whether to open the link in a new tab. Only applies when `href` is set. + * @param props.className - Optional class forwarded to the underlying Notice.Root. + * @return The rendered upgrade notice. + */ +const UpgradeNotice: FC< UpgradeNoticeProps > = ( { + description, + cta, + onClick, + href, + openInNewTab = false, + className, +} ) => { + return ( + + { description } + + { href !== undefined ? ( + + { cta } + + ) : ( + { cta } + ) } + + + ); +}; + +export default UpgradeNotice; diff --git a/projects/plugins/protect/src/js/routes/firewall/index.jsx b/projects/plugins/protect/src/js/routes/firewall/index.jsx index b261029e3119..1a6015eacef3 100644 --- a/projects/plugins/protect/src/js/routes/firewall/index.jsx +++ b/projects/plugins/protect/src/js/routes/firewall/index.jsx @@ -4,7 +4,6 @@ import { Container, Text, ToggleControl, - ContextualUpgradeTrigger, useBreakpointMatch, } from '@automattic/jetpack-components'; import { Popover } from '@wordpress/components'; @@ -15,6 +14,7 @@ import { Notice } from '@wordpress/ui'; import moment from 'moment'; import { useCallback, useEffect, useState, useMemo } from 'react'; import Textarea from '../../components/textarea'; +import UpgradeNotice from '../../components/upgrade-notice'; import { FREE_PLUGIN_SUPPORT_URL, PAID_PLUGIN_SUPPORT_URL } from '../../constants'; import useWafUpgradeSeenMutation from '../../data/waf/use-waf-upgrade-seen-mutation'; import useAnalyticsTracks from '../../hooks/use-analytics-tracks'; @@ -350,7 +350,7 @@ const FirewallPage = () => {
{ ! hasPlan && (
- { ) } -