[Product Block Editor]: Handle Modal Editor visibility from UI state (#41859)
This commit is contained in:
commit
37e824eca8
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: add
|
||||
|
||||
[Product Block Editor]: introduce UI state
|
|
@ -2,13 +2,14 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createElement, useState } from '@wordpress/element';
|
||||
import { createElement } from '@wordpress/element';
|
||||
import {
|
||||
BlockAttributes,
|
||||
BlockInstance,
|
||||
parse,
|
||||
serialize,
|
||||
} from '@wordpress/blocks';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
import { Button } from '@wordpress/components';
|
||||
import { useWooBlockProps } from '@woocommerce/block-templates';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
@ -21,6 +22,7 @@ import { ContentPreview } from '../../../components/content-preview';
|
|||
import { ModalEditor } from '../../../components/modal-editor';
|
||||
import { ProductEditorBlockEditProps } from '../../../types';
|
||||
import ModalEditorWelcomeGuide from '../../../components/modal-editor-welcome-guide';
|
||||
import { store as productEditorUiStore } from '../../../store/product-editor-ui';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -50,19 +52,26 @@ export function DescriptionBlockEdit( {
|
|||
attributes,
|
||||
}: ProductEditorBlockEditProps< BlockAttributes > ) {
|
||||
const blockProps = useWooBlockProps( attributes );
|
||||
const [ isModalOpen, setIsModalOpen ] = useState( false );
|
||||
const [ description, setDescription ] = useEntityProp< string >(
|
||||
'postType',
|
||||
'product',
|
||||
'description'
|
||||
);
|
||||
|
||||
// Check if the Modal editor is open from the store.
|
||||
const isModalEditorOpen = useSelect( ( select ) => {
|
||||
return select( productEditorUiStore ).isModalEditorOpen();
|
||||
}, [] );
|
||||
|
||||
const { openModalEditor, closeModalEditor } =
|
||||
useDispatch( productEditorUiStore );
|
||||
|
||||
return (
|
||||
<div { ...blockProps }>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ () => {
|
||||
setIsModalOpen( true );
|
||||
openModalEditor();
|
||||
recordEvent( 'product_add_description_click' );
|
||||
} }
|
||||
>
|
||||
|
@ -70,7 +79,8 @@ export function DescriptionBlockEdit( {
|
|||
? __( 'Edit description', 'woocommerce' )
|
||||
: __( 'Add description', 'woocommerce' ) }
|
||||
</Button>
|
||||
{ isModalOpen && (
|
||||
|
||||
{ isModalEditorOpen && (
|
||||
<ModalEditor
|
||||
initialBlocks={ parse( description ) }
|
||||
onChange={ ( blocks ) => {
|
||||
|
@ -79,14 +89,16 @@ export function DescriptionBlockEdit( {
|
|||
);
|
||||
setDescription( html );
|
||||
} }
|
||||
onClose={ () => setIsModalOpen( false ) }
|
||||
onClose={ closeModalEditor }
|
||||
title={ __( 'Edit description', 'woocommerce' ) }
|
||||
/>
|
||||
) }
|
||||
|
||||
{ !! description.length && (
|
||||
<ContentPreview content={ description } />
|
||||
) }
|
||||
{ isModalOpen && <ModalEditorWelcomeGuide /> }
|
||||
|
||||
{ isModalEditorOpen && <ModalEditorWelcomeGuide /> }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import registerProductEditorUiStore from './store/product-editor-ui';
|
||||
|
||||
export * from './components';
|
||||
export {
|
||||
DETAILS_SECTION_ID,
|
||||
|
@ -16,6 +21,11 @@ export * from './types';
|
|||
*/
|
||||
export * from './utils';
|
||||
|
||||
/*
|
||||
* Store
|
||||
*/
|
||||
export * from './store/product-editor-ui';
|
||||
|
||||
/**
|
||||
* Hooks
|
||||
*/
|
||||
|
@ -23,3 +33,6 @@ export * from './hooks';
|
|||
export { PostTypeContext } from './contexts/post-type-context';
|
||||
export { useValidation, useValidations } from './contexts/validation-context';
|
||||
export * from './contexts/validation-context/types';
|
||||
|
||||
// Init the store
|
||||
registerProductEditorUiStore();
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# WooCommerce Product Editor UI Store
|
||||
|
||||
This module provides a @wordpress/data store for managing the UI state of a WooCommerce Product Editor.
|
||||
|
||||
## Structure
|
||||
|
||||
Defines action types for the UI state:
|
||||
- `ACTION_MODAL_EDITOR_OPEN`
|
||||
- `ACTION_MODAL_EDITOR_CLOSE`
|
||||
|
||||
### Actions
|
||||
|
||||
- `openModalEditor`
|
||||
- `closeModalEditor`
|
||||
|
||||
### Selectors
|
||||
|
||||
Selector function:
|
||||
|
||||
- `isModalEditorOpen`
|
||||
|
||||
|
||||
### Store
|
||||
|
||||
Registers the WooCommerce Product Editor UI store with the following:
|
||||
|
||||
- Store Name: `woo/product-editor-ui`
|
||||
|
||||
## Usage
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
ACTION_MODAL_EDITOR_CLOSE,
|
||||
ACTION_MODAL_EDITOR_OPEN,
|
||||
} from './constants';
|
||||
|
||||
const modalEditorActions = {
|
||||
openModalEditor: () => ( {
|
||||
type: ACTION_MODAL_EDITOR_OPEN,
|
||||
} ),
|
||||
closeModalEditor: () => ( {
|
||||
type: ACTION_MODAL_EDITOR_CLOSE,
|
||||
} ),
|
||||
};
|
||||
|
||||
export default {
|
||||
...modalEditorActions,
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* Full editor actions
|
||||
*/
|
||||
export const ACTION_MODAL_EDITOR_OPEN = 'MODAL_EDITOROPEN';
|
||||
export const ACTION_MODAL_EDITOR_CLOSE = 'MODAL_EDITORCLOSE';
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createReduxStore, register } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import actions from './actions';
|
||||
import selectors from './selectors';
|
||||
import reducer from './reducer';
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
|
||||
export const store = 'woo/product-editor-ui';
|
||||
|
||||
const wooProductEditorUiStore = createReduxStore( store, {
|
||||
actions,
|
||||
selectors,
|
||||
reducer,
|
||||
} );
|
||||
|
||||
export default function registerProductEditorUiStore() {
|
||||
register( wooProductEditorUiStore );
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
ACTION_MODAL_EDITOR_CLOSE,
|
||||
ACTION_MODAL_EDITOR_OPEN,
|
||||
} from './constants';
|
||||
import type {
|
||||
ProductEditorModalEditorAction,
|
||||
ProductEditorUIStateProps,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* Types & Constants
|
||||
*/
|
||||
const INITIAL_STATE: ProductEditorUIStateProps = {
|
||||
modalEditor: {
|
||||
isOpen: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default function reducer(
|
||||
state = INITIAL_STATE,
|
||||
action: ProductEditorModalEditorAction
|
||||
) {
|
||||
switch ( action.type ) {
|
||||
case ACTION_MODAL_EDITOR_OPEN:
|
||||
return {
|
||||
...state,
|
||||
modalEditor: {
|
||||
isOpen: true,
|
||||
},
|
||||
};
|
||||
case ACTION_MODAL_EDITOR_CLOSE:
|
||||
return {
|
||||
...state,
|
||||
modalEditor: {
|
||||
isOpen: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
|
||||
import type { ProductEditorUIStateProps } from './types';
|
||||
|
||||
export default {
|
||||
isModalEditorOpen: function isModalEditorOpen(
|
||||
state: ProductEditorUIStateProps
|
||||
) {
|
||||
return state.modalEditor.isOpen;
|
||||
},
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import {
|
||||
ACTION_MODAL_EDITOR_CLOSE,
|
||||
ACTION_MODAL_EDITOR_OPEN,
|
||||
} from './constants';
|
||||
|
||||
export type ProductEditorUIStateProps = {
|
||||
modalEditor: {
|
||||
isOpen: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type ProductEditorModalEditorAction = {
|
||||
type: typeof ACTION_MODAL_EDITOR_OPEN | typeof ACTION_MODAL_EDITOR_CLOSE;
|
||||
};
|
Loading…
Reference in New Issue