@automattic/jetpack-components 1.8.1 → 1.8.3

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 (30) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/build/components/admin-page/index.js +4 -1
  3. package/build/components/button/style.module.scss +0 -117
  4. package/build/components/jetpack-footer/style.scss +1 -1
  5. package/build/components/navigator-modal/index.js +22 -3
  6. package/build/components/pricing-card/style.scss +0 -3
  7. package/build/components/radio-control/index.js +1 -2
  8. package/build/components/terms-of-service/styles.scss +0 -1
  9. package/build/components/toggle-control/styles.module.scss +0 -37
  10. package/build/components/upsell-banner/style.scss +0 -6
  11. package/build/index.d.ts +0 -1
  12. package/build/index.js +0 -1
  13. package/components/admin-page/index.tsx +4 -1
  14. package/components/button/style.module.scss +0 -117
  15. package/components/jetpack-footer/style.scss +1 -1
  16. package/components/navigator-modal/index.tsx +23 -2
  17. package/components/pricing-card/style.scss +0 -3
  18. package/components/radio-control/index.tsx +1 -2
  19. package/components/terms-of-service/styles.scss +0 -1
  20. package/components/toggle-control/styles.module.scss +0 -37
  21. package/components/upsell-banner/style.scss +0 -6
  22. package/index.ts +0 -1
  23. package/package.json +20 -20
  24. package/build/components/badge/index.d.ts +0 -19
  25. package/build/components/badge/index.js +0 -22
  26. package/build/components/badge/style.module.scss +0 -25
  27. package/build/components/radio-control/styles.module.scss +0 -26
  28. package/components/badge/index.tsx +0 -39
  29. package/components/badge/style.module.scss +0 -25
  30. package/components/radio-control/styles.module.scss +0 -26
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ### This is a list detailing changes for the Jetpack RNA Components package releases.
4
4
 
5
+ ## [1.8.3] - 2026-04-20
6
+ ### Changed
7
+ - AdminPage: Add a stable, non-hashed `jp-admin-page` class on the component root so shared SCSS mixins and global stylesheets can target AdminPage without coupling to the hashed CSS-Modules className. [#48109]
8
+ - Button, ToggleControl: Remove Jetpack color overrides on core WordPress components. [#47317]
9
+ - Update package dependencies. [#48106] [#48126] [#48141]
10
+
11
+ ### Removed
12
+ - Remove internal Badge component in favor of @wordpress/ui. [#48156]
13
+
14
+ ### Fixed
15
+ - Navigator modal: Allow overlay closing when users click it. [#48121]
16
+
17
+ ## [1.8.2] - 2026-04-15
18
+ ### Changed
19
+ - Update package dependencies. [#47907]
20
+
5
21
  ## [1.8.1] - 2026-04-09
6
22
  ### Changed
7
23
  - Update package dependencies. [#47890]
@@ -1732,6 +1748,8 @@
1732
1748
  ### Changed
1733
1749
  - Update node version requirement to 14.16.1
1734
1750
 
1751
+ [1.8.3]: https://github.com/Automattic/jetpack-components/compare/1.8.2...1.8.3
1752
+ [1.8.2]: https://github.com/Automattic/jetpack-components/compare/1.8.1...1.8.2
1735
1753
  [1.8.1]: https://github.com/Automattic/jetpack-components/compare/1.8.0...1.8.1
1736
1754
  [1.8.0]: https://github.com/Automattic/jetpack-components/compare/1.7.0...1.8.0
1737
1755
  [1.7.0]: https://github.com/Automattic/jetpack-components/compare/1.6.1...1.7.0
@@ -25,7 +25,10 @@ const AdminPage = ({ children, className, showHeader = true, showFooter = true,
25
25
  restApi.setApiRoot(apiRoot);
26
26
  restApi.setApiNonce(apiNonce);
27
27
  }, [apiRoot, apiNonce]);
28
- const rootClassName = clsx(styles['admin-page'], className, {
28
+ // `jp-admin-page` is a stable, non-hashed hook for global stylesheets and
29
+ // shared SCSS mixins (notably `jetpack-admin-page-layout` in
30
+ // @automattic/jetpack-base-styles). Do not rename.
31
+ const rootClassName = clsx(styles['admin-page'], 'jp-admin-page', className, {
29
32
  [styles.background]: showBackground,
30
33
  [styles['without-bottom-border']]: tabs || !showBottomBorder,
31
34
  });
@@ -1,11 +1,4 @@
1
1
  .button {
2
- --wp-admin-theme-color: var(--jp-black);
3
- --wp-admin-theme-color-darker-10: var(--jp-black-80);
4
- --wp-admin-theme-color-darker-20: var(--jp-black-80);
5
- // 1.51px to avoid subpixel rendering issues on Firefox/Linux
6
- --wp-admin-border-width-focus: 1.51px;
7
-
8
- border-radius: var(--jp-border-radius);
9
2
  justify-content: center;
10
3
  font-weight: 600;
11
4
 
@@ -67,32 +60,6 @@
67
60
  min-width: 100%;
68
61
  }
69
62
 
70
- // SPECIFICS
71
- // PRIMARY AND SECONDARY
72
-
73
- // Primary & Secondary
74
- &:global(.is-primary),
75
- &:global(.is-secondary) {
76
- // Disabled
77
- &:disabled {
78
- background: var(--jp-gray);
79
- color: var(--jp-gray-20);
80
- }
81
- }
82
-
83
- // Only Secondary
84
- &:global(.is-secondary) {
85
- background: var(--jp-white);
86
- // 1.51px to avoid subpixel rendering issues on Firefox/Linux
87
- box-shadow: inset 0 0 0 1.51px var(--jp-black);
88
-
89
- // Hover & Active
90
- &:active:not(:disabled),
91
- &:hover:not(:disabled) {
92
- background: var(--jp-gray-0);
93
- }
94
- }
95
-
96
63
  // SPECIFICS
97
64
  // LINK & EXTERNAL LINK
98
65
 
@@ -102,90 +69,6 @@
102
69
  &.small {
103
70
  padding: 0;
104
71
  }
105
-
106
- // Hover State
107
- &:hover:not(:disabled) {
108
- text-decoration-thickness: 3px;
109
- }
110
-
111
- // Focus State
112
- &:focus:not(:disabled) {
113
- text-decoration-line: none;
114
- }
115
- }
116
-
117
- // DESTRUCTIVE
118
-
119
- &:global(.is-destructive) {
120
- // Primary
121
- &:global(.is-primary) {
122
- box-shadow: none;
123
-
124
- &:not(:disabled) {
125
- color: var(--jp-white);
126
- background: var(--jp-red-50);
127
- box-shadow: inset 0 0 0 1px var(--jp-red-50);
128
- }
129
-
130
- &:hover:not(:disabled) {
131
- background: var(--jp-red-60);
132
- box-shadow: inset 0 0 0 1px var(--jp-red-60);
133
- }
134
-
135
- &:focus:not(:disabled) {
136
- box-shadow: inset 0 0 0 1px var(--jp-white), 0 0 0 var(--wp-admin-border-width-focus) var(--jp-red-70);
137
- background: var(--jp-red-70);
138
- color: var(--jp-white);
139
- }
140
-
141
- &:active:not(:disabled) {
142
- background: var(--jp-red-50);
143
- }
144
- }
145
-
146
- // Secondary
147
- &:global(.is-secondary) {
148
- box-shadow: none;
149
-
150
- &:not(:disabled) {
151
- color: var(--jp-red-50);
152
- background: var(--jp-white);
153
- box-shadow: inset 0 0 0 1.5px var(--jp-red-50);
154
- }
155
-
156
- &:hover:not(:disabled) {
157
- background: var(--jp-red-0);
158
- box-shadow: inset 0 0 0 1.5px var(--jp-red-60);
159
- color: var(--jp-red-60);
160
- }
161
-
162
- &:focus:not(:disabled) {
163
- box-shadow: inset 0 0 0 1px var(--jp-white), 0 0 0 var(--wp-admin-border-width-focus) var(--jp-red-70);
164
- color: var(--jp-red-70);
165
- }
166
-
167
- &:active:not(:disabled) {
168
- background: var(--jp-gray-0);
169
- }
170
- }
171
-
172
- // Link
173
- &:global(.is-link) {
174
-
175
- &:not(:disabled) {
176
- color: var(--jp-red-50);
177
- }
178
-
179
- &:hover:not(:disabled) {
180
- color: var(--jp-red-60);
181
- box-shadow: none;
182
- }
183
-
184
- &:focus:not(:disabled) {
185
- color: var(--jp-red-70);
186
- box-shadow: inset 0 0 0 1px var(--jp-white), 0 0 0 var(--wp-admin-border-width-focus) var(--jp-red-70);
187
- }
188
- }
189
72
  }
190
73
 
191
74
  // LOADING
@@ -4,7 +4,7 @@
4
4
  .jetpack-footer {
5
5
  border-top: var(--wpds-border-width-xs, 1px) solid var(--wpds-color-stroke-surface-neutral-weak, #e0e0e0);
6
6
  box-sizing: border-box;
7
- font-size: var(--wpds-font-size-md, 13px);
7
+ font-size: var(--wpds-typography-font-size-md, 13px);
8
8
  padding: var(--wpds-dimension-padding-xl) var(--wpds-dimension-padding-2xl);
9
9
  width: 100%;
10
10
 
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Modal, Navigator } from '@wordpress/components';
3
3
  import clsx from 'clsx';
4
- import { useCallback, useContext } from 'react';
4
+ import { useCallback, useContext, useEffect, useRef } from 'react';
5
5
  import { NavigatorModalContext } from './context.js';
6
6
  import { Screen } from './screen.js';
7
7
  import './styles.scss';
@@ -14,18 +14,37 @@ import './styles.scss';
14
14
  */
15
15
  function InternalNavigatorModal({ children, className, ...props }) {
16
16
  const { onClose, initialPath } = useContext(NavigatorModalContext);
17
+ const overlayRef = useRef(null);
18
+ const isUserInteracting = useRef(false);
19
+ // Track pointer interaction on the overlay so we can distinguish
20
+ // user-initiated overlay clicks from the WP Modal dismisser mechanism,
21
+ // which also calls onRequestClose() without an event argument.
22
+ useEffect(() => {
23
+ const overlay = overlayRef.current;
24
+ if (!overlay) {
25
+ return;
26
+ }
27
+ const handler = () => {
28
+ isUserInteracting.current = true;
29
+ };
30
+ overlay.addEventListener('pointerdown', handler);
31
+ return () => overlay.removeEventListener('pointerdown', handler);
32
+ }, []);
17
33
  // WordPress Modal's dismisser mechanism (ModalContext) calls onRequestClose()
18
34
  // without arguments when another non-nested Modal mounts. We guard against
19
35
  // this so that external modals (e.g. Image Studio) don't destroy this one.
20
36
  // User-initiated closes (Escape, close button) always pass an event.
37
+ // Overlay clicks don't pass an event but are identified by the
38
+ // isUserInteracting flag set via the pointerdown listener above.
21
39
  // The NavigatorModal's own Header/Footer close buttons call context.onClose
22
40
  // directly and are unaffected by this guard.
23
41
  const onRequestClose = useCallback((event) => {
24
- if (event) {
42
+ if (event || isUserInteracting.current) {
43
+ isUserInteracting.current = false;
25
44
  onClose?.();
26
45
  }
27
46
  }, [onClose]);
28
- return (_jsx(Modal, { __experimentalHideHeader: true, onRequestClose: onRequestClose, className: clsx('jp-navigator-modal', className), ...props, children: _jsx(Navigator, { initialPath: initialPath, className: "jp-navigator-modal__navigator", children: children }) }));
47
+ return (_jsx(Modal, { ref: overlayRef, __experimentalHideHeader: true, onRequestClose: onRequestClose, className: clsx('jp-navigator-modal', className), ...props, children: _jsx(Navigator, { initialPath: initialPath, className: "jp-navigator-modal__navigator", children: children }) }));
29
48
  }
30
49
  /**
31
50
  * Renders a modal with navigator capabilities.
@@ -90,9 +90,6 @@
90
90
  width: 100%;
91
91
  height: auto;
92
92
  font-size: 18px;
93
- background: var(--jp-black);
94
- color: var(--jp-white) !important;
95
- border-radius: var(--jp-border-radius);
96
93
  padding: 14px 24px;
97
94
  margin: 24px 0 32px;
98
95
  justify-content: center;
@@ -1,8 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { RadioControl as WPRadioControl } from '@wordpress/components';
3
3
  import clsx from 'clsx';
4
- import styles from './styles.module.scss';
5
4
  const RadioControl = ({ selected, className, disabled, help, label, hideLabelFromVision, options, onChange, }) => {
6
- return (_jsx(WPRadioControl, { selected: selected, className: clsx(styles.radio, className), disabled: disabled, help: help, label: label, hideLabelFromVision: hideLabelFromVision, options: options, onChange: onChange }));
5
+ return (_jsx(WPRadioControl, { selected: selected, className: clsx('radio', className), disabled: disabled, help: help, label: label, hideLabelFromVision: hideLabelFromVision, options: options, onChange: onChange }));
7
6
  };
8
7
  export default RadioControl;
@@ -3,7 +3,6 @@
3
3
  color: var(--jp-black);
4
4
 
5
5
  .terms-of-service__link {
6
- color: var(--jp-green-50);
7
6
  white-space: nowrap;
8
7
  }
9
8
  }
@@ -3,8 +3,6 @@
3
3
  /// Overrides the @wordpress/components ToggleControl component.
4
4
  /// @link https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/form-toggle
5
5
  .toggle {
6
- --base-width: 8px;
7
- --track-width: calc(var(--base-width) * 6);
8
6
 
9
7
  &.is-small {
10
8
  --base-width: 6px;
@@ -13,41 +11,6 @@
13
11
  &.no-label :global(.components-toggle-control__label) {
14
12
  display: none;
15
13
  }
16
-
17
- :global {
18
-
19
- .components-form-toggle {
20
- --wp-admin-theme-color: var(--jp-green-40);
21
- height: calc(var(--base-width) * 3);
22
-
23
-
24
- &__input:focus + .components-form-toggle__track {
25
- box-shadow: 0 0 0 2px var(--jp-white), 0 0 0 4px var(--jp-green-50);
26
- }
27
-
28
- .components-form-toggle__track {
29
- width: var(--track-width);
30
- height: calc(var(--base-width) * 3);
31
- border-radius: 12px;
32
- border-width: 2px;
33
- }
34
-
35
- .components-form-toggle__thumb {
36
- width: calc(var(--base-width) * 2);
37
- height: calc(var(--base-width) * 2);
38
- top: calc(var(--base-width) / 2);
39
- left: calc(var(--base-width) / 2);
40
- }
41
-
42
- &.is-checked .components-form-toggle__thumb {
43
- transform: translateX(calc(var(--base-width) * 3));
44
- }
45
- }
46
-
47
- .components-toggle-control__help {
48
- margin-inline-start: calc(var(--track-width) + var(--spacing-base));
49
- }
50
- }
51
14
  }
52
15
 
53
16
  .toggle.is-toggling {
@@ -74,15 +74,9 @@
74
74
 
75
75
  .upsell-banner--content-cta-button {
76
76
  white-space: nowrap;
77
- box-shadow: inset 0 0 0 1.5px rgb(0, 0, 0);
78
77
  font-weight: 400;
79
78
  padding: 8px 16px;
80
79
 
81
- &.secondary {
82
- background-color: var(--jp-white);
83
- color: var(--jp-black);
84
- }
85
-
86
80
  &.primary {
87
81
  margin-left: 8px;
88
82
  }
package/build/index.d.ts CHANGED
@@ -36,7 +36,6 @@ export { default as Button } from './components/button/index.tsx';
36
36
  export type { ButtonProps } from './components/button/types.ts';
37
37
  export { default as LoadingPlaceholder } from './components/loading-placeholder/index.tsx';
38
38
  export { default as TermsOfService } from './components/terms-of-service/index.tsx';
39
- export { default as Badge } from './components/badge/index.tsx';
40
39
  export { default as Chip } from './components/chip/index.tsx';
41
40
  export { default as PricingTable, PricingTableColumn, PricingTableHeader, PricingTableItem, } from './components/pricing-table/index.tsx';
42
41
  export { default as BoostScoreBar } from './components/boost-score-bar/index.tsx';
package/build/index.js CHANGED
@@ -49,7 +49,6 @@ export { default as QRCode } from './components/qr-code/index.js';
49
49
  export { default as Button } from './components/button/index.js';
50
50
  export { default as LoadingPlaceholder } from './components/loading-placeholder/index.js';
51
51
  export { default as TermsOfService } from './components/terms-of-service/index.js';
52
- export { default as Badge } from './components/badge/index.js';
53
52
  export { default as Chip } from './components/chip/index.js';
54
53
  export { default as PricingTable, PricingTableColumn, PricingTableHeader, PricingTableItem, } from './components/pricing-table/index.js';
55
54
  export { default as BoostScoreBar } from './components/boost-score-bar/index.js';
@@ -47,7 +47,10 @@ const AdminPage: FC< AdminPageProps > = ( {
47
47
  restApi.setApiNonce( apiNonce );
48
48
  }, [ apiRoot, apiNonce ] );
49
49
 
50
- const rootClassName = clsx( styles[ 'admin-page' ], className, {
50
+ // `jp-admin-page` is a stable, non-hashed hook for global stylesheets and
51
+ // shared SCSS mixins (notably `jetpack-admin-page-layout` in
52
+ // @automattic/jetpack-base-styles). Do not rename.
53
+ const rootClassName = clsx( styles[ 'admin-page' ], 'jp-admin-page', className, {
51
54
  [ styles.background ]: showBackground,
52
55
  [ styles[ 'without-bottom-border' ] ]: tabs || ! showBottomBorder,
53
56
  } );
@@ -1,11 +1,4 @@
1
1
  .button {
2
- --wp-admin-theme-color: var(--jp-black);
3
- --wp-admin-theme-color-darker-10: var(--jp-black-80);
4
- --wp-admin-theme-color-darker-20: var(--jp-black-80);
5
- // 1.51px to avoid subpixel rendering issues on Firefox/Linux
6
- --wp-admin-border-width-focus: 1.51px;
7
-
8
- border-radius: var(--jp-border-radius);
9
2
  justify-content: center;
10
3
  font-weight: 600;
11
4
 
@@ -67,32 +60,6 @@
67
60
  min-width: 100%;
68
61
  }
69
62
 
70
- // SPECIFICS
71
- // PRIMARY AND SECONDARY
72
-
73
- // Primary & Secondary
74
- &:global(.is-primary),
75
- &:global(.is-secondary) {
76
- // Disabled
77
- &:disabled {
78
- background: var(--jp-gray);
79
- color: var(--jp-gray-20);
80
- }
81
- }
82
-
83
- // Only Secondary
84
- &:global(.is-secondary) {
85
- background: var(--jp-white);
86
- // 1.51px to avoid subpixel rendering issues on Firefox/Linux
87
- box-shadow: inset 0 0 0 1.51px var(--jp-black);
88
-
89
- // Hover & Active
90
- &:active:not(:disabled),
91
- &:hover:not(:disabled) {
92
- background: var(--jp-gray-0);
93
- }
94
- }
95
-
96
63
  // SPECIFICS
97
64
  // LINK & EXTERNAL LINK
98
65
 
@@ -102,90 +69,6 @@
102
69
  &.small {
103
70
  padding: 0;
104
71
  }
105
-
106
- // Hover State
107
- &:hover:not(:disabled) {
108
- text-decoration-thickness: 3px;
109
- }
110
-
111
- // Focus State
112
- &:focus:not(:disabled) {
113
- text-decoration-line: none;
114
- }
115
- }
116
-
117
- // DESTRUCTIVE
118
-
119
- &:global(.is-destructive) {
120
- // Primary
121
- &:global(.is-primary) {
122
- box-shadow: none;
123
-
124
- &:not(:disabled) {
125
- color: var(--jp-white);
126
- background: var(--jp-red-50);
127
- box-shadow: inset 0 0 0 1px var(--jp-red-50);
128
- }
129
-
130
- &:hover:not(:disabled) {
131
- background: var(--jp-red-60);
132
- box-shadow: inset 0 0 0 1px var(--jp-red-60);
133
- }
134
-
135
- &:focus:not(:disabled) {
136
- box-shadow: inset 0 0 0 1px var(--jp-white), 0 0 0 var(--wp-admin-border-width-focus) var(--jp-red-70);
137
- background: var(--jp-red-70);
138
- color: var(--jp-white);
139
- }
140
-
141
- &:active:not(:disabled) {
142
- background: var(--jp-red-50);
143
- }
144
- }
145
-
146
- // Secondary
147
- &:global(.is-secondary) {
148
- box-shadow: none;
149
-
150
- &:not(:disabled) {
151
- color: var(--jp-red-50);
152
- background: var(--jp-white);
153
- box-shadow: inset 0 0 0 1.5px var(--jp-red-50);
154
- }
155
-
156
- &:hover:not(:disabled) {
157
- background: var(--jp-red-0);
158
- box-shadow: inset 0 0 0 1.5px var(--jp-red-60);
159
- color: var(--jp-red-60);
160
- }
161
-
162
- &:focus:not(:disabled) {
163
- box-shadow: inset 0 0 0 1px var(--jp-white), 0 0 0 var(--wp-admin-border-width-focus) var(--jp-red-70);
164
- color: var(--jp-red-70);
165
- }
166
-
167
- &:active:not(:disabled) {
168
- background: var(--jp-gray-0);
169
- }
170
- }
171
-
172
- // Link
173
- &:global(.is-link) {
174
-
175
- &:not(:disabled) {
176
- color: var(--jp-red-50);
177
- }
178
-
179
- &:hover:not(:disabled) {
180
- color: var(--jp-red-60);
181
- box-shadow: none;
182
- }
183
-
184
- &:focus:not(:disabled) {
185
- color: var(--jp-red-70);
186
- box-shadow: inset 0 0 0 1px var(--jp-white), 0 0 0 var(--wp-admin-border-width-focus) var(--jp-red-70);
187
- }
188
- }
189
72
  }
190
73
 
191
74
  // LOADING
@@ -4,7 +4,7 @@
4
4
  .jetpack-footer {
5
5
  border-top: var(--wpds-border-width-xs, 1px) solid var(--wpds-color-stroke-surface-neutral-weak, #e0e0e0);
6
6
  box-sizing: border-box;
7
- font-size: var(--wpds-font-size-md, 13px);
7
+ font-size: var(--wpds-typography-font-size-md, 13px);
8
8
  padding: var(--wpds-dimension-padding-xl) var(--wpds-dimension-padding-2xl);
9
9
  width: 100%;
10
10
 
@@ -1,6 +1,6 @@
1
1
  import { Modal, Navigator } from '@wordpress/components';
2
2
  import clsx from 'clsx';
3
- import { useCallback, useContext } from 'react';
3
+ import { useCallback, useContext, useEffect, useRef } from 'react';
4
4
  import { NavigatorModalContext } from './context.ts';
5
5
  import { Screen } from './screen.tsx';
6
6
  import './styles.scss';
@@ -24,16 +24,36 @@ function InternalNavigatorModal( {
24
24
  ...props
25
25
  }: Omit< ModalProps, 'onRequestClose' > ) {
26
26
  const { onClose, initialPath } = useContext( NavigatorModalContext );
27
+ const overlayRef = useRef< HTMLDivElement >( null );
28
+ const isUserInteracting = useRef( false );
29
+
30
+ // Track pointer interaction on the overlay so we can distinguish
31
+ // user-initiated overlay clicks from the WP Modal dismisser mechanism,
32
+ // which also calls onRequestClose() without an event argument.
33
+ useEffect( () => {
34
+ const overlay = overlayRef.current;
35
+ if ( ! overlay ) {
36
+ return;
37
+ }
38
+ const handler = () => {
39
+ isUserInteracting.current = true;
40
+ };
41
+ overlay.addEventListener( 'pointerdown', handler );
42
+ return () => overlay.removeEventListener( 'pointerdown', handler );
43
+ }, [] );
27
44
 
28
45
  // WordPress Modal's dismisser mechanism (ModalContext) calls onRequestClose()
29
46
  // without arguments when another non-nested Modal mounts. We guard against
30
47
  // this so that external modals (e.g. Image Studio) don't destroy this one.
31
48
  // User-initiated closes (Escape, close button) always pass an event.
49
+ // Overlay clicks don't pass an event but are identified by the
50
+ // isUserInteracting flag set via the pointerdown listener above.
32
51
  // The NavigatorModal's own Header/Footer close buttons call context.onClose
33
52
  // directly and are unaffected by this guard.
34
53
  const onRequestClose = useCallback(
35
54
  ( event?: React.SyntheticEvent ) => {
36
- if ( event ) {
55
+ if ( event || isUserInteracting.current ) {
56
+ isUserInteracting.current = false;
37
57
  onClose?.();
38
58
  }
39
59
  },
@@ -42,6 +62,7 @@ function InternalNavigatorModal( {
42
62
 
43
63
  return (
44
64
  <Modal
65
+ ref={ overlayRef }
45
66
  __experimentalHideHeader
46
67
  onRequestClose={ onRequestClose }
47
68
  className={ clsx( 'jp-navigator-modal', className ) }
@@ -90,9 +90,6 @@
90
90
  width: 100%;
91
91
  height: auto;
92
92
  font-size: 18px;
93
- background: var(--jp-black);
94
- color: var(--jp-white) !important;
95
- border-radius: var(--jp-border-radius);
96
93
  padding: 14px 24px;
97
94
  margin: 24px 0 32px;
98
95
  justify-content: center;
@@ -1,6 +1,5 @@
1
1
  import { RadioControl as WPRadioControl } from '@wordpress/components';
2
2
  import clsx from 'clsx';
3
- import styles from './styles.module.scss';
4
3
  import type { FC, ReactNode } from 'react';
5
4
 
6
5
  export interface RadioControlProps {
@@ -42,7 +41,7 @@ const RadioControl: FC< RadioControlProps > = ( {
42
41
  return (
43
42
  <WPRadioControl
44
43
  selected={ selected }
45
- className={ clsx( styles.radio, className ) }
44
+ className={ clsx( 'radio', className ) }
46
45
  disabled={ disabled }
47
46
  help={ help }
48
47
  label={ label }
@@ -3,7 +3,6 @@
3
3
  color: var(--jp-black);
4
4
 
5
5
  .terms-of-service__link {
6
- color: var(--jp-green-50);
7
6
  white-space: nowrap;
8
7
  }
9
8
  }
@@ -3,8 +3,6 @@
3
3
  /// Overrides the @wordpress/components ToggleControl component.
4
4
  /// @link https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/form-toggle
5
5
  .toggle {
6
- --base-width: 8px;
7
- --track-width: calc(var(--base-width) * 6);
8
6
 
9
7
  &.is-small {
10
8
  --base-width: 6px;
@@ -13,41 +11,6 @@
13
11
  &.no-label :global(.components-toggle-control__label) {
14
12
  display: none;
15
13
  }
16
-
17
- :global {
18
-
19
- .components-form-toggle {
20
- --wp-admin-theme-color: var(--jp-green-40);
21
- height: calc(var(--base-width) * 3);
22
-
23
-
24
- &__input:focus + .components-form-toggle__track {
25
- box-shadow: 0 0 0 2px var(--jp-white), 0 0 0 4px var(--jp-green-50);
26
- }
27
-
28
- .components-form-toggle__track {
29
- width: var(--track-width);
30
- height: calc(var(--base-width) * 3);
31
- border-radius: 12px;
32
- border-width: 2px;
33
- }
34
-
35
- .components-form-toggle__thumb {
36
- width: calc(var(--base-width) * 2);
37
- height: calc(var(--base-width) * 2);
38
- top: calc(var(--base-width) / 2);
39
- left: calc(var(--base-width) / 2);
40
- }
41
-
42
- &.is-checked .components-form-toggle__thumb {
43
- transform: translateX(calc(var(--base-width) * 3));
44
- }
45
- }
46
-
47
- .components-toggle-control__help {
48
- margin-inline-start: calc(var(--track-width) + var(--spacing-base));
49
- }
50
- }
51
14
  }
52
15
 
53
16
  .toggle.is-toggling {
@@ -74,15 +74,9 @@
74
74
 
75
75
  .upsell-banner--content-cta-button {
76
76
  white-space: nowrap;
77
- box-shadow: inset 0 0 0 1.5px rgb(0, 0, 0);
78
77
  font-weight: 400;
79
78
  padding: 8px 16px;
80
79
 
81
- &.secondary {
82
- background-color: var(--jp-white);
83
- color: var(--jp-black);
84
- }
85
-
86
80
  &.primary {
87
81
  margin-left: 8px;
88
82
  }
package/index.ts CHANGED
@@ -51,7 +51,6 @@ export { default as Button } from './components/button/index.tsx';
51
51
  export type { ButtonProps } from './components/button/types.ts';
52
52
  export { default as LoadingPlaceholder } from './components/loading-placeholder/index.tsx';
53
53
  export { default as TermsOfService } from './components/terms-of-service/index.tsx';
54
- export { default as Badge } from './components/badge/index.tsx';
55
54
  export { default as Chip } from './components/chip/index.tsx';
56
55
  export {
57
56
  default as PricingTable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/jetpack-components",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "Jetpack Components Package",
5
5
  "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/components/#readme",
6
6
  "bugs": {
@@ -45,23 +45,23 @@
45
45
  ],
46
46
  "dependencies": {
47
47
  "@automattic/format-currency": "1.0.1",
48
- "@automattic/jetpack-api": "^1.0.22",
49
- "@automattic/jetpack-boost-score-api": "^1.0.37",
48
+ "@automattic/jetpack-api": "^1.0.23",
49
+ "@automattic/jetpack-boost-score-api": "^1.0.38",
50
50
  "@automattic/jetpack-script-data": "^0.6.2",
51
- "@automattic/number-formatters": "^1.1.5",
51
+ "@automattic/number-formatters": "^1.1.6",
52
52
  "@babel/runtime": "^7",
53
- "@wordpress/admin-ui": "1.10.0",
54
- "@wordpress/browserslist-config": "6.43.0",
55
- "@wordpress/components": "32.5.0",
56
- "@wordpress/compose": "7.43.0",
57
- "@wordpress/data": "10.43.0",
58
- "@wordpress/date": "5.43.0",
59
- "@wordpress/element": "6.43.0",
60
- "@wordpress/i18n": "6.16.0",
61
- "@wordpress/icons": "12.0.0",
62
- "@wordpress/notices": "5.43.0",
63
- "@wordpress/theme": "0.10.0",
64
- "@wordpress/ui": "0.9.0",
53
+ "@wordpress/admin-ui": "1.12.0",
54
+ "@wordpress/browserslist-config": "6.44.0",
55
+ "@wordpress/components": "32.6.0",
56
+ "@wordpress/compose": "7.44.0",
57
+ "@wordpress/data": "10.44.0",
58
+ "@wordpress/date": "5.44.0",
59
+ "@wordpress/element": "6.44.0",
60
+ "@wordpress/i18n": "6.17.0",
61
+ "@wordpress/icons": "12.2.0",
62
+ "@wordpress/notices": "5.44.0",
63
+ "@wordpress/theme": "0.11.0",
64
+ "@wordpress/ui": "0.11.0",
65
65
  "clsx": "2.1.1",
66
66
  "prop-types": "^15.7.2",
67
67
  "qrcode.react": "4.2.0",
@@ -71,12 +71,12 @@
71
71
  "uplot-react": "1.1.4"
72
72
  },
73
73
  "devDependencies": {
74
- "@automattic/jetpack-base-styles": "^1.0.21",
74
+ "@automattic/jetpack-base-styles": "^1.1.0",
75
75
  "@babel/core": "7.29.0",
76
76
  "@babel/preset-react": "7.28.5",
77
77
  "@jest/globals": "30.3.0",
78
- "@storybook/addon-docs": "10.3.3",
79
- "@storybook/react": "10.3.3",
78
+ "@storybook/addon-docs": "10.3.5",
79
+ "@storybook/react": "10.3.5",
80
80
  "@testing-library/dom": "10.4.1",
81
81
  "@testing-library/react": "16.3.2",
82
82
  "@testing-library/user-event": "14.6.1",
@@ -89,7 +89,7 @@
89
89
  "react": "18.3.1",
90
90
  "react-dom": "18.3.1",
91
91
  "require-from-string": "2.0.2",
92
- "storybook": "10.3.3",
92
+ "storybook": "10.3.5",
93
93
  "ts-dedent": "2.2.0",
94
94
  "typescript": "5.9.3",
95
95
  "webpack": "5.105.2",
@@ -1,19 +0,0 @@
1
- import type { ReactNode, FC } from 'react';
2
- type BadgeProps = {
3
- children?: ReactNode;
4
- className?: string;
5
- variant?: 'success' | 'warning' | 'danger';
6
- [key: string]: unknown;
7
- };
8
- /**
9
- * Badge component
10
- *
11
- * @param {object} props - The component properties.
12
- * @param {string} props.variant - The badge variant (i.e. 'success', 'warning', 'danger').
13
- * @param {JSX.Element} props.children - Badge text or content.
14
- * @param {string} props.className - Additional class name to pass to the Badge component.
15
- *
16
- * @return {ReactElement} The `Badge` component.
17
- */
18
- declare const Badge: FC<BadgeProps>;
19
- export default Badge;
@@ -1,22 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import clsx from 'clsx';
3
- import styles from './style.module.scss';
4
- /**
5
- * Badge component
6
- *
7
- * @param {object} props - The component properties.
8
- * @param {string} props.variant - The badge variant (i.e. 'success', 'warning', 'danger').
9
- * @param {JSX.Element} props.children - Badge text or content.
10
- * @param {string} props.className - Additional class name to pass to the Badge component.
11
- *
12
- * @return {ReactElement} The `Badge` component.
13
- */
14
- const Badge = ({ children, className, variant, ...props }) => {
15
- const classes = clsx(styles.badge, {
16
- [styles['is-success']]: variant === 'success',
17
- [styles['is-warning']]: variant === 'warning',
18
- [styles['is-danger']]: variant === 'danger',
19
- }, className);
20
- return (_jsx("span", { className: classes, ...props, children: children }));
21
- };
22
- export default Badge;
@@ -1,25 +0,0 @@
1
- .badge {
2
- display: inline-block;
3
- border-radius: 4px;
4
- background-color: var(--jp-gray-0);
5
- color: var(--jp-gray-80);
6
- padding: 4px 8px;
7
- font-size: 13px;
8
- font-weight: 400;
9
- line-height: 16px;
10
-
11
- &.is-success {
12
- background-color: var(--jp-green-5);
13
- color: var(--jp-green-50);
14
- }
15
-
16
- &.is-warning {
17
- background-color: var(--jp-yellow-5);
18
- color: var(--jp-yellow-60);
19
- }
20
-
21
- &.is-danger {
22
- background-color: var(--jp-red-5);
23
- color: var(--jp-red-70);
24
- }
25
- }
@@ -1,26 +0,0 @@
1
- /// Radio Control
2
- ///
3
- /// Overrides the @wordpress/components RadioControl component.
4
- /// @link https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/radio-control
5
-
6
- .radio {
7
-
8
- :global {
9
-
10
- .components-radio-control {
11
-
12
- &__input[type="radio"] {
13
-
14
- &:checked {
15
- background: var(--jp-green-40);
16
- border-color: var(--jp-green-40);
17
- }
18
-
19
- &:focus {
20
- border-color: var(--jp-green-50);
21
- box-shadow: 0 0 0 2px var(--jp-white), 0 0 0 4px var(--jp-green-50);
22
- }
23
- }
24
- }
25
- }
26
- }
@@ -1,39 +0,0 @@
1
- import clsx from 'clsx';
2
- import styles from './style.module.scss';
3
- import type { ReactNode, ReactElement, FC } from 'react';
4
-
5
- type BadgeProps = {
6
- children?: ReactNode;
7
- className?: string;
8
- variant?: 'success' | 'warning' | 'danger';
9
- [ key: string ]: unknown;
10
- };
11
-
12
- /**
13
- * Badge component
14
- *
15
- * @param {object} props - The component properties.
16
- * @param {string} props.variant - The badge variant (i.e. 'success', 'warning', 'danger').
17
- * @param {JSX.Element} props.children - Badge text or content.
18
- * @param {string} props.className - Additional class name to pass to the Badge component.
19
- *
20
- * @return {ReactElement} The `Badge` component.
21
- */
22
- const Badge: FC< BadgeProps > = ( { children, className, variant, ...props } ) => {
23
- const classes = clsx(
24
- styles.badge,
25
- {
26
- [ styles[ 'is-success' ] ]: variant === 'success',
27
- [ styles[ 'is-warning' ] ]: variant === 'warning',
28
- [ styles[ 'is-danger' ] ]: variant === 'danger',
29
- },
30
- className
31
- );
32
- return (
33
- <span className={ classes } { ...props }>
34
- { children }
35
- </span>
36
- );
37
- };
38
-
39
- export default Badge;
@@ -1,25 +0,0 @@
1
- .badge {
2
- display: inline-block;
3
- border-radius: 4px;
4
- background-color: var(--jp-gray-0);
5
- color: var(--jp-gray-80);
6
- padding: 4px 8px;
7
- font-size: 13px;
8
- font-weight: 400;
9
- line-height: 16px;
10
-
11
- &.is-success {
12
- background-color: var(--jp-green-5);
13
- color: var(--jp-green-50);
14
- }
15
-
16
- &.is-warning {
17
- background-color: var(--jp-yellow-5);
18
- color: var(--jp-yellow-60);
19
- }
20
-
21
- &.is-danger {
22
- background-color: var(--jp-red-5);
23
- color: var(--jp-red-70);
24
- }
25
- }
@@ -1,26 +0,0 @@
1
- /// Radio Control
2
- ///
3
- /// Overrides the @wordpress/components RadioControl component.
4
- /// @link https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/radio-control
5
-
6
- .radio {
7
-
8
- :global {
9
-
10
- .components-radio-control {
11
-
12
- &__input[type="radio"] {
13
-
14
- &:checked {
15
- background: var(--jp-green-40);
16
- border-color: var(--jp-green-40);
17
- }
18
-
19
- &:focus {
20
- border-color: var(--jp-green-50);
21
- box-shadow: 0 0 0 2px var(--jp-white), 0 0 0 4px var(--jp-green-50);
22
- }
23
- }
24
- }
25
- }
26
- }