@automattic/jetpack-components 1.7.0 → 1.8.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 +19 -0
- package/build/components/admin-page/index.js +3 -4
- package/build/components/admin-page/style.module.scss +0 -1
- package/build/components/admin-page/types.d.ts +0 -12
- package/build/components/jetpack-footer/index.d.ts +8 -0
- package/build/components/jetpack-footer/index.js +26 -59
- package/build/components/jetpack-footer/style.scss +20 -90
- package/build/components/jetpack-footer/types.d.ts +3 -32
- package/build/components/navigator-modal/header.d.ts +9 -1
- package/build/components/navigator-modal/header.js +8 -3
- package/build/components/navigator-modal/screen.d.ts +3 -12
- package/build/components/navigator-modal/screen.js +2 -2
- package/components/admin-page/index.tsx +2 -18
- package/components/admin-page/style.module.scss +0 -1
- package/components/admin-page/types.ts +0 -15
- package/components/jetpack-footer/README.md +23 -10
- package/components/jetpack-footer/index.tsx +78 -117
- package/components/jetpack-footer/style.scss +20 -90
- package/components/jetpack-footer/types.ts +3 -39
- package/components/navigator-modal/header.tsx +23 -3
- package/components/navigator-modal/screen.tsx +45 -47
- package/package.json +19 -17
- package/build/tools/get-site-admin-url/index.d.ts +0 -8
- package/build/tools/get-site-admin-url/index.js +0 -17
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
### This is a list detailing changes for the Jetpack RNA Components package releases.
|
|
4
4
|
|
|
5
|
+
## [1.8.1] - 2026-04-09
|
|
6
|
+
### Changed
|
|
7
|
+
- Update package dependencies. [#47890]
|
|
8
|
+
|
|
9
|
+
## [1.8.0] - 2026-04-06
|
|
10
|
+
### Added
|
|
11
|
+
- Add onGoBack and onClose callback props to NavigatorModal Screen and Header components. [#47896]
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- JetpackFooter: Update footer design with Products and Help navigation links, removing About, Privacy, and Terms links and related props. [#47840]
|
|
15
|
+
- Remove padding from admin page header subtitle for consistent spacing. [#47418]
|
|
16
|
+
- Update network admin settings visually. [#47912]
|
|
17
|
+
- Update package dependencies. [#47870]
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- JetpackFooter: Pin base font-size to design token to prevent page context from leaking into footer layout. [#47921]
|
|
21
|
+
|
|
5
22
|
## [1.7.0] - 2026-03-30
|
|
6
23
|
### Changed
|
|
7
24
|
- Remove double heading wrapper from AdminPage title, fixing header title sizing across all Jetpack admin pages. [#47696]
|
|
@@ -1715,6 +1732,8 @@
|
|
|
1715
1732
|
### Changed
|
|
1716
1733
|
- Update node version requirement to 14.16.1
|
|
1717
1734
|
|
|
1735
|
+
[1.8.1]: https://github.com/Automattic/jetpack-components/compare/1.8.0...1.8.1
|
|
1736
|
+
[1.8.0]: https://github.com/Automattic/jetpack-components/compare/1.7.0...1.8.0
|
|
1718
1737
|
[1.7.0]: https://github.com/Automattic/jetpack-components/compare/1.6.1...1.7.0
|
|
1719
1738
|
[1.6.1]: https://github.com/Automattic/jetpack-components/compare/1.6.0...1.6.1
|
|
1720
1739
|
[1.6.0]: https://github.com/Automattic/jetpack-components/compare/1.5.0...1.6.0
|
|
@@ -20,7 +20,7 @@ import styles from './style.module.scss';
|
|
|
20
20
|
* @param {AdminPageProps} props - Component properties.
|
|
21
21
|
* @return {ReactNode} AdminPage component.
|
|
22
22
|
*/
|
|
23
|
-
const AdminPage = ({ children, className,
|
|
23
|
+
const AdminPage = ({ children, className, showHeader = true, showFooter = true, showBackground = true, sandboxedDomain = '', apiRoot = '', apiNonce = '', optionalMenuItems, header, title, subTitle, logo, actions, breadcrumbs, tabs, showBottomBorder = true, }) => {
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
restApi.setApiRoot(apiRoot);
|
|
26
26
|
restApi.setApiNonce(apiNonce);
|
|
@@ -46,14 +46,13 @@ const AdminPage = ({ children, className, moduleName = 'Jetpack' /** "Jetpack" i
|
|
|
46
46
|
// Page's Header wraps this in an <h2> tag, so we just pass the content directly.
|
|
47
47
|
const composedTitle = title ? (_jsxs(HStack, { spacing: 2, justify: "left", children: [logo || _jsx(JetpackLogo, { showText: false, height: 20 }), _jsx("span", { children: title })
|
|
48
48
|
] })) : undefined;
|
|
49
|
-
const footer = showFooter && (_jsx(Container, { className: styles['admin-page-footer'], horizontalSpacing: 5, children: _jsx(Col, { children: _jsx(JetpackFooter, { moduleName: moduleName, moduleNameHref: moduleNameHref, menu: optionalMenuItems, useInternalLinks: useInternalLinks }) }) }));
|
|
50
49
|
// When title or breadcrumbs are provided, use admin-ui Page for the full page layout.
|
|
51
50
|
if (showHeader && (composedTitle || breadcrumbs)) {
|
|
52
|
-
return (_jsx("div", { className: rootClassName, children: _jsxs(Page, { ariaLabel: title, breadcrumbs: breadcrumbs, title: composedTitle, subTitle: subTitle, actions: actions, showSidebarToggle: false, children: [tabs, _jsx(Container, { fluid: true, horizontalSpacing: 0, children: _jsx(Col, { children: children }) }),
|
|
51
|
+
return (_jsx("div", { className: rootClassName, children: _jsxs(Page, { ariaLabel: title, breadcrumbs: breadcrumbs, title: composedTitle, subTitle: subTitle, actions: actions, showSidebarToggle: false, children: [tabs, _jsx(Container, { fluid: true, horizontalSpacing: 0, children: _jsx(Col, { children: children }) }), showFooter && _jsx(JetpackFooter, { menu: optionalMenuItems })] }) }));
|
|
53
52
|
}
|
|
54
53
|
// Legacy path: no title provided, render the classic header.
|
|
55
54
|
return (_jsxs("div", { className: rootClassName, children: [showHeader && (_jsx(Container, { horizontalSpacing: 5, children: _jsxs(Col, { className: clsx(styles['admin-page-header'], 'jp-admin-page-header'), children: [header ? header : _jsx(JetpackLogo, {}), sandboxedDomain && (_jsx("code", { className: styles['sandbox-domain-badge'], onClick: testConnection, onKeyDown: testConnection,
|
|
56
55
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
|
|
57
|
-
role: "button", tabIndex: 0, title: `Sandboxing via ${sandboxedDomain}. Click to test connection.`, children: "API Sandboxed" }))] }) })), _jsx(Container, { fluid: true, horizontalSpacing: 0, children: _jsx(Col, { children: children }) }),
|
|
56
|
+
role: "button", tabIndex: 0, title: `Sandboxing via ${sandboxedDomain}. Click to test connection.`, children: "API Sandboxed" }))] }) })), _jsx(Container, { fluid: true, horizontalSpacing: 0, children: _jsx(Col, { children: children }) }), showFooter && _jsx(JetpackFooter, { menu: optionalMenuItems })] }));
|
|
58
57
|
};
|
|
59
58
|
export default AdminPage;
|
|
@@ -5,10 +5,6 @@ export type AdminPageProps = {
|
|
|
5
5
|
* The page content
|
|
6
6
|
*/
|
|
7
7
|
children: ReactNode;
|
|
8
|
-
/**
|
|
9
|
-
* Name of the module, e.g. 'Jetpack Search' that will be displayed in the footer.
|
|
10
|
-
*/
|
|
11
|
-
moduleName?: string;
|
|
12
8
|
/**
|
|
13
9
|
* Whether or not to display the Header
|
|
14
10
|
*/
|
|
@@ -47,14 +43,6 @@ export type AdminPageProps = {
|
|
|
47
43
|
* Whether or not to display the Footer
|
|
48
44
|
*/
|
|
49
45
|
showFooter?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Whether or not to link to Jetpack plugin admin pages.
|
|
52
|
-
*/
|
|
53
|
-
useInternalLinks?: boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Link that the Footer Module name will link to (optional).
|
|
56
|
-
*/
|
|
57
|
-
moduleNameHref?: string;
|
|
58
46
|
/**
|
|
59
47
|
* Whether or not to display the Background Color
|
|
60
48
|
*/
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import './style.scss';
|
|
2
2
|
import type { JetpackFooterProps } from './types.ts';
|
|
3
3
|
import type { FC } from 'react';
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
JetpackNetworkAdminData?: {
|
|
7
|
+
sitesUrl: string;
|
|
8
|
+
settingsUrl: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
/**
|
|
5
13
|
* JetpackFooter component displays a tiny Jetpack logo with the product name on the left and the Automattic Airline "by line" on the right.
|
|
6
14
|
*
|
|
@@ -1,76 +1,43 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { isWpcomPlatformSite, getAdminUrl } from '@automattic/jetpack-script-data';
|
|
3
|
+
import { __ } from '@wordpress/i18n';
|
|
4
|
+
import { Stack, Text, Link } from '@wordpress/ui';
|
|
4
5
|
import clsx from 'clsx';
|
|
5
6
|
import { getRedirectUrl } from '../../index.js';
|
|
6
|
-
import getSiteAdminUrl from '../../tools/get-site-admin-url/index.js';
|
|
7
7
|
import AutomatticBylineLogo from '../automattic-byline-logo/index.js';
|
|
8
8
|
import './style.scss';
|
|
9
9
|
import JetpackLogo from '../jetpack-logo/index.js';
|
|
10
|
-
import useBreakpointMatch from '../layout/use-breakpoint-match/index.js';
|
|
11
|
-
const JetpackIcon = () => (_jsx(JetpackLogo, { logoColor: "#000", showText: false, height: 16, "aria-hidden": "true" }));
|
|
12
|
-
const ExternalIcon = () => (_jsxs(_Fragment, { children: [
|
|
13
|
-
_jsx(Icon, { icon: external, size: 16 }), _jsx("span", { className: "jp-dashboard-footer__accessible-external-link", children:
|
|
14
|
-
/* translators: accessibility text */
|
|
15
|
-
__('(opens in a new tab)', 'jetpack-components') })
|
|
16
|
-
] }));
|
|
17
10
|
/**
|
|
18
11
|
* JetpackFooter component displays a tiny Jetpack logo with the product name on the left and the Automattic Airline "by line" on the right.
|
|
19
12
|
*
|
|
20
13
|
* @param {JetpackFooterProps} props - Component properties.
|
|
21
14
|
* @return {ReactNode} JetpackFooter component.
|
|
22
15
|
*/
|
|
23
|
-
const JetpackFooter = ({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
label: _x('Privacy', 'Shorthand for Privacy Policy.', 'jetpack-components'),
|
|
40
|
-
title: __("Automattic's Privacy Policy", 'jetpack-components'),
|
|
41
|
-
href: useInternalLinks
|
|
42
|
-
? new URL('admin.php?page=jetpack#/privacy', siteAdminUrl).href
|
|
43
|
-
: getRedirectUrl('a8c-privacy'),
|
|
44
|
-
target: useInternalLinks ? '_self' : '_blank',
|
|
45
|
-
onClick: onPrivacyClick,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
label: _x('Terms', 'Shorthand for Terms of Service.', 'jetpack-components'),
|
|
49
|
-
title: __('WordPress.com Terms of Service', 'jetpack-components'),
|
|
50
|
-
href: getRedirectUrl('wpcom-tos'),
|
|
51
|
-
target: '_blank',
|
|
52
|
-
onClick: onTermsClick,
|
|
53
|
-
},
|
|
54
|
-
];
|
|
16
|
+
const JetpackFooter = ({ className, menu, ...otherProps }) => {
|
|
17
|
+
let items = [];
|
|
18
|
+
if (!isWpcomPlatformSite() && !window?.JetpackNetworkAdminData) {
|
|
19
|
+
items = [
|
|
20
|
+
{
|
|
21
|
+
label: __('Products', 'jetpack-components'),
|
|
22
|
+
href: getAdminUrl('admin.php?page=my-jetpack#/products'),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: __('Help', 'jetpack-components'),
|
|
26
|
+
href: getAdminUrl('admin.php?page=my-jetpack#/help'),
|
|
27
|
+
},
|
|
28
|
+
...items,
|
|
29
|
+
];
|
|
30
|
+
}
|
|
55
31
|
if (menu) {
|
|
56
32
|
items = [...items, ...menu];
|
|
57
33
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
'is-md': isMd,
|
|
63
|
-
'is-lg': isLg,
|
|
64
|
-
}, className), "aria-label": __('Jetpack', 'jetpack-components'), role: "contentinfo", ...otherProps, children: _jsxs("ul", { children: [
|
|
65
|
-
_jsx("li", { className: "jp-dashboard-footer__jp-item", children: moduleNameHref ? (_jsx("a", { href: moduleNameHref, children: jetpackItemContent })) : (jetpackItemContent) }), items.map(item => {
|
|
34
|
+
return (_jsxs(Stack, { render: _jsx("footer", {}), className: clsx('jetpack-footer', className), "aria-label": __('Jetpack', 'jetpack-components'), role: "contentinfo", direction: "row", justify: "flex-start", align: "center", wrap: "wrap", gap: "xl", ...otherProps, children: [
|
|
35
|
+
_jsxs(Stack, { className: "jetpack-footer__logo", direction: "row", gap: "sm", align: "center", children: [
|
|
36
|
+
_jsx(JetpackLogo, { showText: false, height: 16, "aria-hidden": "true" }), _jsx(Text, { variant: "body-md", children: "Jetpack" })
|
|
37
|
+
] }), _jsx(Stack, { render: _jsx("ul", {}), direction: "row", gap: "lg", wrap: "wrap", children: items.map(item => {
|
|
66
38
|
const isButton = item.role === 'button';
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}), role: item.role, rel: isExternalLink ? 'noopener noreferrer' : undefined, tabIndex: isButton ? 0 : undefined, children: [item.label, isExternalLink && _jsx(ExternalIcon, {})] }) }, item.label));
|
|
71
|
-
}), _jsx("li", { className: "jp-dashboard-footer__a8c-item", children: _jsx("a", { href: useInternalLinks
|
|
72
|
-
? new URL('admin.php?page=jetpack_about', siteAdminUrl).href
|
|
73
|
-
: getRedirectUrl('a8c-about'), "aria-label": __('An Automattic Airline', 'jetpack-components'), children: _jsx(AutomatticBylineLogo, { "aria-hidden": "true" }) }) })
|
|
74
|
-
] }) }));
|
|
39
|
+
return (_jsx("li", { children: _jsx(Text, { variant: "body-sm", className: "jetpack-footer__menu-item", render: isButton ? (_jsx(Link, { render: _jsx(Text, { variant: "body-md", render: _jsx("span", {}) }), tone: "neutral", variant: "default", role: item.role, tabIndex: 0, onClick: item.onClick || undefined, onKeyDown: item.onKeyDown || undefined })) : (_jsx(Link, { render: _jsx(Text, { variant: "body-md", render: _jsx("a", {}) }), tone: "neutral", variant: "default", href: item.href || '', title: item.title || '', role: item.role, onClick: item.onClick || undefined, onKeyDown: item.onKeyDown || undefined })), children: item.label }) }, item.label));
|
|
40
|
+
}) }), _jsx("a", { className: "jetpack-footer__a8c", href: getRedirectUrl('a8c-about'), rel: "noopener noreferrer", target: "_blank", children: _jsx(AutomatticBylineLogo, { height: 8 }) })
|
|
41
|
+
] }));
|
|
75
42
|
};
|
|
76
43
|
export default JetpackFooter;
|
|
@@ -1,119 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
@use "sass:meta";
|
|
2
|
+
@include meta.load-css("pkg:@wordpress/theme/design-tokens.css");
|
|
3
|
+
|
|
4
|
+
.jetpack-footer {
|
|
5
|
+
border-top: var(--wpds-border-width-xs, 1px) solid var(--wpds-color-stroke-surface-neutral-weak, #e0e0e0);
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
font-size: var(--wpds-font-size-md, 13px);
|
|
8
|
+
padding: var(--wpds-dimension-padding-xl) var(--wpds-dimension-padding-2xl);
|
|
7
9
|
width: 100%;
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
font-size: var(--font-body-extra-small);
|
|
12
|
-
line-height: 1.333;
|
|
13
|
-
|
|
14
|
-
a {
|
|
15
|
-
text-decoration: none;
|
|
11
|
+
.jetpack-footer__menu-item {
|
|
16
12
|
|
|
17
13
|
&:any-link,
|
|
18
14
|
&[role="button"] {
|
|
19
|
-
color:
|
|
15
|
+
color: var(--wpds-color-fg-interactive-neutral-weak);
|
|
16
|
+
cursor: pointer;
|
|
17
|
+
text-decoration: none;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
&:hover {
|
|
23
21
|
text-decoration: underline;
|
|
24
|
-
text-decoration-thickness: 1.5px;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
&:focus {
|
|
28
|
-
box-shadow: none;
|
|
29
|
-
outline-width: 0;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
&:focus-visible {
|
|
33
|
-
border-radius: 2px;
|
|
34
|
-
box-shadow: none;
|
|
35
|
-
outline: 1.5px solid currentColor;
|
|
36
|
-
outline-offset: 3px;
|
|
37
22
|
}
|
|
38
23
|
}
|
|
39
24
|
|
|
40
|
-
&.is-sm {
|
|
41
|
-
|
|
42
|
-
> ul {
|
|
43
|
-
flex-direction: column;
|
|
44
|
-
align-items: flex-start;
|
|
45
|
-
gap: 0.125rem;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
&.is-md {
|
|
50
|
-
flex-direction: column;
|
|
51
|
-
align-items: flex-start;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
25
|
> ul {
|
|
55
|
-
|
|
56
|
-
flex-wrap: wrap;
|
|
57
|
-
align-items: center;
|
|
58
|
-
gap: 1rem;
|
|
59
|
-
|
|
60
|
-
width: 100%;
|
|
26
|
+
list-style: none;
|
|
61
27
|
margin: 0;
|
|
62
28
|
padding: 0;
|
|
63
29
|
|
|
64
|
-
list-style: none;
|
|
65
|
-
|
|
66
30
|
> li {
|
|
67
|
-
margin
|
|
68
|
-
|
|
69
|
-
> a {
|
|
70
|
-
display: flex;
|
|
71
|
-
align-items: center;
|
|
72
|
-
gap: 0.25rem;
|
|
73
|
-
|
|
74
|
-
min-height: 44px; // Minimum target area size
|
|
75
|
-
}
|
|
31
|
+
margin: 0;
|
|
76
32
|
}
|
|
77
33
|
}
|
|
78
34
|
}
|
|
79
35
|
|
|
80
|
-
.
|
|
81
|
-
|
|
82
|
-
clip-path: inset(50%);
|
|
83
|
-
height: 1px;
|
|
84
|
-
margin: -1px;
|
|
85
|
-
overflow: hidden;
|
|
86
|
-
padding: 0;
|
|
87
|
-
position: absolute;
|
|
88
|
-
width: 1px;
|
|
89
|
-
overflow-wrap: normal;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.jp-dashboard-footer__jp-item {
|
|
93
|
-
padding-inline-end: 1rem;
|
|
94
|
-
|
|
95
|
-
font-weight: 600;
|
|
96
|
-
|
|
97
|
-
.jp-dashboard-footer.is-sm & {
|
|
98
|
-
padding-bottom: 1rem;
|
|
99
|
-
}
|
|
36
|
+
.jetpack-footer__logo {
|
|
37
|
+
flex-shrink: 0;
|
|
100
38
|
}
|
|
101
39
|
|
|
102
|
-
.
|
|
40
|
+
a.jetpack-footer__a8c {
|
|
103
41
|
|
|
104
|
-
|
|
42
|
+
@media (min-width: 480px) {
|
|
105
43
|
margin-inline-start: auto;
|
|
106
44
|
}
|
|
107
45
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.jp-dashboard-footer__jp-item,
|
|
114
|
-
.jp-dashboard-footer__a8c-item {
|
|
115
|
-
|
|
116
|
-
> a {
|
|
117
|
-
text-decoration: none; // Logos typically have no hover effect
|
|
46
|
+
svg {
|
|
47
|
+
fill: var(--wpds-color-fg-interactive-neutral-weak);
|
|
118
48
|
}
|
|
119
49
|
}
|
|
@@ -1,47 +1,18 @@
|
|
|
1
1
|
export type JetpackFooterMenuItem = {
|
|
2
|
-
href
|
|
2
|
+
href?: string;
|
|
3
3
|
label: string;
|
|
4
4
|
onClick?: () => void;
|
|
5
5
|
onKeyDown?: () => void;
|
|
6
|
-
target?: string;
|
|
7
6
|
title?: string;
|
|
8
7
|
role?: string;
|
|
9
8
|
};
|
|
10
9
|
export type JetpackFooterProps = {
|
|
11
10
|
/**
|
|
12
|
-
*
|
|
13
|
-
*/
|
|
14
|
-
moduleName?: string;
|
|
15
|
-
/**
|
|
16
|
-
* additional className of the wrapper, `jp-dashboard-footer` always included.
|
|
11
|
+
* Additional className of the wrapper, `jetpack-footer` always included.
|
|
17
12
|
*/
|
|
18
13
|
className?: string;
|
|
19
14
|
/**
|
|
20
|
-
*
|
|
21
|
-
*/
|
|
22
|
-
moduleNameHref?: string;
|
|
23
|
-
/**
|
|
24
|
-
* Navigation menu to display in the footer.
|
|
15
|
+
* Additional links to display in the footer.
|
|
25
16
|
*/
|
|
26
17
|
menu?: JetpackFooterMenuItem[];
|
|
27
|
-
/**
|
|
28
|
-
* Whether to enable Jetpack admin links.
|
|
29
|
-
*/
|
|
30
|
-
useInternalLinks?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* URL of the site WP Admin.
|
|
33
|
-
*/
|
|
34
|
-
siteAdminUrl?: string;
|
|
35
|
-
/**
|
|
36
|
-
* Function called when the About link is clicked.
|
|
37
|
-
*/
|
|
38
|
-
onAboutClick?: () => void;
|
|
39
|
-
/**
|
|
40
|
-
* Function called when the Privacy link is clicked.
|
|
41
|
-
*/
|
|
42
|
-
onPrivacyClick?: () => void;
|
|
43
|
-
/**
|
|
44
|
-
* Function called when the Terms link is clicked.
|
|
45
|
-
*/
|
|
46
|
-
onTermsClick?: () => void;
|
|
47
18
|
};
|
|
@@ -11,6 +11,14 @@ export type HeaderProps = {
|
|
|
11
11
|
* Optional icon to display in the header.
|
|
12
12
|
*/
|
|
13
13
|
icon?: React.ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Optional callback to run before navigating back.
|
|
16
|
+
*/
|
|
17
|
+
onGoBack?: VoidFunction;
|
|
18
|
+
/**
|
|
19
|
+
* Optional callback to run before closing the modal.
|
|
20
|
+
*/
|
|
21
|
+
onClose?: VoidFunction;
|
|
14
22
|
};
|
|
15
23
|
/**
|
|
16
24
|
* Renders a header for the NavigatorModal.
|
|
@@ -18,4 +26,4 @@ export type HeaderProps = {
|
|
|
18
26
|
*
|
|
19
27
|
* @return component
|
|
20
28
|
*/
|
|
21
|
-
export declare function Header({ icon, title, isScreenLocked }: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export declare function Header({ icon, title, isScreenLocked, onGoBack: onGoBackProp, onClose: onCloseProp }: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,13 +10,18 @@ import { NavigatorModalContext } from './context.js';
|
|
|
10
10
|
*
|
|
11
11
|
* @return component
|
|
12
12
|
*/
|
|
13
|
-
export function Header({ icon, title, isScreenLocked }) {
|
|
13
|
+
export function Header({ icon, title, isScreenLocked, onGoBack: onGoBackProp, onClose: onCloseProp, }) {
|
|
14
14
|
const context = useContext(NavigatorModalContext);
|
|
15
15
|
const navigator = useNavigator();
|
|
16
16
|
const onGoBack = useCallback(() => {
|
|
17
|
+
onGoBackProp?.();
|
|
17
18
|
navigator.goBack();
|
|
18
|
-
}, [navigator]);
|
|
19
|
+
}, [navigator, onGoBackProp]);
|
|
20
|
+
const onCloseModal = useCallback(() => {
|
|
21
|
+
onCloseProp?.();
|
|
22
|
+
context.onClose?.();
|
|
23
|
+
}, [onCloseProp, context]);
|
|
19
24
|
return (_jsxs("div", { className: "jp-navigator-modal__header", children: [
|
|
20
25
|
_jsxs("div", { className: "jp-navigator-modal__title-wrap", children: [!isScreenLocked ? (_jsx(Button, { label: __('Go back', 'jetpack-components'), icon: isRTL() ? chevronRight : chevronLeft, onClick: onGoBack, variant: "tertiary", size: "compact" })) : null, icon, _jsx("h1", { children: title })
|
|
21
|
-
] }), context.isDismissible ? (_jsx(Button, { size: "compact", onClick:
|
|
26
|
+
] }), context.isDismissible ? (_jsx(Button, { size: "compact", onClick: onCloseModal, icon: close, label: __('Close', 'jetpack-components'), variant: "tertiary" })) : null] }));
|
|
22
27
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { Navigator } from '@wordpress/components';
|
|
2
2
|
import { FooterProps } from './footer.tsx';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* The title of the screen.
|
|
6
|
-
*/
|
|
7
|
-
title?: string;
|
|
3
|
+
import { HeaderProps } from './header.tsx';
|
|
4
|
+
export type ScreenProps = Omit<React.ComponentProps<typeof Navigator.Screen>, 'content' | 'children'> & Omit<HeaderProps, 'icon'> & {
|
|
8
5
|
/**
|
|
9
6
|
* Optional icon to display in the header.
|
|
10
7
|
*/
|
|
@@ -17,12 +14,6 @@ export type ScreenProps = Omit<React.ComponentProps<typeof Navigator.Screen>, 'c
|
|
|
17
14
|
* The sidebar content
|
|
18
15
|
*/
|
|
19
16
|
sidebar?: React.ReactNode;
|
|
20
|
-
/**
|
|
21
|
-
* Whether the screen is locked or has a parent screen.
|
|
22
|
-
*
|
|
23
|
-
* When it's locked, it means there will be no navigation back to a previous screen.
|
|
24
|
-
*/
|
|
25
|
-
isScreenLocked?: boolean;
|
|
26
17
|
/**
|
|
27
18
|
* The footer content
|
|
28
19
|
*/
|
|
@@ -51,4 +42,4 @@ export type ScreenProps = Omit<React.ComponentProps<typeof Navigator.Screen>, 'c
|
|
|
51
42
|
*
|
|
52
43
|
* @return The rendered screen.
|
|
53
44
|
*/
|
|
54
|
-
export declare function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, footerContent, footerActions, children, content, ...props }: ScreenProps): import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
export declare function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, onGoBack, onClose, footerContent, footerActions, children, content, ...props }: ScreenProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,9 +10,9 @@ import { Header } from './header.js';
|
|
|
10
10
|
*
|
|
11
11
|
* @return The rendered screen.
|
|
12
12
|
*/
|
|
13
|
-
export function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, footerContent, footerActions, children, content, ...props }) {
|
|
13
|
+
export function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, onGoBack, onClose, footerContent, footerActions, children, content, ...props }) {
|
|
14
14
|
const hasFooter = Boolean(footerContent || (footerActions && footerActions.length));
|
|
15
15
|
return (_jsx(Navigator.Screen, { path: path, className: clsx('jp-navigator-modal__screen', className), ...props, children: _jsxs(Flex, { direction: "column", gap: 0, children: [
|
|
16
|
-
_jsx(Header, { title: title, isScreenLocked: isScreenLocked, icon: headerIcon }), _jsxs(Flex, { gap: 0, align: "start", className: "jp-navigator-modal__body", children: [sidebar ? _jsx("div", { className: "jp-navigator-modal__sidebar", children: sidebar }) : null, _jsx("div", { className: "jp-navigator-modal__content", children: content ?? children })
|
|
16
|
+
_jsx(Header, { title: title, isScreenLocked: isScreenLocked, icon: headerIcon, onGoBack: onGoBack, onClose: onClose }), _jsxs(Flex, { gap: 0, align: "start", className: "jp-navigator-modal__body", children: [sidebar ? _jsx("div", { className: "jp-navigator-modal__sidebar", children: sidebar }) : null, _jsx("div", { className: "jp-navigator-modal__content", children: content ?? children })
|
|
17
17
|
] }), hasFooter ? (_jsx(Footer, { actions: footerActions, isScreenLocked: isScreenLocked, children: footerContent })) : null] }) }));
|
|
18
18
|
}
|
|
@@ -26,11 +26,8 @@ import type { FC, ReactNode } from 'react';
|
|
|
26
26
|
const AdminPage: FC< AdminPageProps > = ( {
|
|
27
27
|
children,
|
|
28
28
|
className,
|
|
29
|
-
moduleName = 'Jetpack' /** "Jetpack" is a product name, do not translate. */,
|
|
30
|
-
moduleNameHref,
|
|
31
29
|
showHeader = true,
|
|
32
30
|
showFooter = true,
|
|
33
|
-
useInternalLinks = false,
|
|
34
31
|
showBackground = true,
|
|
35
32
|
sandboxedDomain = '',
|
|
36
33
|
apiRoot = '',
|
|
@@ -82,19 +79,6 @@ const AdminPage: FC< AdminPageProps > = ( {
|
|
|
82
79
|
</HStack>
|
|
83
80
|
) : undefined;
|
|
84
81
|
|
|
85
|
-
const footer = showFooter && (
|
|
86
|
-
<Container className={ styles[ 'admin-page-footer' ] } horizontalSpacing={ 5 }>
|
|
87
|
-
<Col>
|
|
88
|
-
<JetpackFooter
|
|
89
|
-
moduleName={ moduleName }
|
|
90
|
-
moduleNameHref={ moduleNameHref }
|
|
91
|
-
menu={ optionalMenuItems }
|
|
92
|
-
useInternalLinks={ useInternalLinks }
|
|
93
|
-
/>
|
|
94
|
-
</Col>
|
|
95
|
-
</Container>
|
|
96
|
-
);
|
|
97
|
-
|
|
98
82
|
// When title or breadcrumbs are provided, use admin-ui Page for the full page layout.
|
|
99
83
|
if ( showHeader && ( composedTitle || breadcrumbs ) ) {
|
|
100
84
|
return (
|
|
@@ -111,7 +95,7 @@ const AdminPage: FC< AdminPageProps > = ( {
|
|
|
111
95
|
<Container fluid horizontalSpacing={ 0 }>
|
|
112
96
|
<Col>{ children }</Col>
|
|
113
97
|
</Container>
|
|
114
|
-
{
|
|
98
|
+
{ showFooter && <JetpackFooter menu={ optionalMenuItems } /> }
|
|
115
99
|
</Page>
|
|
116
100
|
</div>
|
|
117
101
|
);
|
|
@@ -143,7 +127,7 @@ const AdminPage: FC< AdminPageProps > = ( {
|
|
|
143
127
|
<Container fluid horizontalSpacing={ 0 }>
|
|
144
128
|
<Col>{ children }</Col>
|
|
145
129
|
</Container>
|
|
146
|
-
{
|
|
130
|
+
{ showFooter && <JetpackFooter menu={ optionalMenuItems } /> }
|
|
147
131
|
</div>
|
|
148
132
|
);
|
|
149
133
|
};
|
|
@@ -7,11 +7,6 @@ export type AdminPageProps = {
|
|
|
7
7
|
*/
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* Name of the module, e.g. 'Jetpack Search' that will be displayed in the footer.
|
|
12
|
-
*/
|
|
13
|
-
moduleName?: string;
|
|
14
|
-
|
|
15
10
|
/**
|
|
16
11
|
* Whether or not to display the Header
|
|
17
12
|
*/
|
|
@@ -59,16 +54,6 @@ export type AdminPageProps = {
|
|
|
59
54
|
*/
|
|
60
55
|
showFooter?: boolean;
|
|
61
56
|
|
|
62
|
-
/**
|
|
63
|
-
* Whether or not to link to Jetpack plugin admin pages.
|
|
64
|
-
*/
|
|
65
|
-
useInternalLinks?: boolean;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Link that the Footer Module name will link to (optional).
|
|
69
|
-
*/
|
|
70
|
-
moduleNameHref?: string;
|
|
71
|
-
|
|
72
57
|
/**
|
|
73
58
|
* Whether or not to display the Background Color
|
|
74
59
|
*/
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
# Jetpack Admin Footer
|
|
2
2
|
|
|
3
3
|
Component that renders Jetpack Admin Footer.
|
|
4
|
-
It takes moduleName and URL to show in the footer.
|
|
5
4
|
|
|
6
|
-
## How to use
|
|
5
|
+
## How to use
|
|
6
|
+
|
|
7
|
+
Note that most of the time you would just use `admin-page` component, which includes the footer. If you must use footer independently, basic usage is:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
<JetpackFooter />
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
In special occasions you might want to use custom className or additional menu links:
|
|
7
14
|
|
|
8
15
|
```js
|
|
9
|
-
|
|
16
|
+
const menu = [
|
|
17
|
+
{
|
|
18
|
+
label: "Support",
|
|
19
|
+
href="https://wordpress.com/support/",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: "Chat",
|
|
23
|
+
onClick: () => {},
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
<JetpackFooter menu={ menu } className="my-footer" />
|
|
10
28
|
```
|
|
11
29
|
|
|
12
30
|
## Props
|
|
13
31
|
|
|
14
|
-
- `className`: String - (default: `
|
|
15
|
-
- `
|
|
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.
|
|
32
|
+
- `className`: String - (default: `jetpack-footer`) the additional class name set on the element.
|
|
33
|
+
- `menu`: JetpackFooterMenuItem[] - (default: `undefined`) set additional menu items to be rendered in the footer.
|