@automattic/jetpack-components 0.40.4 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ### This is a list detailing changes for the Jetpack RNA Components package releases.
4
4
 
5
+ ## [0.41.1] - 2023-08-09
6
+ ### Changed
7
+ - Updated package dependencies. [#32166]
8
+
9
+ ## [0.41.0] - 2023-07-24
10
+ ### Added
11
+ - Jetpack Footer: added generic links [#31627]
12
+
13
+ ### Changed
14
+ - Updated package dependencies. [#31999]
15
+
5
16
  ## [0.40.4] - 2023-07-18
6
17
  ### Changed
7
18
  - Use Connection initial state for fetching Calypso Env. [#31906]
@@ -772,6 +783,8 @@
772
783
  ### Changed
773
784
  - Update node version requirement to 14.16.1
774
785
 
786
+ [0.41.1]: https://github.com/Automattic/jetpack-components/compare/0.41.0...0.41.1
787
+ [0.41.0]: https://github.com/Automattic/jetpack-components/compare/0.40.4...0.41.0
775
788
  [0.40.4]: https://github.com/Automattic/jetpack-components/compare/0.40.3...0.40.4
776
789
  [0.40.3]: https://github.com/Automattic/jetpack-components/compare/0.40.2...0.40.3
777
790
  [0.40.2]: https://github.com/Automattic/jetpack-components/compare/0.40.1...0.40.2
@@ -20,7 +20,6 @@ const AdminPage: React.FC< AdminPageProps > = ( {
20
20
  children,
21
21
  moduleName = __( 'Jetpack', 'jetpack' ),
22
22
  moduleNameHref,
23
- a8cLogoHref,
24
23
  showHeader = true,
25
24
  showFooter = true,
26
25
  showBackground = true,
@@ -43,11 +42,7 @@ const AdminPage: React.FC< AdminPageProps > = ( {
43
42
  { showFooter && (
44
43
  <Container horizontalSpacing={ 5 }>
45
44
  <Col>
46
- <JetpackFooter
47
- moduleName={ moduleName }
48
- a8cLogoHref={ a8cLogoHref }
49
- moduleNameHref={ moduleNameHref }
50
- />
45
+ <JetpackFooter moduleName={ moduleName } moduleNameHref={ moduleNameHref } />
51
46
  </Col>
52
47
  </Container>
53
48
  ) }
@@ -4,11 +4,6 @@ export type AdminPageProps = {
4
4
  */
5
5
  children: React.ReactNode;
6
6
 
7
- /**
8
- * Link for 'An Automattic Airline' in the footer.
9
- */
10
- a8cLogoHref?: string;
11
-
12
7
  /**
13
8
  * Name of the module, e.g. 'Jetpack Search' that will be displayed in the footer.
14
9
  */
@@ -3,19 +3,19 @@
3
3
  Component that renders Jetpack Admin Footer.
4
4
  It takes moduleName and URL to show in the footer.
5
5
 
6
- #### How to use:
6
+ ## How to use:
7
7
 
8
8
  ```js
9
- <JetpackFooter
10
- moduleName="Jetpack Search"
11
- a8cLogoHref="https://www.jetpack.com"
12
- className="jp-dashboard-footer"
13
- />
9
+ <JetpackFooter moduleName="Jetpack Search" className="jp-dashboard-footer" />
14
10
  ```
15
11
 
16
- #### Props
12
+ ## Props
17
13
 
18
14
  - `className`: String - (default: `jp-dashboard-footer`) the additional class name set on the element.
19
- - `a8cLogoHref`: String - (default: `https://www.jetpack.com`) link to be added on 'An Automattic Airline'.
20
15
  - `moduleName`: String - (default: `Jetpack`) set the name of the Module, e.g. `Jetpack Search`.
21
- - `menu`: JetpackFooterMenuItem[] - (default: `null`) set the menu items to be rendered in the footer.
16
+ - `moduleNameHref`: String - (default: `https://jetpack.com`) link that the Module name will link to.
17
+ - `menu`: JetpackFooterMenuItem[] - (default: `undefined`) set the menu items to be rendered in the footer.
18
+ - `onAboutClick`: () => void - (default: `undefined`) function called when the About link is clicked.
19
+ - `onPrivacyClick`: () => void - (default: `undefined`) function called when the Privacy link is clicked.
20
+ - `onTermsClick`: () => void - (default: `undefined`) function called when the Terms link is clicked.
21
+ - `siteAdminUrl`: String - (default: `undefined`) URL of the site WP Admin. Required to link to internal pages when applicable (e.g., Privacy).
@@ -1,12 +1,15 @@
1
- import { __ } from '@wordpress/i18n';
1
+ import { useSelect } from '@wordpress/data';
2
+ import { __, _x } from '@wordpress/i18n';
2
3
  import { Icon, external } from '@wordpress/icons';
3
4
  import classnames from 'classnames';
4
5
  import React from 'react';
6
+ import { getRedirectUrl } from '../..';
7
+ import { STORE_ID as CONNECTION_STORE_ID } from '../../../../js-packages/connection/state/store';
5
8
  import AutomatticBylineLogo from '../automattic-byline-logo';
6
9
  import './style.scss';
7
10
  import JetpackLogo from '../jetpack-logo';
8
11
  import useBreakpointMatch from '../layout/use-breakpoint-match';
9
- import type { JetpackFooterProps } from './types';
12
+ import type { JetpackFooterProps, JetpackFooterMenuItem } from './types';
10
13
 
11
14
  const JetpackIcon: React.FC = () => (
12
15
  <JetpackLogo logoColor="#000" showText={ false } height={ 16 } aria-hidden="true" />
@@ -19,17 +22,74 @@ const JetpackIcon: React.FC = () => (
19
22
  * @returns {React.ReactNode} JetpackFooter component.
20
23
  */
21
24
  const JetpackFooter: React.FC< JetpackFooterProps > = ( {
22
- a8cLogoHref = 'https://automattic.com',
23
25
  moduleName = __( 'Jetpack', 'jetpack' ),
24
26
  className,
25
27
  moduleNameHref = 'https://jetpack.com',
26
28
  menu,
29
+ siteAdminUrl,
30
+ onAboutClick,
31
+ onPrivacyClick,
32
+ onTermsClick,
27
33
  ...otherProps
28
34
  } ) => {
29
35
  const [ isSm ] = useBreakpointMatch( 'sm', '<=' );
30
36
  const [ isMd ] = useBreakpointMatch( 'md', '<=' );
31
37
  const [ isLg ] = useBreakpointMatch( 'lg', '>' );
32
38
 
39
+ const { isActive, connectedPlugins } = useSelect(
40
+ select => {
41
+ const connectionStatus = select( CONNECTION_STORE_ID ) as {
42
+ getConnectedPlugins: () => { slug: string }[];
43
+ getConnectionStatus: () => { isActive: boolean };
44
+ };
45
+
46
+ return {
47
+ connectedPlugins: connectionStatus?.getConnectedPlugins(),
48
+ ...connectionStatus.getConnectionStatus(),
49
+ };
50
+ },
51
+ [ CONNECTION_STORE_ID ]
52
+ );
53
+
54
+ const areAdminLinksEnabled =
55
+ siteAdminUrl &&
56
+ // Some admin pages require the site to be connected (e.g., Privacy)
57
+ isActive &&
58
+ // Admin pages are part of the Jetpack plugin and required it to be installed
59
+ connectedPlugins?.some( ( { slug } ) => 'jetpack' === slug );
60
+
61
+ let items: JetpackFooterMenuItem[] = [
62
+ {
63
+ label: _x( 'About', 'Link to learn more about Jetpack.', 'jetpack' ),
64
+ title: __( 'About Jetpack', 'jetpack' ),
65
+ href: areAdminLinksEnabled
66
+ ? new URL( 'admin.php?page=jetpack_about', siteAdminUrl ).href
67
+ : getRedirectUrl( 'jetpack-about' ),
68
+ target: '_blank',
69
+ onClick: onAboutClick,
70
+ },
71
+ {
72
+ label: _x( 'Privacy', 'Shorthand for Privacy Policy.', 'jetpack' ),
73
+ title: __( "Automattic's Privacy Policy", 'jetpack' ),
74
+ href: areAdminLinksEnabled
75
+ ? new URL( 'admin.php?page=jetpack#/privacy', siteAdminUrl ).href
76
+ : getRedirectUrl( 'a8c-privacy' ),
77
+ target: areAdminLinksEnabled ? '_self' : '_blank',
78
+ onClick: onPrivacyClick,
79
+ },
80
+ {
81
+ label: _x( 'Terms', 'Shorthand for Terms of Service.', 'jetpack' ),
82
+ title: __( 'WordPress.com Terms of Service', 'jetpack' ),
83
+ href: getRedirectUrl( 'wpcom-tos' ),
84
+ target: '_blank',
85
+ onClick: onTermsClick,
86
+ },
87
+ ];
88
+
89
+ if ( menu ) {
90
+ items = [ ...items, ...menu ];
91
+ }
92
+
33
93
  const jetpackItemContent = (
34
94
  <>
35
95
  <JetpackIcon />
@@ -59,7 +119,7 @@ const JetpackFooter: React.FC< JetpackFooterProps > = ( {
59
119
  jetpackItemContent
60
120
  ) }
61
121
  </li>
62
- { menu?.map( item => {
122
+ { items.map( item => {
63
123
  const isButton = item.role === 'button';
64
124
  const isExternalLink = ! isButton && item.target === '_blank';
65
125
 
@@ -85,7 +145,14 @@ const JetpackFooter: React.FC< JetpackFooterProps > = ( {
85
145
  );
86
146
  } ) }
87
147
  <li className="jp-dashboard-footer__a8c-item">
88
- <a href={ a8cLogoHref } aria-label={ __( 'An Automattic Airline', 'jetpack' ) }>
148
+ <a
149
+ href={
150
+ areAdminLinksEnabled
151
+ ? new URL( 'admin.php?page=jetpack_about', siteAdminUrl ).href
152
+ : getRedirectUrl( 'a8c-about' )
153
+ }
154
+ aria-label={ __( 'An Automattic Airline', 'jetpack' ) }
155
+ >
89
156
  <AutomatticBylineLogo aria-hidden="true" />
90
157
  </a>
91
158
  </li>
@@ -9,7 +9,6 @@ export default {
9
9
  const Template: ComponentStory< typeof JetpackFooter > = args => <JetpackFooter { ...args } />;
10
10
 
11
11
  const DefaultArgs = {
12
- a8cLogoHref: 'https://automattic.com',
13
12
  moduleName: 'Jetpack',
14
13
  className: '',
15
14
  moduleNameHref: 'https://jetpack.com',
@@ -36,6 +36,75 @@ exports[`JetpackFooter Render the component should match the snapshot: all props
36
36
  Test module
37
37
  </a>
38
38
  </li>
39
+ <li>
40
+ <a
41
+ class="jp-dashboard-footer__menu-item is-external"
42
+ href="https://jetpack.com/redirect/?source=jetpack-about"
43
+ rel="noopener noreferrer"
44
+ target="_blank"
45
+ title="About Jetpack"
46
+ >
47
+ About
48
+ <svg
49
+ aria-hidden="true"
50
+ focusable="false"
51
+ height="16"
52
+ viewBox="0 0 24 24"
53
+ width="16"
54
+ xmlns="http://www.w3.org/2000/svg"
55
+ >
56
+ <path
57
+ d="M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"
58
+ />
59
+ </svg>
60
+ </a>
61
+ </li>
62
+ <li>
63
+ <a
64
+ class="jp-dashboard-footer__menu-item is-external"
65
+ href="https://jetpack.com/redirect/?source=a8c-privacy"
66
+ rel="noopener noreferrer"
67
+ target="_blank"
68
+ title="Automattic's Privacy Policy"
69
+ >
70
+ Privacy
71
+ <svg
72
+ aria-hidden="true"
73
+ focusable="false"
74
+ height="16"
75
+ viewBox="0 0 24 24"
76
+ width="16"
77
+ xmlns="http://www.w3.org/2000/svg"
78
+ >
79
+ <path
80
+ d="M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"
81
+ />
82
+ </svg>
83
+ </a>
84
+ </li>
85
+ <li>
86
+ <a
87
+ class="jp-dashboard-footer__menu-item is-external"
88
+ href="https://jetpack.com/redirect/?source=wpcom-tos"
89
+ rel="noopener noreferrer"
90
+ target="_blank"
91
+ title="WordPress.com Terms of Service"
92
+ >
93
+ Terms
94
+ <svg
95
+ aria-hidden="true"
96
+ focusable="false"
97
+ height="16"
98
+ viewBox="0 0 24 24"
99
+ width="16"
100
+ xmlns="http://www.w3.org/2000/svg"
101
+ >
102
+ <path
103
+ d="M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"
104
+ />
105
+ </svg>
106
+ </a>
107
+ </li>
39
108
  <li>
40
109
  <a
41
110
  class="jp-dashboard-footer__menu-item"
@@ -81,7 +150,7 @@ exports[`JetpackFooter Render the component should match the snapshot: all props
81
150
  >
82
151
  <a
83
152
  aria-label="An Automattic Airline"
84
- href="https://automattic.com"
153
+ href="https://jetpack.com/redirect/?source=a8c-about"
85
154
  >
86
155
  <svg
87
156
  aria-hidden="true"
@@ -7,7 +7,6 @@ describe( 'JetpackFooter', () => {
7
7
  const className = 'sample-classname';
8
8
  const moduleName = 'Test module';
9
9
  const moduleNameHref = 'https://jetpack.com/path/to-some-page';
10
- const a8cLogoHref = 'https://automattic.com';
11
10
 
12
11
  describe( 'Render the component', () => {
13
12
  const menu = [
@@ -71,12 +70,11 @@ describe( 'JetpackFooter', () => {
71
70
  } );
72
71
 
73
72
  it( 'should render the Automattic logo', () => {
74
- render( <JetpackFooter a8cLogoHref={ a8cLogoHref } /> );
73
+ render( <JetpackFooter /> );
75
74
 
76
75
  const element = screen.getByLabelText( 'An Automattic Airline', { selector: 'a' } );
77
76
 
78
77
  expect( element ).toBeInTheDocument();
79
- expect( element ).toHaveAttribute( 'href', a8cLogoHref );
80
78
  } );
81
79
 
82
80
  it( 'should render a list', () => {
@@ -86,7 +84,7 @@ describe( 'JetpackFooter', () => {
86
84
 
87
85
  expect( element ).toBeInTheDocument();
88
86
  // eslint-disable-next-line testing-library/no-node-access
89
- expect( element.children ).toHaveLength( 2 + menu.length );
87
+ expect( element.children ).toHaveLength( 2 + 3 + menu.length ); // 2 logos, 3 generic links
90
88
  } );
91
89
 
92
90
  it( 'should render the links', () => {
@@ -113,7 +111,6 @@ describe( 'JetpackFooter', () => {
113
111
  className={ className }
114
112
  moduleName={ moduleName }
115
113
  moduleNameHref={ moduleNameHref }
116
- a8cLogoHref={ a8cLogoHref }
117
114
  menu={ menu }
118
115
  />
119
116
  );
@@ -1,4 +1,4 @@
1
- type JetpackFooterMenuItem = {
1
+ export type JetpackFooterMenuItem = {
2
2
  href: string;
3
3
  label: string;
4
4
  onClick?: () => void;
@@ -9,11 +9,6 @@ type JetpackFooterMenuItem = {
9
9
  };
10
10
 
11
11
  export type JetpackFooterProps = {
12
- /**
13
- * Link for 'An Automattic Airline'.
14
- */
15
- a8cLogoHref?: string;
16
-
17
12
  /**
18
13
  * Name of the module, e.g. 'Jetpack Search'.
19
14
  */
@@ -33,4 +28,24 @@ export type JetpackFooterProps = {
33
28
  * Navigation menu to display in the footer.
34
29
  */
35
30
  menu?: JetpackFooterMenuItem[];
31
+
32
+ /**
33
+ * URL of the site WP Admin.
34
+ */
35
+ siteAdminUrl?: string;
36
+
37
+ /**
38
+ * Function called when the About link is clicked.
39
+ */
40
+ onAboutClick?: () => void;
41
+
42
+ /**
43
+ * Function called when the Privacy link is clicked.
44
+ */
45
+ onPrivacyClick?: () => void;
46
+
47
+ /**
48
+ * Function called when the Terms link is clicked.
49
+ */
50
+ onTermsClick?: () => void;
36
51
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/jetpack-components",
3
- "version": "0.40.4",
3
+ "version": "0.41.1",
4
4
  "description": "Jetpack Components Package",
5
5
  "author": "Automattic",
6
6
  "license": "GPL-2.0-or-later",
@@ -16,36 +16,37 @@
16
16
  "dependencies": {
17
17
  "@automattic/format-currency": "1.0.1",
18
18
  "@babel/runtime": "^7",
19
- "@wordpress/browserslist-config": "5.20.0",
20
- "@wordpress/components": "25.3.0",
21
- "@wordpress/compose": "6.14.0",
22
- "@wordpress/date": "4.37.0",
23
- "@wordpress/element": "5.14.0",
24
- "@wordpress/i18n": "4.37.0",
25
- "@wordpress/icons": "9.28.0",
19
+ "@wordpress/browserslist-config": "5.21.0",
20
+ "@wordpress/components": "25.4.0",
21
+ "@wordpress/compose": "6.15.0",
22
+ "@wordpress/data": "9.8.0",
23
+ "@wordpress/date": "4.38.0",
24
+ "@wordpress/element": "5.15.0",
25
+ "@wordpress/i18n": "4.38.0",
26
+ "@wordpress/icons": "9.29.0",
26
27
  "classnames": "2.3.2",
27
28
  "prop-types": "^15.7.2",
28
29
  "qrcode.react": "3.1.0",
29
30
  "react-slider": "2.0.5"
30
31
  },
31
32
  "devDependencies": {
32
- "@automattic/jetpack-base-styles": "^0.6.3",
33
+ "@automattic/jetpack-base-styles": "^0.6.5",
33
34
  "@babel/core": "7.22.9",
34
35
  "@babel/preset-react": "7.22.5",
35
36
  "@jest/globals": "29.4.3",
36
- "@storybook/addon-actions": "7.0.27",
37
- "@storybook/blocks": "7.0.27",
38
- "@storybook/react": "7.0.27",
37
+ "@storybook/addon-actions": "7.1.0",
38
+ "@storybook/blocks": "7.1.0",
39
+ "@storybook/react": "7.1.0",
39
40
  "@testing-library/dom": "8.19.1",
40
41
  "@testing-library/react": "13.4.0",
41
42
  "@testing-library/user-event": "14.4.3",
42
43
  "@types/jest": "29.2.5",
43
44
  "@types/qrcode.react": "1.0.2",
44
- "@types/react": "18.2.14",
45
- "@types/react-dom": "18.2.6",
45
+ "@types/react": "18.2.19",
46
+ "@types/react-dom": "18.2.7",
46
47
  "@types/react-slider": "1.3.1",
47
48
  "@types/react-test-renderer": "18.0.0",
48
- "@types/testing-library__jest-dom": "5.14.6",
49
+ "@types/testing-library__jest-dom": "5.14.9",
49
50
  "jest": "29.4.3",
50
51
  "jest-environment-jsdom": "29.4.3",
51
52
  "react": "18.2.0",