diff --git a/packages/js/product-editor/changelog/update-handle-modal-editor-from-store b/packages/js/product-editor/changelog/update-handle-modal-editor-from-store
new file mode 100644
index 00000000000..13287682bd5
--- /dev/null
+++ b/packages/js/product-editor/changelog/update-handle-modal-editor-from-store
@@ -0,0 +1,4 @@
+Significance: patch
+Type: add
+
+[Product Block Editor]: introduce UI state
diff --git a/packages/js/product-editor/src/blocks/product-fields/description/edit.tsx b/packages/js/product-editor/src/blocks/product-fields/description/edit.tsx
index edc33457ee5..4e2e1078000 100644
--- a/packages/js/product-editor/src/blocks/product-fields/description/edit.tsx
+++ b/packages/js/product-editor/src/blocks/product-fields/description/edit.tsx
@@ -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 (
- { isModalOpen && (
+
+ { isModalEditorOpen && (
{
@@ -79,14 +89,16 @@ export function DescriptionBlockEdit( {
);
setDescription( html );
} }
- onClose={ () => setIsModalOpen( false ) }
+ onClose={ closeModalEditor }
title={ __( 'Edit description', 'woocommerce' ) }
/>
) }
+
{ !! description.length && (
) }
- { isModalOpen && }
+
+ { isModalEditorOpen && }
);
}
diff --git a/packages/js/product-editor/src/index.ts b/packages/js/product-editor/src/index.ts
index ad5ae2a28fb..55964e55a03 100644
--- a/packages/js/product-editor/src/index.ts
+++ b/packages/js/product-editor/src/index.ts
@@ -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();
diff --git a/packages/js/product-editor/src/store/product-editor-ui/Readme.md b/packages/js/product-editor/src/store/product-editor-ui/Readme.md
new file mode 100644
index 00000000000..e11c8b40b13
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/Readme.md
@@ -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
diff --git a/packages/js/product-editor/src/store/product-editor-ui/actions.ts b/packages/js/product-editor/src/store/product-editor-ui/actions.ts
new file mode 100644
index 00000000000..3e1c44fe03e
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/actions.ts
@@ -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,
+};
diff --git a/packages/js/product-editor/src/store/product-editor-ui/constants.ts b/packages/js/product-editor/src/store/product-editor-ui/constants.ts
new file mode 100644
index 00000000000..5fe6baa0ee0
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/constants.ts
@@ -0,0 +1,5 @@
+/**
+ * Full editor actions
+ */
+export const ACTION_MODAL_EDITOR_OPEN = 'MODAL_EDITOROPEN';
+export const ACTION_MODAL_EDITOR_CLOSE = 'MODAL_EDITORCLOSE';
diff --git a/packages/js/product-editor/src/store/product-editor-ui/index.ts b/packages/js/product-editor/src/store/product-editor-ui/index.ts
new file mode 100644
index 00000000000..d3029a0be3a
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/index.ts
@@ -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 );
+}
diff --git a/packages/js/product-editor/src/store/product-editor-ui/reducer.ts b/packages/js/product-editor/src/store/product-editor-ui/reducer.ts
new file mode 100644
index 00000000000..8f48c3fb27f
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/reducer.ts
@@ -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;
+}
diff --git a/packages/js/product-editor/src/store/product-editor-ui/selectors.ts b/packages/js/product-editor/src/store/product-editor-ui/selectors.ts
new file mode 100644
index 00000000000..bced6734a3b
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/selectors.ts
@@ -0,0 +1,13 @@
+/**
+ * Internal dependencies
+ */
+
+import type { ProductEditorUIStateProps } from './types';
+
+export default {
+ isModalEditorOpen: function isModalEditorOpen(
+ state: ProductEditorUIStateProps
+ ) {
+ return state.modalEditor.isOpen;
+ },
+};
diff --git a/packages/js/product-editor/src/store/product-editor-ui/types.ts b/packages/js/product-editor/src/store/product-editor-ui/types.ts
new file mode 100644
index 00000000000..1ef8c1a8e04
--- /dev/null
+++ b/packages/js/product-editor/src/store/product-editor-ui/types.ts
@@ -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;
+};