diff --git a/docs/contributors/code/coding-guidelines.md b/docs/contributors/code/coding-guidelines.md
index 9fc115b8eb9e3a..0404f579de4405 100644
--- a/docs/contributors/code/coding-guidelines.md
+++ b/docs/contributors/code/coding-guidelines.md
@@ -441,6 +441,19 @@ export function MyComponent() {
}
```
+#### Experimental editor settings
+
+WordPress extenders cannot update the experimental block settings on their own. The `updateSettings()` actions of the `@wordpress/block-editor` store will filter out all the settings that are **not** a part of the public API. The only way to actually store them is via private action. `__experimentalUpdateSettings()`.
+
+To privatize a block editor setting, add it to the `privateSettings` list in [/packages/block-editor/src/store/actions.js](/packages/block-editor/src/store/actions.js):
+
+```js
+const privateSettings = [
+ '__unstableInserterMediaCategories',
+ // List a block editor setting here to make it private
+];
+```
+
#### Experimental block.json and theme.json APIs
As of today, there is no way to restrict the `block.json` and `theme.json` APIs
diff --git a/package-lock.json b/package-lock.json
index 25ee3155936ada..ab1314afd8b2ab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17568,6 +17568,7 @@
"@wordpress/data": "file:packages/data",
"@wordpress/dom": "file:packages/dom",
"@wordpress/element": "file:packages/element",
+ "@wordpress/experiments": "file:packages/experiments",
"@wordpress/hooks": "file:packages/hooks",
"@wordpress/i18n": "file:packages/i18n",
"@wordpress/icons": "file:packages/icons",
@@ -17721,6 +17722,7 @@
"@wordpress/deprecated": "file:packages/deprecated",
"@wordpress/editor": "file:packages/editor",
"@wordpress/element": "file:packages/element",
+ "@wordpress/experiments": "file:packages/experiments",
"@wordpress/hooks": "file:packages/hooks",
"@wordpress/i18n": "file:packages/i18n",
"@wordpress/icons": "file:packages/icons",
@@ -17807,6 +17809,7 @@
"@wordpress/deprecated": "file:packages/deprecated",
"@wordpress/dom": "file:packages/dom",
"@wordpress/element": "file:packages/element",
+ "@wordpress/experiments": "file:packages/experiments",
"@wordpress/hooks": "file:packages/hooks",
"@wordpress/i18n": "file:packages/i18n",
"@wordpress/icons": "file:packages/icons",
@@ -17840,6 +17843,7 @@
"@wordpress/deprecated": "file:packages/deprecated",
"@wordpress/dom": "file:packages/dom",
"@wordpress/element": "file:packages/element",
+ "@wordpress/experiments": "file:packages/experiments",
"@wordpress/hooks": "file:packages/hooks",
"@wordpress/html-entities": "file:packages/html-entities",
"@wordpress/i18n": "file:packages/i18n",
diff --git a/packages/block-editor/src/components/block-mover/stories/index.js b/packages/block-editor/src/components/block-mover/stories/index.js
index aac98ecc84d6ed..de30260563f91e 100644
--- a/packages/block-editor/src/components/block-mover/stories/index.js
+++ b/packages/block-editor/src/components/block-mover/stories/index.js
@@ -11,7 +11,7 @@ import { Toolbar } from '@wordpress/components';
* Internal dependencies
*/
import BlockMover from '../';
-import BlockEditorProvider from '../../provider';
+import { ExperimentalBlockEditorProvider } from '../../provider';
import { store as blockEditorStore } from '../../../store';
registerCoreBlocks();
@@ -35,9 +35,9 @@ function Provider( { children } ) {
return (
-
+
{ children }
-
+
);
}
diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js
index 37ba4d1fe3a4cc..df3a7c174e6466 100644
--- a/packages/block-editor/src/components/block-preview/index.js
+++ b/packages/block-editor/src/components/block-preview/index.js
@@ -14,7 +14,7 @@ import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
*/
-import BlockEditorProvider from '../provider';
+import { ExperimentalBlockEditorProvider } from '../provider';
import AutoHeightBlockPreview from './auto';
import { store as blockEditorStore } from '../../store';
import { BlockListItems } from '../block-list';
@@ -66,13 +66,16 @@ export function BlockPreview( {
}
return (
-
+
-
+
);
}
@@ -126,12 +129,15 @@ export function useBlockPreview( {
);
const children = (
-
+
-
+
);
return {
diff --git a/packages/block-editor/src/components/inserter/stories/index.js b/packages/block-editor/src/components/inserter/stories/index.js
index f6949653c87872..960fd86b3bc8ff 100644
--- a/packages/block-editor/src/components/inserter/stories/index.js
+++ b/packages/block-editor/src/components/inserter/stories/index.js
@@ -2,7 +2,7 @@
* Internal dependencies
*/
import BlockLibrary from '../library';
-import BlockEditorProvider from '../../provider';
+import { ExperimentalBlockEditorProvider } from '../../provider';
import { patternCategories, patterns, reusableBlocks } from './utils/fixtures';
import Inserter from '../';
@@ -16,11 +16,11 @@ export const libraryWithoutPatterns = () => {
display: 'inline-block',
};
return (
-
+
-
+
);
};
@@ -32,7 +32,7 @@ export const libraryWithPatterns = () => {
display: 'inline-block',
};
return (
- {
-
+
);
};
@@ -53,7 +53,7 @@ export const libraryWithPatternsAndReusableBlocks = () => {
display: 'inline-block',
};
return (
- {
-
+
);
};
@@ -75,7 +75,7 @@ export const quickInserter = () => {
display: 'inline-block',
};
return (
- {
-
+
);
};
diff --git a/packages/block-editor/src/components/provider/index.js b/packages/block-editor/src/components/provider/index.js
index e9a9da86dc15ef..323ce68765c40a 100644
--- a/packages/block-editor/src/components/provider/index.js
+++ b/packages/block-editor/src/components/provider/index.js
@@ -11,24 +11,43 @@ import withRegistryProvider from './with-registry-provider';
import useBlockSync from './use-block-sync';
import { store as blockEditorStore } from '../../store';
import { BlockRefsProvider } from './block-refs-provider';
+import { unlock } from '../../experiments';
/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */
-function BlockEditorProvider( props ) {
- const { children, settings } = props;
+export const ExperimentalBlockEditorProvider = withRegistryProvider(
+ ( props ) => {
+ const { children, settings, stripExperimentalSettings = false } = props;
- const { updateSettings } = useDispatch( blockEditorStore );
- useEffect( () => {
- updateSettings( {
- ...settings,
- __internalIsInitialized: true,
- } );
- }, [ settings ] );
+ const { __experimentalUpdateSettings } = unlock(
+ useDispatch( blockEditorStore )
+ );
+ useEffect( () => {
+ __experimentalUpdateSettings(
+ {
+ ...settings,
+ __internalIsInitialized: true,
+ },
+ stripExperimentalSettings
+ );
+ }, [ settings ] );
- // Syncs the entity provider with changes in the block-editor store.
- useBlockSync( props );
+ // Syncs the entity provider with changes in the block-editor store.
+ useBlockSync( props );
- return { children };
-}
+ return { children };
+ }
+);
-export default withRegistryProvider( BlockEditorProvider );
+export const BlockEditorProvider = ( props ) => {
+ return (
+
+ { props.children }
+
+ );
+};
+
+export default BlockEditorProvider;
diff --git a/packages/block-editor/src/components/provider/index.native.js b/packages/block-editor/src/components/provider/index.native.js
index 8851a2b9b47a15..1bb790a20c19d2 100644
--- a/packages/block-editor/src/components/provider/index.native.js
+++ b/packages/block-editor/src/components/provider/index.native.js
@@ -14,7 +14,7 @@ import { BlockRefsProvider } from './block-refs-provider';
/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */
-function BlockEditorProvider( props ) {
+const BlockEditorProvider = withRegistryProvider( function ( props ) {
const { children, settings } = props;
const { updateSettings } = useDispatch( blockEditorStore );
@@ -26,6 +26,7 @@ function BlockEditorProvider( props ) {
useBlockSync( props );
return { children };
-}
+} );
-export default withRegistryProvider( BlockEditorProvider );
+export default BlockEditorProvider;
+export { BlockEditorProvider as ExperimentalBlockEditorProvider };
diff --git a/packages/block-editor/src/components/provider/test/experimental-provider.js b/packages/block-editor/src/components/provider/test/experimental-provider.js
new file mode 100644
index 00000000000000..5c0d27602685a5
--- /dev/null
+++ b/packages/block-editor/src/components/provider/test/experimental-provider.js
@@ -0,0 +1,98 @@
+/**
+ * External dependencies
+ */
+import { render } from '@testing-library/react';
+/**
+ * WordPress dependencies
+ */
+import { useRegistry } from '@wordpress/data';
+
+/**
+ * Internal dependencies
+ */
+import { BlockEditorProvider, ExperimentalBlockEditorProvider } from '../';
+import { store as blockEditorStore } from '../../../store';
+
+const HasEditorSetting = ( props ) => {
+ const registry = useRegistry();
+ if ( props.setRegistry ) {
+ props.setRegistry( registry );
+ }
+ return Test.
;
+};
+
+describe( 'BlockEditorProvider', () => {
+ let registry;
+ const setRegistry = ( reg ) => {
+ registry = reg;
+ };
+ beforeEach( () => {
+ registry = undefined;
+ } );
+ it( 'should strip experimental settings', async () => {
+ render(
+
+
+
+ );
+ const settings = registry.select( blockEditorStore ).getSettings();
+ expect( settings ).not.toHaveProperty(
+ '__unstableInserterMediaCategories'
+ );
+ } );
+ it( 'should preserve stable settings', async () => {
+ render(
+
+
+
+ );
+ const settings = registry.select( blockEditorStore ).getSettings();
+ expect( settings ).toHaveProperty( 'stableSetting' );
+ } );
+} );
+
+describe( 'ExperimentalBlockEditorProvider', () => {
+ let registry;
+ const setRegistry = ( reg ) => {
+ registry = reg;
+ };
+ beforeEach( () => {
+ registry = undefined;
+ } );
+ it( 'should preserve experimental settings', async () => {
+ render(
+
+
+
+ );
+ const settings = registry.select( blockEditorStore ).getSettings();
+ expect( settings ).toHaveProperty(
+ '__unstableInserterMediaCategories'
+ );
+ } );
+ it( 'should preserve stable settings', async () => {
+ render(
+
+
+
+ );
+ const settings = registry.select( blockEditorStore ).getSettings();
+ expect( settings ).toHaveProperty( 'stableSetting' );
+ } );
+} );
diff --git a/packages/block-editor/src/components/provider/test/use-block-sync.js b/packages/block-editor/src/components/provider/test/use-block-sync.js
index 9f8b091e52a10b..7901c3d98f3a92 100644
--- a/packages/block-editor/src/components/provider/test/use-block-sync.js
+++ b/packages/block-editor/src/components/provider/test/use-block-sync.js
@@ -14,7 +14,17 @@ import { render } from '@testing-library/react';
import useBlockSync from '../use-block-sync';
import withRegistryProvider from '../with-registry-provider';
import * as blockEditorActions from '../../../store/actions';
+
import { store as blockEditorStore } from '../../../store';
+jest.mock( '../../../store/actions', () => {
+ const actions = jest.requireActual( '../../../store/actions' );
+ return {
+ ...actions,
+ resetBlocks: jest.fn( actions.resetBlocks ),
+ replaceInnerBlocks: jest.fn( actions.replaceInnerBlocks ),
+ setHasControlledInnerBlocks: jest.fn( actions.replaceInnerBlocks ),
+ };
+} );
const TestWrapper = withRegistryProvider( ( props ) => {
if ( props.setRegistry ) {
diff --git a/packages/block-editor/src/experiments.js b/packages/block-editor/src/experiments.js
index b217e14ec273be..a12b3ac68ef6ef 100644
--- a/packages/block-editor/src/experiments.js
+++ b/packages/block-editor/src/experiments.js
@@ -7,6 +7,7 @@ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/exp
* Internal dependencies
*/
import * as globalStyles from './components/global-styles';
+import { ExperimentalBlockEditorProvider } from './components/provider';
export const { lock, unlock } =
__dangerousOptInToUnstableAPIsOnlyForCoreModules(
@@ -20,4 +21,5 @@ export const { lock, unlock } =
export const experiments = {};
lock( experiments, {
...globalStyles,
+ ExperimentalBlockEditorProvider,
} );
diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js
index e1c88c2bd99b49..426e6fae10bd91 100644
--- a/packages/block-editor/src/store/actions.js
+++ b/packages/block-editor/src/store/actions.js
@@ -16,6 +16,7 @@ import { speak } from '@wordpress/a11y';
import { __, _n, sprintf } from '@wordpress/i18n';
import { create, insert, remove, toHTMLString } from '@wordpress/rich-text';
import deprecated from '@wordpress/deprecated';
+import { Platform } from '@wordpress/element';
/**
* Internal dependencies
@@ -1442,9 +1443,45 @@ export function updateBlockListSettings( clientId, settings ) {
* @return {Object} Action object
*/
export function updateSettings( settings ) {
+ return __experimentalUpdateSettings( settings, true );
+}
+
+/**
+ * A list of private/experimental block editor settings that
+ * should not become a part of the WordPress public API.
+ * BlockEditorProvider will remove these settings from the
+ * settings object it receives.
+ *
+ * @see https://github.com/WordPress/gutenberg/pull/46131
+ */
+const privateSettings = [ '__unstableInserterMediaCategories' ];
+
+/**
+ * Action that updates the block editor settings and
+ * conditionally preserves the experimental ones.
+ *
+ * @param {Object} settings Updated settings
+ * @param {boolean} stripExperimentalSettings Whether to strip experimental settings.
+ * @return {Object} Action object
+ */
+export function __experimentalUpdateSettings(
+ settings,
+ stripExperimentalSettings = false
+) {
+ let cleanSettings = settings;
+ // There are no plugins in the mobile apps, so there is no
+ // need to strip the experimental settings:
+ if ( stripExperimentalSettings && Platform.OS === 'web' ) {
+ cleanSettings = {};
+ for ( const key in settings ) {
+ if ( ! privateSettings.includes( key ) ) {
+ cleanSettings[ key ] = settings[ key ];
+ }
+ }
+ }
return {
type: 'UPDATE_SETTINGS',
- settings,
+ settings: cleanSettings,
};
}
diff --git a/packages/block-editor/src/store/index.js b/packages/block-editor/src/store/index.js
index baa14b94ca9ad8..bad1ca2d62d610 100644
--- a/packages/block-editor/src/store/index.js
+++ b/packages/block-editor/src/store/index.js
@@ -8,8 +8,11 @@ import { createReduxStore, register } from '@wordpress/data';
*/
import reducer from './reducer';
import * as selectors from './selectors';
-import * as actions from './actions';
+import * as allActions from './actions';
import { STORE_NAME } from './constants';
+import { unlock } from '../experiments';
+
+const { __experimentalUpdateSettings, ...actions } = allActions;
/**
* Block editor data store configuration.
@@ -33,3 +36,7 @@ export const store = createReduxStore( STORE_NAME, {
} );
register( store );
+
+unlock( store ).registerPrivateActions( {
+ __experimentalUpdateSettings,
+} );
diff --git a/packages/customize-widgets/package.json b/packages/customize-widgets/package.json
index e12865cee03cd3..825baeb95815d9 100644
--- a/packages/customize-widgets/package.json
+++ b/packages/customize-widgets/package.json
@@ -33,6 +33,7 @@
"@wordpress/data": "file:../data",
"@wordpress/dom": "file:../dom",
"@wordpress/element": "file:../element",
+ "@wordpress/experiments": "file:../experiments",
"@wordpress/hooks": "file:../hooks",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
diff --git a/packages/customize-widgets/src/components/sidebar-block-editor/sidebar-editor-provider.js b/packages/customize-widgets/src/components/sidebar-block-editor/sidebar-editor-provider.js
index 95f6259de16bd2..a7be2fbd5969e1 100644
--- a/packages/customize-widgets/src/components/sidebar-block-editor/sidebar-editor-provider.js
+++ b/packages/customize-widgets/src/components/sidebar-block-editor/sidebar-editor-provider.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { BlockEditorProvider } from '@wordpress/block-editor';
+import { experiments as blockEditorExperiments } from '@wordpress/block-editor';
/**
* Internal dependencies
@@ -9,6 +9,10 @@ import { BlockEditorProvider } from '@wordpress/block-editor';
import useSidebarBlockEditor from './use-sidebar-block-editor';
import useBlocksFocusControl from '../focus-control/use-blocks-focus-control';
+import { unlock } from '../../experiments';
+
+const { ExperimentalBlockEditorProvider } = unlock( blockEditorExperiments );
+
export default function SidebarEditorProvider( {
sidebar,
settings,
@@ -19,7 +23,7 @@ export default function SidebarEditorProvider( {
useBlocksFocusControl( blocks );
return (
-
{ children }
-
+
);
}
diff --git a/packages/customize-widgets/src/experiments.js b/packages/customize-widgets/src/experiments.js
new file mode 100644
index 00000000000000..4c5366db618560
--- /dev/null
+++ b/packages/customize-widgets/src/experiments.js
@@ -0,0 +1,10 @@
+/**
+ * WordPress dependencies
+ */
+import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments';
+
+export const { lock, unlock } =
+ __dangerousOptInToUnstableAPIsOnlyForCoreModules(
+ 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.',
+ '@wordpress/customize-widgets'
+ );
diff --git a/packages/edit-navigation/src/experiments.js b/packages/edit-navigation/src/experiments.js
new file mode 100644
index 00000000000000..51758a5c3859d8
--- /dev/null
+++ b/packages/edit-navigation/src/experiments.js
@@ -0,0 +1,10 @@
+/**
+ * WordPress dependencies
+ */
+import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments';
+
+export const { lock, unlock } =
+ __dangerousOptInToUnstableAPIsOnlyForCoreModules(
+ 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.',
+ '@wordpress/edit-navigation'
+ );
diff --git a/packages/edit-post/package.json b/packages/edit-post/package.json
index 6deee3aef7bb7c..4656abd51e485c 100644
--- a/packages/edit-post/package.json
+++ b/packages/edit-post/package.json
@@ -39,6 +39,7 @@
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
+ "@wordpress/experiments": "file:../experiments",
"@wordpress/hooks": "file:../hooks",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
diff --git a/packages/edit-post/src/editor.js b/packages/edit-post/src/editor.js
index f696e6f4c25608..7fa7f33e9ef6e6 100644
--- a/packages/edit-post/src/editor.js
+++ b/packages/edit-post/src/editor.js
@@ -4,10 +4,10 @@
import { store as blocksStore } from '@wordpress/blocks';
import { useSelect, useDispatch } from '@wordpress/data';
import {
- EditorProvider,
ErrorBoundary,
PostLockedModal,
store as editorStore,
+ experiments as editorExperiments,
} from '@wordpress/editor';
import { StrictMode, useMemo } from '@wordpress/element';
import { SlotFillProvider } from '@wordpress/components';
@@ -21,6 +21,9 @@ import { store as preferencesStore } from '@wordpress/preferences';
import Layout from './components/layout';
import EditorInitialization from './components/editor-initialization';
import { store as editPostStore } from './store';
+import { unlock } from './experiments';
+
+const { ExperimentalEditorProvider } = unlock( editorExperiments );
function Editor( {
postId,
@@ -180,7 +183,7 @@ function Editor( {
-
-
+
diff --git a/packages/edit-post/src/experiments.js b/packages/edit-post/src/experiments.js
new file mode 100644
index 00000000000000..afe2e553e2af9a
--- /dev/null
+++ b/packages/edit-post/src/experiments.js
@@ -0,0 +1,10 @@
+/**
+ * WordPress dependencies
+ */
+import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments';
+
+export const { lock, unlock } =
+ __dangerousOptInToUnstableAPIsOnlyForCoreModules(
+ 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.',
+ '@wordpress/edit-post'
+ );
diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js
index 439d26bb7c50b5..d5a7dc7f5730a7 100644
--- a/packages/edit-site/src/components/block-editor/index.js
+++ b/packages/edit-site/src/components/block-editor/index.js
@@ -11,7 +11,6 @@ import { useCallback, useMemo, useRef } from '@wordpress/element';
import { useEntityBlockEditor, store as coreStore } from '@wordpress/core-data';
import {
BlockList,
- BlockEditorProvider,
__experimentalLinkControl,
BlockInspector,
BlockTools,
@@ -19,6 +18,7 @@ import {
__unstableUseTypingObserver as useTypingObserver,
BlockEditorKeyboardShortcuts,
store as blockEditorStore,
+ experiments as blockEditorExperiments,
} from '@wordpress/block-editor';
import {
useMergeRefs,
@@ -39,6 +39,9 @@ import BackButton from './back-button';
import ResizableEditor from './resizable-editor';
import EditorCanvas from './editor-canvas';
import StyleBook from '../style-book';
+import { unlock } from '../../experiments';
+
+const { ExperimentalBlockEditorProvider } = unlock( blockEditorExperiments );
const LAYOUT = {
type: 'default',
@@ -152,7 +155,7 @@ export default function BlockEditor() {
( isTemplatePart && hasBlocks ) || isViewMode ? false : undefined;
return (
-
-
+
);
}
diff --git a/packages/edit-widgets/package.json b/packages/edit-widgets/package.json
index 7ce6947537727e..f176deb220e264 100644
--- a/packages/edit-widgets/package.json
+++ b/packages/edit-widgets/package.json
@@ -38,6 +38,7 @@
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/dom": "file:../dom",
"@wordpress/element": "file:../element",
+ "@wordpress/experiments": "file:../experiments",
"@wordpress/hooks": "file:../hooks",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
diff --git a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
index 8aa616c867473d..917899d7dd99be 100644
--- a/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
+++ b/packages/edit-widgets/src/components/widget-areas-block-editor-provider/index.js
@@ -11,9 +11,9 @@ import {
} from '@wordpress/core-data';
import { useMemo } from '@wordpress/element';
import {
- BlockEditorProvider,
BlockEditorKeyboardShortcuts,
CopyHandler,
+ experiments as blockEditorExperiments,
} from '@wordpress/block-editor';
import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks';
import { ShortcutProvider } from '@wordpress/keyboard-shortcuts';
@@ -27,6 +27,9 @@ import { buildWidgetAreasPostId, KIND, POST_TYPE } from '../../store/utils';
import useLastSelectedWidgetArea from '../../hooks/use-last-selected-widget-area';
import { store as editWidgetsStore } from '../../store';
import { ALLOW_REUSABLE_BLOCKS } from '../../constants';
+import { unlock } from '../../experiments';
+
+const { ExperimentalBlockEditorProvider } = unlock( blockEditorExperiments );
export default function WidgetAreasBlockEditorProvider( {
blockEditorSettings,
@@ -100,7 +103,7 @@ export default function WidgetAreasBlockEditorProvider( {
-
{ children }
-
+
);
diff --git a/packages/edit-widgets/src/experiments.js b/packages/edit-widgets/src/experiments.js
new file mode 100644
index 00000000000000..7a5f0d03a3e596
--- /dev/null
+++ b/packages/edit-widgets/src/experiments.js
@@ -0,0 +1,10 @@
+/**
+ * WordPress dependencies
+ */
+import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments';
+
+export const { lock, unlock } =
+ __dangerousOptInToUnstableAPIsOnlyForCoreModules(
+ 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.',
+ '@wordpress/edit-widgets'
+ );
diff --git a/packages/editor/package.json b/packages/editor/package.json
index affe1d6dea89e2..5a074daf812239 100644
--- a/packages/editor/package.json
+++ b/packages/editor/package.json
@@ -44,6 +44,7 @@
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/dom": "file:../dom",
"@wordpress/element": "file:../element",
+ "@wordpress/experiments": "file:../experiments",
"@wordpress/hooks": "file:../hooks",
"@wordpress/html-entities": "file:../html-entities",
"@wordpress/i18n": "file:../i18n",
diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js
index ef8d03c824b7b1..2618fc33ad1a76 100644
--- a/packages/editor/src/components/provider/index.js
+++ b/packages/editor/src/components/provider/index.js
@@ -8,6 +8,7 @@ import { EntityProvider, useEntityBlockEditor } from '@wordpress/core-data';
import {
BlockEditorProvider,
BlockContextProvider,
+ experiments as blockEditorExperiments,
} from '@wordpress/block-editor';
import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks';
import { store as noticesStore } from '@wordpress/notices';
@@ -18,107 +19,128 @@ import { store as noticesStore } from '@wordpress/notices';
import withRegistryProvider from './with-registry-provider';
import { store as editorStore } from '../../store';
import useBlockEditorSettings from './use-block-editor-settings';
+import { unlock } from '../../lockUnlock';
-function EditorProvider( {
- __unstableTemplate,
- post,
- settings,
- recovery,
- initialEdits,
- children,
-} ) {
- const defaultBlockContext = useMemo( () => {
- if ( post.type === 'wp_template' ) {
- return {};
- }
- return { postId: post.id, postType: post.type };
- }, [ post.id, post.type ] );
- const { selection, isReady } = useSelect( ( select ) => {
- const { getEditorSelection, __unstableIsEditorReady } =
- select( editorStore );
- return {
- isReady: __unstableIsEditorReady(),
- selection: getEditorSelection(),
- };
- }, [] );
- const { id, type } = __unstableTemplate ?? post;
- const [ blocks, onInput, onChange ] = useEntityBlockEditor(
- 'postType',
- type,
- { id }
- );
- const editorSettings = useBlockEditorSettings(
+const { ExperimentalBlockEditorProvider } = unlock( blockEditorExperiments );
+
+export const ExperimentalEditorProvider = withRegistryProvider(
+ ( {
+ __unstableTemplate,
+ post,
settings,
- !! __unstableTemplate
- );
- const {
- updatePostLock,
- setupEditor,
- updateEditorSettings,
- __experimentalTearDownEditor,
- } = useDispatch( editorStore );
- const { createWarningNotice } = useDispatch( noticesStore );
+ recovery,
+ initialEdits,
+ children,
+ BlockEditorProviderComponent = ExperimentalBlockEditorProvider,
+ } ) => {
+ const defaultBlockContext = useMemo( () => {
+ if ( post.type === 'wp_template' ) {
+ return {};
+ }
+ return { postId: post.id, postType: post.type };
+ }, [ post.id, post.type ] );
+ const { selection, isReady } = useSelect( ( select ) => {
+ const { getEditorSelection, __unstableIsEditorReady } =
+ select( editorStore );
+ return {
+ isReady: __unstableIsEditorReady(),
+ selection: getEditorSelection(),
+ };
+ }, [] );
+ const { id, type } = __unstableTemplate ?? post;
+ const [ blocks, onInput, onChange ] = useEntityBlockEditor(
+ 'postType',
+ type,
+ { id }
+ );
+ const editorSettings = useBlockEditorSettings(
+ settings,
+ !! __unstableTemplate
+ );
+ const {
+ updatePostLock,
+ setupEditor,
+ updateEditorSettings,
+ __experimentalTearDownEditor,
+ } = useDispatch( editorStore );
+ const { createWarningNotice } = useDispatch( noticesStore );
- // Initialize and tear down the editor.
- // Ideally this should be synced on each change and not just something you do once.
- useLayoutEffect( () => {
- // Assume that we don't need to initialize in the case of an error recovery.
- if ( recovery ) {
- return;
- }
+ // Initialize and tear down the editor.
+ // Ideally this should be synced on each change and not just something you do once.
+ useLayoutEffect( () => {
+ // Assume that we don't need to initialize in the case of an error recovery.
+ if ( recovery ) {
+ return;
+ }
- updatePostLock( settings.postLock );
- setupEditor( post, initialEdits, settings.template );
- if ( settings.autosave ) {
- createWarningNotice(
- __(
- 'There is an autosave of this post that is more recent than the version below.'
- ),
- {
- id: 'autosave-exists',
- actions: [
- {
- label: __( 'View the autosave' ),
- url: settings.autosave.editLink,
- },
- ],
- }
- );
- }
+ updatePostLock( settings.postLock );
+ setupEditor( post, initialEdits, settings.template );
+ if ( settings.autosave ) {
+ createWarningNotice(
+ __(
+ 'There is an autosave of this post that is more recent than the version below.'
+ ),
+ {
+ id: 'autosave-exists',
+ actions: [
+ {
+ label: __( 'View the autosave' ),
+ url: settings.autosave.editLink,
+ },
+ ],
+ }
+ );
+ }
+
+ return () => {
+ __experimentalTearDownEditor();
+ };
+ }, [] );
- return () => {
- __experimentalTearDownEditor();
- };
- }, [] );
+ // Synchronize the editor settings as they change.
+ useEffect( () => {
+ updateEditorSettings( settings );
+ }, [ settings ] );
- // Synchronize the editor settings as they change.
- useEffect( () => {
- updateEditorSettings( settings );
- }, [ settings ] );
+ if ( ! isReady ) {
+ return null;
+ }
- if ( ! isReady ) {
- return null;
+ return (
+
+
+
+
+ { children }
+
+
+
+
+
+ );
}
+);
+export function EditorProvider( props ) {
return (
-
-
-
-
- { children }
-
-
-
-
-
+
+ { props.children }
+
);
}
-export default withRegistryProvider( EditorProvider );
+export default EditorProvider;
diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js
index 7679901bf37d2c..5b4148d5efef74 100644
--- a/packages/editor/src/components/provider/index.native.js
+++ b/packages/editor/src/components/provider/index.native.js
@@ -345,7 +345,7 @@ class NativeEditorProvider extends Component {
}
}
-export default compose( [
+const ComposedNativeProvider = compose( [
withSelect( ( select ) => {
const {
__unstableIsEditorReady: isEditorReady,
@@ -414,3 +414,6 @@ export default compose( [
};
} ),
] )( NativeEditorProvider );
+
+export default ComposedNativeProvider;
+export { ComposedNativeProvider as ExperimentalEditorProvider };
diff --git a/packages/editor/src/experiments.js b/packages/editor/src/experiments.js
new file mode 100644
index 00000000000000..c54c895d961a03
--- /dev/null
+++ b/packages/editor/src/experiments.js
@@ -0,0 +1,10 @@
+/**
+ * Internal dependencies
+ */
+import { ExperimentalEditorProvider } from './components/provider';
+import { lock } from './lockUnlock';
+
+export const experiments = {};
+lock( experiments, {
+ ExperimentalEditorProvider,
+} );
diff --git a/packages/editor/src/index.js b/packages/editor/src/index.js
index 31fe9a672a72d1..2651b6887723b6 100644
--- a/packages/editor/src/index.js
+++ b/packages/editor/src/index.js
@@ -6,6 +6,7 @@ import './hooks';
export { storeConfig, store } from './store';
export * from './components';
export * from './utils';
+export * from './experiments';
/*
* Backward compatibility
diff --git a/packages/editor/src/index.native.js b/packages/editor/src/index.native.js
index 35fcddf0b80030..3c599ddf6bec5e 100644
--- a/packages/editor/src/index.native.js
+++ b/packages/editor/src/index.native.js
@@ -13,3 +13,4 @@ import './hooks';
export { store } from './store';
export * from './components';
export * from './utils';
+export * from './experiments';
diff --git a/packages/editor/src/lockUnlock.js b/packages/editor/src/lockUnlock.js
new file mode 100644
index 00000000000000..0ca65646f0b3d9
--- /dev/null
+++ b/packages/editor/src/lockUnlock.js
@@ -0,0 +1,9 @@
+/**
+ * WordPress dependencies
+ */
+import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments';
+export const { lock, unlock } =
+ __dangerousOptInToUnstableAPIsOnlyForCoreModules(
+ 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.',
+ '@wordpress/editor'
+ );
diff --git a/packages/experiments/src/implementation.js b/packages/experiments/src/implementation.js
index b818a3669d8e7a..6ba5ef6dfa611f 100644
--- a/packages/experiments/src/implementation.js
+++ b/packages/experiments/src/implementation.js
@@ -11,9 +11,14 @@
*/
const CORE_MODULES_USING_EXPERIMENTS = [
'@wordpress/data',
+ '@wordpress/editor',
'@wordpress/blocks',
'@wordpress/block-editor',
+ '@wordpress/customize-widgets',
'@wordpress/edit-site',
+ '@wordpress/edit-post',
+ '@wordpress/edit-widgets',
+ '@wordpress/edit-navigation',
];
/**