woocommerce/plugins/woocommerce-admin/client/marketplace/components/notice/notice.tsx

97 lines
2.2 KiB
TypeScript
Raw Normal View History

/**
* External dependencies
*/
import classNames from 'classnames';
import { useState } from '@wordpress/element';
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;
}
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',
} = props;
const [ isVisible, setIsVisible ] = useState(
localStorage.getItem( `wc-marketplaceNoticeClosed-${ id }` ) !== 'true'
);
const handleClose = () => {
setIsVisible( false );
localStorage.setItem( `wc-marketplaceNoticeClosed-${ id }`, 'true' );
};
if ( ! isVisible ) return null;
const classes = classNames(
'woocommerce-marketplace__notice',
`woocommerce-marketplace__notice--${ variant }`,
{
'is-dismissible': isDismissible,
}
);
const iconElement = iconMap[ ( icon || 'info' ) as IconKey ];
const iconClass = classNames(
'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>
);
}