From fd30676f6c13c9681a0eccad3628834cfa995f01 Mon Sep 17 00:00:00 2001 From: Sam Seay Date: Tue, 3 Sep 2024 15:23:25 +0800 Subject: [PATCH] Add support to open and close the drawer with the parent context --- .../mini-cart-interactivity/frontend.ts | 8 -- .../interactivity-components/drawer/index.ts | 100 ++++++++++++------ .../Blocks/InteractivityComponents/Drawer.php | 10 +- 3 files changed, 72 insertions(+), 46 deletions(-) diff --git a/plugins/woocommerce-blocks/assets/js/blocks/mini-cart-interactivity/frontend.ts b/plugins/woocommerce-blocks/assets/js/blocks/mini-cart-interactivity/frontend.ts index f42599604e0..4d87591871d 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/mini-cart-interactivity/frontend.ts +++ b/plugins/woocommerce-blocks/assets/js/blocks/mini-cart-interactivity/frontend.ts @@ -23,7 +23,6 @@ import { getMiniCartTotalsFromServer, } from './utils/data'; import setStyles from '../mini-cart/utils/set-styles'; -import { DrawerContext } from '../../../../packages/interactivity-components/drawer'; interface dependencyData { src: string; @@ -180,15 +179,8 @@ 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' ) - // ); - // } }, loadScripts: async () => { diff --git a/plugins/woocommerce-blocks/packages/interactivity-components/drawer/index.ts b/plugins/woocommerce-blocks/packages/interactivity-components/drawer/index.ts index 78bec17a807..2471826fec0 100644 --- a/plugins/woocommerce-blocks/packages/interactivity-components/drawer/index.ts +++ b/plugins/woocommerce-blocks/packages/interactivity-components/drawer/index.ts @@ -9,47 +9,83 @@ export type DrawerContext = { isOpenContextProperty: string; }; -console.log('store woocommerce/interactivity-drawer'); +const getIsOpenFromContext = ( context: DrawerContext, parentContext: any ) => { + const isOpenContextProperty = context.isOpenContextProperty; + + if ( isOpenContextProperty.split( '::' ).length === 2 ) { + const [ , property ] = isOpenContextProperty.split( '::' ); + return parentContext[ property.split( '.' )[ 1 ] ]; + } + + return false; +}; + +const getParentContextPropertyName = ( namespace: string ) => { + if ( namespace.split( '::' ).length === 2 ) { + const [ , property ] = namespace.split( '::' ); + return property.split( '.' )[ 1 ]; + } + + return ''; +}; + +const getParentContextNamespace = ( namespace: string ) => { + if ( namespace.split( '::' ).length === 2 ) { + return namespace.split( '::' )[ 0 ]; + } + + return ''; +}; store( 'woocommerce/interactivity-drawer', { state: { - get gday() { - return 'hi frontend'; - - }, - get slideClasses() { - console.log('slideClasses'); const context = getContext< DrawerContext >(); + const parentContext = getContext( + getParentContextNamespace( context.isOpenContextProperty ) + ); + const isOpen = getIsOpenFromContext( context, parentContext ); - const isOpenContextProperty = context.isOpenContextProperty; + const baseClass = + 'wc-block-components-drawer__screen-overlay wc-block-components-drawer__screen-overlay'; + const slide = isOpen + ? '--with-slide-in' + : '--with-slide-out wc-block-components-drawer__screen-overlay--is-hidden'; - 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 ''; + return `${ baseClass }${ slide }`; }, }, - actions: { - handleEscapeKeyDown: ( e: KeyboardEvent ) => { - const context = getContext< DrawerContext >(); - if ( e.code === 'Escape' && ! e.defaultPrevented ) { - e.preventDefault(); - context.isOpen = false; - } - } + actions: { + initialize: () => { + const context = getContext< DrawerContext >(); + const parentContext = getContext( + getParentContextNamespace( context.isOpenContextProperty ) + ); + + const handleEscapeKey = ( e: KeyboardEvent ) => { + if ( e.code === 'Escape' && ! e.defaultPrevented ) { + e.preventDefault(); + + const parentContextPropertyName = + getParentContextPropertyName( + context.isOpenContextProperty + ); + + parentContext[ parentContextPropertyName ] = false; + } + }; + + // Attach keydown event listener to document - note that when we update Interactivity API we can use on-window directive to handle this. + document.addEventListener( 'keydown', handleEscapeKey ); + + // Set initial open state + context.isOpen = context.isInitiallyOpen; + + // Return a cleanup function to remove the event listener + return () => { + document.removeEventListener( 'keydown', handleEscapeKey ); + }; + }, }, } ); diff --git a/plugins/woocommerce/src/Blocks/InteractivityComponents/Drawer.php b/plugins/woocommerce/src/Blocks/InteractivityComponents/Drawer.php index ccc457e17d7..7f6de1f3506 100644 --- a/plugins/woocommerce/src/Blocks/InteractivityComponents/Drawer.php +++ b/plugins/woocommerce/src/Blocks/InteractivityComponents/Drawer.php @@ -12,7 +12,7 @@ class Drawer { * Render the drawer. * * @param mixed $props The properties to render the drawer with. - * children: string of the children to render. + * children: string of the children to render. Please ensure that you take responsibility to escape attributes and values in the passed HTML. * 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 @@ -26,19 +26,17 @@ class Drawer { '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(); ?> -
-
-

Hi

+
+