-
Notifications
You must be signed in to change notification settings - Fork 10.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce
<Notice>
component for WooCommerce Admin (#44620)
* Introduce Notice component * minor alignment fix * Fix MD title increment * Fix readme lint * add changelog entry * fix CSS lints * Small tweaks. Regularising the spelling of isDismissible. Using sanitizeHTML to sanitize the notice description. Making the variant classes like &-success to make them a bit shorter. Adjusting wording of README to convey that this component is designed for the marketplace, though it can be used elsewhere. Tweaking whitespace in one place in the TSX to please the linter. * Update plugins/woocommerce-admin/client/marketplace/components/notice/notice.tsx Co-authored-by: Michal Iwanow <4765119+mcliwanow@users.noreply.github.com> * address feedback * Changed notice classnames to use `__{$variant}` pattern as well. Restored 40px bottom margin to notices on viewports 600px and above. Added height 24px on icons to ensure they're nicely vertically centred. --------- Co-authored-by: Remi Corson <1649788+corsonr@users.noreply.github.com> Co-authored-by: And Finally <andfinally@users.noreply.github.com> Co-authored-by: Michal Iwanow <4765119+mcliwanow@users.noreply.github.com>
- Loading branch information
1 parent
267d530
commit 1cbc044
Showing
4 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
150 changes: 150 additions & 0 deletions
150
plugins/woocommerce-admin/client/marketplace/components/notice/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
# Notice Component | ||
|
||
The `Notice` component is a versatile notification UI element designed for use within the WooCommerce in-app marketplace. | ||
It leverages the `@wordpress/icons` for displaying various icons and provides customizable options for content, appearance, and behavior. | ||
|
||
## Usage | ||
|
||
To use the Notice component, import it into your React component file and include it in your component's render method. Here is a basic example: | ||
|
||
```jsx | ||
import Notice from '../notice/notice'; | ||
|
||
function MyComponent() { | ||
return ( | ||
<Notice | ||
id="unique-notice-id" | ||
description="This is a notice description." | ||
icon="info" | ||
isDismissible={true} | ||
variant="info" | ||
> | ||
<p>Additional content can go here.</p> | ||
</Notice> | ||
); | ||
} | ||
|
||
export default MyComponent; | ||
``` | ||
|
||
## Props | ||
|
||
The Notice component accepts the following props for customization: | ||
|
||
- `id` (string): A unique identifier for the notice. This is used for dismissing and storing the dismissal state. | ||
- `children` (JSX.Element): Optional. Additional React components or HTML elements to be displayed within the notice. | ||
- `description` (string): The content of the notice. Can include HTML. | ||
- `icon` (string): Optional. The name of the icon to display. Available options are info, check, percent. | ||
- `isDismissible` (boolean): Optional. If true, displays a close button that hides the notice. Defaults to true. | ||
- `variant` (string): Determines the style of the notice. Options are info, warning, error, success. | ||
|
||
## Styling | ||
|
||
The notice component can be styled using the following CSS classes, based on the variant prop: | ||
|
||
- `.woocommerce-marketplace__notice-info`: Styles the notice with an info appearance. | ||
- `.woocommerce-marketplace__notice-warning`: Styles the notice with a warning appearance. | ||
- `.woocommerce-marketplace__notice-error`: Styles the notice with an error appearance. | ||
- `.woocommerce-marketplace__notice-success`: Styles the notice with a success appearance. | ||
|
||
Icons within the notice adopt the variant prop to determine their color, aligning with the overall style of the notice. | ||
|
||
## Dismissal Behavior | ||
|
||
Notices can be dismissed if `isDismissible` is set to `true`. The dismissal state is persisted in the browser's localStorage, preventing the notice from reappearing on future visits. | ||
|
||
## Examples | ||
|
||
Here are more detailed examples, some require that you import the Button component and/or internationalization functions: | ||
|
||
```jsx | ||
<Notice | ||
id="marketplace-sale-march-2024" | ||
variant="info" | ||
description={ __( | ||
'<strong>Limited time sale</strong> Tup to 40% off on extensions and themes. Sale ends March 29 at 2pm UTC.', | ||
'woocommerce' | ||
) } | ||
icon="percent" | ||
isDismissible | ||
> | ||
<Button | ||
variant="secondary" | ||
onClick={ () => { | ||
console.log( 'Primary button clicked' ); | ||
} } | ||
text="Label" | ||
/> | ||
<Button | ||
variant="tertiary" | ||
onClick={ () => { | ||
console.log( 'Secondary button clicked' ); | ||
} } | ||
text="Label" | ||
/> | ||
</Notice> | ||
``` | ||
|
||
```jsx | ||
<Notice | ||
id="success-notice" | ||
variant="success" | ||
description={ __( | ||
'<strong>Congratulations</strong> You successfully installed the plugin.', | ||
'woocommerce' | ||
) } | ||
icon="check" | ||
isDismissible | ||
> | ||
<Button | ||
variant="secondary" | ||
onClick={ () => { | ||
console.log( 'Primary button clicked' ); | ||
} } | ||
text="Label" | ||
/> | ||
<Button | ||
variant="tertiary" | ||
onClick={ () => { | ||
console.log( 'Secondary button clicked' ); | ||
} } | ||
text="Label" | ||
/> | ||
</Notice> | ||
``` | ||
|
||
```jsx | ||
<Notice | ||
id="warning-notice" | ||
variant="warning" | ||
description={ __( | ||
'This is a warning and I cannot be dismissed. Nope.', | ||
'woocommerce' | ||
) } | ||
icon="info" | ||
isDismissible={ false } | ||
/> | ||
|
||
<Notice | ||
id="error-notice" | ||
variant="error" | ||
description={ __( | ||
'I am red and I cannot be dismissed. Nope. But I support <i>HTML</i> <strong>tags</strong>. So <a href="#">I can have links</a>.', | ||
'woocommerce' | ||
) } | ||
icon="info" | ||
isDismissible={ false } | ||
/> | ||
``` | ||
|
||
```jsx | ||
<Notice | ||
id="success-notice-no-icon" | ||
variant="success" | ||
description={ __( | ||
'I am a success! But I am sad because I do not have an icon.', | ||
'woocommerce' | ||
) } | ||
isDismissible={ false } | ||
/> | ||
``` |
95 changes: 95 additions & 0 deletions
95
plugins/woocommerce-admin/client/marketplace/components/notice/notice.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
@import '../../stylesheets/_variables.scss'; | ||
|
||
.woocommerce-marketplace { | ||
&__notice { | ||
align-items: center; | ||
border: 1px solid #f0f0f0; | ||
box-shadow: 0 2px 6px 0 #0000000d; | ||
display: flex; | ||
gap: 12px; | ||
margin-bottom: 32px; | ||
opacity: 1; | ||
padding: 12px; | ||
transition: opacity 1s ease-out; | ||
|
||
&--info { | ||
border-left: 4px solid var(--wp-admin-theme-color, #007cba); | ||
} | ||
|
||
&--error { | ||
border-left: 4px solid $alert-red; | ||
} | ||
|
||
&--warning { | ||
border-left: 4px solid $alert-yellow; | ||
} | ||
|
||
&--success { | ||
border-left: 4px solid $valid-green; | ||
} | ||
|
||
&-icon { | ||
align-self: flex-start; | ||
height: 24px; | ||
|
||
&--info { | ||
fill: var(--wp-admin-theme-color, #007cba); | ||
} | ||
|
||
&--error { | ||
fill: $alert-red; | ||
} | ||
|
||
&--warning { | ||
fill: $alert-yellow; | ||
} | ||
|
||
&--success { | ||
fill: $valid-green; | ||
} | ||
} | ||
|
||
&-content { | ||
align-items: flex-start; | ||
display: flex; | ||
flex-direction: column; | ||
flex: 1; | ||
gap: 12px; | ||
} | ||
|
||
&-description { | ||
color: $gray-900; | ||
font-size: 13px; | ||
font-weight: 400; | ||
line-height: 20px; | ||
margin: 0; | ||
} | ||
|
||
&-children { | ||
color: $gray-900; | ||
font-size: 13px; | ||
font-weight: 400; | ||
gap: 8px; | ||
line-height: 20px; | ||
margin: 0; | ||
|
||
.components-button { | ||
margin-right: 12px; | ||
} | ||
} | ||
|
||
&-close { | ||
align-self: flex-start; | ||
background: none; | ||
border: none; | ||
cursor: pointer; | ||
height: 24px; | ||
} | ||
} | ||
} | ||
|
||
@media only screen and (min-width: 600px) { | ||
.woocommerce-marketplace__notice { | ||
margin-bottom: 40px; | ||
} | ||
} |
96 changes: 96 additions & 0 deletions
96
plugins/woocommerce-admin/client/marketplace/components/notice/notice.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/** | ||
* 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> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: minor | ||
Type: add | ||
|
||
Introduce WooCommerce Admin Notice component |