196 lines
4.8 KiB
TypeScript
196 lines
4.8 KiB
TypeScript
/* eslint-disable jsdoc/check-alignment */
|
|
/**
|
|
* External dependencies
|
|
*/
|
|
import {
|
|
useBlockProps,
|
|
InnerBlocks,
|
|
InspectorControls,
|
|
} from '@wordpress/block-editor';
|
|
import { EditorProvider } from '@woocommerce/base-context';
|
|
import { isFeaturePluginBuild } from '@woocommerce/block-settings';
|
|
import type { TemplateArray } from '@wordpress/blocks';
|
|
import { useEffect } from '@wordpress/element';
|
|
import type { FocusEvent, ReactElement } from 'react';
|
|
import { __ } from '@wordpress/i18n';
|
|
import {
|
|
PanelBody,
|
|
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
|
|
__experimentalUnitControl as UnitControl,
|
|
} from '@wordpress/components';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { useForcedLayout } from '../../cart-checkout-shared';
|
|
import { MiniCartInnerBlocksStyle } from './inner-blocks-style';
|
|
import './editor.scss';
|
|
import { attributes as defaultAttributes } from './attributes';
|
|
|
|
// Array of allowed block names.
|
|
const ALLOWED_BLOCKS = [
|
|
'woocommerce/filled-mini-cart-contents-block',
|
|
'woocommerce/empty-mini-cart-contents-block',
|
|
];
|
|
const MIN_WIDTH = 300;
|
|
|
|
interface Props {
|
|
clientId: string;
|
|
attributes: Record< string, unknown >;
|
|
setAttributes: ( attributes: Record< string, unknown > ) => void;
|
|
}
|
|
|
|
const Edit = ( {
|
|
clientId,
|
|
attributes,
|
|
setAttributes,
|
|
}: Props ): ReactElement => {
|
|
const { currentView, width } = attributes;
|
|
|
|
const blockProps = useBlockProps( {
|
|
/**
|
|
* This is a workaround for the Site Editor to calculate the
|
|
* correct height of the Mini-Cart template part on the first load.
|
|
*
|
|
* @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5825
|
|
*/
|
|
style: {
|
|
minHeight: '100vh',
|
|
width,
|
|
},
|
|
} );
|
|
|
|
const defaultTemplate = [
|
|
[ 'woocommerce/filled-mini-cart-contents-block', {}, [] ],
|
|
[ 'woocommerce/empty-mini-cart-contents-block', {}, [] ],
|
|
] as TemplateArray;
|
|
|
|
useForcedLayout( {
|
|
clientId,
|
|
registeredBlocks: ALLOWED_BLOCKS,
|
|
defaultTemplate,
|
|
} );
|
|
|
|
/**
|
|
* This is a workaround for the Site Editor to set the correct
|
|
* background color of the Mini-Cart Contents block base on
|
|
* the main background color set by the theme.
|
|
*/
|
|
useEffect( () => {
|
|
const canvasEl = document.querySelector(
|
|
'.edit-site-visual-editor__editor-canvas'
|
|
);
|
|
if ( ! ( canvasEl instanceof HTMLIFrameElement ) ) {
|
|
return;
|
|
}
|
|
const canvas =
|
|
canvasEl.contentDocument || canvasEl.contentWindow?.document;
|
|
if ( ! canvas ) {
|
|
return;
|
|
}
|
|
if ( canvas.getElementById( 'mini-cart-contents-background-color' ) ) {
|
|
return;
|
|
}
|
|
const styles = canvas.querySelectorAll( 'style' );
|
|
const [ cssRule ] = Array.from( styles )
|
|
.map( ( style ) => Array.from( style.sheet?.cssRules || [] ) )
|
|
.flatMap( ( style ) => style )
|
|
.filter( Boolean )
|
|
.filter(
|
|
( rule ) =>
|
|
rule.selectorText === '.editor-styles-wrapper' &&
|
|
rule.style.backgroundColor
|
|
);
|
|
if ( ! cssRule ) {
|
|
return;
|
|
}
|
|
const backgroundColor = cssRule.style.backgroundColor;
|
|
if ( ! backgroundColor ) {
|
|
return;
|
|
}
|
|
const style = document.createElement( 'style' );
|
|
style.id = 'mini-cart-contents-background-color';
|
|
style.appendChild(
|
|
document.createTextNode(
|
|
`:where(.wp-block-woocommerce-mini-cart-contents) {
|
|
background-color: ${ backgroundColor };
|
|
}`
|
|
)
|
|
);
|
|
const body = canvas.querySelector( '.editor-styles-wrapper' );
|
|
if ( ! body ) {
|
|
return;
|
|
}
|
|
body.appendChild( style );
|
|
}, [] );
|
|
|
|
return (
|
|
<>
|
|
{ isFeaturePluginBuild() && (
|
|
<InspectorControls key="inspector">
|
|
<PanelBody
|
|
title={ __(
|
|
'Dimensions',
|
|
'woo-gutenberg-products-block'
|
|
) }
|
|
initialOpen
|
|
>
|
|
<UnitControl
|
|
onChange={ ( value ) => {
|
|
setAttributes( { width: value } );
|
|
} }
|
|
onBlur={ ( e: FocusEvent< HTMLInputElement > ) => {
|
|
if ( e.target.value === '' ) {
|
|
setAttributes( {
|
|
width: defaultAttributes.width.default,
|
|
} );
|
|
} else if (
|
|
Number( e.target.value ) < MIN_WIDTH
|
|
) {
|
|
setAttributes( {
|
|
width: MIN_WIDTH + 'px',
|
|
} );
|
|
}
|
|
} }
|
|
value={ width }
|
|
units={ [
|
|
{
|
|
value: 'px',
|
|
label: 'px',
|
|
default: defaultAttributes.width.default,
|
|
},
|
|
] }
|
|
/>
|
|
</PanelBody>
|
|
</InspectorControls>
|
|
) }
|
|
<div
|
|
className="wc-block-components-drawer__screen-overlay"
|
|
aria-hidden="true"
|
|
></div>
|
|
<div className="wc-block-editor-mini-cart-contents__wrapper">
|
|
<div { ...blockProps }>
|
|
<EditorProvider currentView={ currentView }>
|
|
<InnerBlocks
|
|
allowedBlocks={ ALLOWED_BLOCKS }
|
|
template={ defaultTemplate }
|
|
templateLock={ false }
|
|
/>
|
|
</EditorProvider>
|
|
<MiniCartInnerBlocksStyle style={ blockProps.style } />
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Edit;
|
|
|
|
export const Save = (): JSX.Element => {
|
|
return (
|
|
<div { ...useBlockProps.save() }>
|
|
<InnerBlocks.Content />
|
|
</div>
|
|
);
|
|
};
|