diff --git a/projects/js-packages/components/changelog/add-social-add-connection-modal b/projects/js-packages/components/changelog/add-social-add-connection-modal
new file mode 100644
index 0000000000000..ca75984c66759
--- /dev/null
+++ b/projects/js-packages/components/changelog/add-social-add-connection-modal
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Social: Added add connection modal
diff --git a/projects/js-packages/components/components/icons/index.tsx b/projects/js-packages/components/components/icons/index.tsx
index 748f13e6d4aa5..bed624ca12b1c 100644
--- a/projects/js-packages/components/components/icons/index.tsx
+++ b/projects/js-packages/components/components/icons/index.tsx
@@ -278,11 +278,13 @@ export function getIconBySlug< Slug extends IconSlug >( slug: Slug ): IconsMap[
export const SocialServiceIcon: React.FC< {
serviceName: React.ComponentProps< typeof SocialLogo >[ 'icon' ];
className?: string;
-} > = ( { serviceName, className } ) => {
+ iconSize?: number;
+} > = ( { serviceName, className, iconSize } ) => {
return (
);
};
diff --git a/projects/js-packages/publicize-components/changelog/add-social-add-connection-modal b/projects/js-packages/publicize-components/changelog/add-social-add-connection-modal
new file mode 100644
index 0000000000000..ca75984c66759
--- /dev/null
+++ b/projects/js-packages/publicize-components/changelog/add-social-add-connection-modal
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Social: Added add connection modal
diff --git a/projects/js-packages/publicize-components/index.ts b/projects/js-packages/publicize-components/index.ts
index 18d4c6eb130a7..e19797da1d221 100644
--- a/projects/js-packages/publicize-components/index.ts
+++ b/projects/js-packages/publicize-components/index.ts
@@ -18,6 +18,7 @@ export { default as ReviewPrompt } from './src/components/review-prompt';
export { default as PostPublishReviewPrompt } from './src/components/post-publish-review-prompt';
export { default as PostPublishManualSharing } from './src/components/post-publish-manual-sharing';
export { default as RefreshJetpackSocialSettingsWrapper } from './src/components/refresh-jetpack-social-settings';
+export { default as AddConnectionModal } from './src/components/add-connection-modal';
export { default as ConnectionManagement } from './src/components/connection-management';
export { default as useSocialMediaConnections } from './src/hooks/use-social-media-connections';
diff --git a/projects/js-packages/publicize-components/package.json b/projects/js-packages/publicize-components/package.json
index ddd3e582f7258..ba5e622ec4be4 100644
--- a/projects/js-packages/publicize-components/package.json
+++ b/projects/js-packages/publicize-components/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-publicize-components",
- "version": "0.50.0",
+ "version": "0.51.0-alpha",
"description": "A library of JS components required by the Publicize editor plugin",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/publicize-components/#readme",
"bugs": {
diff --git a/projects/js-packages/publicize-components/src/assets/connections-button-facebook.png b/projects/js-packages/publicize-components/src/assets/connections-button-facebook.png
new file mode 100644
index 0000000000000..5882335ce7c49
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-button-facebook.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-button-linkedin.png b/projects/js-packages/publicize-components/src/assets/connections-button-linkedin.png
new file mode 100644
index 0000000000000..fbb02c632709f
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-button-linkedin.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-button-tumblr.png b/projects/js-packages/publicize-components/src/assets/connections-button-tumblr.png
new file mode 100644
index 0000000000000..0029fb1ee3c28
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-button-tumblr.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-facebook.png b/projects/js-packages/publicize-components/src/assets/connections-facebook.png
new file mode 100644
index 0000000000000..de2e00744782d
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-facebook.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-instagram-business.png b/projects/js-packages/publicize-components/src/assets/connections-instagram-business.png
new file mode 100644
index 0000000000000..f4dedd427391a
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-instagram-business.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-linkedin.png b/projects/js-packages/publicize-components/src/assets/connections-linkedin.png
new file mode 100644
index 0000000000000..b7be697d0c9cb
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-linkedin.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-nextdoor.png b/projects/js-packages/publicize-components/src/assets/connections-nextdoor.png
new file mode 100644
index 0000000000000..28e2903d40718
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-nextdoor.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/connections-tumblr.png b/projects/js-packages/publicize-components/src/assets/connections-tumblr.png
new file mode 100644
index 0000000000000..eb40c6a10cf5e
Binary files /dev/null and b/projects/js-packages/publicize-components/src/assets/connections-tumblr.png differ
diff --git a/projects/js-packages/publicize-components/src/assets/index.d.ts b/projects/js-packages/publicize-components/src/assets/index.d.ts
new file mode 100644
index 0000000000000..e2937d470ee8a
--- /dev/null
+++ b/projects/js-packages/publicize-components/src/assets/index.d.ts
@@ -0,0 +1 @@
+declare module '*.png';
diff --git a/projects/js-packages/publicize-components/src/components/add-connection-modal/connect-page/connect-page.tsx b/projects/js-packages/publicize-components/src/components/add-connection-modal/connect-page/connect-page.tsx
new file mode 100644
index 0000000000000..0f22238f56a74
--- /dev/null
+++ b/projects/js-packages/publicize-components/src/components/add-connection-modal/connect-page/connect-page.tsx
@@ -0,0 +1,52 @@
+import { Button, useBreakpointMatch } from '@automattic/jetpack-components';
+import { __ } from '@wordpress/i18n';
+import classNames from 'classnames';
+import { Connection } from '../constants';
+import styles from './style.module.scss';
+
+type ConnectPageProps = {
+ service: Connection;
+ onBackClicked: () => void;
+};
+
+export const ConnectPage: React.FC< ConnectPageProps > = ( { service, onBackClicked } ) => {
+ const [ isSmall ] = useBreakpointMatch( 'sm' );
+
+ return (
+ <>
+
+ { service.examples.map( ( Example, idx ) => (
+
+
+
+ ) ) }
+
+
+
+
+
+ >
+ );
+};
diff --git a/projects/js-packages/publicize-components/src/components/add-connection-modal/connect-page/style.module.scss b/projects/js-packages/publicize-components/src/components/add-connection-modal/connect-page/style.module.scss
new file mode 100644
index 0000000000000..b07292d0e8970
--- /dev/null
+++ b/projects/js-packages/publicize-components/src/components/add-connection-modal/connect-page/style.module.scss
@@ -0,0 +1,53 @@
+.example-wrapper {
+ display: grid;
+ grid-auto-columns: minmax(0, 1fr);
+ grid-auto-flow: column;
+ font-size: 15px;
+ margin-top: 0.4rem;
+ min-height: 300px;
+
+ &.small {
+ grid-auto-flow: row;
+ grid-gap: 2rem;
+ height: auto;
+ min-height: unset;
+ }
+
+ img {
+ max-height: 520px;
+ max-width: 100%;
+ }
+
+ > div {
+ padding: 0.4rem;
+
+ &:has(img) {
+ margin-inline-start: auto;
+ margin-inline-end: auto;
+ }
+ }
+}
+
+.actions-wrapper {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 1rem;
+}
+
+.chevron-back {
+ display: block;
+}
+
+.connect-form {
+ display: grid;
+ gap: 0.5rem;
+
+ & > input {
+ height: 100%;
+ width: 18rem;
+ }
+
+ &:not(.small) {
+ grid-auto-flow: column;
+ }
+}
\ No newline at end of file
diff --git a/projects/js-packages/publicize-components/src/components/add-connection-modal/constants.tsx b/projects/js-packages/publicize-components/src/components/add-connection-modal/constants.tsx
new file mode 100644
index 0000000000000..d96490aa29840
--- /dev/null
+++ b/projects/js-packages/publicize-components/src/components/add-connection-modal/constants.tsx
@@ -0,0 +1,265 @@
+import { SocialServiceIcon } from '@automattic/jetpack-components';
+import { ExternalLink } from '@wordpress/components';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import connectionsButtonFacebook from '../../assets/connections-button-facebook.png';
+import connectionsButtonLinkedin from '../../assets/connections-button-linkedin.png';
+import connectionsButtonTumblr from '../../assets/connections-button-tumblr.png';
+import connectionsFacebook from '../../assets/connections-facebook.png';
+import connectionsInstagramBusiness from '../../assets/connections-instagram-business.png';
+import connectionsLinkedin from '../../assets/connections-linkedin.png';
+import connectionsNextdoor from '../../assets/connections-nextdoor.png';
+import connectionsTumblr from '../../assets/connections-tumblr.png';
+
+const sharingButtonLink = 'https://wordpress.com/support/sharing/';
+
+export interface Connection {
+ title: string;
+ icon: React.ComponentType< { iconSize: number } >;
+ description: string;
+ name: string;
+ examples?: Array< React.ComponentType >;
+}
+
+export const getSupportedConnections = (): Connection[] => {
+ return [
+ {
+ title: __( 'Facebook', 'jetpack' ),
+ icon: props => ,
+ description: __(
+ "Facebook's massive active user base makes for a great place to share your posts and connect with your followers.",
+ 'jetpack'
+ ),
+ name: 'facebook',
+ examples: [
+ () => (
+ <>
+
+
+
+ { createInterpolateElement(
+ __(
+ 'Connect to automatically share posts on your Facebook page.',
+ 'jetpack'
+ ),
+ { strong: }
+ ) }
+ >
+ ),
+ () => (
+ <>
+
+
+
+ { createInterpolateElement(
+ __(
+ 'Add a to your posts so readers can share your story with their friends.',
+ 'jetpack'
+ ),
+ {
+ strong: ,
+ link: (
+
+ { __( 'sharing button', 'jetpack' ) }
+
+ ),
+ }
+ ) }
+ >
+ ),
+ ],
+ },
+ {
+ title: __( 'Instagram Business', 'jetpack' ),
+ icon: props => ,
+ description: __(
+ 'Share photos from your site to your Instagram Business account.',
+ 'jetpack'
+ ),
+ name: 'instagram',
+ examples: [
+ () => (
+ <>
+ { __(
+ 'Drive engagement and save time by automatically sharing images to Instagram when you publish blog posts.',
+ 'jetpack'
+ ) }
+
+
{ __( 'Requirements for connecting Instagram:', 'jetpack' ) }
+
+ - { __( 'You must have an Instagram Business account.', 'jetpack' ) }
+ -
+ { __(
+ 'Your Instagram Business account must be linked to a Facebook page.',
+ 'jetpack'
+ ) }
+
+
+
+ { createInterpolateElement(
+ __(
+ "When you click “connect” you'll be asked to log into Facebook. If your Instagram Business account isn't listed, ensure it's linked to a Facebook page.",
+ 'jetpack'
+ ),
+ { strong: , i: }
+ ) }
+
+
+
+ { __( 'Learn how to convert & link your Instagram account.', 'jetpack' ) }
+
+ >
+ ),
+ () => (
+
+ ),
+ ],
+ },
+ {
+ title: __( 'LinkedIn', 'jetpack' ),
+ icon: props => ,
+ description: __(
+ 'Reach a professional audience and contribute valuable content by sharing your posts with the LinkedIn community.',
+ 'jetpack'
+ ),
+ name: 'linkedin',
+ examples: [
+ () => (
+ <>
+
+
+
+ { createInterpolateElement(
+ __(
+ 'Connect to automatically share posts with your LinkedIn connections.',
+ 'jetpack'
+ ),
+ { strong: }
+ ) }
+ >
+ ),
+ () => (
+ <>
+
+
+
+ { createInterpolateElement(
+ __(
+ 'Add a to your posts so readers can share your story with their connections.',
+ 'jetpack'
+ ),
+ {
+ strong: ,
+ link: (
+
+ { __( 'sharing button', 'jetpack' ) }
+
+ ),
+ }
+ ) }
+ >
+ ),
+ ],
+ },
+ {
+ title: __( 'Nextdoor', 'jetpack' ),
+ icon: props => ,
+ description: __(
+ 'Share your posts with your local community on Nextdoor, facilitating meaningful interactions and fostering a sense of belonging among neighbors.',
+ 'jetpack'
+ ),
+ name: 'nextdoor',
+ examples: [
+ () => (
+ <>
+ { createInterpolateElement(
+ __(
+ 'Connect with friends, neighbors, and local businesses by automatically sharing your posts to Nextdoor.',
+ 'jetpack'
+ ),
+ { strong: }
+ ) }
+ >
+ ),
+ () => ,
+ ],
+ },
+ {
+ title: __( 'Tumblr', 'jetpack' ),
+ icon: props => ,
+ description: __(
+ 'Share posts on your Tumblr blog to expand your reach to a diverse younger audience in a fun and creative community.',
+ 'jetpack'
+ ),
+ name: 'tumblr',
+ examples: [
+ () => (
+ <>
+
+
+
+ { createInterpolateElement(
+ __(
+ 'Connect to automatically share posts to your Tumblr blog.',
+ 'jetpack'
+ ),
+ { strong: }
+ ) }
+ >
+ ),
+ () => (
+ <>
+
+
+
+ { createInterpolateElement(
+ __(
+ 'Add a to your posts so readers can share your story with their followers.',
+ 'jetpack'
+ ),
+ {
+ strong: ,
+ link: (
+
+ { __( 'sharing button', 'jetpack' ) }
+
+ ),
+ }
+ ) }
+ >
+ ),
+ ],
+ },
+ {
+ title: __( 'Mastodon', 'jetpack' ),
+ icon: props => ,
+ description: __(
+ 'Share your posts to an open-source social network with a community that values privacy and freedom.',
+ 'jetpack'
+ ),
+ name: 'mastodon',
+ examples: [
+ () => (
+ <>
+ { __(
+ 'To share to Mastodon please enter your Mastodon username below, then click connect.',
+ 'jetpack'
+ ) }
+ >
+ ),
+ ],
+ },
+ ];
+};
diff --git a/projects/js-packages/publicize-components/src/components/add-connection-modal/index.tsx b/projects/js-packages/publicize-components/src/components/add-connection-modal/index.tsx
new file mode 100644
index 0000000000000..95cdf4eb959d3
--- /dev/null
+++ b/projects/js-packages/publicize-components/src/components/add-connection-modal/index.tsx
@@ -0,0 +1,96 @@
+import { Button, useBreakpointMatch } from '@automattic/jetpack-components';
+import { Modal } from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { Icon, chevronDown } from '@wordpress/icons';
+import classNames from 'classnames';
+import { useCallback, useState } from 'react';
+import { ConnectPage } from './connect-page/connect-page';
+import { getSupportedConnections } from './constants';
+import styles from './style.module.scss';
+
+const AddConnectionModal = ( { onCloseModal } ) => {
+ const [ currentService, setCurrentService ] = useState( null );
+
+ const [ isSmall ] = useBreakpointMatch( 'sm' );
+
+ const onServiceSelected = useCallback(
+ service => () => {
+ setCurrentService( service );
+ },
+ []
+ );
+
+ const onBackClicked = useCallback( () => {
+ setCurrentService( null );
+ }, [] );
+
+ return (
+
+ { currentService ? (
+
+ ) : (
+
+
+
+ |
+ |
+ |
+
+
+
+ { getSupportedConnections().map( service => (
+
+
+
+ |
+
+ { service.title }
+ { ! isSmall ? (
+ { service.description }
+ ) : null }
+ |
+
+
+
+
+
+ |
+
+ ) ) }
+
+
+ ) }
+
+ );
+};
+
+export default AddConnectionModal;
diff --git a/projects/js-packages/publicize-components/src/components/add-connection-modal/style.module.scss b/projects/js-packages/publicize-components/src/components/add-connection-modal/style.module.scss
new file mode 100644
index 0000000000000..618bf32ed0382
--- /dev/null
+++ b/projects/js-packages/publicize-components/src/components/add-connection-modal/style.module.scss
@@ -0,0 +1,66 @@
+.modal {
+ width: 65rem;
+ &.service-selector {
+ min-height: 700px;
+ }
+
+ &:not(.small) {
+ display: table;
+ }
+}
+
+.title {
+ margin: 0;
+}
+
+.description {
+ font-size: 15px;
+ margin-top: 0.7rem;
+ margin-bottom: 0;
+}
+
+.chevron {
+ display: block;
+}
+
+// Table padding
+td {
+ padding-top: 0.8rem;
+ padding-bottom: 0.8rem;
+
+ &:first-child {
+ padding-inline-start: 1rem;
+ padding-inline-end: 1rem;
+ }
+
+ &:last-child {
+ padding-inline-end: 1rem;
+ }
+}
+
+// Table border
+table {
+ border-collapse: separate;
+ border-spacing: 0;
+ border-radius: 4px;
+ outline: 1px solid var(--jp-gray-5);
+}
+
+tr:not(:last-child) > td {
+ border-bottom: solid 1px var(--jp-gray-5);
+}
+
+.column-description {
+ padding-inline-end: 6rem;
+}
+
+.column-actions {
+ display: grid;
+ grid-auto-flow: column;
+}
+
+.chevron-button.chevron-button.chevron-button {
+ padding-inline-start: 0.5rem;
+ padding-inline-end: 0.5rem;
+ margin-inline-start: 0.4rem;
+}
diff --git a/projects/js-packages/publicize-components/src/components/connection-management/index.tsx b/projects/js-packages/publicize-components/src/components/connection-management/index.tsx
index d5dc2974786ba..09ea84ae86516 100644
--- a/projects/js-packages/publicize-components/src/components/connection-management/index.tsx
+++ b/projects/js-packages/publicize-components/src/components/connection-management/index.tsx
@@ -4,9 +4,10 @@ import { ExternalLink } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import classNames from 'classnames';
-import { useCallback, useEffect } from 'react';
+import { useCallback, useEffect, useReducer } from 'react';
import useSocialMediaConnections from '../../hooks/use-social-media-connections';
import { store } from '../../social-store';
+import AddConnectionModal from '../add-connection-modal';
import ConnectionIcon from '../connection-icon';
import styles from './style.module.scss';
@@ -24,7 +25,7 @@ const ConnectionManagement = ( { className = null } ) => {
return a.service_name.localeCompare( b.service_name );
} );
- // const [ isModalOpen, toggleModal ] = useReducer( state => ! state, false );
+ const [ isModalOpen, toggleModal ] = useReducer( state => ! state, false );
useEffect( () => {
refresh();
@@ -97,8 +98,10 @@ const ConnectionManagement = ( { className = null } ) => {
) : (
{ __( 'There are no connections added yet.', 'jetpack' ) }
) }
-
- { /* { isModalOpen && } */ }
+
+ { isModalOpen && }
);
};
diff --git a/projects/plugins/jetpack/changelog/add-social-add-connection-modal b/projects/plugins/jetpack/changelog/add-social-add-connection-modal
new file mode 100644
index 0000000000000..176d81a3d098e
--- /dev/null
+++ b/projects/plugins/jetpack/changelog/add-social-add-connection-modal
@@ -0,0 +1,4 @@
+Significance: patch
+Type: other
+
+Fixed TS compile error for image imports in js-packages
diff --git a/projects/plugins/jetpack/global.d.ts b/projects/plugins/jetpack/global.d.ts
new file mode 100644
index 0000000000000..e2937d470ee8a
--- /dev/null
+++ b/projects/plugins/jetpack/global.d.ts
@@ -0,0 +1 @@
+declare module '*.png';
diff --git a/projects/plugins/jetpack/tsconfig.json b/projects/plugins/jetpack/tsconfig.json
index 3f22d2bb0df11..cd68380ba4f61 100644
--- a/projects/plugins/jetpack/tsconfig.json
+++ b/projects/plugins/jetpack/tsconfig.json
@@ -7,7 +7,7 @@
"*": [ "*", "./_inc/client/*" ]
}
},
- "include": [ "./_inc", "./extensions" ],
+ "include": [ "./_inc", "./extensions", "./global.d.ts" ],
// Jetpack puts build files into `_inc`, so we need exclude rules to skip those.
"exclude": [ "**/build/*", "_inc/blocks/*" ]
}
diff --git a/projects/plugins/social/changelog/add-social-add-connection-modal b/projects/plugins/social/changelog/add-social-add-connection-modal
new file mode 100644
index 0000000000000..ca75984c66759
--- /dev/null
+++ b/projects/plugins/social/changelog/add-social-add-connection-modal
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Social: Added add connection modal