@automattic/jetpack-components 1.4.8 → 1.4.9
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 +9 -0
- package/build/components/button/index.js +15 -2
- package/build/components/button/types.d.ts +6 -3
- package/build/components/icon-tooltip/index.js +1 -1
- package/build/components/navigator-modal/footer.d.ts +2 -3
- package/build/components/navigator-modal/footer.js +7 -7
- package/build/components/navigator-modal/header.js +1 -2
- package/build/components/navigator-modal/index.d.ts +7 -3
- package/build/components/navigator-modal/index.js +7 -7
- package/build/components/navigator-modal/screen.d.ts +7 -8
- package/build/components/navigator-modal/screen.js +2 -3
- package/build/components/navigator-modal/types.d.ts +0 -10
- package/build/components/number-control/index.d.ts +3 -2
- package/build/components/number-control/index.js +2 -1
- package/build/components/pricing-card/types.d.ts +2 -3
- package/build/components/split-button/index.js +7 -1
- package/components/button/index.tsx +16 -15
- package/components/button/types.ts +11 -3
- package/components/copy-to-clipboard/index.tsx +3 -3
- package/components/icon-tooltip/index.tsx +2 -2
- package/components/navigator-modal/footer.tsx +9 -10
- package/components/navigator-modal/header.tsx +2 -3
- package/components/navigator-modal/index.tsx +22 -9
- package/components/navigator-modal/screen.tsx +25 -22
- package/components/navigator-modal/{styles.module.scss → styles.scss} +31 -42
- package/components/navigator-modal/types.ts +0 -12
- package/components/number-control/index.jsx +2 -1
- package/components/pricing-card/types.ts +2 -3
- package/components/split-button/index.tsx +8 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
### This is a list detailing changes for the Jetpack RNA Components package releases.
|
|
4
4
|
|
|
5
|
+
## [1.4.9] - 2026-02-02
|
|
6
|
+
### Added
|
|
7
|
+
- NavigatorModal: Allow passing all the props supported by underlying components. [#46856]
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- NavigatorModal: Allow customizing the modal via stable BEM class names. [#46818]
|
|
11
|
+
- Update package dependencies. [#46854]
|
|
12
|
+
|
|
5
13
|
## [1.4.8] - 2026-01-26
|
|
6
14
|
### Changed
|
|
7
15
|
- Update dependencies.
|
|
@@ -1624,6 +1632,7 @@
|
|
|
1624
1632
|
### Changed
|
|
1625
1633
|
- Update node version requirement to 14.16.1
|
|
1626
1634
|
|
|
1635
|
+
[1.4.9]: https://github.com/Automattic/jetpack-components/compare/1.4.8...1.4.9
|
|
1627
1636
|
[1.4.8]: https://github.com/Automattic/jetpack-components/compare/1.4.7...1.4.8
|
|
1628
1637
|
[1.4.7]: https://github.com/Automattic/jetpack-components/compare/1.4.6...1.4.7
|
|
1629
1638
|
[1.4.6]: https://github.com/Automattic/jetpack-components/compare/1.4.5...1.4.6
|
|
@@ -22,7 +22,6 @@ const Button = forwardRef((props, ref) => {
|
|
|
22
22
|
[styles['full-width']]: fullWidth,
|
|
23
23
|
[styles['is-icon-button']]: Boolean(icon) && !children,
|
|
24
24
|
});
|
|
25
|
-
componentProps.ref = ref;
|
|
26
25
|
const externalIconSize = size === 'normal' ? 20 : 16;
|
|
27
26
|
const externalIcon = isExternalLink && (_jsxs(_Fragment, { children: [_jsx(Icon, { size: externalIconSize, icon: external, className: styles['external-icon'] }), _jsx(VisuallyHidden, { as: "span", children:
|
|
28
27
|
/* translators: accessibility text */
|
|
@@ -33,7 +32,21 @@ const Button = forwardRef((props, ref) => {
|
|
|
33
32
|
children[0] !== null &&
|
|
34
33
|
// Tooltip should not considered as a child
|
|
35
34
|
children?.[0]?.props?.className !== 'components-tooltip';
|
|
36
|
-
|
|
35
|
+
// Cast to work around WPButton's strict union type that can't be satisfied when spreading props
|
|
36
|
+
const wpButtonProps = {
|
|
37
|
+
ref,
|
|
38
|
+
target: externalTarget,
|
|
39
|
+
variant,
|
|
40
|
+
className: clsx(className, { 'has-text': !!icon && hasChildren }),
|
|
41
|
+
icon: !isExternalLink ? icon : undefined,
|
|
42
|
+
iconSize,
|
|
43
|
+
disabled,
|
|
44
|
+
'aria-disabled': disabled,
|
|
45
|
+
isDestructive,
|
|
46
|
+
text,
|
|
47
|
+
...componentProps,
|
|
48
|
+
};
|
|
49
|
+
return (_jsxs(WPButton, { ...wpButtonProps, children: [isLoading && _jsx(Spinner, {}), _jsx("span", { children: children }), externalIcon] }));
|
|
37
50
|
});
|
|
38
51
|
Button.displayName = 'Button';
|
|
39
52
|
export default Button;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button } from '@wordpress/components';
|
|
2
|
-
import type { ComponentProps, ForwardedRef, ReactNode } from 'react';
|
|
2
|
+
import type { ComponentProps, ForwardedRef, MouseEventHandler, ReactNode } from 'react';
|
|
3
3
|
type JetpackButtonBaseProps = {
|
|
4
4
|
className?: string;
|
|
5
5
|
children?: ReactNode;
|
|
@@ -13,7 +13,10 @@ type JetpackButtonBaseProps = {
|
|
|
13
13
|
weight?: 'bold' | 'regular';
|
|
14
14
|
fullWidth?: boolean;
|
|
15
15
|
ref?: ForwardedRef<unknown>;
|
|
16
|
+
href?: string;
|
|
17
|
+
target?: string;
|
|
18
|
+
onClick?: MouseEventHandler<HTMLButtonElement> | MouseEventHandler<HTMLAnchorElement>;
|
|
16
19
|
};
|
|
17
|
-
type
|
|
18
|
-
export type ButtonProps = JetpackButtonBaseProps &
|
|
20
|
+
type WPButtonBaseProps = Omit<ComponentProps<typeof Button>, 'size' | 'variant' | 'disabled' | 'href' | 'target' | 'onClick'>;
|
|
21
|
+
export type ButtonProps = JetpackButtonBaseProps & WPButtonBaseProps;
|
|
19
22
|
export {};
|
|
@@ -40,7 +40,7 @@ const IconTooltip = ({ className = '', iconClassName = '', placement = 'bottom-e
|
|
|
40
40
|
resize: false,
|
|
41
41
|
flip: false,
|
|
42
42
|
offset, // The distance (in px) between the anchor and the popover.
|
|
43
|
-
focusOnMount: '
|
|
43
|
+
focusOnMount: 'firstElement',
|
|
44
44
|
onClose: hideTooltip,
|
|
45
45
|
className: 'icon-tooltip-container',
|
|
46
46
|
inline,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Button } from '@wordpress/components';
|
|
2
|
-
|
|
3
|
-
export type FooterProps = SharedProps & {
|
|
2
|
+
export type FooterProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
4
3
|
actions?: Array<((props: {
|
|
5
4
|
navigate: VoidFunction;
|
|
6
5
|
}) => React.ReactElement) | React.ComponentProps<typeof Button>>;
|
|
@@ -13,4 +12,4 @@ export type FooterProps = SharedProps & {
|
|
|
13
12
|
*
|
|
14
13
|
* @return The rendered footer.
|
|
15
14
|
*/
|
|
16
|
-
export declare function Footer({ children, actions, isScreenLocked }: FooterProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function Footer({ children, actions, isScreenLocked, className, ...props }: FooterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Flex, FlexBlock, FlexItem, useNavigator } from '@wordpress/components';
|
|
3
|
+
import clsx from 'clsx';
|
|
3
4
|
import { useCallback, useContext } from 'react';
|
|
4
5
|
import { NavigatorModalContext } from "./context.js";
|
|
5
|
-
import styles from './styles.module.scss';
|
|
6
6
|
/**
|
|
7
7
|
* Renders a footer.
|
|
8
8
|
*
|
|
@@ -10,7 +10,7 @@ import styles from './styles.module.scss';
|
|
|
10
10
|
*
|
|
11
11
|
* @return The rendered footer.
|
|
12
12
|
*/
|
|
13
|
-
export function Footer({ children, actions, isScreenLocked }) {
|
|
13
|
+
export function Footer({ children, actions, isScreenLocked, className, ...props }) {
|
|
14
14
|
const navigator = useNavigator();
|
|
15
15
|
const context = useContext(NavigatorModalContext);
|
|
16
16
|
const navigate = useCallback(() => {
|
|
@@ -21,14 +21,14 @@ export function Footer({ children, actions, isScreenLocked }) {
|
|
|
21
21
|
context.onClose?.();
|
|
22
22
|
}
|
|
23
23
|
}, [isScreenLocked, navigator, context]);
|
|
24
|
-
return (_jsxs(Flex, { className:
|
|
25
|
-
if (typeof
|
|
26
|
-
return
|
|
24
|
+
return (_jsxs(Flex, { className: clsx('jp-navigator-modal__footer', className), ...props, children: [_jsx(FlexBlock, { children: children }), actions ? (_jsx(FlexItem, { children: _jsx(Flex, { children: actions.map((action, index) => {
|
|
25
|
+
if (typeof action === 'function') {
|
|
26
|
+
return action({ navigate });
|
|
27
27
|
}
|
|
28
|
-
return (_jsx(Button, { ...
|
|
28
|
+
return (_jsx(Button, { ...action,
|
|
29
29
|
// eslint-disable-next-line react/jsx-no-bind
|
|
30
30
|
onClick: event => {
|
|
31
|
-
|
|
31
|
+
action.onClick?.(event);
|
|
32
32
|
navigate();
|
|
33
33
|
} }, index));
|
|
34
34
|
}) }) })) : null] }));
|
|
@@ -4,7 +4,6 @@ import { __, isRTL } from '@wordpress/i18n';
|
|
|
4
4
|
import { chevronLeft, chevronRight, close } from '@wordpress/icons';
|
|
5
5
|
import { useCallback, useContext } from 'react';
|
|
6
6
|
import { NavigatorModalContext } from "./context.js";
|
|
7
|
-
import styles from './styles.module.scss';
|
|
8
7
|
/**
|
|
9
8
|
* Renders a header for the NavigatorModal.
|
|
10
9
|
* @param {HeaderProps} props - Props
|
|
@@ -17,5 +16,5 @@ export function Header({ icon, title, isScreenLocked }) {
|
|
|
17
16
|
const onGoBack = useCallback(() => {
|
|
18
17
|
navigator.goBack();
|
|
19
18
|
}, [navigator]);
|
|
20
|
-
return (_jsxs("div", { className:
|
|
19
|
+
return (_jsxs("div", { className: "jp-navigator-modal__header", children: [_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 })] }), context.isDismissible ? (_jsx(Button, { size: "compact", onClick: context.onClose, icon: close, label: __('Close', 'jetpack-components'), variant: "tertiary" })) : null] }));
|
|
21
20
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { Modal } from '@wordpress/components';
|
|
1
2
|
import { Screen } from './screen.tsx';
|
|
2
|
-
import
|
|
3
|
+
import './styles.scss';
|
|
4
|
+
import { TNavigatorModalContext } from './types.ts';
|
|
5
|
+
type ModalProps = React.ComponentProps<typeof Modal>;
|
|
6
|
+
type NavigatorModalProps = Omit<ModalProps, 'onRequestClose'> & TNavigatorModalContext;
|
|
3
7
|
/**
|
|
4
8
|
* Renders a modal with navigator capabilities.
|
|
5
9
|
*
|
|
6
|
-
* @param {
|
|
10
|
+
* @param {NavigatorModalProps} props - Props
|
|
7
11
|
*
|
|
8
12
|
* @return Component
|
|
9
13
|
*/
|
|
10
|
-
declare function NavigatorModalMain({ children, className, initialPath, onClose, isDismissible, }:
|
|
14
|
+
declare function NavigatorModalMain({ children, className, initialPath, onClose, isDismissible, ...props }: NavigatorModalProps): import("react/jsx-runtime").JSX.Element;
|
|
11
15
|
export declare const NavigatorModal: typeof NavigatorModalMain & {
|
|
12
16
|
Screen: typeof Screen & {
|
|
13
17
|
displayName: string;
|
|
@@ -4,27 +4,27 @@ import clsx from 'clsx';
|
|
|
4
4
|
import { useContext } from 'react';
|
|
5
5
|
import { NavigatorModalContext } from "./context.js";
|
|
6
6
|
import { Screen } from "./screen.js";
|
|
7
|
-
import
|
|
7
|
+
import './styles.scss';
|
|
8
8
|
/**
|
|
9
9
|
* Renders the internal NavigatorModal component.
|
|
10
10
|
*
|
|
11
|
-
* @param {
|
|
11
|
+
* @param { ModalProps } props - Props
|
|
12
12
|
*
|
|
13
13
|
* @return Component
|
|
14
14
|
*/
|
|
15
|
-
function InternalNavigatorModal({ children, className }) {
|
|
15
|
+
function InternalNavigatorModal({ children, className, ...props }) {
|
|
16
16
|
const context = useContext(NavigatorModalContext);
|
|
17
|
-
return (_jsx(Modal, { __experimentalHideHeader: true, onRequestClose: context.onClose, className: clsx(
|
|
17
|
+
return (_jsx(Modal, { __experimentalHideHeader: true, onRequestClose: context.onClose, className: clsx('jp-navigator-modal', className), ...props, children: _jsx(Navigator, { initialPath: context.initialPath, className: "jp-navigator-modal__navigator", children: children }) }));
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Renders a modal with navigator capabilities.
|
|
21
21
|
*
|
|
22
|
-
* @param {
|
|
22
|
+
* @param {NavigatorModalProps} props - Props
|
|
23
23
|
*
|
|
24
24
|
* @return Component
|
|
25
25
|
*/
|
|
26
|
-
function NavigatorModalMain({ children, className, initialPath = '/', onClose, isDismissible = true, }) {
|
|
27
|
-
return (_jsx(NavigatorModalContext.Provider, { value: { onClose, initialPath, isDismissible }, children: _jsx(InternalNavigatorModal, { className: className, children: children }) }));
|
|
26
|
+
function NavigatorModalMain({ children, className, initialPath = '/', onClose, isDismissible = true, ...props }) {
|
|
27
|
+
return (_jsx(NavigatorModalContext.Provider, { value: { onClose, initialPath, isDismissible }, children: _jsx(InternalNavigatorModal, { className: className, ...props, children: children }) }));
|
|
28
28
|
}
|
|
29
29
|
export const NavigatorModal = Object.assign(NavigatorModalMain, {
|
|
30
30
|
Screen: Object.assign(Screen, {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { Navigator } from '@wordpress/components';
|
|
1
2
|
import { FooterProps } from './footer.tsx';
|
|
2
|
-
export type ScreenProps = {
|
|
3
|
+
export type ScreenProps = Omit<React.ComponentProps<typeof Navigator.Screen>, 'content' | 'children'> & {
|
|
3
4
|
/**
|
|
4
5
|
* The title of the screen.
|
|
5
6
|
*/
|
|
@@ -34,17 +35,15 @@ export type ScreenProps = {
|
|
|
34
35
|
* className to be applied to the modal.
|
|
35
36
|
*/
|
|
36
37
|
className?: string;
|
|
37
|
-
} & ({
|
|
38
38
|
/**
|
|
39
39
|
* The content of the screen.
|
|
40
40
|
*/
|
|
41
|
-
|
|
42
|
-
} | {
|
|
41
|
+
content?: React.ReactNode;
|
|
43
42
|
/**
|
|
44
|
-
* The
|
|
43
|
+
* The children of the screen. Alternative to `content`.
|
|
45
44
|
*/
|
|
46
|
-
|
|
47
|
-
}
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
};
|
|
48
47
|
/**
|
|
49
48
|
* Renders a screen.
|
|
50
49
|
*
|
|
@@ -52,4 +51,4 @@ export type ScreenProps = {
|
|
|
52
51
|
*
|
|
53
52
|
* @return The rendered screen.
|
|
54
53
|
*/
|
|
55
|
-
export declare function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, footerContent, footerActions, ...props }: ScreenProps): import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
export declare function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, footerContent, footerActions, children, content, ...props }: ScreenProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,7 +3,6 @@ import { Flex, Navigator } from '@wordpress/components';
|
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
import { Footer } from "./footer.js";
|
|
5
5
|
import { Header } from "./header.js";
|
|
6
|
-
import styles from './styles.module.scss';
|
|
7
6
|
/**
|
|
8
7
|
* Renders a screen.
|
|
9
8
|
*
|
|
@@ -11,7 +10,7 @@ import styles from './styles.module.scss';
|
|
|
11
10
|
*
|
|
12
11
|
* @return The rendered screen.
|
|
13
12
|
*/
|
|
14
|
-
export function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, footerContent, footerActions, ...props }) {
|
|
13
|
+
export function Screen({ path, className, title, sidebar, headerIcon, isScreenLocked, footerContent, footerActions, children, content, ...props }) {
|
|
15
14
|
const hasFooter = Boolean(footerContent || (footerActions && footerActions.length));
|
|
16
|
-
return (_jsx(Navigator.Screen, { path: path, className: clsx(
|
|
15
|
+
return (_jsx(Navigator.Screen, { path: path, className: clsx('jp-navigator-modal__screen', className), ...props, children: _jsxs(Flex, { direction: "column", gap: 0, children: [_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 })] }), hasFooter ? (_jsx(Footer, { actions: footerActions, isScreenLocked: isScreenLocked, children: footerContent })) : null] }) }));
|
|
17
16
|
}
|
|
@@ -12,13 +12,3 @@ export type TNavigatorModalContext = {
|
|
|
12
12
|
*/
|
|
13
13
|
onClose?: VoidFunction;
|
|
14
14
|
};
|
|
15
|
-
export type SharedProps = {
|
|
16
|
-
/**
|
|
17
|
-
* The content of the component.
|
|
18
|
-
*/
|
|
19
|
-
children: React.ReactNode;
|
|
20
|
-
/**
|
|
21
|
-
* className to be applied to the modal.
|
|
22
|
-
*/
|
|
23
|
-
className?: string;
|
|
24
|
-
};
|
|
@@ -3,8 +3,9 @@ export default NumberControl;
|
|
|
3
3
|
* This uses the experimental NumberControl from the block
|
|
4
4
|
* editor where available, otherwise it falls back to a
|
|
5
5
|
* standard TextControl, limited to numbers.
|
|
6
|
+
* @type {import('react').ComponentType<any>}
|
|
6
7
|
*
|
|
7
8
|
* @param {any} props - the NumberControl component props
|
|
8
|
-
* @return {
|
|
9
|
+
* @return {import('react').ReactNode} - NumberControl component
|
|
9
10
|
*/
|
|
10
|
-
declare const NumberControl: any
|
|
11
|
+
declare const NumberControl: import("react").ComponentType<any>;
|
|
@@ -5,9 +5,10 @@ TextControl, } from '@wordpress/components';
|
|
|
5
5
|
* This uses the experimental NumberControl from the block
|
|
6
6
|
* editor where available, otherwise it falls back to a
|
|
7
7
|
* standard TextControl, limited to numbers.
|
|
8
|
+
* @type {import('react').ComponentType<any>}
|
|
8
9
|
*
|
|
9
10
|
* @param {any} props - the NumberControl component props
|
|
10
|
-
* @return {
|
|
11
|
+
* @return {import('react').ReactNode} - NumberControl component
|
|
11
12
|
*/
|
|
12
13
|
const NumberControl = ExperimentalNumberControl ||
|
|
13
14
|
function CustomNumberControl(props) {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
import type { ComponentProps, ReactNode } from 'react';
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
6
5
|
export type PricingCardProps = {
|
|
7
6
|
/**
|
|
8
7
|
* The Title.
|
|
@@ -35,7 +34,7 @@ export type PricingCardProps = {
|
|
|
35
34
|
/**
|
|
36
35
|
* The CTA callback to be called on click.
|
|
37
36
|
*/
|
|
38
|
-
onCtaClick?:
|
|
37
|
+
onCtaClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
39
38
|
/**
|
|
40
39
|
* Optional informative text.
|
|
41
40
|
*/
|
|
@@ -3,6 +3,12 @@ import { Button, Flex, DropdownMenu } from '@wordpress/components';
|
|
|
3
3
|
import styles from './style.module.scss';
|
|
4
4
|
const DownIcon = () => (_jsx("svg", { width: "15", height: "9", fill: "none", xmlns: "http://www.w3.org/2000/svg", viewBox: "10 9 4 7", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "m18.004 10.555-6.005 5.459-6.004-5.459 1.009-1.11 4.995 4.542 4.996-4.542 1.009 1.11Z" }) }));
|
|
5
5
|
const SplitButton = ({ variant, controls, popoverProps, toggleProps, label, ...buttonProps }) => {
|
|
6
|
-
|
|
6
|
+
// Cast to work around WPButton's strict union type
|
|
7
|
+
const wpButtonProps = {
|
|
8
|
+
variant,
|
|
9
|
+
className: styles.button,
|
|
10
|
+
...buttonProps,
|
|
11
|
+
};
|
|
12
|
+
return (_jsx(Flex, { className: styles['split-button'], children: _jsxs("div", { role: "group", className: "components-button-group", children: [_jsx(Button, { ...wpButtonProps }), _jsx(DropdownMenu, { toggleProps: { variant, className: styles.button, ...toggleProps }, popoverProps: { noArrow: false, ...popoverProps }, icon: _jsx(DownIcon, {}), disableOpenOnArrowDown: true, controls: controls, label: label })] }) }));
|
|
7
13
|
};
|
|
8
14
|
export default SplitButton;
|
|
@@ -5,7 +5,6 @@ import clsx from 'clsx';
|
|
|
5
5
|
import { forwardRef } from 'react';
|
|
6
6
|
import styles from './style.module.scss';
|
|
7
7
|
import type { ButtonProps } from './types.ts';
|
|
8
|
-
import type { ReactNode } from 'react';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Button component
|
|
@@ -41,8 +40,6 @@ const Button = forwardRef< HTMLInputElement, ButtonProps >( ( props, ref ) => {
|
|
|
41
40
|
[ styles[ 'is-icon-button' ] ]: Boolean( icon ) && ! children,
|
|
42
41
|
} );
|
|
43
42
|
|
|
44
|
-
componentProps.ref = ref;
|
|
45
|
-
|
|
46
43
|
const externalIconSize = size === 'normal' ? 20 : 16;
|
|
47
44
|
const externalIcon = isExternalLink && (
|
|
48
45
|
<>
|
|
@@ -64,19 +61,23 @@ const Button = forwardRef< HTMLInputElement, ButtonProps >( ( props, ref ) => {
|
|
|
64
61
|
// Tooltip should not considered as a child
|
|
65
62
|
children?.[ 0 ]?.props?.className !== 'components-tooltip';
|
|
66
63
|
|
|
64
|
+
// Cast to work around WPButton's strict union type that can't be satisfied when spreading props
|
|
65
|
+
const wpButtonProps = {
|
|
66
|
+
ref,
|
|
67
|
+
target: externalTarget,
|
|
68
|
+
variant,
|
|
69
|
+
className: clsx( className, { 'has-text': !! icon && hasChildren } ),
|
|
70
|
+
icon: ! isExternalLink ? icon : undefined,
|
|
71
|
+
iconSize,
|
|
72
|
+
disabled,
|
|
73
|
+
'aria-disabled': disabled,
|
|
74
|
+
isDestructive,
|
|
75
|
+
text,
|
|
76
|
+
...componentProps,
|
|
77
|
+
} as React.ComponentProps< typeof WPButton >;
|
|
78
|
+
|
|
67
79
|
return (
|
|
68
|
-
<WPButton
|
|
69
|
-
target={ externalTarget }
|
|
70
|
-
variant={ variant }
|
|
71
|
-
className={ clsx( className, { 'has-text': !! icon && hasChildren } ) }
|
|
72
|
-
icon={ ! isExternalLink ? icon : undefined }
|
|
73
|
-
iconSize={ iconSize }
|
|
74
|
-
disabled={ disabled }
|
|
75
|
-
aria-disabled={ disabled }
|
|
76
|
-
isDestructive={ isDestructive }
|
|
77
|
-
text={ text }
|
|
78
|
-
{ ...componentProps }
|
|
79
|
-
>
|
|
80
|
+
<WPButton { ...wpButtonProps }>
|
|
80
81
|
{ isLoading && <Spinner /> }
|
|
81
82
|
<span>{ children }</span>
|
|
82
83
|
{ externalIcon }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button } from '@wordpress/components';
|
|
2
|
-
import type { ComponentProps, ForwardedRef, ReactNode } from 'react';
|
|
2
|
+
import type { ComponentProps, ForwardedRef, MouseEventHandler, ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
type JetpackButtonBaseProps = {
|
|
5
5
|
className?: string;
|
|
@@ -14,8 +14,16 @@ type JetpackButtonBaseProps = {
|
|
|
14
14
|
weight?: 'bold' | 'regular';
|
|
15
15
|
fullWidth?: boolean;
|
|
16
16
|
ref?: ForwardedRef< unknown >;
|
|
17
|
+
href?: string;
|
|
18
|
+
target?: string;
|
|
19
|
+
onClick?: MouseEventHandler< HTMLButtonElement > | MouseEventHandler< HTMLAnchorElement >;
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
// Extract base props from WordPress Button, omitting the union-discriminated properties
|
|
23
|
+
// that cause type conflicts (size, variant, disabled, href)
|
|
24
|
+
type WPButtonBaseProps = Omit<
|
|
25
|
+
ComponentProps< typeof Button >,
|
|
26
|
+
'size' | 'variant' | 'disabled' | 'href' | 'target' | 'onClick'
|
|
27
|
+
>;
|
|
20
28
|
|
|
21
|
-
export type ButtonProps = JetpackButtonBaseProps &
|
|
29
|
+
export type ButtonProps = JetpackButtonBaseProps & WPButtonBaseProps;
|
|
@@ -4,7 +4,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
4
4
|
import Button from '../button/index.tsx';
|
|
5
5
|
import { ClipboardIcon, CheckmarkIcon } from '../icons/index.tsx';
|
|
6
6
|
import { CopyToClipboardProps } from './types.ts';
|
|
7
|
-
import type { FC
|
|
7
|
+
import type { FC } from 'react';
|
|
8
8
|
|
|
9
9
|
export const CopyToClipboard: FC< CopyToClipboardProps > = ( {
|
|
10
10
|
buttonStyle = 'icon',
|
|
@@ -40,8 +40,8 @@ export const CopyToClipboard: FC< CopyToClipboardProps > = ( {
|
|
|
40
40
|
};
|
|
41
41
|
}, [] );
|
|
42
42
|
|
|
43
|
-
let icon:
|
|
44
|
-
let label:
|
|
43
|
+
let icon: JSX.Element = null;
|
|
44
|
+
let label: string = null;
|
|
45
45
|
|
|
46
46
|
if ( 'text' !== buttonStyle ) {
|
|
47
47
|
icon = hasCopied ? <CheckmarkIcon /> : <ClipboardIcon />;
|
|
@@ -64,12 +64,12 @@ const IconTooltip: FC< IconTooltipProps > = ( {
|
|
|
64
64
|
resize: false,
|
|
65
65
|
flip: false,
|
|
66
66
|
offset, // The distance (in px) between the anchor and the popover.
|
|
67
|
-
focusOnMount: '
|
|
67
|
+
focusOnMount: 'firstElement',
|
|
68
68
|
onClose: hideTooltip,
|
|
69
69
|
className: 'icon-tooltip-container',
|
|
70
70
|
inline,
|
|
71
71
|
shift,
|
|
72
|
-
}
|
|
72
|
+
} satisfies Omit< React.ComponentProps< typeof Popover >, 'children' >;
|
|
73
73
|
|
|
74
74
|
const isAnchorWrapper = popoverAnchorStyle === 'wrapper';
|
|
75
75
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Button, Flex, FlexBlock, FlexItem, useNavigator } from '@wordpress/components';
|
|
2
|
+
import clsx from 'clsx';
|
|
2
3
|
import { useCallback, useContext } from 'react';
|
|
3
4
|
import { NavigatorModalContext } from './context.ts';
|
|
4
|
-
import styles from './styles.module.scss';
|
|
5
|
-
import { SharedProps } from './types.ts';
|
|
6
5
|
|
|
7
|
-
export type FooterProps =
|
|
6
|
+
export type FooterProps = React.HTMLAttributes< HTMLDivElement > & {
|
|
8
7
|
actions?: Array<
|
|
9
8
|
| ( ( props: { navigate: VoidFunction } ) => React.ReactElement )
|
|
10
9
|
| React.ComponentProps< typeof Button >
|
|
@@ -19,7 +18,7 @@ export type FooterProps = SharedProps & {
|
|
|
19
18
|
*
|
|
20
19
|
* @return The rendered footer.
|
|
21
20
|
*/
|
|
22
|
-
export function Footer( { children, actions, isScreenLocked }: FooterProps ) {
|
|
21
|
+
export function Footer( { children, actions, isScreenLocked, className, ...props }: FooterProps ) {
|
|
23
22
|
const navigator = useNavigator();
|
|
24
23
|
const context = useContext( NavigatorModalContext );
|
|
25
24
|
|
|
@@ -32,23 +31,23 @@ export function Footer( { children, actions, isScreenLocked }: FooterProps ) {
|
|
|
32
31
|
}, [ isScreenLocked, navigator, context ] );
|
|
33
32
|
|
|
34
33
|
return (
|
|
35
|
-
<Flex className={
|
|
34
|
+
<Flex className={ clsx( 'jp-navigator-modal__footer', className ) } { ...props }>
|
|
36
35
|
<FlexBlock>{ children }</FlexBlock>
|
|
37
36
|
{ actions ? (
|
|
38
37
|
<FlexItem>
|
|
39
38
|
<Flex>
|
|
40
|
-
{ actions.map( (
|
|
41
|
-
if ( typeof
|
|
42
|
-
return
|
|
39
|
+
{ actions.map( ( action, index ) => {
|
|
40
|
+
if ( typeof action === 'function' ) {
|
|
41
|
+
return action( { navigate } );
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
return (
|
|
46
45
|
<Button
|
|
47
46
|
key={ index }
|
|
48
|
-
{ ...
|
|
47
|
+
{ ...action }
|
|
49
48
|
// eslint-disable-next-line react/jsx-no-bind
|
|
50
49
|
onClick={ event => {
|
|
51
|
-
|
|
50
|
+
action.onClick?.( event );
|
|
52
51
|
navigate();
|
|
53
52
|
} }
|
|
54
53
|
/>
|
|
@@ -3,7 +3,6 @@ import { __, isRTL } from '@wordpress/i18n';
|
|
|
3
3
|
import { chevronLeft, chevronRight, close } from '@wordpress/icons';
|
|
4
4
|
import { useCallback, useContext } from 'react';
|
|
5
5
|
import { NavigatorModalContext } from './context.ts';
|
|
6
|
-
import styles from './styles.module.scss';
|
|
7
6
|
|
|
8
7
|
export type HeaderProps = {
|
|
9
8
|
/**
|
|
@@ -35,8 +34,8 @@ export function Header( { icon, title, isScreenLocked }: HeaderProps ) {
|
|
|
35
34
|
}, [ navigator ] );
|
|
36
35
|
|
|
37
36
|
return (
|
|
38
|
-
<div className=
|
|
39
|
-
<div className=
|
|
37
|
+
<div className="jp-navigator-modal__header">
|
|
38
|
+
<div className="jp-navigator-modal__title-wrap">
|
|
40
39
|
{ ! isScreenLocked ? (
|
|
41
40
|
<Button
|
|
42
41
|
label={ __( 'Go back', 'jetpack-components' ) }
|
|
@@ -3,26 +3,36 @@ import clsx from 'clsx';
|
|
|
3
3
|
import { useContext } from 'react';
|
|
4
4
|
import { NavigatorModalContext } from './context.ts';
|
|
5
5
|
import { Screen } from './screen.tsx';
|
|
6
|
-
import
|
|
7
|
-
import { TNavigatorModalContext
|
|
6
|
+
import './styles.scss';
|
|
7
|
+
import { TNavigatorModalContext } from './types.ts';
|
|
8
|
+
|
|
9
|
+
type ModalProps = React.ComponentProps< typeof Modal >;
|
|
10
|
+
|
|
11
|
+
// Omit onRequestClose since NavigatorModal uses onClose from TNavigatorModalContext instead
|
|
12
|
+
type NavigatorModalProps = Omit< ModalProps, 'onRequestClose' > & TNavigatorModalContext;
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Renders the internal NavigatorModal component.
|
|
11
16
|
*
|
|
12
|
-
* @param {
|
|
17
|
+
* @param { ModalProps } props - Props
|
|
13
18
|
*
|
|
14
19
|
* @return Component
|
|
15
20
|
*/
|
|
16
|
-
function InternalNavigatorModal( {
|
|
21
|
+
function InternalNavigatorModal( {
|
|
22
|
+
children,
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}: Omit< ModalProps, 'onRequestClose' > ) {
|
|
17
26
|
const context = useContext( NavigatorModalContext );
|
|
18
27
|
|
|
19
28
|
return (
|
|
20
29
|
<Modal
|
|
21
30
|
__experimentalHideHeader
|
|
22
31
|
onRequestClose={ context.onClose }
|
|
23
|
-
className={ clsx(
|
|
32
|
+
className={ clsx( 'jp-navigator-modal', className ) }
|
|
33
|
+
{ ...props }
|
|
24
34
|
>
|
|
25
|
-
<Navigator initialPath={ context.initialPath } className=
|
|
35
|
+
<Navigator initialPath={ context.initialPath } className="jp-navigator-modal__navigator">
|
|
26
36
|
{ children }
|
|
27
37
|
</Navigator>
|
|
28
38
|
</Modal>
|
|
@@ -32,7 +42,7 @@ function InternalNavigatorModal( { children, className }: SharedProps ) {
|
|
|
32
42
|
/**
|
|
33
43
|
* Renders a modal with navigator capabilities.
|
|
34
44
|
*
|
|
35
|
-
* @param {
|
|
45
|
+
* @param {NavigatorModalProps} props - Props
|
|
36
46
|
*
|
|
37
47
|
* @return Component
|
|
38
48
|
*/
|
|
@@ -42,10 +52,13 @@ function NavigatorModalMain( {
|
|
|
42
52
|
initialPath = '/',
|
|
43
53
|
onClose,
|
|
44
54
|
isDismissible = true,
|
|
45
|
-
|
|
55
|
+
...props
|
|
56
|
+
}: NavigatorModalProps ) {
|
|
46
57
|
return (
|
|
47
58
|
<NavigatorModalContext.Provider value={ { onClose, initialPath, isDismissible } }>
|
|
48
|
-
<InternalNavigatorModal className={ className }
|
|
59
|
+
<InternalNavigatorModal className={ className } { ...props }>
|
|
60
|
+
{ children }
|
|
61
|
+
</InternalNavigatorModal>
|
|
49
62
|
</NavigatorModalContext.Provider>
|
|
50
63
|
);
|
|
51
64
|
}
|
|
@@ -2,9 +2,11 @@ import { Flex, Navigator } from '@wordpress/components';
|
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { Footer, FooterProps } from './footer.tsx';
|
|
4
4
|
import { Header } from './header.tsx';
|
|
5
|
-
import styles from './styles.module.scss';
|
|
6
5
|
|
|
7
|
-
export type ScreenProps =
|
|
6
|
+
export type ScreenProps = Omit<
|
|
7
|
+
React.ComponentProps< typeof Navigator.Screen >,
|
|
8
|
+
'content' | 'children'
|
|
9
|
+
> & {
|
|
8
10
|
/**
|
|
9
11
|
* The title of the screen.
|
|
10
12
|
*/
|
|
@@ -43,20 +45,17 @@ export type ScreenProps = {
|
|
|
43
45
|
* className to be applied to the modal.
|
|
44
46
|
*/
|
|
45
47
|
className?: string;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
content: React.ReactNode;
|
|
58
|
-
}
|
|
59
|
-
);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The content of the screen.
|
|
51
|
+
*/
|
|
52
|
+
content?: React.ReactNode;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The children of the screen. Alternative to `content`.
|
|
56
|
+
*/
|
|
57
|
+
children?: React.ReactNode;
|
|
58
|
+
};
|
|
60
59
|
|
|
61
60
|
/**
|
|
62
61
|
* Renders a screen.
|
|
@@ -74,20 +73,24 @@ export function Screen( {
|
|
|
74
73
|
isScreenLocked,
|
|
75
74
|
footerContent,
|
|
76
75
|
footerActions,
|
|
76
|
+
children,
|
|
77
|
+
content,
|
|
77
78
|
...props
|
|
78
79
|
}: ScreenProps ) {
|
|
79
80
|
const hasFooter = Boolean( footerContent || ( footerActions && footerActions.length ) );
|
|
80
81
|
|
|
81
82
|
return (
|
|
82
|
-
<Navigator.Screen
|
|
83
|
+
<Navigator.Screen
|
|
84
|
+
path={ path }
|
|
85
|
+
className={ clsx( 'jp-navigator-modal__screen', className ) }
|
|
86
|
+
{ ...props }
|
|
87
|
+
>
|
|
83
88
|
<Flex direction="column" gap={ 0 }>
|
|
84
89
|
<Header title={ title } isScreenLocked={ isScreenLocked } icon={ headerIcon } />
|
|
85
90
|
|
|
86
|
-
<Flex gap={ 0 } align="start" className=
|
|
87
|
-
{ sidebar ? <div className=
|
|
88
|
-
<div className={
|
|
89
|
-
{ ( 'children' in props && props.children ) || ( 'content' in props && props.content ) }
|
|
90
|
-
</div>
|
|
91
|
+
<Flex gap={ 0 } align="start" className="jp-navigator-modal__body">
|
|
92
|
+
{ sidebar ? <div className="jp-navigator-modal__sidebar">{ sidebar }</div> : null }
|
|
93
|
+
<div className="jp-navigator-modal__content">{ content ?? children }</div>
|
|
91
94
|
</Flex>
|
|
92
95
|
{ hasFooter ? (
|
|
93
96
|
<Footer actions={ footerActions } isScreenLocked={ isScreenLocked }>
|
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
@use "@automattic/jetpack-base-styles/gutenberg-base-styles" as gb;
|
|
2
2
|
|
|
3
|
-
.modal {
|
|
3
|
+
.components-modal__screen-overlay:has(.jp-navigator-modal) {
|
|
4
|
+
z-index: 99999; // Slightly lower than snackbar z-index (100001) so snackbars remain visible above the modal
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.jp-navigator-modal {
|
|
4
8
|
container-type: inline-size;
|
|
5
9
|
container-name: navigator-modal;
|
|
6
|
-
|
|
7
|
-
:global(.components-modal__screen-overlay):has(&) {
|
|
8
|
-
z-index: 99999; // Slightly lower than snackbar z-index (100001) so snackbars remain visible above the modal
|
|
9
|
-
}
|
|
10
|
-
|
|
11
10
|
width: 100%;
|
|
12
11
|
|
|
13
12
|
@include gb.break-medium() {
|
|
14
13
|
max-height: 90%;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
.components-modal__content {
|
|
18
17
|
padding: 0;
|
|
19
18
|
|
|
20
19
|
> div {
|
|
21
20
|
height: 100%;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
|
-
}
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
24
|
+
&__navigator {
|
|
25
|
+
height: 100%;
|
|
26
|
+
}
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
&__screen {
|
|
29
|
+
height: 100%;
|
|
30
|
+
padding: 0;
|
|
31
|
+
}
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
&__header {
|
|
35
34
|
display: flex;
|
|
36
35
|
align-items: center;
|
|
37
36
|
justify-content: space-between;
|
|
@@ -40,12 +39,6 @@
|
|
|
40
39
|
border-bottom: 1px solid gb.$gray-200;
|
|
41
40
|
flex-shrink: 0;
|
|
42
41
|
|
|
43
|
-
.title-wrap {
|
|
44
|
-
display: flex;
|
|
45
|
-
align-items: center;
|
|
46
|
-
gap: 1rem;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
42
|
h1 {
|
|
50
43
|
margin: 0;
|
|
51
44
|
font-size: 15px;
|
|
@@ -55,55 +48,51 @@
|
|
|
55
48
|
}
|
|
56
49
|
}
|
|
57
50
|
|
|
58
|
-
|
|
51
|
+
&__title-wrap {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: 1rem;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&__body {
|
|
59
58
|
height: 100%;
|
|
60
59
|
overflow: auto;
|
|
61
60
|
flex-direction: column;
|
|
62
61
|
|
|
63
62
|
@container navigator-modal (width >= #{gb.$break-small}) {
|
|
64
|
-
|
|
65
|
-
& {
|
|
66
|
-
flex-direction: row;
|
|
67
|
-
}
|
|
63
|
+
flex-direction: row;
|
|
68
64
|
}
|
|
69
65
|
}
|
|
70
66
|
|
|
71
|
-
|
|
67
|
+
&__sidebar {
|
|
72
68
|
width: 100%;
|
|
73
69
|
display: flex;
|
|
74
70
|
flex-direction: column;
|
|
75
71
|
gap: 1.5rem;
|
|
76
72
|
|
|
77
73
|
@container navigator-modal (width >= #{gb.$break-small}) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
border-inline-end: 1px solid gb.$gray-300;
|
|
84
|
-
overflow: auto;
|
|
85
|
-
}
|
|
74
|
+
flex-basis: 30%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
flex-shrink: 0;
|
|
77
|
+
border-inline-end: 1px solid gb.$gray-300;
|
|
78
|
+
overflow: auto;
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
81
|
|
|
89
|
-
|
|
82
|
+
&__content {
|
|
90
83
|
width: 100%;
|
|
91
84
|
height: 100%;
|
|
92
85
|
flex: 1;
|
|
93
86
|
|
|
94
87
|
@container navigator-modal (width >= #{gb.$break-small}) {
|
|
95
|
-
|
|
96
|
-
& {
|
|
97
|
-
overflow: auto;
|
|
98
|
-
}
|
|
88
|
+
overflow: auto;
|
|
99
89
|
}
|
|
100
90
|
}
|
|
101
91
|
|
|
102
|
-
|
|
92
|
+
&__footer {
|
|
103
93
|
padding: 1rem 1.5rem;
|
|
104
94
|
border-top: 1px solid gb.$gray-300;
|
|
105
95
|
height: 4.5rem;
|
|
106
96
|
flex-shrink: 0;
|
|
107
97
|
}
|
|
108
|
-
|
|
109
98
|
}
|
|
@@ -13,15 +13,3 @@ export type TNavigatorModalContext = {
|
|
|
13
13
|
*/
|
|
14
14
|
onClose?: VoidFunction;
|
|
15
15
|
};
|
|
16
|
-
|
|
17
|
-
export type SharedProps = {
|
|
18
|
-
/**
|
|
19
|
-
* The content of the component.
|
|
20
|
-
*/
|
|
21
|
-
children: React.ReactNode;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* className to be applied to the modal.
|
|
25
|
-
*/
|
|
26
|
-
className?: string;
|
|
27
|
-
};
|
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
* This uses the experimental NumberControl from the block
|
|
8
8
|
* editor where available, otherwise it falls back to a
|
|
9
9
|
* standard TextControl, limited to numbers.
|
|
10
|
+
* @type {import('react').ComponentType<any>}
|
|
10
11
|
*
|
|
11
12
|
* @param {any} props - the NumberControl component props
|
|
12
|
-
* @return {
|
|
13
|
+
* @return {import('react').ReactNode} - NumberControl component
|
|
13
14
|
*/
|
|
14
15
|
const NumberControl =
|
|
15
16
|
ExperimentalNumberControl ||
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
import type { ComponentProps, ReactNode } from 'react';
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
6
5
|
|
|
7
6
|
export type PricingCardProps = {
|
|
8
7
|
/**
|
|
@@ -36,7 +35,7 @@ export type PricingCardProps = {
|
|
|
36
35
|
/**
|
|
37
36
|
* The CTA callback to be called on click.
|
|
38
37
|
*/
|
|
39
|
-
onCtaClick?:
|
|
38
|
+
onCtaClick?: React.MouseEventHandler< HTMLButtonElement >;
|
|
40
39
|
/**
|
|
41
40
|
* Optional informative text.
|
|
42
41
|
*/
|
|
@@ -21,10 +21,17 @@ const SplitButton: FC< SplitButtonProps > = ( {
|
|
|
21
21
|
label,
|
|
22
22
|
...buttonProps
|
|
23
23
|
} ) => {
|
|
24
|
+
// Cast to work around WPButton's strict union type
|
|
25
|
+
const wpButtonProps = {
|
|
26
|
+
variant,
|
|
27
|
+
className: styles.button,
|
|
28
|
+
...buttonProps,
|
|
29
|
+
} as React.ComponentProps< typeof Button >;
|
|
30
|
+
|
|
24
31
|
return (
|
|
25
32
|
<Flex className={ styles[ 'split-button' ] }>
|
|
26
33
|
<div role="group" className="components-button-group">
|
|
27
|
-
<Button
|
|
34
|
+
<Button { ...wpButtonProps } />
|
|
28
35
|
<DropdownMenu
|
|
29
36
|
toggleProps={ { variant, className: styles.button, ...toggleProps } }
|
|
30
37
|
popoverProps={ { noArrow: false, ...popoverProps } }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/jetpack-components",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.9",
|
|
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,20 +45,20 @@
|
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@automattic/format-currency": "1.0.1",
|
|
48
|
-
"@automattic/jetpack-api": "^1.0.
|
|
49
|
-
"@automattic/jetpack-boost-score-api": "^1.0.
|
|
48
|
+
"@automattic/jetpack-api": "^1.0.16",
|
|
49
|
+
"@automattic/jetpack-boost-score-api": "^1.0.27",
|
|
50
50
|
"@automattic/jetpack-script-data": "^0.5.4",
|
|
51
51
|
"@automattic/number-formatters": "^1.0.16",
|
|
52
52
|
"@babel/runtime": "^7",
|
|
53
|
-
"@wordpress/browserslist-config": "6.
|
|
54
|
-
"@wordpress/components": "32.
|
|
55
|
-
"@wordpress/compose": "7.
|
|
56
|
-
"@wordpress/data": "10.
|
|
57
|
-
"@wordpress/date": "5.
|
|
58
|
-
"@wordpress/element": "6.
|
|
59
|
-
"@wordpress/i18n": "6.
|
|
60
|
-
"@wordpress/icons": "11.
|
|
61
|
-
"@wordpress/notices": "5.
|
|
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",
|
|
62
62
|
"clsx": "2.1.1",
|
|
63
63
|
"prop-types": "^15.7.2",
|
|
64
64
|
"qrcode.react": "4.2.0",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"uplot-react": "1.1.4"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@automattic/jetpack-base-styles": "^1.0.
|
|
71
|
+
"@automattic/jetpack-base-styles": "^1.0.15",
|
|
72
72
|
"@babel/core": "7.28.4",
|
|
73
73
|
"@babel/preset-react": "7.27.1",
|
|
74
74
|
"@jest/globals": "30.2.0",
|