2024-02-20 14:52:41 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2024-05-31 03:49:36 +00:00
|
|
|
import clsx from 'clsx';
|
2024-05-13 06:45:43 +00:00
|
|
|
import { useEffect, useState } from '@wordpress/element';
|
2024-02-20 14:52:41 +00:00
|
|
|
import { Icon, check, closeSmall, info, percent } from '@wordpress/icons'; // See: https://wordpress.github.io/gutenberg/?path=/docs/icons-icon--docs
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import './notice.scss';
|
|
|
|
import sanitizeHTML from '../../../lib/sanitize-html';
|
|
|
|
|
|
|
|
export interface NoticeProps {
|
|
|
|
id: string;
|
|
|
|
children?: React.ReactNode;
|
|
|
|
description: string;
|
|
|
|
icon?: string;
|
|
|
|
isDismissible: boolean;
|
|
|
|
variant: string;
|
2024-04-17 10:13:24 +00:00
|
|
|
onClose?: () => void;
|
2024-05-13 06:45:43 +00:00
|
|
|
onLoad?: () => void;
|
2024-02-20 14:52:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type IconKey = keyof typeof iconMap;
|
|
|
|
|
|
|
|
// Map the icon name (string) to the actual icon component
|
|
|
|
const iconMap = {
|
|
|
|
info,
|
|
|
|
check,
|
|
|
|
percent,
|
|
|
|
};
|
|
|
|
|
|
|
|
export default function Notice( props: NoticeProps ): JSX.Element | null {
|
|
|
|
const {
|
|
|
|
id,
|
|
|
|
description,
|
|
|
|
children,
|
|
|
|
icon,
|
|
|
|
isDismissible = true,
|
|
|
|
variant = 'info',
|
2024-04-17 10:13:24 +00:00
|
|
|
onClose,
|
2024-05-13 06:45:43 +00:00
|
|
|
onLoad,
|
2024-02-20 14:52:41 +00:00
|
|
|
} = props;
|
|
|
|
const [ isVisible, setIsVisible ] = useState(
|
|
|
|
localStorage.getItem( `wc-marketplaceNoticeClosed-${ id }` ) !== 'true'
|
|
|
|
);
|
|
|
|
|
|
|
|
const handleClose = () => {
|
|
|
|
setIsVisible( false );
|
|
|
|
localStorage.setItem( `wc-marketplaceNoticeClosed-${ id }`, 'true' );
|
2024-04-17 10:13:24 +00:00
|
|
|
if ( typeof onClose === 'function' ) {
|
|
|
|
onClose();
|
|
|
|
}
|
2024-02-20 14:52:41 +00:00
|
|
|
};
|
|
|
|
|
2024-05-13 06:45:43 +00:00
|
|
|
useEffect( () => {
|
|
|
|
if ( isVisible && typeof onLoad === 'function' ) {
|
|
|
|
onLoad();
|
|
|
|
}
|
|
|
|
// only run once
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [ isVisible ] );
|
|
|
|
|
2024-02-20 14:52:41 +00:00
|
|
|
if ( ! isVisible ) return null;
|
|
|
|
|
2024-05-31 03:49:36 +00:00
|
|
|
const classes = clsx(
|
2024-02-20 14:52:41 +00:00
|
|
|
'woocommerce-marketplace__notice',
|
|
|
|
`woocommerce-marketplace__notice--${ variant }`,
|
|
|
|
{
|
|
|
|
'is-dismissible': isDismissible,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const iconElement = iconMap[ ( icon || 'info' ) as IconKey ];
|
|
|
|
|
2024-05-31 03:49:36 +00:00
|
|
|
const iconClass = clsx(
|
2024-02-20 14:52:41 +00:00
|
|
|
'woocommerce-marketplace__notice-icon',
|
|
|
|
`woocommerce-marketplace__notice-icon--${ variant }`
|
|
|
|
);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={ classes }>
|
|
|
|
{ icon && (
|
|
|
|
<span className={ iconClass }>
|
|
|
|
<Icon icon={ iconElement } />
|
|
|
|
</span>
|
|
|
|
) }
|
|
|
|
<div className="woocommerce-marketplace__notice-content">
|
|
|
|
<p
|
|
|
|
className="woocommerce-marketplace__notice-description"
|
|
|
|
dangerouslySetInnerHTML={ sanitizeHTML( description ) }
|
|
|
|
/>
|
|
|
|
{ children && (
|
|
|
|
<div className="woocommerce-marketplace__notice-children">
|
|
|
|
{ children }
|
|
|
|
</div>
|
|
|
|
) }
|
|
|
|
</div>
|
|
|
|
{ isDismissible && (
|
|
|
|
<button
|
|
|
|
className="woocommerce-marketplace__notice-close"
|
|
|
|
aria-label="Close"
|
|
|
|
onClick={ handleClose }
|
|
|
|
>
|
|
|
|
<Icon icon={ closeSmall } />
|
|
|
|
</button>
|
|
|
|
) }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|