From 2dcfbb15e251036a0d4edcc13a4b2d4aa3688781 Mon Sep 17 00:00:00 2001 From: Filipe Varela Date: Thu, 7 May 2026 11:17:42 -0400 Subject: [PATCH 1/7] Newsletter: convert the settings sections to WPDS Card primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all 9 settings sections from `@wordpress/components`'s `Card` / `CardHeader` / `CardBody` / `CardFooter` over to `Card.Root` / `Card.Header` / `Card.Title` / `Card.Content` from `@wordpress/ui`. `__experimentalHeading` (legacy heading inside the header) becomes `Card.Title`; `__experimentalText` becomes WPDS `Text`. Section internals — DataForm fields, save handlers, change tracking — stay byte-for-byte identical. WPDS `Card` doesn't ship a `Footer` slot, so the row that used to live inside `` becomes a `
` at the bottom of ``. The shared style: * save-button rows (Subscriptions, Newsletter categories, Sender settings, Welcome email) right-align via `justify-content: flex-end`, * the Newsletter section's two-link row (Privacy + Manage subscribers) brackets via a `:has(> :nth-child(2))` rule that switches to `space-between` only when there's more than one child. Save and action buttons (`Save`, `Add plans` / `Manage plans`) opt into `__next40pxDefaultSize` so they ship the WordPress 7 default height ahead of the upgrade. Pure refactor — no behaviour changes. --- .../sections/email-byline-section.tsx | 22 +++---- .../sections/email-content-section.tsx | 23 +++---- .../email-reply-to-settings-section.tsx | 21 +++---- .../email-sender-settings-section.tsx | 46 +++++++------- .../newsletter-categories-section.tsx | 60 ++++++++----------- .../settings/sections/newsletter-section.tsx | 51 +++++++--------- .../sections/paid-newsletter-section.tsx | 25 ++++---- .../sections/subscriptions-section.tsx | 46 +++++++------- .../sections/welcome-email-section.tsx | 46 +++++++------- .../newsletter/src/settings/style.scss | 13 ++-- 10 files changed, 151 insertions(+), 202 deletions(-) diff --git a/projects/packages/newsletter/src/settings/sections/email-byline-section.tsx b/projects/packages/newsletter/src/settings/sections/email-byline-section.tsx index d49cacc0f254..c3f5ec0fbca5 100644 --- a/projects/packages/newsletter/src/settings/sections/email-byline-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/email-byline-section.tsx @@ -2,15 +2,9 @@ * External dependencies */ import { getAdminUrl, getScriptData } from '@automattic/jetpack-script-data'; -import { - Card, - CardHeader, - CardBody, - __experimentalText as Text, // eslint-disable-line @wordpress/no-unsafe-wp-apis - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { __ } from '@wordpress/i18n'; +import { Card, Text } from '@wordpress/ui'; /** * Internal dependencies */ @@ -84,11 +78,11 @@ export function EmailBylineSection( { ]; return ( - - - { __( 'Email byline', 'jetpack-newsletter' ) } - - + + + { __( 'Email byline', 'jetpack-newsletter' ) } + +

{ __( @@ -126,7 +120,7 @@ export function EmailBylineSection( { /> ) } - - + + ); } diff --git a/projects/packages/newsletter/src/settings/sections/email-content-section.tsx b/projects/packages/newsletter/src/settings/sections/email-content-section.tsx index ef79ba3e0eae..acfeeb0c6e8f 100644 --- a/projects/packages/newsletter/src/settings/sections/email-content-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/email-content-section.tsx @@ -1,15 +1,10 @@ /** * External dependencies */ -import { - Card, - CardHeader, - CardBody, - Notice, - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { Notice } from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { __ } from '@wordpress/i18n'; +import { Card } from '@wordpress/ui'; /** * Internal dependencies */ @@ -66,11 +61,11 @@ export function EmailContentSection( { ]; return ( - - - { __( 'Email content', 'jetpack-newsletter' ) } - - + + + { __( 'Email content', 'jetpack-newsletter' ) } + +

{ ! isSitePublic && ( @@ -94,7 +89,7 @@ export function EmailContentSection( { onChange={ onChange } />
-
-
+
+ ); } diff --git a/projects/packages/newsletter/src/settings/sections/email-reply-to-settings-section.tsx b/projects/packages/newsletter/src/settings/sections/email-reply-to-settings-section.tsx index dd21b6448608..2c5a3b32a428 100644 --- a/projects/packages/newsletter/src/settings/sections/email-reply-to-settings-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/email-reply-to-settings-section.tsx @@ -1,14 +1,9 @@ /** * External dependencies */ -import { - Card, - CardHeader, - CardBody, - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { __ } from '@wordpress/i18n'; +import { Card } from '@wordpress/ui'; /** * Internal dependencies */ @@ -58,11 +53,11 @@ export function EmailReplyToSettingsSection( { ]; return ( - - - { __( 'Reply-to settings', 'jetpack-newsletter' ) } - - + + + { __( 'Reply-to settings', 'jetpack-newsletter' ) } + +
-
-
+ + ); } diff --git a/projects/packages/newsletter/src/settings/sections/email-sender-settings-section.tsx b/projects/packages/newsletter/src/settings/sections/email-sender-settings-section.tsx index 2163fd3bcc1c..c08a8ffd29e3 100644 --- a/projects/packages/newsletter/src/settings/sections/email-sender-settings-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/email-sender-settings-section.tsx @@ -3,18 +3,11 @@ */ import analytics from '@automattic/jetpack-analytics'; import { getSiteData, getSiteType } from '@automattic/jetpack-script-data'; -import { - Button, - Card, - CardHeader, - CardBody, - CardFooter, - __experimentalText as Text, // eslint-disable-line @wordpress/no-unsafe-wp-apis - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { Button } from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { createInterpolateElement, useCallback } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; +import { Card, Text } from '@wordpress/ui'; /** * Internal dependencies */ @@ -79,11 +72,11 @@ export function EmailSenderSettingsSection( { const senderName = data.jetpack_subscriptions_from_name || ''; return ( - - - { __( 'Sender settings', 'jetpack-newsletter' ) } - - + + + { __( 'Sender settings', 'jetpack-newsletter' ) } + +

-
- - - -
+
+ +
+ + ); } diff --git a/projects/packages/newsletter/src/settings/sections/newsletter-categories-section.tsx b/projects/packages/newsletter/src/settings/sections/newsletter-categories-section.tsx index 30db6f487aca..0d5bc2a3e69f 100644 --- a/projects/packages/newsletter/src/settings/sections/newsletter-categories-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/newsletter-categories-section.tsx @@ -9,20 +9,11 @@ import { isWpcomPlatformSite, } from '@automattic/jetpack-script-data'; import { WpcomSupportLink } from '@automattic/jetpack-shared-extension-utils/components/wpcom-support-link'; -import { - Button, - Card, - CardHeader, - CardBody, - CardFooter, - Notice, - __experimentalText as Text, // eslint-disable-line @wordpress/no-unsafe-wp-apis - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { Button, Notice } from '@wordpress/components'; import { DataForm, type Field, useFormValidity } from '@wordpress/dataviews/wp'; import { createInterpolateElement, useCallback, useEffect, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { Link } from '@wordpress/ui'; +import { Card, Link, Text } from '@wordpress/ui'; /** * Internal dependencies */ @@ -166,11 +157,11 @@ export function NewsletterCategoriesSection( { ); return ( - - - { __( 'Newsletter categories', 'jetpack-newsletter' ) } - - + + + { __( 'Newsletter categories', 'jetpack-newsletter' ) } + +

{ createInterpolateElement( @@ -211,23 +202,24 @@ export function NewsletterCategoriesSection( {

) } -
- - - -
+
+ +
+ + ); } diff --git a/projects/packages/newsletter/src/settings/sections/newsletter-section.tsx b/projects/packages/newsletter/src/settings/sections/newsletter-section.tsx index 67739bc18be7..65ae606f9b67 100644 --- a/projects/packages/newsletter/src/settings/sections/newsletter-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/newsletter-section.tsx @@ -4,18 +4,11 @@ import analytics from '@automattic/jetpack-analytics'; import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect'; import { getSiteType, isSimpleSite } from '@automattic/jetpack-script-data'; -import { - Card, - CardHeader, - CardBody, - CardFooter, - ToggleControl, - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { ToggleControl } from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { useCallback, useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { Link } from '@wordpress/ui'; +import { Card, Link } from '@wordpress/ui'; /** * Internal dependencies */ @@ -113,11 +106,11 @@ export function NewsletterSection( { data, onChange }: NewsletterSectionProps ): ]; return ( - - - { __( 'Newsletter', 'jetpack-newsletter' ) } - - + + + { __( 'Newsletter', 'jetpack-newsletter' ) } + + - - - - { __( 'Privacy information', 'jetpack-newsletter' ) } - - { data.subscriptions && newsletterScriptData && ( +
- { __( 'Manage all subscribers', 'jetpack-newsletter' ) } + { __( 'Privacy information', 'jetpack-newsletter' ) } - ) } - - + { data.subscriptions && newsletterScriptData && ( + + { __( 'Manage all subscribers', 'jetpack-newsletter' ) } + + ) } +
+ + ); } diff --git a/projects/packages/newsletter/src/settings/sections/paid-newsletter-section.tsx b/projects/packages/newsletter/src/settings/sections/paid-newsletter-section.tsx index fd14641d4939..526a8bdde4c6 100644 --- a/projects/packages/newsletter/src/settings/sections/paid-newsletter-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/paid-newsletter-section.tsx @@ -3,16 +3,10 @@ */ import analytics from '@automattic/jetpack-analytics'; import { getSiteType } from '@automattic/jetpack-script-data'; -import { - Button, - Card, - CardHeader, - CardBody, - __experimentalText as Text, // eslint-disable-line @wordpress/no-unsafe-wp-apis - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { Button } from '@wordpress/components'; import { useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { Card, Text } from '@wordpress/ui'; /** * Internal dependencies */ @@ -54,11 +48,11 @@ export function PaidNewsletterSection( { const buttonText = hasActivePlan ? managePlansText : addPlansText; return ( - - - { __( 'Paid newsletter', 'jetpack-newsletter' ) } - - + + + { __( 'Paid newsletter', 'jetpack-newsletter' ) } + +

{ __( @@ -69,6 +63,7 @@ export function PaidNewsletterSection( {

-
-
+ + ); } diff --git a/projects/packages/newsletter/src/settings/sections/subscriptions-section.tsx b/projects/packages/newsletter/src/settings/sections/subscriptions-section.tsx index 06dc25acff0a..3518cb35cc44 100644 --- a/projects/packages/newsletter/src/settings/sections/subscriptions-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/subscriptions-section.tsx @@ -3,18 +3,11 @@ */ import analytics from '@automattic/jetpack-analytics'; import { getSiteType } from '@automattic/jetpack-script-data'; -import { - Button, - Card, - CardHeader, - CardBody, - CardFooter, - __experimentalText as Text, // eslint-disable-line @wordpress/no-unsafe-wp-apis - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { Button } from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { Card, Text } from '@wordpress/ui'; /** * Internal dependencies */ @@ -205,11 +198,11 @@ export function SubscriptionsSection( { ]; return ( - - - { __( 'Subscriptions', 'jetpack-newsletter' ) } - - + + + { __( 'Subscriptions', 'jetpack-newsletter' ) } + +

{ __( @@ -256,17 +249,18 @@ export function SubscriptionsSection( { onChange={ onChange } /> - - - - - +

+ +
+
+
); } diff --git a/projects/packages/newsletter/src/settings/sections/welcome-email-section.tsx b/projects/packages/newsletter/src/settings/sections/welcome-email-section.tsx index 940eddaea9a5..1d5cfa2eaaf6 100644 --- a/projects/packages/newsletter/src/settings/sections/welcome-email-section.tsx +++ b/projects/packages/newsletter/src/settings/sections/welcome-email-section.tsx @@ -3,18 +3,11 @@ */ import analytics from '@automattic/jetpack-analytics'; import { getSiteType } from '@automattic/jetpack-script-data'; -import { - Button, - Card, - CardHeader, - CardBody, - CardFooter, - __experimentalText as Text, // eslint-disable-line @wordpress/no-unsafe-wp-apis - __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis -} from '@wordpress/components'; +import { Button } from '@wordpress/components'; import { DataForm, type Field } from '@wordpress/dataviews/wp'; import { useCallback, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { Card, Text } from '@wordpress/ui'; /** * Internal dependencies */ @@ -103,11 +96,11 @@ export function WelcomeEmailSection( { ); return ( - - - { __( 'Welcome email message', 'jetpack-newsletter' ) } - - + + + { __( 'Welcome email message', 'jetpack-newsletter' ) } + +

{ __( @@ -130,17 +123,18 @@ export function WelcomeEmailSection( { onChange={ handleDataFormChange } /> - - - - - +

+ +
+
+
); } diff --git a/projects/packages/newsletter/src/settings/style.scss b/projects/packages/newsletter/src/settings/style.scss index 14cae720468e..cf15c9360f15 100644 --- a/projects/packages/newsletter/src/settings/style.scss +++ b/projects/packages/newsletter/src/settings/style.scss @@ -60,14 +60,17 @@ body.jetpack_page_jetpack-newsletter { margin-block-end: var(--wpds-dimension-gap-lg, 24px); } - .components-card__body > p:first-child { - margin-top: 0; - } - .newsletter-card-footer { display: flex; flex-wrap: wrap; - justify-content: space-between; gap: 8px; + justify-content: flex-end; + margin-block-start: var(--wpds-dimension-gap-lg, 16px); + + // Two-element footer (NewsletterSection's privacy + manage links) + // brackets each child to opposite ends instead of stacking right. + &:has(> :nth-child(2)) { + justify-content: space-between; + } } } From 46929dc6dd3a7b358e23f0f60992d315c37cd629 Mon Sep 17 00:00:00 2001 From: Filipe Varela Date: Thu, 7 May 2026 11:17:56 -0400 Subject: [PATCH 2/7] Newsletter: changelog for the WPDS Card migration --- projects/packages/newsletter/changelog/add-wp-build-wpds-cards | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 projects/packages/newsletter/changelog/add-wp-build-wpds-cards diff --git a/projects/packages/newsletter/changelog/add-wp-build-wpds-cards b/projects/packages/newsletter/changelog/add-wp-build-wpds-cards new file mode 100644 index 000000000000..d929f7d35242 --- /dev/null +++ b/projects/packages/newsletter/changelog/add-wp-build-wpds-cards @@ -0,0 +1,3 @@ +Significance: patch +Type: changed +Comment: Settings sections on the Newsletter modernization chassis now use the WPDS Card primitives, behind the same feature flag; no user-visible change unless the flag is enabled. From 11b2ac776bae5961e9d10810bbbe9d5327df7287 Mon Sep 17 00:00:00 2001 From: Filipe Varela Date: Thu, 7 May 2026 11:32:47 -0400 Subject: [PATCH 3/7] Newsletter: space the settings cards 24px apart with breathing room below MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The settings body stacked its cards with `gap="md"` (12px), which left them sitting too close together on the modernized chassis once they got the new WPDS Card chrome. Switch the inner and outer `Stack`s to `gap="xl"` so each card pair sits exactly 24px apart via `--wpds-dimension-gap-xl` — same rhythm as the page-header padding inset, no magic numbers. Add a `padding-block-end` of `--wpds-dimension-padding-3xl` (32px) to `.newsletter-settings` so the last card has room before the page bottom on overflow scroll. --- .../packages/newsletter/src/settings/newsletter-settings.tsx | 4 ++-- projects/packages/newsletter/src/settings/style.scss | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/packages/newsletter/src/settings/newsletter-settings.tsx b/projects/packages/newsletter/src/settings/newsletter-settings.tsx index 92fb91ba8890..0ddb47cad661 100644 --- a/projects/packages/newsletter/src/settings/newsletter-settings.tsx +++ b/projects/packages/newsletter/src/settings/newsletter-settings.tsx @@ -419,11 +419,11 @@ export function NewsletterSettingsBody( { isDisabled={ ! hasConnectedOwner } className={ ! hasConnectedOwner ? 'newsletter-settings-disabled' : undefined } > - + - + Date: Thu, 7 May 2026 12:52:21 -0400 Subject: [PATCH 4/7] Newsletter: port the subscribe-placement card primitive from #48420 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the prototype's placement-card surface back: a selectable card composed from `