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.
diff --git a/projects/packages/newsletter/src/settings/newsletter-settings.tsx b/projects/packages/newsletter/src/settings/newsletter-settings.tsx
index 92fb91ba8890..90833cd81fd2 100644
--- a/projects/packages/newsletter/src/settings/newsletter-settings.tsx
+++ b/projects/packages/newsletter/src/settings/newsletter-settings.tsx
@@ -23,9 +23,9 @@ import { getNewsletterScriptData } from './script-data';
import {
EmailContentSection,
EmailBylineSection,
+ EmailDefaultsSection,
EmailSenderSettingsSection,
EmailReplyToSettingsSection,
- NewsletterSection,
NewsletterCategoriesSection,
PaidNewsletterSection,
SubscriptionsSection,
@@ -419,31 +419,27 @@ export function NewsletterSettingsBody( {
isDisabled={ ! hasConnectedOwner }
className={ ! hasConnectedOwner ? 'newsletter-settings-disabled' : undefined }
>
-
-
-
+
-
+
+
+
-
-
-
@@ -465,6 +461,7 @@ export function NewsletterSettingsBody( {
onSave={ saveSenderName }
isSaving={ isSavingSenderName }
hasChanges={ hasSenderNameChanges }
+ changedKeys={ Object.keys( senderNameChanges ) }
isNewsletterEnabled={ data.subscriptions }
/>
@@ -480,6 +477,17 @@ export function NewsletterSettingsBody( {
onSave={ saveWelcomeEmail }
isSaving={ isSavingWelcomeEmail }
hasChanges={ hasWelcomeEmailChanges }
+ changedKeys={ Object.keys( welcomeEmailChanges ) }
+ isNewsletterEnabled={ data.subscriptions }
+ />
+
+
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' ) }
+
+
-
-
+
+
);
}
diff --git a/projects/packages/newsletter/src/settings/sections/email-defaults-section.tsx b/projects/packages/newsletter/src/settings/sections/email-defaults-section.tsx
new file mode 100644
index 000000000000..689e1fcc00a9
--- /dev/null
+++ b/projects/packages/newsletter/src/settings/sections/email-defaults-section.tsx
@@ -0,0 +1,92 @@
+/**
+ * External dependencies
+ */
+import { isSimpleSite } from '@automattic/jetpack-script-data';
+import { ToggleControl } from '@wordpress/components';
+import { DataForm, type Field } from '@wordpress/dataviews/wp';
+import { useCallback } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { Card } from '@wordpress/ui';
+/**
+ * Internal dependencies
+ */
+import type { NewsletterSettings } from '../types';
+
+interface EmailDefaultsSectionProps {
+ data: NewsletterSettings;
+ onChange: ( updates: Partial< NewsletterSettings > ) => void;
+ isNewsletterEnabled: boolean;
+}
+
+/**
+ * Email Defaults Section Component.
+ *
+ * Renders the "Email new posts to subscribers by default" toggle. The
+ * legacy master `subscriptions` toggle that used to live here moved to
+ * the global Newsletter module activation control — flipping the module
+ * off-page disables this card via the orchestrator's `` wrapper.
+ *
+ * @param props - Component props.
+ * @param props.data - Newsletter settings data.
+ * @param props.onChange - Auto-save callback for setting updates.
+ * @param props.isNewsletterEnabled - Whether the Newsletter module is on.
+ * @return The email defaults section.
+ */
+export function EmailDefaultsSection( {
+ data,
+ onChange,
+ isNewsletterEnabled,
+}: EmailDefaultsSectionProps ): JSX.Element {
+ const fields: Field< NewsletterSettings >[] = [
+ {
+ id: 'wpcom_newsletter_send_default',
+ label: __( 'Email new posts to subscribers by default', 'jetpack-newsletter' ),
+ type: 'boolean' as const,
+ Edit( { field, onChange: onChangeField, data: formData } ) {
+ const handleToggle = useCallback( () => {
+ onChangeField(
+ field.setValue( {
+ item: formData,
+ value: ! field.getValue( { item: formData } ),
+ } )
+ );
+ }, [ onChangeField, field, formData ] );
+ return (
+
+ );
+ },
+ description: __(
+ 'When on, the newsletter option will be pre-selected each time you publish. You can change it in the newsletter panel in the editor before publishing any post.',
+ 'jetpack-newsletter'
+ ),
+ },
+ ];
+
+ return (
+
+
+ { __( 'Email defaults', 'jetpack-newsletter' ) }
+
+
+
+
+
+ );
+}
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..92921126b92b 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
*/
@@ -26,6 +19,8 @@ interface EmailSenderSettingsSectionProps {
onSave: () => void;
isSaving: boolean;
hasChanges: boolean;
+ /** Setting keys staged in this section's changeset, fed into section_save analytics. */
+ changedKeys?: string[];
isNewsletterEnabled: boolean;
}
@@ -43,6 +38,7 @@ export function EmailSenderSettingsSection( {
onSave,
isSaving,
hasChanges,
+ changedKeys,
isNewsletterEnabled,
}: EmailSenderSettingsSectionProps ): JSX.Element {
const siteType = getSiteType();
@@ -51,14 +47,16 @@ export function EmailSenderSettingsSection( {
const savingText = __( 'Saving…', 'jetpack-newsletter' );
const saveText = __( 'Save', 'jetpack-newsletter' );
- // Track section save
+ // Track section save with the keys that changed since the last save.
const handleSave = useCallback( () => {
analytics.tracks.recordEvent( 'jetpack_newsletter_section_save', {
site_type: siteType,
section: 'sender_settings',
+ changed_keys: ( changedKeys ?? [] ).join( ',' ),
+ change_count: ( changedKeys ?? [] ).length,
} );
onSave();
- }, [ onSave, siteType ] );
+ }, [ changedKeys, onSave, siteType ] );
const siteName = getSiteData()?.title;
@@ -79,11 +77,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/index.ts b/projects/packages/newsletter/src/settings/sections/index.ts
index e97af8a64210..39b868627aa7 100644
--- a/projects/packages/newsletter/src/settings/sections/index.ts
+++ b/projects/packages/newsletter/src/settings/sections/index.ts
@@ -3,9 +3,9 @@
*/
export { EmailContentSection } from './email-content-section';
export { EmailBylineSection } from './email-byline-section';
+export { EmailDefaultsSection } from './email-defaults-section';
export { EmailSenderSettingsSection } from './email-sender-settings-section';
export { EmailReplyToSettingsSection } from './email-reply-to-settings-section';
-export { NewsletterSection } from './newsletter-section';
export { NewsletterCategoriesSection } from './newsletter-categories-section';
export { PaidNewsletterSection } from './paid-newsletter-section';
export { SubscriptionsSection } from './subscriptions-section';
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..a80ac63b3d5e 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
*/
@@ -35,6 +26,8 @@ interface NewsletterCategoriesSectionProps {
onSave: () => void;
isSaving: boolean;
hasChanges: boolean;
+ /** Setting keys staged in this section's changeset, fed into section_save analytics. */
+ changedKeys?: string[];
isNewsletterEnabled: boolean;
}
@@ -50,6 +43,7 @@ export function NewsletterCategoriesSection( {
onSave,
isSaving,
hasChanges,
+ changedKeys,
isNewsletterEnabled,
}: NewsletterCategoriesSectionProps ): JSX.Element {
const siteType = getSiteType();
@@ -57,14 +51,16 @@ export function NewsletterCategoriesSection( {
const [ isFetchingCategories, setIsFetchingCategories ] = useState( true );
const [ categoriesError, setCategoriesError ] = useState< string | null >( null );
- // Track section save
+ // Track section save with the keys that changed since the last save.
const handleSave = useCallback( () => {
analytics.tracks.recordEvent( 'jetpack_newsletter_section_save', {
site_type: siteType,
section: 'newsletter_categories',
+ changed_keys: ( changedKeys ?? [] ).join( ',' ),
+ change_count: ( changedKeys ?? [] ).length,
} );
onSave();
- }, [ onSave, siteType ] );
+ }, [ changedKeys, onSave, siteType ] );
// Fetch WordPress categories on mount
useEffect( () => {
@@ -166,11 +162,11 @@ export function NewsletterCategoriesSection( {
);
return (
-
-
- { __( 'Newsletter categories', 'jetpack-newsletter' ) }
-
-
+
+
+ { __( 'Newsletter categories', 'jetpack-newsletter' ) }
+
+
{ createInterpolateElement(
@@ -211,23 +207,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
deleted file mode 100644
index 67739bc18be7..000000000000
--- a/projects/packages/newsletter/src/settings/sections/newsletter-section.tsx
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * External dependencies
- */
-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 { DataForm, type Field } from '@wordpress/dataviews/wp';
-import { useCallback, useRef } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { Link } from '@wordpress/ui';
-/**
- * Internal dependencies
- */
-import { getNewsletterScriptData } from '../script-data';
-import type { NewsletterSettings } from '../types';
-
-interface NewsletterSectionProps {
- data: NewsletterSettings;
- onChange: ( updates: Partial< NewsletterSettings > ) => void;
-}
-
-/**
- * Newsletter Section Component
- *
- * @param {NewsletterSectionProps} props - Component props
- * @return {JSX.Element} The newsletter section
- */
-export function NewsletterSection( { data, onChange }: NewsletterSectionProps ): JSX.Element {
- const newsletterScriptData = getNewsletterScriptData();
- const siteType = getSiteType();
- const previousSubscriptionsValue = useRef( data.subscriptions );
-
- // Wrap onChange to track module toggle
- const handleChange = useCallback(
- ( updates: Partial< NewsletterSettings > ) => {
- if (
- 'subscriptions' in updates &&
- updates.subscriptions !== previousSubscriptionsValue.current
- ) {
- analytics.tracks.recordEvent( 'jetpack_newsletter_module_toggle', {
- site_type: siteType,
- enabled: !! updates.subscriptions,
- } );
- previousSubscriptionsValue.current = !! updates.subscriptions;
- }
- onChange( updates );
- },
- [ onChange, siteType ]
- );
-
- // Track manage subscribers click
- const handleManageSubscribersClick = useCallback( () => {
- analytics.tracks.recordEvent( 'jetpack_newsletter_manage_subscribers_click', {
- site_type: siteType,
- } );
- }, [ siteType ] );
-
- const fields: Field< NewsletterSettings >[] = [
- ...( ! isSimpleSite()
- ? [
- {
- id: 'subscriptions',
- label: __(
- 'Let visitors subscribe to this site and receive emails when you publish a post',
- 'jetpack-newsletter'
- ),
- type: 'boolean' as const,
- Edit: 'toggle' as const,
- },
- ]
- : [] ),
- {
- id: 'wpcom_newsletter_send_default',
- label: __( 'Email new posts to subscribers by default', 'jetpack-newsletter' ),
- type: 'boolean' as const,
- Edit( { field, onChange: onChangeField, data: formData } ) {
- const handleToggle = useCallback( () => {
- onChangeField(
- field.setValue( {
- item: formData,
- value: ! field.getValue( { item: formData } ),
- } )
- );
- }, [ onChangeField, field, formData ] );
- return (
-
- );
- },
- description: __(
- 'When on, the newsletter option will be pre-selected each time you publish. You can change it in the newsletter panel in the editor before publishing any post.',
- 'jetpack-newsletter'
- ),
- },
- ];
-
- const formFields = [
- ...( ! isSimpleSite() ? [ 'subscriptions' ] : [] ),
- 'wpcom_newsletter_send_default',
- ];
-
- return (
-
-
- { __( 'Newsletter', '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/placement-card.scss b/projects/packages/newsletter/src/settings/sections/placement-card.scss
new file mode 100644
index 000000000000..665a01c127ea
--- /dev/null
+++ b/projects/packages/newsletter/src/settings/sections/placement-card.scss
@@ -0,0 +1,118 @@
+// PlacementCard — selectable card composed from `