@automattic/jetpack-components 1.4.15 → 1.5.0

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/build/components/action-button/index.d.ts +4 -14
  3. package/build/components/action-button/index.js +2 -2
  4. package/build/components/action-popover/index.js +10 -6
  5. package/build/components/admin-page/index.d.ts +1 -0
  6. package/build/components/admin-page/index.js +26 -6
  7. package/build/components/admin-page/style.module.scss +26 -0
  8. package/build/components/admin-page/types.d.ts +28 -1
  9. package/build/components/alert/index.js +2 -1
  10. package/build/components/automattic-byline-logo/index.js +3 -1
  11. package/build/components/automattic-for-agencies-logo/index.d.ts +1 -1
  12. package/build/components/automattic-icon-logo/index.d.ts +1 -1
  13. package/build/components/automattic-icon-logo/index.js +3 -1
  14. package/build/components/boost-score-bar/index.js +7 -2
  15. package/build/components/boost-score-graph/background.js +13 -1
  16. package/build/components/boost-score-graph/index.js +3 -3
  17. package/build/components/boost-score-graph/tooltip.js +23 -3
  18. package/build/components/boost-score-graph/tooltips-plugin.js +1 -1
  19. package/build/components/boost-score-graph/uplot-line-chart.js +7 -7
  20. package/build/components/button/index.d.ts +1 -1
  21. package/build/components/button/index.js +5 -3
  22. package/build/components/contextual-upgrade-trigger/index.js +8 -3
  23. package/build/components/copy-to-clipboard/index.js +2 -2
  24. package/build/components/decorative-card/index.js +2 -1
  25. package/build/components/details-viewer/index.js +5 -3
  26. package/build/components/dialog/index.js +7 -5
  27. package/build/components/diff-viewer/index.js +12 -6
  28. package/build/components/donut-meter/index.js +4 -2
  29. package/build/components/dot-pager/index.js +4 -2
  30. package/build/components/global-notices/global-notices.js +1 -1
  31. package/build/components/global-notices/index.js +2 -2
  32. package/build/components/gridicon/index.js +4 -2
  33. package/build/components/icon-tooltip/index.js +5 -3
  34. package/build/components/icons/index.js +12 -4
  35. package/build/components/jetpack-footer/index.js +17 -12
  36. package/build/components/jetpack-logo/index.js +5 -2
  37. package/build/components/jetpack-protect-logo/index.js +5 -2
  38. package/build/components/jetpack-search-logo/index.js +6 -2
  39. package/build/components/jetpack-vaultpress-backup-logo/index.js +7 -2
  40. package/build/components/jetpack-videopress-logo/index.js +5 -2
  41. package/build/components/layout/container/style.module.scss +2 -2
  42. package/build/components/layout/use-breakpoint-match/index.d.ts +1 -3
  43. package/build/components/loading-placeholder/index.d.ts +1 -1
  44. package/build/components/marked-lines/index.js +5 -3
  45. package/build/components/navigator-modal/footer.js +3 -2
  46. package/build/components/navigator-modal/header.js +4 -2
  47. package/build/components/navigator-modal/index.js +16 -5
  48. package/build/components/navigator-modal/screen.js +5 -3
  49. package/build/components/notice/index.js +2 -1
  50. package/build/components/popover/index.js +3 -1
  51. package/build/components/pricing-card/index.js +9 -3
  52. package/build/components/pricing-table/index.js +18 -10
  53. package/build/components/product-offer/icons-card.js +3 -2
  54. package/build/components/product-offer/index.js +14 -9
  55. package/build/components/product-offer/product-offer-header.js +4 -2
  56. package/build/components/product-price/index.js +15 -7
  57. package/build/components/product-price/price.js +4 -3
  58. package/build/components/record-meter-bar/index.js +20 -5
  59. package/build/components/spinner/index.d.ts +8 -8
  60. package/build/components/split-button/index.js +3 -1
  61. package/build/components/stat-card/index.js +5 -2
  62. package/build/components/status/index.js +4 -2
  63. package/build/components/swipeable/index.d.ts +3 -3
  64. package/build/components/swipeable/index.js +8 -4
  65. package/build/components/terms-of-service/index.js +2 -2
  66. package/build/components/testimonials/index.js +2 -2
  67. package/build/components/testimonials/testimonial.js +11 -1
  68. package/build/components/text/index.js +2 -2
  69. package/build/components/upsell-banner/index.js +7 -2
  70. package/build/components/zendesk-chat/index.js +1 -1
  71. package/build/index.js +66 -66
  72. package/components/admin-page/index.tsx +65 -13
  73. package/components/admin-page/style.module.scss +26 -0
  74. package/components/admin-page/types.ts +34 -1
  75. package/components/button/index.tsx +1 -1
  76. package/components/jetpack-footer/index.tsx +1 -1
  77. package/components/layout/container/style.module.scss +2 -2
  78. package/components/navigator-modal/index.tsx +19 -4
  79. package/package.json +24 -23
  80. package/tools/copy-scss-to-build.mjs +1 -1
@@ -3,8 +3,8 @@ import { ExternalLink } from '@wordpress/components';
3
3
  import { createInterpolateElement } from '@wordpress/element';
4
4
  import { __, sprintf } from '@wordpress/i18n';
5
5
  import clsx from 'clsx';
6
- import { getRedirectUrl } from "../../index.js";
7
- import Text from "../text/index.js";
6
+ import { getRedirectUrl } from '../../index.js';
7
+ import Text from '../text/index.js';
8
8
  import './styles.scss';
9
9
  const TermsOfService = ({ className, multipleButtons, agreeButtonLabel, isTextOnly, ...textProps }) => {
10
10
  const getTOSContent = () => {
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useCallback } from '@wordpress/element';
3
- import Gridicon from "../gridicon/index.js";
4
- import { Testimonial } from "./testimonial.js";
3
+ import Gridicon from '../gridicon/index.js';
4
+ import { Testimonial } from './testimonial.js';
5
5
  const Testimonials = ({ testimonials }) => {
6
6
  const [currentTestimonialIndex, setcurrentTestimonialIndex] = useState(0);
7
7
  const incrementTestimonial = useCallback(() => {
@@ -2,6 +2,16 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import clsx from 'clsx';
3
3
  import './style.scss';
4
4
  const Testimonial = ({ quote, author, profession, img, hidden }) => {
5
- return (_jsxs("div", { className: clsx('testimonial', hidden ? 'hidden' : 'show'), children: [_jsx("img", { className: "testimonial__author-img", src: img, alt: author }), _jsxs("div", { className: "testimonial__content", children: [_jsxs("svg", { width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "testimonial__quote-icon", children: [_jsx("path", { d: "M14.6667 24L6.66675 24L6.66675 16L14.6667 16L14.6667 24Z", fill: "#1E1E1E" }), _jsx("path", { d: "M26.6667 24L18.6667 24L18.6667 16L26.6667 16L26.6667 24Z", fill: "#1E1E1E" }), _jsx("path", { d: "M6.66675 24.0001C6.66675 19.5573 6.66675 14.9337 6.66675 10.6686C6.66675 6.40254 10.0001 6.67016 12.0001 6.66987", stroke: "#1E1E1E", strokeWidth: "1.5" }), _jsx("path", { d: "M18.6668 24.0001C18.6667 19.5573 18.6667 14.9337 18.6667 10.6686C18.6667 6.40254 22.0001 6.67016 24.0001 6.66987", stroke: "#1E1E1E", strokeWidth: "1.5" })] }), _jsxs("div", { className: "testimonial__text-block", children: [_jsxs("blockquote", { className: "testimonial__quote", children: ["\u201C", quote, "\u201D"] }), _jsxs("figcaption", { children: [_jsx("span", { className: "testimonial__author", children: author }), _jsx("span", { className: "testimonial__profession", children: profession })] })] })] })] }, author));
5
+ return (_jsxs("div", { className: clsx('testimonial', hidden ? 'hidden' : 'show'), children: [
6
+ _jsx("img", { className: "testimonial__author-img", src: img, alt: author }), _jsxs("div", { className: "testimonial__content", children: [
7
+ _jsxs("svg", { width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "testimonial__quote-icon", children: [
8
+ _jsx("path", { d: "M14.6667 24L6.66675 24L6.66675 16L14.6667 16L14.6667 24Z", fill: "#1E1E1E" }), _jsx("path", { d: "M26.6667 24L18.6667 24L18.6667 16L26.6667 16L26.6667 24Z", fill: "#1E1E1E" }), _jsx("path", { d: "M6.66675 24.0001C6.66675 19.5573 6.66675 14.9337 6.66675 10.6686C6.66675 6.40254 10.0001 6.67016 12.0001 6.66987", stroke: "#1E1E1E", strokeWidth: "1.5" }), _jsx("path", { d: "M18.6668 24.0001C18.6667 19.5573 18.6667 14.9337 18.6667 10.6686C18.6667 6.40254 22.0001 6.67016 24.0001 6.66987", stroke: "#1E1E1E", strokeWidth: "1.5" })
9
+ ] }), _jsxs("div", { className: "testimonial__text-block", children: [
10
+ _jsxs("blockquote", { className: "testimonial__quote", children: ["\u201C", quote, "\u201D"] }), _jsxs("figcaption", { children: [
11
+ _jsx("span", { className: "testimonial__author", children: author }), _jsx("span", { className: "testimonial__profession", children: profession })
12
+ ] })
13
+ ] })
14
+ ] })
15
+ ] }, author));
6
16
  };
7
17
  export { Testimonial };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import clsx from 'clsx';
3
3
  import { forwardRef, useMemo } from 'react';
4
- import { BOX_MODEL_VALUES, VARIANTS_MAPPING } from "./constants.js";
4
+ import { BOX_MODEL_VALUES, VARIANTS_MAPPING } from './constants.js';
5
5
  import styles from './style.module.scss';
6
6
  /**
7
7
  * Text component.
@@ -50,4 +50,4 @@ export const H3 = ({ children, weight = 'bold', ...componentProps }) => {
50
50
  * @return {ReactElement} - JSX.Element
51
51
  */
52
52
  export const Title = ({ children, size = 'medium', ...componentProps }) => (_jsx(Text, { variant: `title-${size}`, mb: 1, ...componentProps, children: children }));
53
- export * from "./constants.js";
53
+ export * from './constants.js';
@@ -14,8 +14,13 @@ import './style.scss';
14
14
  */
15
15
  const UpsellBanner = props => {
16
16
  const { icon, title, description, primaryCtaLabel, primaryCtaURL, primaryCtaIsExternalLink, primaryCtaOnClick, secondaryCtaLabel, secondaryCtaURL, secondaryCtaIsExternalLink, secondaryCtaOnClick, } = props;
17
- return (_jsx(Card, { isRounded: true, size: "large", children: _jsxs(CardBody, { className: "upsell-banner", size: "large", children: [icon && (_jsx("div", { className: "upsell-banner--icon", children: _jsx("img", { src: icon, alt: "" }) })), _jsxs("div", { className: "upsell-banner--content", children: [_jsxs("div", { className: "upsell-banner--content-info", children: [_jsx("h3", { children: title }), _jsx("p", { children: createInterpolateElement(description, {
17
+ return (_jsx(Card, { isRounded: true, size: "large", children: _jsxs(CardBody, { className: "upsell-banner", size: "large", children: [icon && (_jsx("div", { className: "upsell-banner--icon", children: _jsx("img", { src: icon, alt: "" }) })), _jsxs("div", { className: "upsell-banner--content", children: [
18
+ _jsxs("div", { className: "upsell-banner--content-info", children: [
19
+ _jsx("h3", { children: title }), _jsx("p", { children: createInterpolateElement(description, {
18
20
  br: _jsx("br", {}),
19
- }) })] }), _jsxs("div", { className: "upsell-banner--content-cta", children: [secondaryCtaLabel && secondaryCtaURL && (_jsx(Button, { className: "upsell-banner--content-cta-button secondary", href: secondaryCtaURL, onClick: secondaryCtaOnClick ?? undefined, isExternalLink: secondaryCtaIsExternalLink, children: secondaryCtaLabel })), primaryCtaLabel && primaryCtaURL && (_jsx(Button, { className: "upsell-banner--content-cta-button primary", href: primaryCtaURL, onClick: primaryCtaOnClick ?? undefined, isExternalLink: primaryCtaIsExternalLink, children: primaryCtaLabel }))] })] })] }) }));
21
+ }) })
22
+ ] }), _jsxs("div", { className: "upsell-banner--content-cta", children: [secondaryCtaLabel && secondaryCtaURL && (_jsx(Button, { className: "upsell-banner--content-cta-button secondary", href: secondaryCtaURL, onClick: secondaryCtaOnClick ?? undefined, isExternalLink: secondaryCtaIsExternalLink, children: secondaryCtaLabel })), primaryCtaLabel && primaryCtaURL && (_jsx(Button, { className: "upsell-banner--content-cta-button primary", href: primaryCtaURL, onClick: primaryCtaOnClick ?? undefined, isExternalLink: primaryCtaIsExternalLink, children: primaryCtaLabel }))] })
23
+ ] })
24
+ ] }) }));
20
25
  };
21
26
  export default UpsellBanner;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useCallback } from 'react';
3
- import { chatKey } from "./constants.js";
3
+ import { chatKey } from './constants.js';
4
4
  export const ZendeskChat = ({ jwt_token }) => {
5
5
  const authenticateUser = useCallback(() => {
6
6
  if (typeof window !== 'undefined' && typeof window.zE === 'function') {
package/build/index.js CHANGED
@@ -12,69 +12,69 @@ GNU General Public License for more details.
12
12
  You should have received a copy of the GNU General Public License
13
13
  along with this program; if not, see <https://www.gnu.org/licenses/>.
14
14
  */
15
- export { default as JetpackLogo } from "./components/jetpack-logo/index.js";
16
- export { default as JetpackSearchLogo } from "./components/jetpack-search-logo/index.js";
17
- export { default as JetpackProtectLogo } from "./components/jetpack-protect-logo/index.js";
18
- export { default as JetpackVaultPressBackupLogo } from "./components/jetpack-vaultpress-backup-logo/index.js";
19
- export { default as JetpackVideoPressLogo } from "./components/jetpack-videopress-logo/index.js";
20
- export { default as getRedirectUrl } from "./tools/jp-redirect/index.js";
21
- export { default as getProductCheckoutUrl } from "./tools/get-product-checkout-url/index.js";
22
- export { isFirstMonthTrial } from "./tools/pricing-utils/index.js";
23
- export { default as AutomatticBylineLogo } from "./components/automattic-byline-logo/index.js";
24
- export { default as AutomatticIconLogo } from "./components/automattic-icon-logo/index.js";
25
- export { default as AutomatticForAgenciesLogo } from "./components/automattic-for-agencies-logo/index.js";
26
- export { default as JetpackFooter } from "./components/jetpack-footer/index.js";
27
- export { default as Spinner } from "./components/spinner/index.js";
28
- export { default as Gridicon } from "./components/gridicon/index.js";
29
- export { default as IconTooltip } from "./components/icon-tooltip/index.js";
30
- export { default as ActionButton } from "./components/action-button/index.js";
31
- export { default as PricingCard } from "./components/pricing-card/index.js";
32
- export { default as NumberSlider } from "./components/number-slider/index.js";
33
- export { default as AdminSection } from "./components/admin-section/basic/index.js";
34
- export { default as AdminSectionHero } from "./components/admin-section/hero/index.js";
35
- export { default as AdminPage } from "./components/admin-page/index.js";
36
- export { default as DecorativeCard } from "./components/decorative-card/index.js";
37
- export { default as Col } from "./components/layout/col/index.js";
38
- export { default as Testimonials } from "./components/testimonials/index.js";
39
- export { default as Container } from "./components/layout/container/index.js";
40
- export { default as useBreakpointMatch } from "./components/layout/use-breakpoint-match/index.js";
41
- export { default as CopyToClipboard } from "./components/copy-to-clipboard/index.js";
42
- export * from "./components/icons/index.js";
43
- export { default as SplitButton } from "./components/split-button/index.js";
44
- export { default as ThemeProvider } from "./components/theme-provider/index.js";
45
- export { default as Text, H2, H3, Title } from "./components/text/index.js";
46
- export { default as ToggleControl } from "./components/toggle-control/index.js";
47
- export { default as NumberControl } from "./components/number-control/index.js";
48
- export { default as QRCode } from "./components/qr-code/index.js";
49
- export { default as Button } from "./components/button/index.js";
50
- export { default as LoadingPlaceholder } from "./components/loading-placeholder/index.js";
51
- export { default as TermsOfService } from "./components/terms-of-service/index.js";
52
- export { default as Badge } from "./components/badge/index.js";
53
- export { default as Chip } from "./components/chip/index.js";
54
- export { default as PricingTable, PricingTableColumn, PricingTableHeader, PricingTableItem, } from "./components/pricing-table/index.js";
55
- export { default as BoostScoreBar } from "./components/boost-score-bar/index.js";
56
- export { default as BoostScoreGraph } from "./components/boost-score-graph/index.js";
57
- export { default as ProductPrice } from "./components/product-price/index.js";
58
- export { default as ProductOffer, IconsCard } from "./components/product-offer/index.js";
59
- export { default as Dialog } from "./components/dialog/index.js";
60
- export { default as DotPager } from "./components/dot-pager/index.js";
61
- export { default as DonutMeter } from "./components/donut-meter/index.js";
62
- export { default as RecordMeterBar } from "./components/record-meter-bar/index.js";
63
- export { default as ContextualUpgradeTrigger } from "./components/contextual-upgrade-trigger/index.js";
64
- export { default as Alert } from "./components/alert/index.js";
65
- export { default as Notice } from "./components/notice/index.js";
66
- export { default as Popover } from "./components/popover/index.js";
67
- export { default as Status } from "./components/status/index.js";
68
- export { default as IndeterminateProgressBar } from "./components/indeterminate-progress-bar/index.js";
69
- export { default as ActionPopover } from "./components/action-popover/index.js";
70
- export { default as ZendeskChat } from "./components/zendesk-chat/index.js";
71
- export { default as ProgressBar } from "./components/progress-bar/index.js";
72
- export { default as UpsellBanner } from "./components/upsell-banner/index.js";
73
- export { getUserLocale, cleanLocale } from "./lib/locale/index.js";
74
- export { default as RadioControl } from "./components/radio-control/index.js";
75
- export { default as StatCard } from "./components/stat-card/index.js";
76
- export { default as DiffViewer } from "./components/diff-viewer/index.js";
77
- export { default as MarkedLines } from "./components/marked-lines/index.js";
78
- export { default as DetailsViewer } from "./components/details-viewer/index.js";
79
- export * from "./components/global-notices/index.js";
80
- export * from "./components/navigator-modal/index.js";
15
+ export { default as JetpackLogo } from './components/jetpack-logo/index.js';
16
+ export { default as JetpackSearchLogo } from './components/jetpack-search-logo/index.js';
17
+ export { default as JetpackProtectLogo } from './components/jetpack-protect-logo/index.js';
18
+ export { default as JetpackVaultPressBackupLogo } from './components/jetpack-vaultpress-backup-logo/index.js';
19
+ export { default as JetpackVideoPressLogo } from './components/jetpack-videopress-logo/index.js';
20
+ export { default as getRedirectUrl } from './tools/jp-redirect/index.js';
21
+ export { default as getProductCheckoutUrl } from './tools/get-product-checkout-url/index.js';
22
+ export { isFirstMonthTrial } from './tools/pricing-utils/index.js';
23
+ export { default as AutomatticBylineLogo } from './components/automattic-byline-logo/index.js';
24
+ export { default as AutomatticIconLogo } from './components/automattic-icon-logo/index.js';
25
+ export { default as AutomatticForAgenciesLogo } from './components/automattic-for-agencies-logo/index.js';
26
+ export { default as JetpackFooter } from './components/jetpack-footer/index.js';
27
+ export { default as Spinner } from './components/spinner/index.js';
28
+ export { default as Gridicon } from './components/gridicon/index.js';
29
+ export { default as IconTooltip } from './components/icon-tooltip/index.js';
30
+ export { default as ActionButton } from './components/action-button/index.js';
31
+ export { default as PricingCard } from './components/pricing-card/index.js';
32
+ export { default as NumberSlider } from './components/number-slider/index.js';
33
+ export { default as AdminSection } from './components/admin-section/basic/index.js';
34
+ export { default as AdminSectionHero } from './components/admin-section/hero/index.js';
35
+ export { default as AdminPage } from './components/admin-page/index.js';
36
+ export { default as DecorativeCard } from './components/decorative-card/index.js';
37
+ export { default as Col } from './components/layout/col/index.js';
38
+ export { default as Testimonials } from './components/testimonials/index.js';
39
+ export { default as Container } from './components/layout/container/index.js';
40
+ export { default as useBreakpointMatch } from './components/layout/use-breakpoint-match/index.js';
41
+ export { default as CopyToClipboard } from './components/copy-to-clipboard/index.js';
42
+ export * from './components/icons/index.js';
43
+ export { default as SplitButton } from './components/split-button/index.js';
44
+ export { default as ThemeProvider } from './components/theme-provider/index.js';
45
+ export { default as Text, H2, H3, Title } from './components/text/index.js';
46
+ export { default as ToggleControl } from './components/toggle-control/index.js';
47
+ export { default as NumberControl } from './components/number-control/index.js';
48
+ export { default as QRCode } from './components/qr-code/index.js';
49
+ export { default as Button } from './components/button/index.js';
50
+ export { default as LoadingPlaceholder } from './components/loading-placeholder/index.js';
51
+ export { default as TermsOfService } from './components/terms-of-service/index.js';
52
+ export { default as Badge } from './components/badge/index.js';
53
+ export { default as Chip } from './components/chip/index.js';
54
+ export { default as PricingTable, PricingTableColumn, PricingTableHeader, PricingTableItem, } from './components/pricing-table/index.js';
55
+ export { default as BoostScoreBar } from './components/boost-score-bar/index.js';
56
+ export { default as BoostScoreGraph } from './components/boost-score-graph/index.js';
57
+ export { default as ProductPrice } from './components/product-price/index.js';
58
+ export { default as ProductOffer, IconsCard } from './components/product-offer/index.js';
59
+ export { default as Dialog } from './components/dialog/index.js';
60
+ export { default as DotPager } from './components/dot-pager/index.js';
61
+ export { default as DonutMeter } from './components/donut-meter/index.js';
62
+ export { default as RecordMeterBar } from './components/record-meter-bar/index.js';
63
+ export { default as ContextualUpgradeTrigger } from './components/contextual-upgrade-trigger/index.js';
64
+ export { default as Alert } from './components/alert/index.js';
65
+ export { default as Notice } from './components/notice/index.js';
66
+ export { default as Popover } from './components/popover/index.js';
67
+ export { default as Status } from './components/status/index.js';
68
+ export { default as IndeterminateProgressBar } from './components/indeterminate-progress-bar/index.js';
69
+ export { default as ActionPopover } from './components/action-popover/index.js';
70
+ export { default as ZendeskChat } from './components/zendesk-chat/index.js';
71
+ export { default as ProgressBar } from './components/progress-bar/index.js';
72
+ export { default as UpsellBanner } from './components/upsell-banner/index.js';
73
+ export { getUserLocale, cleanLocale } from './lib/locale/index.js';
74
+ export { default as RadioControl } from './components/radio-control/index.js';
75
+ export { default as StatCard } from './components/stat-card/index.js';
76
+ export { default as DiffViewer } from './components/diff-viewer/index.js';
77
+ export { default as MarkedLines } from './components/marked-lines/index.js';
78
+ export { default as DetailsViewer } from './components/details-viewer/index.js';
79
+ export * from './components/global-notices/index.js';
80
+ export * from './components/navigator-modal/index.js';
@@ -1,4 +1,10 @@
1
1
  import restApi from '@automattic/jetpack-api';
2
+ import { Page } from '@wordpress/admin-ui';
3
+ import '@wordpress/admin-ui/build-style/style.css';
4
+ import {
5
+ __experimentalHeading as Heading, // eslint-disable-line @wordpress/no-unsafe-wp-apis
6
+ __experimentalHStack as HStack, // eslint-disable-line @wordpress/no-unsafe-wp-apis
7
+ } from '@wordpress/components';
2
8
  import { __, sprintf } from '@wordpress/i18n';
3
9
  import clsx from 'clsx';
4
10
  import { useEffect, useCallback } from 'react';
@@ -21,7 +27,7 @@ import type { FC, ReactNode } from 'react';
21
27
  const AdminPage: FC< AdminPageProps > = ( {
22
28
  children,
23
29
  className,
24
- moduleName = __( 'Jetpack', 'jetpack-components' ),
30
+ moduleName = 'Jetpack' /** "Jetpack" is a product name, do not translate. */,
25
31
  moduleNameHref,
26
32
  showHeader = true,
27
33
  showFooter = true,
@@ -32,6 +38,12 @@ const AdminPage: FC< AdminPageProps > = ( {
32
38
  apiNonce = '',
33
39
  optionalMenuItems,
34
40
  header,
41
+ title,
42
+ subTitle,
43
+ logo,
44
+ actions,
45
+ tabs,
46
+ showBottomBorder = true,
35
47
  } ) => {
36
48
  useEffect( () => {
37
49
  restApi.setApiRoot( apiRoot );
@@ -40,6 +52,7 @@ const AdminPage: FC< AdminPageProps > = ( {
40
52
 
41
53
  const rootClassName = clsx( styles[ 'admin-page' ], className, {
42
54
  [ styles.background ]: showBackground,
55
+ [ styles[ 'without-bottom-border' ] ]: tabs || ! showBottomBorder,
43
56
  } );
44
57
 
45
58
  const testConnection = useCallback( async () => {
@@ -60,6 +73,56 @@ const AdminPage: FC< AdminPageProps > = ( {
60
73
  }
61
74
  }, [] );
62
75
 
76
+ // Compose the title with logo for the admin-ui Page header.
77
+ // Note: The inner Heading causes a double h2 wrapping because Page's Header
78
+ // also wraps title in a Heading. This is a known issue — the inner Heading is
79
+ // needed until https://github.com/WordPress/gutenberg/pull/75899 fixes
80
+ // non-string title rendering in admin-ui. Once that lands, remove the Heading
81
+ // here and pass the plain HStack with a string child.
82
+ const composedTitle = title ? (
83
+ <HStack spacing={ 2 } justify="left">
84
+ { logo || <JetpackLogo showText={ false } height={ 20 } /> }
85
+ <Heading as="h2" level={ 3 } weight={ 500 } truncate>
86
+ { title }
87
+ </Heading>
88
+ </HStack>
89
+ ) : undefined;
90
+
91
+ const footer = showFooter && (
92
+ <Container horizontalSpacing={ 5 }>
93
+ <Col>
94
+ <JetpackFooter
95
+ moduleName={ moduleName }
96
+ moduleNameHref={ moduleNameHref }
97
+ menu={ optionalMenuItems }
98
+ useInternalLinks={ useInternalLinks }
99
+ />
100
+ </Col>
101
+ </Container>
102
+ );
103
+
104
+ // When title is provided, use admin-ui Page for the full page layout.
105
+ if ( showHeader && composedTitle ) {
106
+ return (
107
+ <div className={ rootClassName }>
108
+ <Page
109
+ ariaLabel={ title }
110
+ title={ composedTitle }
111
+ subTitle={ subTitle }
112
+ actions={ actions }
113
+ showSidebarToggle={ false }
114
+ >
115
+ { tabs }
116
+ <Container fluid horizontalSpacing={ 0 }>
117
+ <Col>{ children }</Col>
118
+ </Container>
119
+ { footer }
120
+ </Page>
121
+ </div>
122
+ );
123
+ }
124
+
125
+ // Legacy path: no title provided, render the classic header.
63
126
  return (
64
127
  <div className={ rootClassName }>
65
128
  { showHeader && (
@@ -85,18 +148,7 @@ const AdminPage: FC< AdminPageProps > = ( {
85
148
  <Container fluid horizontalSpacing={ 0 }>
86
149
  <Col>{ children }</Col>
87
150
  </Container>
88
- { showFooter && (
89
- <Container horizontalSpacing={ 5 }>
90
- <Col>
91
- <JetpackFooter
92
- moduleName={ moduleName }
93
- moduleNameHref={ moduleNameHref }
94
- menu={ optionalMenuItems }
95
- useInternalLinks={ useInternalLinks }
96
- />
97
- </Col>
98
- </Container>
99
- ) }
151
+ { footer }
100
152
  </div>
101
153
  );
102
154
  };
@@ -9,6 +9,26 @@
9
9
  background-color: var(--jp-white);
10
10
  }
11
11
 
12
+ // Remove the admin-ui header border when tabs are present,
13
+ // or when showBottomBorder is false.
14
+ // Ideally admin-ui would expose a prop or CSS custom property for this:
15
+ // https://github.com/WordPress/gutenberg/issues/75428
16
+ &.without-bottom-border :global(.admin-ui-page__header) {
17
+ border-bottom: none;
18
+ }
19
+
20
+ // Disable sticky header until we make it work better across all pages.
21
+ // JETPACK-1386
22
+ :global(.admin-ui-page__header) {
23
+ position: relative;
24
+ }
25
+
26
+ // Normalize admin headers: implementation of admin-ui needs to
27
+ // comprehend old wp-admin floating containers, such as Hello Dolly.
28
+ :global(.admin-ui-page) {
29
+ clear: both;
30
+ }
31
+
12
32
  .admin-page-header {
13
33
  display: flex;
14
34
  align-items: center;
@@ -26,3 +46,9 @@
26
46
  color: #fff;
27
47
  }
28
48
  }
49
+
50
+ // Make Hello Dolly background white for Jetpack admin pages.
51
+ :global(.jetpack-admin-page #dolly) {
52
+ background-color: #fff;
53
+ }
54
+
@@ -18,10 +18,37 @@ export type AdminPageProps = {
18
18
  showHeader?: boolean;
19
19
 
20
20
  /**
21
- * Custom header. Optional
21
+ * Custom header. Optional.
22
+ * @deprecated Use `title` and `subTitle` props instead for the unified header.
22
23
  */
23
24
  header?: ReactNode;
24
25
 
26
+ /**
27
+ * Product title displayed in the unified header (e.g. "Social", "Backup").
28
+ * When provided, renders the admin-ui Page header instead of the legacy header slot.
29
+ */
30
+ title?: string;
31
+
32
+ /**
33
+ * Optional tagline displayed below the title in the unified header.
34
+ */
35
+ subTitle?: ReactNode;
36
+
37
+ /**
38
+ * Custom logo element for the unified header. Defaults to JetpackLogo icon.
39
+ */
40
+ logo?: ReactNode;
41
+
42
+ /**
43
+ * Action elements displayed on the right side of the unified header.
44
+ */
45
+ actions?: ReactNode;
46
+
47
+ /**
48
+ * Tab navigation displayed below the title/tagline in the unified header.
49
+ */
50
+ tabs?: ReactNode;
51
+
25
52
  /**
26
53
  * Whether or not to display the Footer
27
54
  */
@@ -71,4 +98,10 @@ export type AdminPageProps = {
71
98
  * Class name to be applied to the root element of the component.
72
99
  */
73
100
  className?: string;
101
+
102
+ /**
103
+ * Show bottom border of the header. Defaults to true.
104
+ * Hidden when `tabs` is used.
105
+ */
106
+ showBottomBorder?: boolean;
74
107
  };
@@ -12,7 +12,7 @@ import type { ButtonProps } from './types.ts';
12
12
  * @param {ButtonProps} props - Component Props
13
13
  * @return {ReactNode} Rendered button
14
14
  */
15
- const Button = forwardRef< HTMLInputElement, ButtonProps >( ( props, ref ) => {
15
+ const Button = forwardRef< HTMLElement, ButtonProps >( ( props, ref ) => {
16
16
  const {
17
17
  children,
18
18
  variant = 'primary',
@@ -33,7 +33,7 @@ const ExternalIcon: FC = () => (
33
33
  * @return {ReactNode} JetpackFooter component.
34
34
  */
35
35
  const JetpackFooter: FC< JetpackFooterProps > = ( {
36
- moduleName = __( 'Jetpack', 'jetpack-components' ),
36
+ moduleName = 'Jetpack' /** "Jetpack" is a product name, do not translate. */,
37
37
  className,
38
38
  moduleNameHref = 'https://jetpack.com',
39
39
  menu,
@@ -8,11 +8,12 @@
8
8
  @include breakpoints.media(#{$size}) using ($columns) {
9
9
  padding: 0 #{$padding};
10
10
  grid-template-columns: repeat(#{$columns}, minmax(0, 1fr));
11
+ max-width: calc(var(--max-container-width) + 2 * #{$padding});
11
12
  }
12
13
  }
13
14
 
14
15
  .container {
15
- --max-container-width: 1128px;
16
+ --max-container-width: 1040px;
16
17
  // vertical spacing
17
18
  --vertical-gutter: 24px;
18
19
  // horizontal spacing
@@ -20,7 +21,6 @@
20
21
 
21
22
  display: grid;
22
23
  column-gap: var(--vertical-gutter);
23
- max-width: var(--max-container-width);
24
24
  margin: 0 auto;
25
25
  width: 100%;
26
26
 
@@ -1,6 +1,6 @@
1
1
  import { Modal, Navigator } from '@wordpress/components';
2
2
  import clsx from 'clsx';
3
- import { useContext } from 'react';
3
+ import { useCallback, useContext } from 'react';
4
4
  import { NavigatorModalContext } from './context.ts';
5
5
  import { Screen } from './screen.tsx';
6
6
  import './styles.scss';
@@ -23,16 +23,31 @@ function InternalNavigatorModal( {
23
23
  className,
24
24
  ...props
25
25
  }: Omit< ModalProps, 'onRequestClose' > ) {
26
- const context = useContext( NavigatorModalContext );
26
+ const { onClose, initialPath } = useContext( NavigatorModalContext );
27
+
28
+ // WordPress Modal's dismisser mechanism (ModalContext) calls onRequestClose()
29
+ // without arguments when another non-nested Modal mounts. We guard against
30
+ // this so that external modals (e.g. Image Studio) don't destroy this one.
31
+ // User-initiated closes (Escape, close button) always pass an event.
32
+ // The NavigatorModal's own Header/Footer close buttons call context.onClose
33
+ // directly and are unaffected by this guard.
34
+ const onRequestClose = useCallback(
35
+ ( event?: React.SyntheticEvent ) => {
36
+ if ( event ) {
37
+ onClose?.();
38
+ }
39
+ },
40
+ [ onClose ]
41
+ );
27
42
 
28
43
  return (
29
44
  <Modal
30
45
  __experimentalHideHeader
31
- onRequestClose={ context.onClose }
46
+ onRequestClose={ onRequestClose }
32
47
  className={ clsx( 'jp-navigator-modal', className ) }
33
48
  { ...props }
34
49
  >
35
- <Navigator initialPath={ context.initialPath } className="jp-navigator-modal__navigator">
50
+ <Navigator initialPath={ initialPath } className="jp-navigator-modal__navigator">
36
51
  { children }
37
52
  </Navigator>
38
53
  </Modal>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/jetpack-components",
3
- "version": "1.4.15",
3
+ "version": "1.5.0",
4
4
  "description": "Jetpack Components Package",
5
5
  "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/components/#readme",
6
6
  "bugs": {
@@ -34,60 +34,61 @@
34
34
  "scripts": {
35
35
  "build": "pnpm run clean && pnpm run compile-ts && pnpm run copy-scss",
36
36
  "clean": "rm -rf build/",
37
- "compile-ts": "tsc --pretty --project tsconfig.build.json",
37
+ "compile-ts": "tsgo --pretty --project tsconfig.build.json",
38
38
  "copy-scss": "node ./tools/copy-scss-to-build.mjs",
39
39
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
40
40
  "test-coverage": "pnpm run test --coverage",
41
- "typecheck": "tsc --noEmit"
41
+ "typecheck": "tsgo --noEmit"
42
42
  },
43
43
  "browserslist": [
44
44
  "extends @wordpress/browserslist-config"
45
45
  ],
46
46
  "dependencies": {
47
47
  "@automattic/format-currency": "1.0.1",
48
- "@automattic/jetpack-api": "^1.0.17",
49
- "@automattic/jetpack-boost-score-api": "^1.0.30",
50
- "@automattic/jetpack-script-data": "^0.5.5",
51
- "@automattic/number-formatters": "^1.1.0",
48
+ "@automattic/jetpack-api": "^1.0.18",
49
+ "@automattic/jetpack-boost-score-api": "^1.0.32",
50
+ "@automattic/jetpack-script-data": "^0.6.1",
51
+ "@automattic/number-formatters": "^1.1.1",
52
52
  "@babel/runtime": "^7",
53
- "@wordpress/browserslist-config": "6.39.0",
54
- "@wordpress/components": "32.1.0",
55
- "@wordpress/compose": "7.39.0",
56
- "@wordpress/data": "10.39.0",
57
- "@wordpress/date": "5.39.0",
58
- "@wordpress/element": "6.39.0",
59
- "@wordpress/i18n": "6.12.0",
60
- "@wordpress/icons": "11.6.0",
61
- "@wordpress/notices": "5.39.0",
53
+ "@wordpress/admin-ui": "1.9.0",
54
+ "@wordpress/browserslist-config": "6.40.0",
55
+ "@wordpress/components": "32.2.0",
56
+ "@wordpress/compose": "7.40.0",
57
+ "@wordpress/data": "10.40.0",
58
+ "@wordpress/date": "5.40.0",
59
+ "@wordpress/element": "6.40.0",
60
+ "@wordpress/i18n": "6.13.0",
61
+ "@wordpress/icons": "11.7.0",
62
+ "@wordpress/notices": "5.40.0",
62
63
  "clsx": "2.1.1",
63
64
  "prop-types": "^15.7.2",
64
65
  "qrcode.react": "4.2.0",
65
66
  "react-slider": "2.0.5",
66
- "social-logos": "^3.3.9",
67
+ "social-logos": "^3.3.11",
67
68
  "uplot": "1.6.31",
68
69
  "uplot-react": "1.1.4"
69
70
  },
70
71
  "devDependencies": {
71
- "@automattic/jetpack-base-styles": "^1.0.17",
72
+ "@automattic/jetpack-base-styles": "^1.0.18",
72
73
  "@babel/core": "7.29.0",
73
74
  "@babel/preset-react": "7.28.5",
74
75
  "@jest/globals": "30.2.0",
75
- "@storybook/addon-docs": "10.2.3",
76
- "@storybook/react": "10.2.3",
76
+ "@storybook/addon-docs": "10.2.11",
77
+ "@storybook/react": "10.2.11",
77
78
  "@testing-library/dom": "10.4.1",
78
79
  "@testing-library/react": "16.3.0",
79
80
  "@testing-library/user-event": "14.6.1",
80
81
  "@types/jest": "30.0.0",
81
- "@types/react": "18.3.27",
82
+ "@types/react": "18.3.28",
82
83
  "@types/react-dom": "18.3.7",
83
84
  "@types/react-slider": "1.3.6",
85
+ "@typescript/native-preview": "7.0.0-dev.20260225.1",
84
86
  "jest": "30.2.0",
85
87
  "react": "18.3.1",
86
88
  "react-dom": "18.3.1",
87
89
  "require-from-string": "2.0.2",
88
- "storybook": "10.2.3",
90
+ "storybook": "10.2.11",
89
91
  "ts-dedent": "2.2.0",
90
- "typescript": "5.9.3",
91
92
  "webpack": "5.105.2",
92
93
  "webpack-cli": "6.0.1"
93
94
  },
@@ -50,7 +50,7 @@ async function main() {
50
50
  return;
51
51
  }
52
52
 
53
- for await ( const filePath of fs.glob( '**/*.scss', {
53
+ for await ( const filePath of fs.glob( '**/*.{scss,css}', {
54
54
  cwd: packageRoot,
55
55
  exclude: Array.from( IGNORED_DIRS, dir => `**/${ dir }/**` ),
56
56
  } ) ) {