2023-09-19 09:58:18 +00:00
/ * *
* External dependencies
* /
import {
BlockInstance ,
createBlock ,
registerBlockType ,
} from '@wordpress/blocks' ;
import type { BlockEditProps } from '@wordpress/blocks' ;
import {
useBlockProps ,
BlockPreview ,
store as blockEditorStore ,
} from '@wordpress/block-editor' ;
import {
Button ,
Placeholder ,
Popover ,
ExternalLink ,
2023-10-19 15:43:43 +00:00
TabbableContainer ,
2023-09-19 09:58:18 +00:00
} from '@wordpress/components' ;
import { __ } from '@wordpress/i18n' ;
2023-10-19 15:43:43 +00:00
import { shortcode , Icon } from '@wordpress/icons' ;
2023-09-19 09:58:18 +00:00
import { useDispatch , useSelect } from '@wordpress/data' ;
import { useState , createInterpolateElement } from '@wordpress/element' ;
import { store as noticesStore } from '@wordpress/notices' ;
import { woo } from '@woocommerce/icons' ;
2023-10-19 15:43:43 +00:00
import { findBlock } from '@woocommerce/utils' ;
2023-09-19 09:58:18 +00:00
/ * *
* Internal dependencies
* /
import './editor.scss' ;
import './style.scss' ;
2023-10-19 15:43:43 +00:00
import { CartPlaceholder , CheckoutPlaceholder } from './placeholder' ;
2023-09-19 09:58:18 +00:00
import { TEMPLATES , TYPES } from './constants' ;
import { getTemplateDetailsBySlug } from './utils' ;
import * as blockifiedCheckout from './checkout' ;
import * as blockifiedCart from './cart' ;
2023-10-19 15:43:43 +00:00
import metadata from './block.json' ;
2023-09-19 09:58:18 +00:00
import type { BlockifiedTemplateConfig } from './types' ;
type Attributes = {
shortcode : string ;
align : string ;
} ;
const blockifiedFallbackConfig = {
isConversionPossible : ( ) = > false ,
getBlockifiedTemplate : ( ) = > [ ] ,
getDescription : ( ) = > '' ,
onClickCallback : ( ) = > void 0 ,
} ;
const conversionConfig : { [ key : string ] : BlockifiedTemplateConfig } = {
[ TYPES . cart ] : blockifiedCart ,
[ TYPES . checkout ] : blockifiedCheckout ,
fallback : blockifiedFallbackConfig ,
} ;
const ConvertTemplate = ( { blockifyConfig , clientId , attributes } ) = > {
const { getButtonLabel , onClickCallback , getBlockifiedTemplate } =
blockifyConfig ;
const [ isPopoverOpen , setIsPopoverOpen ] = useState ( false ) ;
2023-10-19 15:43:43 +00:00
const { replaceBlock , selectBlock } = useDispatch ( blockEditorStore ) ;
const { createInfoNotice } = useDispatch ( noticesStore ) ;
2023-09-19 09:58:18 +00:00
const { getBlocks } = useSelect ( ( sel ) = > {
return {
getBlocks : sel ( blockEditorStore ) . getBlocks ,
} ;
} , [ ] ) ;
return (
2023-10-19 15:43:43 +00:00
< TabbableContainer className = "wp-block-woocommerce-classic-shortcode__placeholder-migration-button-container" >
2023-09-19 09:58:18 +00:00
< Button
variant = "primary"
onClick = { ( ) = > {
onClickCallback ( {
clientId ,
getBlocks ,
attributes ,
replaceBlock ,
selectBlock ,
} ) ;
createInfoNotice (
__ (
2023-10-19 15:43:43 +00:00
'Classic shortcode transformed to blocks.' ,
2023-09-19 09:58:18 +00:00
'woo-gutenberg-products-block'
) ,
{
actions : [
{
label : __ (
'Undo' ,
'woo-gutenberg-products-block'
) ,
onClick : ( ) = > {
2023-10-19 15:43:43 +00:00
const targetBlocks = [
'woocommerce/cart' ,
'woocommerce/checkout' ,
] ;
const cartCheckoutBlock = findBlock ( {
blocks : getBlocks ( ) ,
findCondition : (
foundBlock : BlockInstance
) = >
targetBlocks . includes (
foundBlock . name
) ,
} ) ;
if ( ! cartCheckoutBlock ) {
return ;
}
replaceBlock (
cartCheckoutBlock . clientId ,
2023-09-19 09:58:18 +00:00
createBlock (
2023-10-19 15:43:43 +00:00
'woocommerce/classic-shortcode' ,
2023-09-19 09:58:18 +00:00
{
2023-10-19 15:43:43 +00:00
shortcode :
attributes . shortcode ,
}
2023-09-19 09:58:18 +00:00
)
) ;
} ,
} ,
] ,
type : 'snackbar' ,
}
) ;
} }
onMouseEnter = { ( ) = > setIsPopoverOpen ( true ) }
onMouseLeave = { ( ) = > setIsPopoverOpen ( false ) }
text = { getButtonLabel ? getButtonLabel ( ) : '' }
2023-10-19 15:43:43 +00:00
tabIndex = { 0 }
2023-09-19 09:58:18 +00:00
>
{ isPopoverOpen && (
< Popover resize = { false } placement = "right-end" >
< div
style = { {
minWidth : '250px' ,
width : '250px' ,
maxWidth : '250px' ,
minHeight : '300px' ,
height : '300px' ,
maxHeight : '300px' ,
cursor : 'pointer' ,
} }
>
< BlockPreview
2023-10-19 15:43:43 +00:00
blocks = { getBlockifiedTemplate ( {
. . . attributes ,
isPreview : true ,
} ) }
2023-09-19 09:58:18 +00:00
viewportWidth = { 1200 }
additionalStyles = { [
{
css : 'body { padding: 20px !important; height: fit-content !important; overflow:hidden}' ,
} ,
] }
/ >
< / div >
< / Popover >
) }
< / Button >
< Button
variant = "secondary"
href = "https://woocommerce.com/document/cart-checkout-blocks-support-status/"
target = "_blank"
2023-10-19 15:43:43 +00:00
tabIndex = { 0 }
2023-09-19 09:58:18 +00:00
>
{ __ ( 'Learn more' , 'woo-gutenberg-products-block' ) }
< / Button >
2023-10-19 15:43:43 +00:00
< / TabbableContainer >
2023-09-19 09:58:18 +00:00
) ;
} ;
const Edit = ( { clientId , attributes } : BlockEditProps < Attributes > ) = > {
const blockProps = useBlockProps ( ) ;
const templateDetails = getTemplateDetailsBySlug (
attributes . shortcode ,
TEMPLATES
) ;
const templateTitle = attributes . shortcode ;
2023-10-19 15:43:43 +00:00
const templatePlaceholder = templateDetails ? . placeholder ? ? 'cart' ;
2023-09-19 09:58:18 +00:00
const templateType = templateDetails ? . type ? ? 'fallback' ;
const { isConversionPossible , getDescription , getTitle , blockifyConfig } =
conversionConfig [ templateType ] ;
const canConvert = isConversionPossible ( ) ;
const placeholderTitle = getTitle
? getTitle ( )
: __ ( 'Classic Shortcode Placeholder' , 'woo-gutenberg-products-block' ) ;
const placeholderDescription = getDescription ( templateTitle , canConvert ) ;
const learnMoreContent = createInterpolateElement (
__ (
'You can learn more about the benefits of switching to blocks, compatibility with extensions, and how to switch back to shortcodes <a>in our documentation</a>.' ,
'woo-gutenberg-products-block'
) ,
{
a : (
// Suppress the warning as this <a> will be interpolated into the string with content.
// eslint-disable-next-line jsx-a11y/anchor-has-content
< ExternalLink href = "https://woocommerce.com/document/cart-checkout-blocks-support-status/" / >
) ,
}
) ;
return (
< div { ...blockProps } >
< Placeholder className = "wp-block-woocommerce-classic-shortcode__placeholder" >
< div className = "wp-block-woocommerce-classic-shortcode__placeholder-wireframe" >
2023-10-19 15:43:43 +00:00
{ templatePlaceholder === 'cart' ? (
< CartPlaceholder / >
) : (
< CheckoutPlaceholder / >
) }
2023-09-19 09:58:18 +00:00
< / div >
< div className = "wp-block-woocommerce-classic-shortcode__placeholder-copy" >
< div className = "wp-block-woocommerce-classic-shortcode__placeholder-copy__icon-container" >
< span className = "woo-icon" >
< Icon icon = { woo } / > { ' ' }
{ __ (
'WooCommerce' ,
'woo-gutenberg-products-block'
) }
< / span >
< span > { placeholderTitle } < / span >
< / div >
< p
dangerouslySetInnerHTML = { {
__html : placeholderDescription ,
} }
/ >
< p > { learnMoreContent } < / p >
{ canConvert && blockifyConfig && (
< ConvertTemplate
clientId = { clientId }
blockifyConfig = { blockifyConfig }
attributes = { attributes }
/ >
) }
< / div >
< / Placeholder >
< / div >
) ;
} ;
2023-10-19 15:43:43 +00:00
const settings = {
2023-09-19 09:58:18 +00:00
icon : (
2023-10-19 15:43:43 +00:00
< Icon
icon = { shortcode }
className = "wc-block-editor-components-block-icon"
/ >
2023-09-19 09:58:18 +00:00
) ,
edit : ( {
attributes ,
clientId ,
setAttributes ,
} : BlockEditProps < Attributes > ) = > {
return (
< Edit
attributes = { attributes }
setAttributes = { setAttributes }
clientId = { clientId }
/ >
) ;
} ,
save : ( ) = > null ,
2023-10-19 15:43:43 +00:00
variations : [
{
name : 'checkout' ,
title : __ ( 'Classic Checkout' , 'woo-gutenberg-products-block' ) ,
attributes : {
shortcode : 'checkout' ,
} ,
isActive : ( blockAttributes , variationAttributes ) = >
blockAttributes . shortcode === variationAttributes . shortcode ,
scope : [ 'inserter' ] ,
} ,
{
name : 'cart' ,
title : __ ( 'Classic Cart' , 'woo-gutenberg-products-block' ) ,
attributes : {
shortcode : 'cart' ,
} ,
isActive : ( blockAttributes , variationAttributes ) = >
blockAttributes . shortcode === variationAttributes . shortcode ,
scope : [ 'inserter' ] ,
isDefault : true ,
} ,
] ,
} ;
registerBlockType ( metadata , settings ) ;