Add support to open and close the drawer with the parent context

This commit is contained in:
Sam Seay 2024-09-03 15:23:25 +08:00
parent 01bfa56551
commit fd30676f6c
No known key found for this signature in database
GPG Key ID: 2223711A9151668A
3 changed files with 72 additions and 46 deletions

View File

@ -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 () => {

View File

@ -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 );
};
},
},
} );

View File

@ -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();
?>
<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 data-wc-body data-wc-init="actions.initialize" data-wc-interactive="<?php echo esc_attr( $namespace ); ?>" data-wc-context="<?php echo esc_attr( wp_json_encode( $context ) ); ?>" >
<div tab-index="0" data-wc-bind--class="state.slideClasses" class="wc-block-components-drawer__screen-overlay wc-block-components-drawer__screen-overlay--is-hidden" >
<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>