WIP experiment with accessing parent context from inside the Drawer component.

This commit is contained in:
Sam Seay 2024-09-02 22:32:14 +08:00
parent 451dcf8a4a
commit 01bfa56551
No known key found for this signature in database
GPG Key ID: 2223711A9151668A
8 changed files with 108 additions and 111 deletions

View File

@ -31,47 +31,47 @@ const renderMiniCartFrontend = () => {
}
/* eslint-enable @wordpress/no-global-active-element */
renderFrontend( {
selector: '.wc-block-components-drawer__screen-overlay',
Block: MiniCartDrawer,
getProps: ( el ) => {
const button = document.querySelector(
'.wc-block-mini-cart__button'
);
const dataset =
button instanceof HTMLButtonElement
? button.dataset
: { isInitiallyOpen: 'false' };
const colorClassNames =
button instanceof HTMLButtonElement
? button.classList
.toString()
.replace( 'wc-block-mini-cart__button', '' )
: '';
// renderFrontend( {
// selector: '.wc-block-components-drawer__screen-overlay',
// Block: MiniCartDrawer,
// getProps: ( el ) => {
// const button = document.querySelector(
// '.wc-block-mini-cart__button'
// );
// const dataset =
// button instanceof HTMLButtonElement
// ? button.dataset
// : { isInitiallyOpen: 'false' };
// const colorClassNames =
// button instanceof HTMLButtonElement
// ? button.classList
// .toString()
// .replace( 'wc-block-mini-cart__button', '' )
// : '';
const isInitiallyOpen = dataset.isInitiallyOpen === 'true';
// const isInitiallyOpen = dataset.isInitiallyOpen === 'true';
return {
initialCartTotals: el.dataset.cartTotals
? JSON.parse( el.dataset.cartTotals )
: null,
initialCartItemsCount: el.dataset.cartItemsCount
? parseInt( el.dataset.cartItemsCount, 10 )
: 0,
isInitiallyOpen,
colorClassNames,
onClose,
style: el.dataset.style ? JSON.parse( el.dataset.style ) : {},
addToCartBehaviour: el.dataset.addToCartBehaviour || 'none',
hasHiddenPrice: el.dataset.hasHiddenPrice !== 'false',
contents:
document.querySelector(
'.wc-block-mini-cart-interactivity__template-part'
)?.innerHTML ?? '',
productCountVisibility: el.dataset.productCountVisibility,
};
},
} );
// return {
// initialCartTotals: el.dataset.cartTotals
// ? JSON.parse( el.dataset.cartTotals )
// : null,
// initialCartItemsCount: el.dataset.cartItemsCount
// ? parseInt( el.dataset.cartItemsCount, 10 )
// : 0,
// isInitiallyOpen,
// colorClassNames,
// onClose,
// style: el.dataset.style ? JSON.parse( el.dataset.style ) : {},
// addToCartBehaviour: el.dataset.addToCartBehaviour || 'none',
// hasHiddenPrice: el.dataset.hasHiddenPrice !== 'false',
// contents:
// document.querySelector(
// '.wc-block-mini-cart-interactivity__template-part'
// )?.innerHTML ?? '',
// productCountVisibility: el.dataset.productCountVisibility,
// };
// },
// } );
// Refocus previously focused button if drawer is not open.
if (

View File

@ -23,6 +23,7 @@ import {
getMiniCartTotalsFromServer,
} from './utils/data';
import setStyles from '../mini-cart/utils/set-styles';
import { DrawerContext } from '../../../../packages/interactivity-components/drawer';
interface dependencyData {
src: string;
@ -179,14 +180,15 @@ store< Store >( 'woocommerce/mini-cart-interactivity', {
},
toggleDrawerOpen: () => {
console.log('toggleDrawerOpen');
const context = getContext< Context >();
context.drawerOpen = ! context.drawerOpen;
if ( context.drawerOpen ) {
document.body.dispatchEvent(
new Event( 'wc-mini-cart-interactivity-open-drawer' )
);
}
// if ( context.drawerOpen ) {
// document.body.dispatchEvent(
// new Event( 'wc-mini-cart-interactivity-open-drawer' )
// );
// }
},
loadScripts: async () => {

View File

@ -223,8 +223,10 @@ const entries = {
'./packages/interactivity-components/checkbox-list/index.ts',
'wc-interactivity-dropdown':
'./packages/interactivity-components/dropdown/index.ts',
// Templates
'wc-interactivity-drawer':
'./packages/interactivity-components/drawer/index.ts',
// Templates
'wc-blocks-classic-template-revert-button-style':
'./assets/js/templates/revert-button/index.tsx',
},
@ -243,6 +245,8 @@ const entries = {
'./packages/interactivity-components/dropdown/index.ts',
'wc-interactivity-checkbox-list':
'./packages/interactivity-components/checkbox-list/index.ts',
'wc-interactivity-drawer':
'./packages/interactivity-components/drawer/index.ts',
},
main: {
// Shared blocks code

View File

@ -3,21 +3,43 @@
*/
import { getContext, store } from '@woocommerce/interactivity';
/**
* Internal dependencies
*/
import './style.scss';
export type DrawerContext = {
isInitiallyOpen: boolean;
isOpen: boolean;
isOpenContextProperty: string;
};
console.log('store woocommerce/interactivity-drawer');
store( 'woocommerce/interactivity-drawer', {
state: {
get gday() {
return 'hi frontend';
},
get slideClasses() {
console.log('slideClasses');
const context = getContext< DrawerContext >();
return context.isOpen ? 'wc-block-components-drawer__screen-overlay--is-hidden' : 'wc-block-components-drawer__screen-overlay--is-visible';
const isOpenContextProperty = context.isOpenContextProperty;
console.log(isOpenContextProperty);
if (isOpenContextProperty.split('::').length === 2) {
const [ namespace, property ] = isOpenContextProperty.split('::');
const parentContext = getContext( namespace );
const isOpen = parentContext[ property.split('.')[1] ];
console.log(parentContext);
const baseClass = 'wc-block-components-drawer__screen-overlay';
const slide = isOpen ? '--with-slide-out' : '--with-slide-in';
return `${baseClass}${slide}`;
}
return '';
},
},
actions: {

View File

@ -75,6 +75,7 @@ final class AssetsController {
// Register the interactivity components here for now.
$this->api->register_script( 'wc-interactivity-dropdown', 'assets/client/blocks/wc-interactivity-dropdown.js', array() );
$this->api->register_script( 'wc-interactivity-checkbox-list', 'assets/client/blocks/wc-interactivity-checkbox-list.js', array() );
$this->api->register_script( 'wc-interactivity-drawer', 'assets/client/blocks/wc-interactivity-drawer.js', array() );
$this->register_style( 'wc-interactivity-checkbox-list', plugins_url( $this->api->get_block_asset_build_path( 'wc-interactivity-checkbox-list', 'css' ), dirname( __DIR__ ) ), array(), 'all', true );
$this->register_style( 'wc-interactivity-dropdown', plugins_url( $this->api->get_block_asset_build_path( 'wc-interactivity-dropdown', 'css' ), dirname( __DIR__ ) ), array(), 'all', true );

View File

@ -511,32 +511,25 @@ class MiniCartInteractivity extends AbstractBlock {
ob_start();
?>
<div style="<?php echo esc_attr( $wrapper_styles ); ?>" <?php echo esc_attr( $wrapper_attributes ); ?> >
<div style="<?php echo esc_attr( $wrapper_styles ); ?>" class="wp-block-woocommerce-mini-cart-interactivity">
<div data-wc-interactive='<?php echo esc_attr( $interactivity_namespace ); ?>' data-wc-context='<?php echo esc_attr( wp_json_encode( $cart_context ) ); ?>'>
<?php
// Output is already escaped in the function call.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $this->render_mini_cart_button( $attributes, $cart_item_count, false );
?>
<?php
echo Drawer::render(
array(
'is_initially_open' => false,
'children' => $this->get_template_part_contents_container( $template_part_contents ),
// TODO - clean up this concept.
'is_open_context_property' => 'woocommerce/mini-cart-interactivity::context.drawerOpen',
)
);
?>
</div>
<?php
echo Drawer::render(
array(
'is_initially_open' => false,
'children' => $this->get_template_part_contents_container( $template_part_contents ),
)
);
?>
<?php // Keep the drawer separate so that we don't mutate DOM within the interactivity API powered mini cart icon. ?>
<div class="is-loading wc-block-components-drawer__screen-overlay wc-block-components-drawer__screen-overlay--is-hidden" aria-hidden="true">
<div class="wc-block-mini-cart-interactivity__template-part" style="display:none">
<?php echo wp_kses_post( $template_part_contents ); ?>
</div>
<div class="wc-block-mini-cart__drawer wc-block-components-drawer">
<div class="wc-block-components-drawer__content">
</div>
</div>
</div>
</div>
<?php
return ob_get_clean();

View File

@ -1,31 +0,0 @@
<?php
namespace Automattic\WooCommerce\Blocks\BlockTypes;
/**
* MiniCartInteractivityDrawer class.
*
* @package Automattic\WooCommerce\Blocks\BlockTypes
*/
class MiniCartInteractivityDrawer {
/**
* Render the MiniCartInteractivityDrawer. Using the Interactivity body directive we render the drawer in the body.
*
* @return string|false
*/
public static function render() {
ob_start();
?>
<div data-wc-on--keydown="actions.handleEscapeKeyDown" class="wc-block-components-drawer__screen-overlay wc-block-components-drawer__screen-overlay--is-hidden">
<div data-wc-body class="wc-block-components-drawer" role="dialog" tab-index="-1">
<div className="wc-block-components-drawer__content" role="document">
<!-- TODO: CloseButtonPortal -->
<!-- TODO: children -->
</div>
</div>
</div>
</div>
<?php
return ob_get_clean();
}
}

View File

@ -14,26 +14,32 @@ class Drawer {
* @param mixed $props The properties to render the drawer with.
* children: string of the children to render.
* is_initially_open: boolean to indicate if the drawer is initially open.
* is_open_context: namespaced context that controls if the drawer is open.
* @return string|false
*/
public static function render( $props ) {
// wp_enqueue_script( 'wc-interactivity-checkbox-list' );
// wp_enqueue_style( 'wc-interactivity-checkbox-list' );
wp_enqueue_script( 'wc-interactivity-drawer' );
// wp_enqueue_style( 'wc-interactivity-drawer' );
$namespace = wp_json_encode( array( 'namespace' => 'woocommerce/interactivity-drawer' ), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP );
$context = array(
'isInitiallyOpen' => $props['is_initially_open'] ?? false,
'isOpen' => $props['is_initially_open'] ?? false,
'isInitiallyOpen' => $props['is_initially_open'] ?? false,
'isOpen' => $props['is_initially_open'] ?? false,
'isOpenContextProperty' => $props['is_open_context_property'] ?? 'woocommerce/interactivity-drawer',
'gday' => 'hi mate',
// 'slideClasses' => 'hi mate',
);
ob_start();
?>
<div data-wc-context="<?php echo wp_json_encode( $context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ); ?>" data-wc-interactive="<?php echo esc_attr( $namespace ); ?>" data-wc-on--keydown="actions.handleEscapeKeyDown" class="wc-block-components-drawer__screen-overlay wc-block-components-drawer__screen-overlay--is-hidden">
<div data-wc-body class="wc-block-components-drawer" role="dialog" tab-index="-1">
<div className="wc-block-components-drawer__content" role="document">
<!-- TODO: CloseButtonPortal -->
<?php echo wp_kses_post( $props['children'] ); ?>
<div data-wc-interactive="<?php echo esc_attr( $namespace ); ?>" data-wc-context="<?php echo esc_attr( wp_json_encode( $context ) ); ?>" >
<div class="wc-block-components-drawer__screen-overlay wc-block-components-drawer__screen-overlay--is-hidden" data-wc-on--keydown="actions.handleEscapeKeyDown" >
<p data-wc-text="state.slideClasses">Hi</p>
<div class="wc-block-components-drawer" role="dialog" tab-index="-1">
<div class="wc-block-components-drawer__content" role="document">
<!-- TODO: CloseButtonPortal -->
</div>
</div>
</div>
</div>